15ca02815Sjsg /* 27ccd5a2cSjsg * \file radeon_drv.c 37ccd5a2cSjsg * ATI Radeon driver 47ccd5a2cSjsg * 57ccd5a2cSjsg * \author Gareth Hughes <gareth@valinux.com> 67ccd5a2cSjsg */ 77ccd5a2cSjsg 87ccd5a2cSjsg /* 97ccd5a2cSjsg * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 107ccd5a2cSjsg * All Rights Reserved. 117ccd5a2cSjsg * 127ccd5a2cSjsg * Permission is hereby granted, free of charge, to any person obtaining a 137ccd5a2cSjsg * copy of this software and associated documentation files (the "Software"), 147ccd5a2cSjsg * to deal in the Software without restriction, including without limitation 157ccd5a2cSjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 167ccd5a2cSjsg * and/or sell copies of the Software, and to permit persons to whom the 177ccd5a2cSjsg * Software is furnished to do so, subject to the following conditions: 187ccd5a2cSjsg * 197ccd5a2cSjsg * The above copyright notice and this permission notice (including the next 207ccd5a2cSjsg * paragraph) shall be included in all copies or substantial portions of the 217ccd5a2cSjsg * Software. 227ccd5a2cSjsg * 237ccd5a2cSjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 247ccd5a2cSjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 257ccd5a2cSjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 267ccd5a2cSjsg * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 277ccd5a2cSjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 287ccd5a2cSjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 297ccd5a2cSjsg * OTHER DEALINGS IN THE SOFTWARE. 307ccd5a2cSjsg */ 317ccd5a2cSjsg 327ccd5a2cSjsg 33c349dbc7Sjsg #include <linux/compat.h> 347f4dd379Sjsg #include <linux/module.h> 357f4dd379Sjsg #include <linux/pm_runtime.h> 367f4dd379Sjsg #include <linux/vga_switcheroo.h> 37c349dbc7Sjsg #include <linux/mmu_notifier.h> 38ad8b1aafSjsg #include <linux/pci.h> 397ccd5a2cSjsg 405ca02815Sjsg #include <drm/drm_aperture.h> 41c349dbc7Sjsg #include <drm/drm_drv.h> 42c349dbc7Sjsg #include <drm/drm_file.h> 43c349dbc7Sjsg #include <drm/drm_gem.h> 44c349dbc7Sjsg #include <drm/drm_ioctl.h> 45c349dbc7Sjsg #include <drm/drm_pciids.h> 46c349dbc7Sjsg #include <drm/drm_probe_helper.h> 47c349dbc7Sjsg #include <drm/drm_vblank.h> 48c349dbc7Sjsg #include <drm/radeon_drm.h> 49c349dbc7Sjsg 50c349dbc7Sjsg #include "radeon_drv.h" 51c349dbc7Sjsg #include "radeon.h" 525ca02815Sjsg #include "radeon_kms.h" 535ca02815Sjsg #include "radeon_ttm.h" 545ca02815Sjsg #include "radeon_device.h" 555ca02815Sjsg #include "radeon_prime.h" 567ccd5a2cSjsg 577ccd5a2cSjsg /* 587ccd5a2cSjsg * KMS wrapper. 597ccd5a2cSjsg * - 2.0.0 - initial interface 607ccd5a2cSjsg * - 2.1.0 - add square tiling interface 617ccd5a2cSjsg * - 2.2.0 - add r6xx/r7xx const buffer support 627ccd5a2cSjsg * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs 637ccd5a2cSjsg * - 2.4.0 - add crtc id query 647ccd5a2cSjsg * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen 657ccd5a2cSjsg * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) 667ccd5a2cSjsg * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs 677ccd5a2cSjsg * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query 687ccd5a2cSjsg * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query 697ccd5a2cSjsg * 2.10.0 - fusion 2D tiling 707ccd5a2cSjsg * 2.11.0 - backend map, initial compute support for the CS checker 717ccd5a2cSjsg * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS 727ccd5a2cSjsg * 2.13.0 - virtual memory support, streamout 737ccd5a2cSjsg * 2.14.0 - add evergreen tiling informations 747ccd5a2cSjsg * 2.15.0 - add max_pipes query 757ccd5a2cSjsg * 2.16.0 - fix evergreen 2D tiled surface calculation 767ccd5a2cSjsg * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx 777ccd5a2cSjsg * 2.18.0 - r600-eg: allow "invalid" DB formats 787ccd5a2cSjsg * 2.19.0 - r600-eg: MSAA textures 797ccd5a2cSjsg * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query 807ccd5a2cSjsg * 2.21.0 - r600-r700: FMASK and CMASK 817ccd5a2cSjsg * 2.22.0 - r600 only: RESOLVE_BOX allowed 827ccd5a2cSjsg * 2.23.0 - allow STRMOUT_BASE_UPDATE on RS780 and RS880 837ccd5a2cSjsg * 2.24.0 - eg only: allow MIP_ADDRESS=0 for MSAA textures 847ccd5a2cSjsg * 2.25.0 - eg+: new info request for num SE and num SH 857ccd5a2cSjsg * 2.26.0 - r600-eg: fix htile size computation 867ccd5a2cSjsg * 2.27.0 - r600-SI: Add CS ioctl support for async DMA 877ccd5a2cSjsg * 2.28.0 - r600-eg: Add MEM_WRITE packet support 887ccd5a2cSjsg * 2.29.0 - R500 FP16 color clear registers 897ccd5a2cSjsg * 2.30.0 - fix for FMASK texturing 907ccd5a2cSjsg * 2.31.0 - Add fastfb support for rs690 917ccd5a2cSjsg * 2.32.0 - new info request for rings working 927ccd5a2cSjsg * 2.33.0 - Add SI tiling mode array query 937ccd5a2cSjsg * 2.34.0 - Add CIK tiling mode array query 947ccd5a2cSjsg * 2.35.0 - Add CIK macrotile mode array query 957ccd5a2cSjsg * 2.36.0 - Fix CIK DCE tiling setup 967ccd5a2cSjsg * 2.37.0 - allow GS ring setup on r6xx/r7xx 977ccd5a2cSjsg * 2.38.0 - RADEON_GEM_OP (GET_INITIAL_DOMAIN, SET_INITIAL_DOMAIN), 987ccd5a2cSjsg * CIK: 1D and linear tiling modes contain valid PIPE_CONFIG 997ccd5a2cSjsg * 2.39.0 - Add INFO query for number of active CUs 1007ccd5a2cSjsg * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting 1017ccd5a2cSjsg * CS to GPU on >= r600 1027ccd5a2cSjsg * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support 1037ccd5a2cSjsg * 2.42.0 - Add VCE/VUI (Video Usability Information) support 1047ccd5a2cSjsg * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER 1057f4dd379Sjsg * 2.44.0 - SET_APPEND_CNT packet3 support 1067f4dd379Sjsg * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI 1077f4dd379Sjsg * 2.46.0 - Add PFP_SYNC_ME support on evergreen 1087f4dd379Sjsg * 2.47.0 - Add UVD_NO_OP register support 1097f4dd379Sjsg * 2.48.0 - TA_CS_BC_BASE_ADDR allowed on SI 1107f4dd379Sjsg * 2.49.0 - DRM_RADEON_GEM_INFO ioctl returns correct vram_size/visible values 1117f4dd379Sjsg * 2.50.0 - Allows unaligned shader loads on CIK. (needed by OpenGL) 1127ccd5a2cSjsg */ 1137ccd5a2cSjsg #define KMS_DRIVER_MAJOR 2 1147f4dd379Sjsg #define KMS_DRIVER_MINOR 50 1157ccd5a2cSjsg #define KMS_DRIVER_PATCHLEVEL 0 1167ccd5a2cSjsg 1177ccd5a2cSjsg int radeon_no_wb; 1187ccd5a2cSjsg int radeon_modeset = -1; 1197ccd5a2cSjsg int radeon_dynclks = -1; 120f005ef32Sjsg int radeon_r4xx_atom; 1217f4dd379Sjsg int radeon_agpmode = -1; 122f005ef32Sjsg int radeon_vram_limit; 1237ccd5a2cSjsg int radeon_gart_size = -1; /* auto */ 124f005ef32Sjsg int radeon_benchmarking; 125f005ef32Sjsg int radeon_testing; 126f005ef32Sjsg int radeon_connector_table; 1277ccd5a2cSjsg int radeon_tv = 1; 1287ccd5a2cSjsg int radeon_audio = -1; 129f005ef32Sjsg int radeon_disp_priority; 130f005ef32Sjsg int radeon_hw_i2c; 1317ccd5a2cSjsg int radeon_pcie_gen2 = -1; 1327ccd5a2cSjsg int radeon_msi = -1; 1337ccd5a2cSjsg int radeon_lockup_timeout = 10000; 134f005ef32Sjsg int radeon_fastfb; 1357ccd5a2cSjsg int radeon_dpm = -1; 1367ccd5a2cSjsg int radeon_aspm = -1; 1377ccd5a2cSjsg int radeon_runtime_pm = -1; 138f005ef32Sjsg int radeon_hard_reset; 1397ccd5a2cSjsg int radeon_vm_size = 8; 1407ccd5a2cSjsg int radeon_vm_block_size = -1; 141f005ef32Sjsg int radeon_deep_color; 1427ccd5a2cSjsg int radeon_use_pflipirq = 2; 1437ccd5a2cSjsg int radeon_bapm = -1; 1447ccd5a2cSjsg int radeon_backlight = -1; 1457ccd5a2cSjsg int radeon_auxch = -1; 1467f4dd379Sjsg int radeon_uvd = 1; 1477f4dd379Sjsg int radeon_vce = 1; 1487ccd5a2cSjsg 1497ccd5a2cSjsg MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 1507ccd5a2cSjsg module_param_named(no_wb, radeon_no_wb, int, 0444); 1517ccd5a2cSjsg 1527ccd5a2cSjsg MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 1537ccd5a2cSjsg module_param_named(modeset, radeon_modeset, int, 0400); 1547ccd5a2cSjsg 1557ccd5a2cSjsg MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks"); 1567ccd5a2cSjsg module_param_named(dynclks, radeon_dynclks, int, 0444); 1577ccd5a2cSjsg 1587ccd5a2cSjsg MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx"); 1597ccd5a2cSjsg module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444); 1607ccd5a2cSjsg 1617ccd5a2cSjsg MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); 1627ccd5a2cSjsg module_param_named(vramlimit, radeon_vram_limit, int, 0600); 1637ccd5a2cSjsg 1647ccd5a2cSjsg MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); 1657ccd5a2cSjsg module_param_named(agpmode, radeon_agpmode, int, 0444); 1667ccd5a2cSjsg 1677ccd5a2cSjsg MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc., -1 = auto)"); 1687ccd5a2cSjsg module_param_named(gartsize, radeon_gart_size, int, 0600); 1697ccd5a2cSjsg 1707ccd5a2cSjsg MODULE_PARM_DESC(benchmark, "Run benchmark"); 1717ccd5a2cSjsg module_param_named(benchmark, radeon_benchmarking, int, 0444); 1727ccd5a2cSjsg 1737ccd5a2cSjsg MODULE_PARM_DESC(test, "Run tests"); 1747ccd5a2cSjsg module_param_named(test, radeon_testing, int, 0444); 1757ccd5a2cSjsg 1767ccd5a2cSjsg MODULE_PARM_DESC(connector_table, "Force connector table"); 1777ccd5a2cSjsg module_param_named(connector_table, radeon_connector_table, int, 0444); 1787ccd5a2cSjsg 1797ccd5a2cSjsg MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); 1807ccd5a2cSjsg module_param_named(tv, radeon_tv, int, 0444); 1817ccd5a2cSjsg 1827ccd5a2cSjsg MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)"); 1837ccd5a2cSjsg module_param_named(audio, radeon_audio, int, 0444); 1847ccd5a2cSjsg 1857ccd5a2cSjsg MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)"); 1867ccd5a2cSjsg module_param_named(disp_priority, radeon_disp_priority, int, 0444); 1877ccd5a2cSjsg 1887ccd5a2cSjsg MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); 1897ccd5a2cSjsg module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); 1907ccd5a2cSjsg 1917ccd5a2cSjsg MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (-1 = auto, 0 = disable, 1 = enable)"); 1927ccd5a2cSjsg module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); 1937ccd5a2cSjsg 1947ccd5a2cSjsg MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); 1957ccd5a2cSjsg module_param_named(msi, radeon_msi, int, 0444); 1967ccd5a2cSjsg 1977ccd5a2cSjsg MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default 10000 = 10 seconds, 0 = disable)"); 1987ccd5a2cSjsg module_param_named(lockup_timeout, radeon_lockup_timeout, int, 0444); 1997ccd5a2cSjsg 2007ccd5a2cSjsg MODULE_PARM_DESC(fastfb, "Direct FB access for IGP chips (0 = disable, 1 = enable)"); 2017ccd5a2cSjsg module_param_named(fastfb, radeon_fastfb, int, 0444); 2027ccd5a2cSjsg 2037ccd5a2cSjsg MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); 2047ccd5a2cSjsg module_param_named(dpm, radeon_dpm, int, 0444); 2057ccd5a2cSjsg 2067ccd5a2cSjsg MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); 2077ccd5a2cSjsg module_param_named(aspm, radeon_aspm, int, 0444); 2087ccd5a2cSjsg 2097ccd5a2cSjsg MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); 2107ccd5a2cSjsg module_param_named(runpm, radeon_runtime_pm, int, 0444); 2117ccd5a2cSjsg 2127ccd5a2cSjsg MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))"); 2137ccd5a2cSjsg module_param_named(hard_reset, radeon_hard_reset, int, 0444); 2147ccd5a2cSjsg 2157ccd5a2cSjsg MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 4GB)"); 2167ccd5a2cSjsg module_param_named(vm_size, radeon_vm_size, int, 0444); 2177ccd5a2cSjsg 2187ccd5a2cSjsg MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)"); 2197ccd5a2cSjsg module_param_named(vm_block_size, radeon_vm_block_size, int, 0444); 2207ccd5a2cSjsg 2217ccd5a2cSjsg MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))"); 2227ccd5a2cSjsg module_param_named(deep_color, radeon_deep_color, int, 0444); 2237ccd5a2cSjsg 2247ccd5a2cSjsg MODULE_PARM_DESC(use_pflipirq, "Pflip irqs for pageflip completion (0 = disable, 1 = as fallback, 2 = exclusive (default))"); 2257ccd5a2cSjsg module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444); 2267ccd5a2cSjsg 2277ccd5a2cSjsg MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); 2287ccd5a2cSjsg module_param_named(bapm, radeon_bapm, int, 0444); 2297ccd5a2cSjsg 2307ccd5a2cSjsg MODULE_PARM_DESC(backlight, "backlight support (1 = enable, 0 = disable, -1 = auto)"); 2317ccd5a2cSjsg module_param_named(backlight, radeon_backlight, int, 0444); 2327ccd5a2cSjsg 2337ccd5a2cSjsg MODULE_PARM_DESC(auxch, "Use native auxch experimental support (1 = enable, 0 = disable, -1 = auto)"); 2347ccd5a2cSjsg module_param_named(auxch, radeon_auxch, int, 0444); 2357ccd5a2cSjsg 2367f4dd379Sjsg MODULE_PARM_DESC(uvd, "uvd enable/disable uvd support (1 = enable, 0 = disable)"); 2377f4dd379Sjsg module_param_named(uvd, radeon_uvd, int, 0444); 2387f4dd379Sjsg 2397f4dd379Sjsg MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)"); 2407f4dd379Sjsg module_param_named(vce, radeon_vce, int, 0444); 2417f4dd379Sjsg 2427f4dd379Sjsg int radeon_si_support = 1; 2437f4dd379Sjsg MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)"); 2447f4dd379Sjsg module_param_named(si_support, radeon_si_support, int, 0444); 2457f4dd379Sjsg 2467f4dd379Sjsg int radeon_cik_support = 1; 2477f4dd379Sjsg MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); 2487f4dd379Sjsg module_param_named(cik_support, radeon_cik_support, int, 0444); 2497f4dd379Sjsg 2501bb76ff1Sjsg static const struct pci_device_id pciidlist[] = { 2517ccd5a2cSjsg radeon_PCI_IDS 2527ccd5a2cSjsg }; 2537ccd5a2cSjsg 2547ccd5a2cSjsg MODULE_DEVICE_TABLE(pci, pciidlist); 2557ccd5a2cSjsg 2565ca02815Sjsg static const struct drm_driver kms_driver; 2577ccd5a2cSjsg 2587ccd5a2cSjsg #ifdef __linux__ 2597ccd5a2cSjsg static int radeon_pci_probe(struct pci_dev *pdev, 2607ccd5a2cSjsg const struct pci_device_id *ent) 2617ccd5a2cSjsg { 2620ea2688eSjsg unsigned long flags = 0; 263c349dbc7Sjsg struct drm_device *dev; 2647ccd5a2cSjsg int ret; 2657ccd5a2cSjsg 2660ea2688eSjsg if (!ent) 2670ea2688eSjsg return -ENODEV; /* Avoid NULL-ptr deref in drm_get_pci_dev */ 2680ea2688eSjsg 2690ea2688eSjsg flags = ent->driver_data; 2700ea2688eSjsg 2710ea2688eSjsg if (!radeon_si_support) { 2720ea2688eSjsg switch (flags & RADEON_FAMILY_MASK) { 2730ea2688eSjsg case CHIP_TAHITI: 2740ea2688eSjsg case CHIP_PITCAIRN: 2750ea2688eSjsg case CHIP_VERDE: 2760ea2688eSjsg case CHIP_OLAND: 2770ea2688eSjsg case CHIP_HAINAN: 2780ea2688eSjsg dev_info(&pdev->dev, 2790ea2688eSjsg "SI support disabled by module param\n"); 2800ea2688eSjsg return -ENODEV; 2810ea2688eSjsg } 2820ea2688eSjsg } 2830ea2688eSjsg if (!radeon_cik_support) { 2840ea2688eSjsg switch (flags & RADEON_FAMILY_MASK) { 2850ea2688eSjsg case CHIP_KAVERI: 2860ea2688eSjsg case CHIP_BONAIRE: 2870ea2688eSjsg case CHIP_HAWAII: 2880ea2688eSjsg case CHIP_KABINI: 2890ea2688eSjsg case CHIP_MULLINS: 2900ea2688eSjsg dev_info(&pdev->dev, 2910ea2688eSjsg "CIK support disabled by module param\n"); 2920ea2688eSjsg return -ENODEV; 2930ea2688eSjsg } 2940ea2688eSjsg } 2950ea2688eSjsg 2967f4dd379Sjsg if (vga_switcheroo_client_probe_defer(pdev)) 2977f4dd379Sjsg return -EPROBE_DEFER; 2987f4dd379Sjsg 2997ccd5a2cSjsg /* Get rid of things like offb */ 3005ca02815Sjsg ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &kms_driver); 3017ccd5a2cSjsg if (ret) 3027ccd5a2cSjsg return ret; 3037ccd5a2cSjsg 304c349dbc7Sjsg dev = drm_dev_alloc(&kms_driver, &pdev->dev); 305c349dbc7Sjsg if (IS_ERR(dev)) 306c349dbc7Sjsg return PTR_ERR(dev); 307c349dbc7Sjsg 308c349dbc7Sjsg ret = pci_enable_device(pdev); 309c349dbc7Sjsg if (ret) 310c349dbc7Sjsg goto err_free; 311c349dbc7Sjsg 312c349dbc7Sjsg pci_set_drvdata(pdev, dev); 313c349dbc7Sjsg 314c349dbc7Sjsg ret = drm_dev_register(dev, ent->driver_data); 315c349dbc7Sjsg if (ret) 316c349dbc7Sjsg goto err_agp; 317c349dbc7Sjsg 318f005ef32Sjsg radeon_fbdev_setup(dev->dev_private); 319f005ef32Sjsg 320c349dbc7Sjsg return 0; 321c349dbc7Sjsg 322c349dbc7Sjsg err_agp: 323c349dbc7Sjsg pci_disable_device(pdev); 324c349dbc7Sjsg err_free: 325c349dbc7Sjsg drm_dev_put(dev); 326c349dbc7Sjsg return ret; 3277ccd5a2cSjsg } 3287ccd5a2cSjsg 3297ccd5a2cSjsg static void 3307ccd5a2cSjsg radeon_pci_remove(struct pci_dev *pdev) 3317ccd5a2cSjsg { 3327ccd5a2cSjsg struct drm_device *dev = pci_get_drvdata(pdev); 3337ccd5a2cSjsg 3347ccd5a2cSjsg drm_put_dev(dev); 3357ccd5a2cSjsg } 3367ccd5a2cSjsg 3377f4dd379Sjsg static void 3387f4dd379Sjsg radeon_pci_shutdown(struct pci_dev *pdev) 3397f4dd379Sjsg { 3407f4dd379Sjsg /* if we are running in a VM, make sure the device 3417f4dd379Sjsg * torn down properly on reboot/shutdown 3427f4dd379Sjsg */ 3437f4dd379Sjsg if (radeon_device_is_virtual()) 3447f4dd379Sjsg radeon_pci_remove(pdev); 345c349dbc7Sjsg 346d2397ff5Sjsg #if defined(CONFIG_PPC64) || defined(CONFIG_MACH_LOONGSON64) 347c349dbc7Sjsg /* 348c349dbc7Sjsg * Some adapters need to be suspended before a 349c349dbc7Sjsg * shutdown occurs in order to prevent an error 350d2397ff5Sjsg * during kexec, shutdown or reboot. 351d2397ff5Sjsg * Make this power and Loongson specific because 352d2397ff5Sjsg * it breaks some other boards. 353c349dbc7Sjsg */ 354c349dbc7Sjsg radeon_suspend_kms(pci_get_drvdata(pdev), true, true, false); 355c349dbc7Sjsg #endif 3567f4dd379Sjsg } 3577f4dd379Sjsg 3587ccd5a2cSjsg static int radeon_pmops_suspend(struct device *dev) 3597ccd5a2cSjsg { 360c349dbc7Sjsg struct drm_device *drm_dev = dev_get_drvdata(dev); 361f005ef32Sjsg 3627f4dd379Sjsg return radeon_suspend_kms(drm_dev, true, true, false); 3637ccd5a2cSjsg } 3647ccd5a2cSjsg 3657ccd5a2cSjsg static int radeon_pmops_resume(struct device *dev) 3667ccd5a2cSjsg { 367c349dbc7Sjsg struct drm_device *drm_dev = dev_get_drvdata(dev); 3687f4dd379Sjsg 3697f4dd379Sjsg /* GPU comes up enabled by the bios on resume */ 3707f4dd379Sjsg if (radeon_is_px(drm_dev)) { 3717f4dd379Sjsg pm_runtime_disable(dev); 3727f4dd379Sjsg pm_runtime_set_active(dev); 3737f4dd379Sjsg pm_runtime_enable(dev); 3747f4dd379Sjsg } 3757f4dd379Sjsg 3767ccd5a2cSjsg return radeon_resume_kms(drm_dev, true, true); 3777ccd5a2cSjsg } 3787ccd5a2cSjsg 3797ccd5a2cSjsg static int radeon_pmops_freeze(struct device *dev) 3807ccd5a2cSjsg { 381c349dbc7Sjsg struct drm_device *drm_dev = dev_get_drvdata(dev); 382f005ef32Sjsg 3837f4dd379Sjsg return radeon_suspend_kms(drm_dev, false, true, true); 3847ccd5a2cSjsg } 3857ccd5a2cSjsg 3867ccd5a2cSjsg static int radeon_pmops_thaw(struct device *dev) 3877ccd5a2cSjsg { 388c349dbc7Sjsg struct drm_device *drm_dev = dev_get_drvdata(dev); 389f005ef32Sjsg 3907ccd5a2cSjsg return radeon_resume_kms(drm_dev, false, true); 3917ccd5a2cSjsg } 3927ccd5a2cSjsg 3937ccd5a2cSjsg static int radeon_pmops_runtime_suspend(struct device *dev) 3947ccd5a2cSjsg { 3957ccd5a2cSjsg struct pci_dev *pdev = to_pci_dev(dev); 3967ccd5a2cSjsg struct drm_device *drm_dev = pci_get_drvdata(pdev); 3977ccd5a2cSjsg 3987ccd5a2cSjsg if (!radeon_is_px(drm_dev)) { 3997ccd5a2cSjsg pm_runtime_forbid(dev); 4007ccd5a2cSjsg return -EBUSY; 4017ccd5a2cSjsg } 4027ccd5a2cSjsg 4037ccd5a2cSjsg drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 4047ccd5a2cSjsg drm_kms_helper_poll_disable(drm_dev); 4057ccd5a2cSjsg 4065ca02815Sjsg radeon_suspend_kms(drm_dev, false, false, false); 4077ccd5a2cSjsg pci_save_state(pdev); 4087ccd5a2cSjsg pci_disable_device(pdev); 4097ccd5a2cSjsg pci_ignore_hotplug(pdev); 4107f4dd379Sjsg if (radeon_is_atpx_hybrid()) 4117ccd5a2cSjsg pci_set_power_state(pdev, PCI_D3cold); 4127f4dd379Sjsg else if (!radeon_has_atpx_dgpu_power_cntl()) 4137f4dd379Sjsg pci_set_power_state(pdev, PCI_D3hot); 4147ccd5a2cSjsg drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; 4157ccd5a2cSjsg 4167ccd5a2cSjsg return 0; 4177ccd5a2cSjsg } 4187ccd5a2cSjsg 4197ccd5a2cSjsg static int radeon_pmops_runtime_resume(struct device *dev) 4207ccd5a2cSjsg { 4217ccd5a2cSjsg struct pci_dev *pdev = to_pci_dev(dev); 4227ccd5a2cSjsg struct drm_device *drm_dev = pci_get_drvdata(pdev); 4237ccd5a2cSjsg int ret; 4247ccd5a2cSjsg 4257ccd5a2cSjsg if (!radeon_is_px(drm_dev)) 4267ccd5a2cSjsg return -EINVAL; 4277ccd5a2cSjsg 4287ccd5a2cSjsg drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 4297ccd5a2cSjsg 4307f4dd379Sjsg if (radeon_is_atpx_hybrid() || 4317f4dd379Sjsg !radeon_has_atpx_dgpu_power_cntl()) 4327ccd5a2cSjsg pci_set_power_state(pdev, PCI_D0); 4337ccd5a2cSjsg pci_restore_state(pdev); 4347ccd5a2cSjsg ret = pci_enable_device(pdev); 4357ccd5a2cSjsg if (ret) 4367ccd5a2cSjsg return ret; 4377ccd5a2cSjsg pci_set_master(pdev); 4387ccd5a2cSjsg 4397ccd5a2cSjsg ret = radeon_resume_kms(drm_dev, false, false); 4407ccd5a2cSjsg drm_kms_helper_poll_enable(drm_dev); 4417ccd5a2cSjsg drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 4427ccd5a2cSjsg return 0; 4437ccd5a2cSjsg } 4447ccd5a2cSjsg 4457ccd5a2cSjsg static int radeon_pmops_runtime_idle(struct device *dev) 4467ccd5a2cSjsg { 447c349dbc7Sjsg struct drm_device *drm_dev = dev_get_drvdata(dev); 4487ccd5a2cSjsg struct drm_crtc *crtc; 4497ccd5a2cSjsg 4507ccd5a2cSjsg if (!radeon_is_px(drm_dev)) { 4517ccd5a2cSjsg pm_runtime_forbid(dev); 4527ccd5a2cSjsg return -EBUSY; 4537ccd5a2cSjsg } 4547ccd5a2cSjsg 4557ccd5a2cSjsg list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) { 4567ccd5a2cSjsg if (crtc->enabled) { 4577ccd5a2cSjsg DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); 4587ccd5a2cSjsg return -EBUSY; 4597ccd5a2cSjsg } 4607ccd5a2cSjsg } 4617ccd5a2cSjsg 4627ccd5a2cSjsg pm_runtime_mark_last_busy(dev); 4637ccd5a2cSjsg pm_runtime_autosuspend(dev); 4647ccd5a2cSjsg /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ 4657ccd5a2cSjsg return 1; 4667ccd5a2cSjsg } 4677ccd5a2cSjsg 4687ccd5a2cSjsg long radeon_drm_ioctl(struct file *filp, 4697ccd5a2cSjsg unsigned int cmd, unsigned long arg) 4707ccd5a2cSjsg { 4717ccd5a2cSjsg struct drm_file *file_priv = filp->private_data; 4727ccd5a2cSjsg struct drm_device *dev; 4737ccd5a2cSjsg long ret; 474f005ef32Sjsg 4757ccd5a2cSjsg dev = file_priv->minor->dev; 4767ccd5a2cSjsg ret = pm_runtime_get_sync(dev->dev); 4770edad55bSjsg if (ret < 0) { 4780edad55bSjsg pm_runtime_put_autosuspend(dev->dev); 4797ccd5a2cSjsg return ret; 4800edad55bSjsg } 4817ccd5a2cSjsg 4827ccd5a2cSjsg ret = drm_ioctl(filp, cmd, arg); 4837ccd5a2cSjsg 4847ccd5a2cSjsg pm_runtime_mark_last_busy(dev->dev); 4857ccd5a2cSjsg pm_runtime_put_autosuspend(dev->dev); 4867ccd5a2cSjsg return ret; 4877ccd5a2cSjsg } 4887ccd5a2cSjsg 4897f4dd379Sjsg #ifdef CONFIG_COMPAT 4907f4dd379Sjsg static long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 4917f4dd379Sjsg { 4927f4dd379Sjsg unsigned int nr = DRM_IOCTL_NR(cmd); 4937f4dd379Sjsg 4947f4dd379Sjsg if (nr < DRM_COMMAND_BASE) 4957f4dd379Sjsg return drm_compat_ioctl(filp, cmd, arg); 4967f4dd379Sjsg 4971bb76ff1Sjsg return radeon_drm_ioctl(filp, cmd, arg); 4987f4dd379Sjsg } 4997f4dd379Sjsg #endif 5007f4dd379Sjsg 5017ccd5a2cSjsg static const struct dev_pm_ops radeon_pm_ops = { 5027ccd5a2cSjsg .suspend = radeon_pmops_suspend, 5037ccd5a2cSjsg .resume = radeon_pmops_resume, 5047ccd5a2cSjsg .freeze = radeon_pmops_freeze, 5057ccd5a2cSjsg .thaw = radeon_pmops_thaw, 5067ccd5a2cSjsg .poweroff = radeon_pmops_freeze, 5077ccd5a2cSjsg .restore = radeon_pmops_resume, 5087ccd5a2cSjsg .runtime_suspend = radeon_pmops_runtime_suspend, 5097ccd5a2cSjsg .runtime_resume = radeon_pmops_runtime_resume, 5107ccd5a2cSjsg .runtime_idle = radeon_pmops_runtime_idle, 5117ccd5a2cSjsg }; 5127ccd5a2cSjsg 5137ccd5a2cSjsg static const struct file_operations radeon_driver_kms_fops = { 5147ccd5a2cSjsg .owner = THIS_MODULE, 5157ccd5a2cSjsg .open = drm_open, 5167ccd5a2cSjsg .release = drm_release, 5177ccd5a2cSjsg .unlocked_ioctl = radeon_drm_ioctl, 5185ca02815Sjsg .mmap = drm_gem_mmap, 5197ccd5a2cSjsg .poll = drm_poll, 5207ccd5a2cSjsg .read = drm_read, 5217ccd5a2cSjsg #ifdef CONFIG_COMPAT 5227ccd5a2cSjsg .compat_ioctl = radeon_kms_compat_ioctl, 5237ccd5a2cSjsg #endif 5247ccd5a2cSjsg }; 5257ccd5a2cSjsg 526c349dbc7Sjsg #endif /* __linux__ */ 5277f4dd379Sjsg 5285ca02815Sjsg static const struct drm_ioctl_desc radeon_ioctls_kms[] = { 5295ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5305ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5315ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5325ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5335ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, drm_invalid_op, DRM_AUTH), 5345ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, drm_invalid_op, DRM_AUTH), 5355ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_RESET, drm_invalid_op, DRM_AUTH), 5365ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, drm_invalid_op, DRM_AUTH), 5375ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_SWAP, drm_invalid_op, DRM_AUTH), 5385ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CLEAR, drm_invalid_op, DRM_AUTH), 5395ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_VERTEX, drm_invalid_op, DRM_AUTH), 5405ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_INDICES, drm_invalid_op, DRM_AUTH), 5415ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, drm_invalid_op, DRM_AUTH), 5425ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, drm_invalid_op, DRM_AUTH), 5435ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5445ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, drm_invalid_op, DRM_AUTH), 5455ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, drm_invalid_op, DRM_AUTH), 5465ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, drm_invalid_op, DRM_AUTH), 5475ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_FLIP, drm_invalid_op, DRM_AUTH), 5485ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_ALLOC, drm_invalid_op, DRM_AUTH), 5495ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_FREE, drm_invalid_op, DRM_AUTH), 5505ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 5515ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, drm_invalid_op, DRM_AUTH), 5525ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, drm_invalid_op, DRM_AUTH), 5535ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, drm_invalid_op, DRM_AUTH), 5545ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, drm_invalid_op, DRM_AUTH), 5555ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, drm_invalid_op, DRM_AUTH), 5565ca02815Sjsg /* KMS */ 5575ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5585ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5595ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5605ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5615ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5625ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5635ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5645ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5655ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5665ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5675ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5685ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5695ca02815Sjsg DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 5705ca02815Sjsg }; 5715ca02815Sjsg 5721bb76ff1Sjsg static const struct drm_driver kms_driver = { 5737ccd5a2cSjsg .driver_features = 5745ca02815Sjsg DRIVER_GEM | DRIVER_RENDER | DRIVER_MODESET, 5757ccd5a2cSjsg #ifdef notyet 5767ccd5a2cSjsg .load = radeon_driver_load_kms, 5777ccd5a2cSjsg #endif 5787ccd5a2cSjsg .open = radeon_driver_open_kms, 579c349dbc7Sjsg #ifdef __OpenBSD__ 5805ca02815Sjsg .mmap = drm_gem_mmap, 581c349dbc7Sjsg #endif 5827ccd5a2cSjsg .postclose = radeon_driver_postclose_kms, 5837ccd5a2cSjsg #ifdef notyet 5847ccd5a2cSjsg .unload = radeon_driver_unload_kms, 5857ccd5a2cSjsg #endif 5867ccd5a2cSjsg .ioctls = radeon_ioctls_kms, 5875ca02815Sjsg .num_ioctls = ARRAY_SIZE(radeon_ioctls_kms), 588c349dbc7Sjsg #ifdef __OpenBSD__ 5897ccd5a2cSjsg .gem_size = sizeof(struct radeon_bo), 590c349dbc7Sjsg #endif 5917ccd5a2cSjsg .dumb_create = radeon_mode_dumb_create, 5927ccd5a2cSjsg .dumb_map_offset = radeon_mode_dumb_mmap, 593a9ee023bSkettenis #ifdef __linux__ 5947ccd5a2cSjsg .fops = &radeon_driver_kms_fops, 595a9ee023bSkettenis #endif 5967ccd5a2cSjsg 597a9ee023bSkettenis #ifdef notyet 5987ccd5a2cSjsg .gem_prime_import_sg_table = radeon_gem_prime_import_sg_table, 5997ccd5a2cSjsg #endif 6007ccd5a2cSjsg 6017ccd5a2cSjsg .name = DRIVER_NAME, 6027ccd5a2cSjsg .desc = DRIVER_DESC, 6037ccd5a2cSjsg .date = DRIVER_DATE, 6047ccd5a2cSjsg .major = KMS_DRIVER_MAJOR, 6057ccd5a2cSjsg .minor = KMS_DRIVER_MINOR, 6067ccd5a2cSjsg .patchlevel = KMS_DRIVER_PATCHLEVEL, 6077ccd5a2cSjsg }; 6087ccd5a2cSjsg 6097ccd5a2cSjsg #ifdef __linux__ 6107ccd5a2cSjsg static struct pci_driver radeon_kms_pci_driver = { 6117ccd5a2cSjsg .name = DRIVER_NAME, 6127ccd5a2cSjsg .id_table = pciidlist, 6137ccd5a2cSjsg .probe = radeon_pci_probe, 6147ccd5a2cSjsg .remove = radeon_pci_remove, 6157f4dd379Sjsg .shutdown = radeon_pci_shutdown, 6167ccd5a2cSjsg .driver.pm = &radeon_pm_ops, 6177ccd5a2cSjsg }; 6185ca02815Sjsg #endif 6197ccd5a2cSjsg 6207ccd5a2cSjsg #ifdef notyet 6215ca02815Sjsg static int __init radeon_module_init(void) 6227ccd5a2cSjsg { 6231bb76ff1Sjsg if (drm_firmware_drivers_only() && radeon_modeset == -1) 6247ccd5a2cSjsg radeon_modeset = 0; 6257ccd5a2cSjsg 6261bb76ff1Sjsg if (radeon_modeset == 0) 6277ccd5a2cSjsg return -EINVAL; 6287ccd5a2cSjsg 6295ca02815Sjsg DRM_INFO("radeon kernel modesetting enabled.\n"); 6305ca02815Sjsg radeon_register_atpx_handler(); 6315ca02815Sjsg 6325ca02815Sjsg return pci_register_driver(&radeon_kms_pci_driver); 6337ccd5a2cSjsg } 6347ccd5a2cSjsg 6355ca02815Sjsg static void __exit radeon_module_exit(void) 6367ccd5a2cSjsg { 6375ca02815Sjsg pci_unregister_driver(&radeon_kms_pci_driver); 6387ccd5a2cSjsg radeon_unregister_atpx_handler(); 639c349dbc7Sjsg mmu_notifier_synchronize(); 6407ccd5a2cSjsg } 641c349dbc7Sjsg #endif /* notyet */ 6427ccd5a2cSjsg 6435ca02815Sjsg module_init(radeon_module_init); 6445ca02815Sjsg module_exit(radeon_module_exit); 6457ccd5a2cSjsg 6467ccd5a2cSjsg MODULE_AUTHOR(DRIVER_AUTHOR); 6477ccd5a2cSjsg MODULE_DESCRIPTION(DRIVER_DESC); 6487ccd5a2cSjsg MODULE_LICENSE("GPL and additional rights"); 6491bb76ff1Sjsg 6501bb76ff1Sjsg #if defined(CONFIG_VGA_SWITCHEROO) 6511bb76ff1Sjsg bool radeon_has_atpx(void); 6521bb76ff1Sjsg #else 6531bb76ff1Sjsg static inline bool radeon_has_atpx(void) { return false; } 6541bb76ff1Sjsg #endif 6551bb76ff1Sjsg 6561bb76ff1Sjsg #include <drm/drm_drv.h> 657f005ef32Sjsg #include <drm/drm_fb_helper.h> 6581bb76ff1Sjsg #include "vga.h" 6591bb76ff1Sjsg 6601bb76ff1Sjsg #if NVGA > 0 6611bb76ff1Sjsg #include <dev/ic/mc6845reg.h> 6621bb76ff1Sjsg #include <dev/ic/pcdisplayvar.h> 6631bb76ff1Sjsg #include <dev/ic/vgareg.h> 6641bb76ff1Sjsg #include <dev/ic/vgavar.h> 6651bb76ff1Sjsg 6661bb76ff1Sjsg extern int vga_console_attached; 6671bb76ff1Sjsg #endif 6681bb76ff1Sjsg 6691bb76ff1Sjsg #ifdef __amd64__ 6701bb76ff1Sjsg #include "efifb.h" 6711bb76ff1Sjsg #include <machine/biosvar.h> 6721bb76ff1Sjsg #endif 6731bb76ff1Sjsg 6741bb76ff1Sjsg #if NEFIFB > 0 6751bb76ff1Sjsg #include <machine/efifbvar.h> 6761bb76ff1Sjsg #endif 6771bb76ff1Sjsg 6781bb76ff1Sjsg int radeondrm_probe(struct device *, void *, void *); 6791bb76ff1Sjsg void radeondrm_attach_kms(struct device *, struct device *, void *); 6801bb76ff1Sjsg int radeondrm_detach_kms(struct device *, int); 6811bb76ff1Sjsg int radeondrm_activate_kms(struct device *, int); 6821bb76ff1Sjsg void radeondrm_attachhook(struct device *); 6831bb76ff1Sjsg int radeondrm_forcedetach(struct radeon_device *); 6841bb76ff1Sjsg 6851bb76ff1Sjsg bool radeon_msi_ok(struct radeon_device *); 6861bb76ff1Sjsg irqreturn_t radeon_driver_irq_handler_kms(void *); 6871bb76ff1Sjsg 6881bb76ff1Sjsg /* 6891bb76ff1Sjsg * set if the mountroot hook has a fatal error 6901bb76ff1Sjsg * such as not being able to find the firmware on newer cards 6911bb76ff1Sjsg */ 6921bb76ff1Sjsg int radeon_fatal_error; 6931bb76ff1Sjsg 6941bb76ff1Sjsg const struct cfattach radeondrm_ca = { 6951bb76ff1Sjsg sizeof (struct radeon_device), radeondrm_probe, radeondrm_attach_kms, 6961bb76ff1Sjsg radeondrm_detach_kms, radeondrm_activate_kms 6971bb76ff1Sjsg }; 6981bb76ff1Sjsg 6991bb76ff1Sjsg struct cfdriver radeondrm_cd = { 7001bb76ff1Sjsg NULL, "radeondrm", DV_DULL 7011bb76ff1Sjsg }; 7021bb76ff1Sjsg 7031bb76ff1Sjsg int 7041bb76ff1Sjsg radeondrm_probe(struct device *parent, void *match, void *aux) 7051bb76ff1Sjsg { 7061bb76ff1Sjsg if (radeon_fatal_error) 7071bb76ff1Sjsg return 0; 7081bb76ff1Sjsg if (drm_pciprobe(aux, pciidlist)) 7091bb76ff1Sjsg return 20; 7101bb76ff1Sjsg return 0; 7111bb76ff1Sjsg } 7121bb76ff1Sjsg 7131bb76ff1Sjsg int 7141bb76ff1Sjsg radeondrm_detach_kms(struct device *self, int flags) 7151bb76ff1Sjsg { 7161bb76ff1Sjsg struct radeon_device *rdev = (struct radeon_device *)self; 7171bb76ff1Sjsg 7181bb76ff1Sjsg if (rdev == NULL) 7191bb76ff1Sjsg return 0; 7201bb76ff1Sjsg 7211bb76ff1Sjsg pci_intr_disestablish(rdev->pc, rdev->irqh); 7221bb76ff1Sjsg 7231bb76ff1Sjsg #ifdef notyet 7241bb76ff1Sjsg pm_runtime_get_sync(dev->dev); 7251bb76ff1Sjsg 7261bb76ff1Sjsg radeon_kfd_device_fini(rdev); 7271bb76ff1Sjsg #endif 7281bb76ff1Sjsg 7291bb76ff1Sjsg radeon_acpi_fini(rdev); 7301bb76ff1Sjsg 7311bb76ff1Sjsg radeon_modeset_fini(rdev); 7321bb76ff1Sjsg radeon_device_fini(rdev); 7331bb76ff1Sjsg 7341bb76ff1Sjsg if (rdev->ddev != NULL) { 7351bb76ff1Sjsg config_detach(rdev->ddev->dev, flags); 7361bb76ff1Sjsg rdev->ddev = NULL; 7371bb76ff1Sjsg } 7381bb76ff1Sjsg 7391bb76ff1Sjsg return 0; 7401bb76ff1Sjsg } 7411bb76ff1Sjsg 7421bb76ff1Sjsg void radeondrm_burner(void *, u_int, u_int); 7431bb76ff1Sjsg int radeondrm_wsioctl(void *, u_long, caddr_t, int, struct proc *); 7441bb76ff1Sjsg paddr_t radeondrm_wsmmap(void *, off_t, int); 7451bb76ff1Sjsg int radeondrm_alloc_screen(void *, const struct wsscreen_descr *, 7461bb76ff1Sjsg void **, int *, int *, uint32_t *); 7471bb76ff1Sjsg void radeondrm_free_screen(void *, void *); 7481bb76ff1Sjsg int radeondrm_show_screen(void *, void *, int, 7491bb76ff1Sjsg void (*)(void *, int, int), void *); 7501bb76ff1Sjsg void radeondrm_doswitch(void *); 7511bb76ff1Sjsg void radeondrm_enter_ddb(void *, void *); 7521bb76ff1Sjsg #ifdef __sparc64__ 7531bb76ff1Sjsg void radeondrm_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); 7541bb76ff1Sjsg #endif 7551bb76ff1Sjsg void radeondrm_setpal(struct radeon_device *, struct rasops_info *); 7561bb76ff1Sjsg 7571bb76ff1Sjsg struct wsscreen_descr radeondrm_stdscreen = { 7581bb76ff1Sjsg "std", 7591bb76ff1Sjsg 0, 0, 7601bb76ff1Sjsg 0, 7611bb76ff1Sjsg 0, 0, 7621bb76ff1Sjsg WSSCREEN_UNDERLINE | WSSCREEN_HILIT | 7631bb76ff1Sjsg WSSCREEN_REVERSE | WSSCREEN_WSCOLORS 7641bb76ff1Sjsg }; 7651bb76ff1Sjsg 7661bb76ff1Sjsg const struct wsscreen_descr *radeondrm_scrlist[] = { 7671bb76ff1Sjsg &radeondrm_stdscreen, 7681bb76ff1Sjsg }; 7691bb76ff1Sjsg 7701bb76ff1Sjsg struct wsscreen_list radeondrm_screenlist = { 7711bb76ff1Sjsg nitems(radeondrm_scrlist), radeondrm_scrlist 7721bb76ff1Sjsg }; 7731bb76ff1Sjsg 7741bb76ff1Sjsg struct wsdisplay_accessops radeondrm_accessops = { 7751bb76ff1Sjsg .ioctl = radeondrm_wsioctl, 7761bb76ff1Sjsg .mmap = radeondrm_wsmmap, 7771bb76ff1Sjsg .alloc_screen = radeondrm_alloc_screen, 7781bb76ff1Sjsg .free_screen = radeondrm_free_screen, 7791bb76ff1Sjsg .show_screen = radeondrm_show_screen, 7801bb76ff1Sjsg .enter_ddb = radeondrm_enter_ddb, 7811bb76ff1Sjsg .getchar = rasops_getchar, 7821bb76ff1Sjsg .load_font = rasops_load_font, 7831bb76ff1Sjsg .list_font = rasops_list_font, 7841bb76ff1Sjsg .scrollback = rasops_scrollback, 7851bb76ff1Sjsg .burn_screen = radeondrm_burner 7861bb76ff1Sjsg }; 7871bb76ff1Sjsg 7881bb76ff1Sjsg int 7891bb76ff1Sjsg radeondrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 7901bb76ff1Sjsg { 7911bb76ff1Sjsg struct rasops_info *ri = v; 7921bb76ff1Sjsg struct wsdisplay_fbinfo *wdf; 7931bb76ff1Sjsg struct wsdisplay_param *dp = (struct wsdisplay_param *)data; 7941bb76ff1Sjsg 7951bb76ff1Sjsg switch (cmd) { 7961bb76ff1Sjsg case WSDISPLAYIO_GTYPE: 7971bb76ff1Sjsg *(u_int *)data = WSDISPLAY_TYPE_RADEONDRM; 7981bb76ff1Sjsg return 0; 7991bb76ff1Sjsg case WSDISPLAYIO_GINFO: 8001bb76ff1Sjsg wdf = (struct wsdisplay_fbinfo *)data; 8011bb76ff1Sjsg wdf->width = ri->ri_width; 8021bb76ff1Sjsg wdf->height = ri->ri_height; 8031bb76ff1Sjsg wdf->depth = ri->ri_depth; 8041bb76ff1Sjsg wdf->stride = ri->ri_stride; 8051bb76ff1Sjsg wdf->offset = 0; 8061bb76ff1Sjsg wdf->cmsize = 0; 8071bb76ff1Sjsg return 0; 8081bb76ff1Sjsg case WSDISPLAYIO_GETPARAM: 8091bb76ff1Sjsg if (ws_get_param == NULL) 8101bb76ff1Sjsg return 0; 8111bb76ff1Sjsg return ws_get_param(dp); 8121bb76ff1Sjsg case WSDISPLAYIO_SETPARAM: 8131bb76ff1Sjsg if (ws_set_param == NULL) 8141bb76ff1Sjsg return 0; 8151bb76ff1Sjsg return ws_set_param(dp); 816804fcafaSjsg case WSDISPLAYIO_SVIDEO: 817804fcafaSjsg case WSDISPLAYIO_GVIDEO: 818804fcafaSjsg return 0; 8191bb76ff1Sjsg default: 8201bb76ff1Sjsg return -1; 8211bb76ff1Sjsg } 8221bb76ff1Sjsg } 8231bb76ff1Sjsg 8241bb76ff1Sjsg paddr_t 8251bb76ff1Sjsg radeondrm_wsmmap(void *v, off_t off, int prot) 8261bb76ff1Sjsg { 8271bb76ff1Sjsg return (-1); 8281bb76ff1Sjsg } 8291bb76ff1Sjsg 8301bb76ff1Sjsg int 8311bb76ff1Sjsg radeondrm_alloc_screen(void *v, const struct wsscreen_descr *type, 8321bb76ff1Sjsg void **cookiep, int *curxp, int *curyp, uint32_t *attrp) 8331bb76ff1Sjsg { 8341bb76ff1Sjsg return rasops_alloc_screen(v, cookiep, curxp, curyp, attrp); 8351bb76ff1Sjsg } 8361bb76ff1Sjsg 8371bb76ff1Sjsg void 8381bb76ff1Sjsg radeondrm_free_screen(void *v, void *cookie) 8391bb76ff1Sjsg { 8401bb76ff1Sjsg return rasops_free_screen(v, cookie); 8411bb76ff1Sjsg } 8421bb76ff1Sjsg 8431bb76ff1Sjsg int 8441bb76ff1Sjsg radeondrm_show_screen(void *v, void *cookie, int waitok, 8451bb76ff1Sjsg void (*cb)(void *, int, int), void *cbarg) 8461bb76ff1Sjsg { 8471bb76ff1Sjsg struct rasops_info *ri = v; 8481bb76ff1Sjsg struct radeon_device *rdev = ri->ri_hw; 8491bb76ff1Sjsg 8501bb76ff1Sjsg if (cookie == ri->ri_active) 8511bb76ff1Sjsg return (0); 8521bb76ff1Sjsg 8531bb76ff1Sjsg rdev->switchcb = cb; 8541bb76ff1Sjsg rdev->switchcbarg = cbarg; 8551bb76ff1Sjsg rdev->switchcookie = cookie; 8561bb76ff1Sjsg if (cb) { 8571bb76ff1Sjsg task_add(systq, &rdev->switchtask); 8581bb76ff1Sjsg return (EAGAIN); 8591bb76ff1Sjsg } 8601bb76ff1Sjsg 8611bb76ff1Sjsg radeondrm_doswitch(v); 8621bb76ff1Sjsg 8631bb76ff1Sjsg return (0); 8641bb76ff1Sjsg } 8651bb76ff1Sjsg 8661bb76ff1Sjsg void 8671bb76ff1Sjsg radeondrm_doswitch(void *v) 8681bb76ff1Sjsg { 8691bb76ff1Sjsg struct rasops_info *ri = v; 8701bb76ff1Sjsg struct radeon_device *rdev = ri->ri_hw; 8711bb76ff1Sjsg 8721bb76ff1Sjsg rasops_show_screen(ri, rdev->switchcookie, 0, NULL, NULL); 8731bb76ff1Sjsg #ifdef __sparc64__ 8741bb76ff1Sjsg fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); 8751bb76ff1Sjsg #else 8761bb76ff1Sjsg radeondrm_setpal(rdev, ri); 8771bb76ff1Sjsg #endif 878f005ef32Sjsg drm_fb_helper_restore_fbdev_mode_unlocked(rdev->ddev->fb_helper); 8791bb76ff1Sjsg 8801bb76ff1Sjsg if (rdev->switchcb) 8811bb76ff1Sjsg (rdev->switchcb)(rdev->switchcbarg, 0, 0); 8821bb76ff1Sjsg } 8831bb76ff1Sjsg 8841bb76ff1Sjsg void 8851bb76ff1Sjsg radeondrm_enter_ddb(void *v, void *cookie) 8861bb76ff1Sjsg { 8871bb76ff1Sjsg struct rasops_info *ri = v; 8881bb76ff1Sjsg struct radeon_device *rdev = ri->ri_hw; 889f005ef32Sjsg struct drm_fb_helper *fb_helper = rdev->ddev->fb_helper; 8901bb76ff1Sjsg 8911bb76ff1Sjsg if (cookie == ri->ri_active) 8921bb76ff1Sjsg return; 8931bb76ff1Sjsg 8941bb76ff1Sjsg rasops_show_screen(ri, cookie, 0, NULL, NULL); 895f005ef32Sjsg drm_fb_helper_debug_enter(fb_helper->info); 8961bb76ff1Sjsg } 8971bb76ff1Sjsg 8981bb76ff1Sjsg #ifdef __sparc64__ 8991bb76ff1Sjsg void 9001bb76ff1Sjsg radeondrm_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) 9011bb76ff1Sjsg { 9021bb76ff1Sjsg struct sunfb *sf = v; 9031bb76ff1Sjsg struct radeon_device *rdev = sf->sf_ro.ri_hw; 9041bb76ff1Sjsg 9051bb76ff1Sjsg /* see legacy_crtc_load_lut() */ 9061bb76ff1Sjsg if (rdev->family < CHIP_RS600) { 9071bb76ff1Sjsg WREG8(RADEON_PALETTE_INDEX, index); 9081bb76ff1Sjsg WREG32(RADEON_PALETTE_30_DATA, 9091bb76ff1Sjsg (r << 22) | (g << 12) | (b << 2)); 9101bb76ff1Sjsg } else { 9111bb76ff1Sjsg printf("%s: setcolor family %d not handled\n", 9121bb76ff1Sjsg rdev->self.dv_xname, rdev->family); 9131bb76ff1Sjsg } 9141bb76ff1Sjsg } 9151bb76ff1Sjsg #endif 9161bb76ff1Sjsg 9171bb76ff1Sjsg void 9181bb76ff1Sjsg radeondrm_setpal(struct radeon_device *rdev, struct rasops_info *ri) 9191bb76ff1Sjsg { 920*33a3edb1Sjsg struct drm_device *dev = rdev_to_drm(rdev); 9211bb76ff1Sjsg struct drm_crtc *crtc; 9221bb76ff1Sjsg uint16_t *r_base, *g_base, *b_base; 9231bb76ff1Sjsg int i, index, ret = 0; 9241bb76ff1Sjsg const u_char *p; 9251bb76ff1Sjsg 9261bb76ff1Sjsg if (ri->ri_depth != 8) 9271bb76ff1Sjsg return; 9281bb76ff1Sjsg 9291bb76ff1Sjsg for (i = 0; i < rdev->num_crtc; i++) { 9301bb76ff1Sjsg struct drm_modeset_acquire_ctx ctx; 9311bb76ff1Sjsg crtc = &rdev->mode_info.crtcs[i]->base; 9321bb76ff1Sjsg 9331bb76ff1Sjsg r_base = crtc->gamma_store; 9341bb76ff1Sjsg g_base = r_base + crtc->gamma_size; 9351bb76ff1Sjsg b_base = g_base + crtc->gamma_size; 9361bb76ff1Sjsg 9371bb76ff1Sjsg DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); 9381bb76ff1Sjsg 9391bb76ff1Sjsg p = rasops_cmap; 9401bb76ff1Sjsg for (index = 0; index < 256; index++) { 9411bb76ff1Sjsg r_base[index] = *p++ << 8; 9421bb76ff1Sjsg g_base[index] = *p++ << 8; 9431bb76ff1Sjsg b_base[index] = *p++ << 8; 9441bb76ff1Sjsg } 9451bb76ff1Sjsg 9461bb76ff1Sjsg crtc->funcs->gamma_set(crtc, NULL, NULL, NULL, 0, NULL); 9471bb76ff1Sjsg 9481bb76ff1Sjsg DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); 9491bb76ff1Sjsg } 9501bb76ff1Sjsg } 9511bb76ff1Sjsg 9521bb76ff1Sjsg void 9531bb76ff1Sjsg radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) 9541bb76ff1Sjsg { 9551bb76ff1Sjsg struct radeon_device *rdev = (struct radeon_device *)self; 9561bb76ff1Sjsg struct drm_device *dev; 9571bb76ff1Sjsg struct pci_attach_args *pa = aux; 9581bb76ff1Sjsg const struct pci_device_id *id_entry; 9591bb76ff1Sjsg int is_agp; 9601bb76ff1Sjsg pcireg_t type; 9611bb76ff1Sjsg int i; 9621bb76ff1Sjsg uint8_t rmmio_bar; 9631bb76ff1Sjsg paddr_t fb_aper; 9641bb76ff1Sjsg pcireg_t addr, mask; 9651bb76ff1Sjsg int s; 9661bb76ff1Sjsg 9671bb76ff1Sjsg #if defined(__sparc64__) || defined(__macppc__) 9681bb76ff1Sjsg extern int fbnode; 9691bb76ff1Sjsg #endif 9701bb76ff1Sjsg 9711bb76ff1Sjsg id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), 9721bb76ff1Sjsg PCI_PRODUCT(pa->pa_id), pciidlist); 9731bb76ff1Sjsg rdev->flags = id_entry->driver_data; 9741bb76ff1Sjsg rdev->family = rdev->flags & RADEON_FAMILY_MASK; 9751bb76ff1Sjsg rdev->pc = pa->pa_pc; 9761bb76ff1Sjsg rdev->pa_tag = pa->pa_tag; 9771bb76ff1Sjsg rdev->iot = pa->pa_iot; 9781bb76ff1Sjsg rdev->memt = pa->pa_memt; 9791bb76ff1Sjsg rdev->dmat = pa->pa_dmat; 9801bb76ff1Sjsg 9811bb76ff1Sjsg #if defined(__sparc64__) || defined(__macppc__) 9821bb76ff1Sjsg if (fbnode == PCITAG_NODE(rdev->pa_tag)) 9831bb76ff1Sjsg rdev->console = rdev->primary = 1; 9841bb76ff1Sjsg #else 9851bb76ff1Sjsg if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && 9861bb76ff1Sjsg PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && 9871bb76ff1Sjsg (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) 9881bb76ff1Sjsg & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) 9891bb76ff1Sjsg == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { 9901bb76ff1Sjsg rdev->primary = 1; 9911bb76ff1Sjsg #if NVGA > 0 9921bb76ff1Sjsg rdev->console = vga_is_console(pa->pa_iot, -1); 9931bb76ff1Sjsg vga_console_attached = 1; 9941bb76ff1Sjsg #endif 9951bb76ff1Sjsg } 9961bb76ff1Sjsg 9971bb76ff1Sjsg #if NEFIFB > 0 9981bb76ff1Sjsg if (efifb_is_primary(pa)) { 9991bb76ff1Sjsg rdev->primary = 1; 10001bb76ff1Sjsg rdev->console = efifb_is_console(pa); 10011bb76ff1Sjsg efifb_detach(); 10021bb76ff1Sjsg } 10031bb76ff1Sjsg #endif 10041bb76ff1Sjsg #endif 10051bb76ff1Sjsg 10061bb76ff1Sjsg #define RADEON_PCI_MEM 0x10 10071bb76ff1Sjsg 10081bb76ff1Sjsg type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); 10091bb76ff1Sjsg if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || 10101bb76ff1Sjsg pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, 10111bb76ff1Sjsg type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { 1012961f2fc7Sjsg printf(": can't get framebuffer info\n"); 10131bb76ff1Sjsg return; 10141bb76ff1Sjsg } 10151bb76ff1Sjsg if (rdev->fb_aper_offset == 0) { 10161bb76ff1Sjsg bus_size_t start, end; 10171bb76ff1Sjsg bus_addr_t base; 10181bb76ff1Sjsg 10191bb76ff1Sjsg KASSERT(pa->pa_memex != NULL); 10201bb76ff1Sjsg 10211bb76ff1Sjsg start = max(PCI_MEM_START, pa->pa_memex->ex_start); 10221bb76ff1Sjsg end = min(PCI_MEM_END, pa->pa_memex->ex_end); 10231bb76ff1Sjsg if (extent_alloc_subregion(pa->pa_memex, start, end, 10241bb76ff1Sjsg rdev->fb_aper_size, rdev->fb_aper_size, 0, 0, 0, &base)) { 10251bb76ff1Sjsg printf(": can't reserve framebuffer space\n"); 10261bb76ff1Sjsg return; 10271bb76ff1Sjsg } 10281bb76ff1Sjsg pci_conf_write(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, base); 10291bb76ff1Sjsg if (PCI_MAPREG_MEM_TYPE(type) == PCI_MAPREG_MEM_TYPE_64BIT) 10301bb76ff1Sjsg pci_conf_write(pa->pa_pc, pa->pa_tag, 10311bb76ff1Sjsg RADEON_PCI_MEM + 4, (uint64_t)base >> 32); 10321bb76ff1Sjsg rdev->fb_aper_offset = base; 10331bb76ff1Sjsg } 10341bb76ff1Sjsg 10351bb76ff1Sjsg for (i = PCI_MAPREG_START; i < PCI_MAPREG_END; i += 4) { 10361bb76ff1Sjsg type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, i); 10371bb76ff1Sjsg if (type == PCI_MAPREG_TYPE_IO) { 10381bb76ff1Sjsg pci_mapreg_map(pa, i, type, 0, NULL, 10391bb76ff1Sjsg &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0); 10401bb76ff1Sjsg break; 10411bb76ff1Sjsg } 10421bb76ff1Sjsg if (type == PCI_MAPREG_MEM_TYPE_64BIT) 10431bb76ff1Sjsg i += 4; 10441bb76ff1Sjsg } 10451bb76ff1Sjsg 10461bb76ff1Sjsg if (rdev->family >= CHIP_BONAIRE) { 10471bb76ff1Sjsg type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x18); 10481bb76ff1Sjsg if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || 10491bb76ff1Sjsg pci_mapreg_map(pa, 0x18, type, BUS_SPACE_MAP_LINEAR, NULL, 10501bb76ff1Sjsg &rdev->doorbell.bsh, &rdev->doorbell.base, 10511bb76ff1Sjsg &rdev->doorbell.size, 0)) { 10521bb76ff1Sjsg printf(": can't map doorbell space\n"); 10531bb76ff1Sjsg return; 10541bb76ff1Sjsg } 10551bb76ff1Sjsg rdev->doorbell.ptr = bus_space_vaddr(rdev->memt, 10561bb76ff1Sjsg rdev->doorbell.bsh); 10571bb76ff1Sjsg } 10581bb76ff1Sjsg 10591bb76ff1Sjsg if (rdev->family >= CHIP_BONAIRE) 10601bb76ff1Sjsg rmmio_bar = 0x24; 10611bb76ff1Sjsg else 10621bb76ff1Sjsg rmmio_bar = 0x18; 10631bb76ff1Sjsg 10641bb76ff1Sjsg type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, rmmio_bar); 10651bb76ff1Sjsg if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || 10661bb76ff1Sjsg pci_mapreg_map(pa, rmmio_bar, type, BUS_SPACE_MAP_LINEAR, NULL, 10671bb76ff1Sjsg &rdev->rmmio_bsh, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { 10681bb76ff1Sjsg printf(": can't map rmmio space\n"); 10691bb76ff1Sjsg return; 10701bb76ff1Sjsg } 10711bb76ff1Sjsg rdev->rmmio = bus_space_vaddr(rdev->memt, rdev->rmmio_bsh); 10721bb76ff1Sjsg 10731bb76ff1Sjsg /* 10741bb76ff1Sjsg * Make sure we have a base address for the ROM such that we 10751bb76ff1Sjsg * can map it later. 10761bb76ff1Sjsg */ 10771bb76ff1Sjsg s = splhigh(); 10781bb76ff1Sjsg addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); 10791bb76ff1Sjsg pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE); 10801bb76ff1Sjsg mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); 10811bb76ff1Sjsg pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr); 10821bb76ff1Sjsg splx(s); 10831bb76ff1Sjsg 10841bb76ff1Sjsg if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) { 10851bb76ff1Sjsg bus_size_t size, start, end; 10861bb76ff1Sjsg bus_addr_t base; 10871bb76ff1Sjsg 10881bb76ff1Sjsg size = PCI_ROM_SIZE(mask); 10891bb76ff1Sjsg start = max(PCI_MEM_START, pa->pa_memex->ex_start); 10901bb76ff1Sjsg end = min(PCI_MEM_END, pa->pa_memex->ex_end); 10911bb76ff1Sjsg if (extent_alloc_subregion(pa->pa_memex, start, end, size, 10921bb76ff1Sjsg size, 0, 0, 0, &base) == 0) 10931bb76ff1Sjsg pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base); 10941bb76ff1Sjsg } 10951bb76ff1Sjsg 10961bb76ff1Sjsg /* update BUS flag */ 10971bb76ff1Sjsg if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { 10981bb76ff1Sjsg rdev->flags |= RADEON_IS_AGP; 10991bb76ff1Sjsg } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, 11001bb76ff1Sjsg PCI_CAP_PCIEXPRESS, NULL, NULL)) { 11011bb76ff1Sjsg rdev->flags |= RADEON_IS_PCIE; 11021bb76ff1Sjsg } else { 11031bb76ff1Sjsg rdev->flags |= RADEON_IS_PCI; 11041bb76ff1Sjsg } 11051bb76ff1Sjsg 11061bb76ff1Sjsg if ((radeon_runtime_pm != 0) && 11071bb76ff1Sjsg radeon_has_atpx() && 11081bb76ff1Sjsg ((rdev->flags & RADEON_IS_IGP) == 0)) 11091bb76ff1Sjsg rdev->flags |= RADEON_IS_PX; 11101bb76ff1Sjsg 11111bb76ff1Sjsg DRM_DEBUG("%s card detected\n", 11121bb76ff1Sjsg ((rdev->flags & RADEON_IS_AGP) ? "AGP" : 11131bb76ff1Sjsg (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); 11141bb76ff1Sjsg 11151bb76ff1Sjsg is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, 11161bb76ff1Sjsg NULL, NULL); 11171bb76ff1Sjsg 11181bb76ff1Sjsg printf("\n"); 11191bb76ff1Sjsg 11201bb76ff1Sjsg dev = drm_attach_pci(&kms_driver, pa, is_agp, rdev->primary, 11211bb76ff1Sjsg self, NULL); 11221bb76ff1Sjsg if (dev == NULL) { 11231bb76ff1Sjsg printf("%s: drm attach failed\n", rdev->self.dv_xname); 11241bb76ff1Sjsg return; 11251bb76ff1Sjsg } 11261bb76ff1Sjsg rdev->ddev = dev; 11271bb76ff1Sjsg rdev->pdev = dev->pdev; 11281bb76ff1Sjsg 11291bb76ff1Sjsg if (!radeon_msi_ok(rdev)) 11301bb76ff1Sjsg pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; 11311bb76ff1Sjsg 11321bb76ff1Sjsg rdev->msi_enabled = 0; 11331bb76ff1Sjsg if (pci_intr_map_msi(pa, &rdev->intrh) == 0) 11341bb76ff1Sjsg rdev->msi_enabled = 1; 11351bb76ff1Sjsg else if (pci_intr_map(pa, &rdev->intrh) != 0) { 11361bb76ff1Sjsg printf("%s: couldn't map interrupt\n", rdev->self.dv_xname); 11371bb76ff1Sjsg return; 11381bb76ff1Sjsg } 11391bb76ff1Sjsg printf("%s: %s\n", rdev->self.dv_xname, 11401bb76ff1Sjsg pci_intr_string(pa->pa_pc, rdev->intrh)); 11411bb76ff1Sjsg 11421bb76ff1Sjsg rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, 11431bb76ff1Sjsg radeon_driver_irq_handler_kms, rdev->ddev, rdev->self.dv_xname); 11441bb76ff1Sjsg if (rdev->irqh == NULL) { 11451bb76ff1Sjsg printf("%s: couldn't establish interrupt\n", 11461bb76ff1Sjsg rdev->self.dv_xname); 11471bb76ff1Sjsg return; 11481bb76ff1Sjsg } 11491bb76ff1Sjsg rdev->pdev->irq = -1; 11501bb76ff1Sjsg 11511bb76ff1Sjsg #ifdef __sparc64__ 11521bb76ff1Sjsg { 11531bb76ff1Sjsg struct rasops_info *ri; 11541bb76ff1Sjsg int node, console; 11551bb76ff1Sjsg 11561bb76ff1Sjsg node = PCITAG_NODE(pa->pa_tag); 11571bb76ff1Sjsg console = (fbnode == node); 11581bb76ff1Sjsg 11591bb76ff1Sjsg fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); 11601bb76ff1Sjsg 11611bb76ff1Sjsg /* 11621bb76ff1Sjsg * The firmware sets up the framebuffer such that it starts at 11631bb76ff1Sjsg * an offset from the start of video memory. 11641bb76ff1Sjsg */ 11651bb76ff1Sjsg rdev->fb_offset = 11661bb76ff1Sjsg bus_space_read_4(rdev->memt, rdev->rmmio_bsh, RADEON_CRTC_OFFSET); 11671bb76ff1Sjsg if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, 11681bb76ff1Sjsg rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { 11691bb76ff1Sjsg printf("%s: can't map video memory\n", rdev->self.dv_xname); 11701bb76ff1Sjsg return; 11711bb76ff1Sjsg } 11721bb76ff1Sjsg 11731bb76ff1Sjsg ri = &rdev->sf.sf_ro; 11741bb76ff1Sjsg ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); 11751bb76ff1Sjsg ri->ri_hw = rdev; 11761bb76ff1Sjsg ri->ri_updatecursor = NULL; 11771bb76ff1Sjsg 11781bb76ff1Sjsg fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); 11791bb76ff1Sjsg if (console) 11801bb76ff1Sjsg fbwscons_console_init(&rdev->sf, -1); 11811bb76ff1Sjsg } 11821bb76ff1Sjsg #endif 11831bb76ff1Sjsg 11841bb76ff1Sjsg fb_aper = bus_space_mmap(rdev->memt, rdev->fb_aper_offset, 0, 0, 0); 11851bb76ff1Sjsg if (fb_aper != -1) 11861bb76ff1Sjsg rasops_claim_framebuffer(fb_aper, rdev->fb_aper_size, self); 11871bb76ff1Sjsg 11881bb76ff1Sjsg rdev->shutdown = true; 11891bb76ff1Sjsg config_mountroot(self, radeondrm_attachhook); 11901bb76ff1Sjsg } 11911bb76ff1Sjsg 11921bb76ff1Sjsg int 11931bb76ff1Sjsg radeondrm_forcedetach(struct radeon_device *rdev) 11941bb76ff1Sjsg { 11951bb76ff1Sjsg struct pci_softc *sc = (struct pci_softc *)rdev->self.dv_parent; 11961bb76ff1Sjsg pcitag_t tag = rdev->pa_tag; 11971bb76ff1Sjsg 11981bb76ff1Sjsg #if NVGA > 0 11991bb76ff1Sjsg if (rdev->primary) 12001bb76ff1Sjsg vga_console_attached = 0; 12011bb76ff1Sjsg #endif 12021bb76ff1Sjsg 12031bb76ff1Sjsg /* reprobe pci device for non efi systems */ 12041bb76ff1Sjsg #if NEFIFB > 0 12051bb76ff1Sjsg if (bios_efiinfo == NULL && !efifb_cb_found()) { 12061bb76ff1Sjsg #endif 12071bb76ff1Sjsg config_detach(&rdev->self, 0); 12081bb76ff1Sjsg return pci_probe_device(sc, tag, NULL, NULL); 12091bb76ff1Sjsg #if NEFIFB > 0 12101bb76ff1Sjsg } else if (rdev->primary) { 12111bb76ff1Sjsg efifb_reattach(); 12121bb76ff1Sjsg } 12131bb76ff1Sjsg #endif 12141bb76ff1Sjsg 12151bb76ff1Sjsg return 0; 12161bb76ff1Sjsg } 12171bb76ff1Sjsg 12181bb76ff1Sjsg void 12191bb76ff1Sjsg radeondrm_attachhook(struct device *self) 12201bb76ff1Sjsg { 12211bb76ff1Sjsg struct radeon_device *rdev = (struct radeon_device *)self; 1222*33a3edb1Sjsg struct drm_device *dev = rdev_to_drm(rdev); 12231bb76ff1Sjsg int r, acpi_status; 12241bb76ff1Sjsg 12251bb76ff1Sjsg /* radeon_device_init should report only fatal error 12261bb76ff1Sjsg * like memory allocation failure or iomapping failure, 12271bb76ff1Sjsg * or memory manager initialization failure, it must 12281bb76ff1Sjsg * properly initialize the GPU MC controller and permit 12291bb76ff1Sjsg * VRAM allocation 12301bb76ff1Sjsg */ 12311bb76ff1Sjsg r = radeon_device_init(rdev, rdev->ddev, rdev->ddev->pdev, rdev->flags); 12321bb76ff1Sjsg if (r) { 12331bb76ff1Sjsg dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); 12341bb76ff1Sjsg radeon_fatal_error = 1; 12351bb76ff1Sjsg radeondrm_forcedetach(rdev); 12361bb76ff1Sjsg return; 12371bb76ff1Sjsg } 12381bb76ff1Sjsg 12391bb76ff1Sjsg /* Again modeset_init should fail only on fatal error 12401bb76ff1Sjsg * otherwise it should provide enough functionalities 12411bb76ff1Sjsg * for shadowfb to run 12421bb76ff1Sjsg */ 12431bb76ff1Sjsg r = radeon_modeset_init(rdev); 12441bb76ff1Sjsg if (r) 12451bb76ff1Sjsg dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); 12461bb76ff1Sjsg 12471bb76ff1Sjsg /* Call ACPI methods: require modeset init 12481bb76ff1Sjsg * but failure is not fatal 12491bb76ff1Sjsg */ 12501bb76ff1Sjsg if (!r) { 12511bb76ff1Sjsg acpi_status = radeon_acpi_init(rdev); 12521bb76ff1Sjsg if (acpi_status) 12531bb76ff1Sjsg DRM_DEBUG("Error during ACPI methods call\n"); 12541bb76ff1Sjsg } 12551bb76ff1Sjsg 12561bb76ff1Sjsg #ifdef notyet 12571bb76ff1Sjsg radeon_kfd_device_probe(rdev); 12581bb76ff1Sjsg radeon_kfd_device_init(rdev); 12591bb76ff1Sjsg #endif 12601bb76ff1Sjsg 12611bb76ff1Sjsg if (radeon_is_px(rdev->ddev)) { 12621bb76ff1Sjsg pm_runtime_use_autosuspend(dev->dev); 12631bb76ff1Sjsg pm_runtime_set_autosuspend_delay(dev->dev, 5000); 12641bb76ff1Sjsg pm_runtime_set_active(dev->dev); 12651bb76ff1Sjsg pm_runtime_allow(dev->dev); 12661bb76ff1Sjsg pm_runtime_mark_last_busy(dev->dev); 12671bb76ff1Sjsg pm_runtime_put_autosuspend(dev->dev); 12681bb76ff1Sjsg } 12691bb76ff1Sjsg 12701bb76ff1Sjsg { 12711bb76ff1Sjsg struct wsemuldisplaydev_attach_args aa; 12721bb76ff1Sjsg struct rasops_info *ri = &rdev->ro; 12731bb76ff1Sjsg 12741bb76ff1Sjsg task_set(&rdev->switchtask, radeondrm_doswitch, ri); 12751bb76ff1Sjsg 1276241151fdSjsg /* from linux radeon_pci_probe() */ 1277241151fdSjsg 1278241151fdSjsg pci_set_drvdata(dev->pdev, dev); 1279241151fdSjsg 1280241151fdSjsg drm_dev_register(dev, rdev->flags); 1281f005ef32Sjsg 1282f005ef32Sjsg radeon_fbdev_setup(rdev); 1283f005ef32Sjsg 12841bb76ff1Sjsg if (ri->ri_bits == NULL) 12851bb76ff1Sjsg return; 12861bb76ff1Sjsg 12871bb76ff1Sjsg #ifdef __sparc64__ 12881bb76ff1Sjsg fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); 12891bb76ff1Sjsg ri = &rdev->sf.sf_ro; 12901bb76ff1Sjsg #else 12911bb76ff1Sjsg radeondrm_setpal(rdev, ri); 12921bb76ff1Sjsg ri->ri_flg = RI_CENTER | RI_VCONS | RI_WRONLY; 12931bb76ff1Sjsg rasops_init(ri, 160, 160); 12941bb76ff1Sjsg 12951bb76ff1Sjsg ri->ri_hw = rdev; 12961bb76ff1Sjsg #endif 12971bb76ff1Sjsg 12981bb76ff1Sjsg radeondrm_stdscreen.capabilities = ri->ri_caps; 12991bb76ff1Sjsg radeondrm_stdscreen.nrows = ri->ri_rows; 13001bb76ff1Sjsg radeondrm_stdscreen.ncols = ri->ri_cols; 13011bb76ff1Sjsg radeondrm_stdscreen.textops = &ri->ri_ops; 13021bb76ff1Sjsg radeondrm_stdscreen.fontwidth = ri->ri_font->fontwidth; 13031bb76ff1Sjsg radeondrm_stdscreen.fontheight = ri->ri_font->fontheight; 13041bb76ff1Sjsg 13051bb76ff1Sjsg aa.console = rdev->console; 13061bb76ff1Sjsg aa.primary = rdev->primary; 13071bb76ff1Sjsg aa.scrdata = &radeondrm_screenlist; 13081bb76ff1Sjsg aa.accessops = &radeondrm_accessops; 13091bb76ff1Sjsg aa.accesscookie = ri; 13101bb76ff1Sjsg aa.defaultscreens = 0; 13111bb76ff1Sjsg 13121bb76ff1Sjsg if (rdev->console) { 13131bb76ff1Sjsg uint32_t defattr; 13141bb76ff1Sjsg 13151bb76ff1Sjsg ri->ri_ops.pack_attr(ri->ri_active, 0, 0, 0, &defattr); 13161bb76ff1Sjsg wsdisplay_cnattach(&radeondrm_stdscreen, ri->ri_active, 13171bb76ff1Sjsg ri->ri_ccol, ri->ri_crow, defattr); 13181bb76ff1Sjsg } 13191bb76ff1Sjsg 13201bb76ff1Sjsg /* 13211bb76ff1Sjsg * Now that we've taken over the console, disable decoding of 13221bb76ff1Sjsg * VGA legacy addresses, and opt out of arbitration. 13231bb76ff1Sjsg */ 13241bb76ff1Sjsg radeon_vga_set_state(rdev, false); 13251bb76ff1Sjsg pci_disable_legacy_vga(&rdev->self); 13261bb76ff1Sjsg 13271bb76ff1Sjsg printf("%s: %dx%d, %dbpp\n", rdev->self.dv_xname, 13281bb76ff1Sjsg ri->ri_width, ri->ri_height, ri->ri_depth); 13291bb76ff1Sjsg 13301bb76ff1Sjsg config_found_sm(&rdev->self, &aa, wsemuldisplaydevprint, 13311bb76ff1Sjsg wsemuldisplaydevsubmatch); 13321bb76ff1Sjsg } 13331bb76ff1Sjsg } 13341bb76ff1Sjsg 13351bb76ff1Sjsg int 13361bb76ff1Sjsg radeondrm_activate_kms(struct device *self, int act) 13371bb76ff1Sjsg { 13381bb76ff1Sjsg struct radeon_device *rdev = (struct radeon_device *)self; 13391bb76ff1Sjsg int rv = 0; 13401bb76ff1Sjsg 13411bb76ff1Sjsg if (rdev->ddev == NULL || radeon_fatal_error) 13421bb76ff1Sjsg return (0); 13431bb76ff1Sjsg 13441bb76ff1Sjsg switch (act) { 13451bb76ff1Sjsg case DVACT_QUIESCE: 13461bb76ff1Sjsg rv = config_activate_children(self, act); 13471bb76ff1Sjsg radeon_suspend_kms(rdev->ddev, true, true, false); 13481bb76ff1Sjsg break; 13491bb76ff1Sjsg case DVACT_SUSPEND: 13501bb76ff1Sjsg break; 13511bb76ff1Sjsg case DVACT_RESUME: 13521bb76ff1Sjsg break; 13531bb76ff1Sjsg case DVACT_WAKEUP: 13541bb76ff1Sjsg radeon_resume_kms(rdev->ddev, true, true); 13551bb76ff1Sjsg rv = config_activate_children(self, act); 13561bb76ff1Sjsg break; 13571bb76ff1Sjsg } 13581bb76ff1Sjsg 13591bb76ff1Sjsg return (rv); 13601bb76ff1Sjsg } 1361