diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 685 |
1 files changed, 459 insertions, 226 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 7b65e4efe8af..bc54b26cb32f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | 47 | #define EVERGREEN_PFP_UCODE_SIZE 1120 |
48 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | 48 | #define EVERGREEN_PM4_UCODE_SIZE 1376 |
49 | #define EVERGREEN_RLC_UCODE_SIZE 768 | 49 | #define EVERGREEN_RLC_UCODE_SIZE 768 |
50 | #define CAYMAN_RLC_UCODE_SIZE 1024 | ||
50 | 51 | ||
51 | /* Firmware Names */ | 52 | /* Firmware Names */ |
52 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); | 53 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); |
@@ -83,6 +84,13 @@ MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); | |||
83 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); | 84 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); |
84 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); | 85 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); |
85 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); | 86 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); |
87 | MODULE_FIRMWARE("radeon/PALM_pfp.bin"); | ||
88 | MODULE_FIRMWARE("radeon/PALM_me.bin"); | ||
89 | MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); | ||
90 | MODULE_FIRMWARE("radeon/SUMO_pfp.bin"); | ||
91 | MODULE_FIRMWARE("radeon/SUMO_me.bin"); | ||
92 | MODULE_FIRMWARE("radeon/SUMO2_pfp.bin"); | ||
93 | MODULE_FIRMWARE("radeon/SUMO2_me.bin"); | ||
86 | 94 | ||
87 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | 95 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); |
88 | 96 | ||
@@ -91,18 +99,17 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
91 | void r600_gpu_init(struct radeon_device *rdev); | 99 | void r600_gpu_init(struct radeon_device *rdev); |
92 | void r600_fini(struct radeon_device *rdev); | 100 | void r600_fini(struct radeon_device *rdev); |
93 | void r600_irq_disable(struct radeon_device *rdev); | 101 | void r600_irq_disable(struct radeon_device *rdev); |
102 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | ||
94 | 103 | ||
95 | /* get temperature in millidegrees */ | 104 | /* get temperature in millidegrees */ |
96 | u32 rv6xx_get_temp(struct radeon_device *rdev) | 105 | int rv6xx_get_temp(struct radeon_device *rdev) |
97 | { | 106 | { |
98 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> | 107 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> |
99 | ASIC_T_SHIFT; | 108 | ASIC_T_SHIFT; |
100 | u32 actual_temp = 0; | 109 | int actual_temp = temp & 0xff; |
101 | 110 | ||
102 | if ((temp >> 7) & 1) | 111 | if (temp & 0x100) |
103 | actual_temp = 0; | 112 | actual_temp -= 256; |
104 | else | ||
105 | actual_temp = (temp >> 1) & 0xff; | ||
106 | 113 | ||
107 | return actual_temp * 1000; | 114 | return actual_temp * 1000; |
108 | } | 115 | } |
@@ -583,8 +590,11 @@ void r600_pm_misc(struct radeon_device *rdev) | |||
583 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 590 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
584 | 591 | ||
585 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 592 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
593 | /* 0xff01 is a flag rather then an actual voltage */ | ||
594 | if (voltage->voltage == 0xff01) | ||
595 | return; | ||
586 | if (voltage->voltage != rdev->pm.current_vddc) { | 596 | if (voltage->voltage != rdev->pm.current_vddc) { |
587 | radeon_atom_set_voltage(rdev, voltage->voltage); | 597 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
588 | rdev->pm.current_vddc = voltage->voltage; | 598 | rdev->pm.current_vddc = voltage->voltage; |
589 | DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); | 599 | DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); |
590 | } | 600 | } |
@@ -884,12 +894,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
884 | u32 tmp; | 894 | u32 tmp; |
885 | 895 | ||
886 | /* flush hdp cache so updates hit vram */ | 896 | /* flush hdp cache so updates hit vram */ |
887 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 897 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
898 | !(rdev->flags & RADEON_IS_AGP)) { | ||
888 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 899 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; |
889 | u32 tmp; | 900 | u32 tmp; |
890 | 901 | ||
891 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 902 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
892 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 903 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
904 | * This seems to cause problems on some AGP cards. Just use the old | ||
905 | * method for them. | ||
893 | */ | 906 | */ |
894 | WREG32(HDP_DEBUG1, 0); | 907 | WREG32(HDP_DEBUG1, 0); |
895 | tmp = readl((void __iomem *)ptr); | 908 | tmp = readl((void __iomem *)ptr); |
@@ -919,7 +932,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) | |||
919 | int r; | 932 | int r; |
920 | 933 | ||
921 | if (rdev->gart.table.vram.robj) { | 934 | if (rdev->gart.table.vram.robj) { |
922 | WARN(1, "R600 PCIE GART already initialized.\n"); | 935 | WARN(1, "R600 PCIE GART already initialized\n"); |
923 | return 0; | 936 | return 0; |
924 | } | 937 | } |
925 | /* Initialize common gart structure */ | 938 | /* Initialize common gart structure */ |
@@ -1167,7 +1180,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
1167 | * Note: GTT start, end, size should be initialized before calling this | 1180 | * Note: GTT start, end, size should be initialized before calling this |
1168 | * function on AGP platform. | 1181 | * function on AGP platform. |
1169 | */ | 1182 | */ |
1170 | void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 1183 | static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
1171 | { | 1184 | { |
1172 | u64 size_bf, size_af; | 1185 | u64 size_bf, size_af; |
1173 | 1186 | ||
@@ -1201,8 +1214,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
1201 | mc->vram_end, mc->real_vram_size >> 20); | 1214 | mc->vram_end, mc->real_vram_size >> 20); |
1202 | } else { | 1215 | } else { |
1203 | u64 base = 0; | 1216 | u64 base = 0; |
1204 | if (rdev->flags & RADEON_IS_IGP) | 1217 | if (rdev->flags & RADEON_IS_IGP) { |
1205 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | 1218 | base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; |
1219 | base <<= 24; | ||
1220 | } | ||
1206 | radeon_vram_location(rdev, &rdev->mc, base); | 1221 | radeon_vram_location(rdev, &rdev->mc, base); |
1207 | rdev->mc.gtt_base_align = 0; | 1222 | rdev->mc.gtt_base_align = 0; |
1208 | radeon_gtt_location(rdev, mc); | 1223 | radeon_gtt_location(rdev, mc); |
@@ -1248,7 +1263,6 @@ int r600_mc_init(struct radeon_device *rdev) | |||
1248 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1263 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
1249 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1264 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
1250 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1265 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
1251 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
1252 | r600_vram_gtt_location(rdev, &rdev->mc); | 1266 | r600_vram_gtt_location(rdev, &rdev->mc); |
1253 | 1267 | ||
1254 | if (rdev->flags & RADEON_IS_IGP) { | 1268 | if (rdev->flags & RADEON_IS_IGP) { |
@@ -1284,6 +1298,9 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1284 | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); | 1298 | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); |
1285 | u32 tmp; | 1299 | u32 tmp; |
1286 | 1300 | ||
1301 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
1302 | return 0; | ||
1303 | |||
1287 | dev_info(rdev->dev, "GPU softreset \n"); | 1304 | dev_info(rdev->dev, "GPU softreset \n"); |
1288 | dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", | 1305 | dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", |
1289 | RREG32(R_008010_GRBM_STATUS)); | 1306 | RREG32(R_008010_GRBM_STATUS)); |
@@ -1343,13 +1360,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) | |||
1343 | u32 srbm_status; | 1360 | u32 srbm_status; |
1344 | u32 grbm_status; | 1361 | u32 grbm_status; |
1345 | u32 grbm_status2; | 1362 | u32 grbm_status2; |
1363 | struct r100_gpu_lockup *lockup; | ||
1346 | int r; | 1364 | int r; |
1347 | 1365 | ||
1366 | if (rdev->family >= CHIP_RV770) | ||
1367 | lockup = &rdev->config.rv770.lockup; | ||
1368 | else | ||
1369 | lockup = &rdev->config.r600.lockup; | ||
1370 | |||
1348 | srbm_status = RREG32(R_000E50_SRBM_STATUS); | 1371 | srbm_status = RREG32(R_000E50_SRBM_STATUS); |
1349 | grbm_status = RREG32(R_008010_GRBM_STATUS); | 1372 | grbm_status = RREG32(R_008010_GRBM_STATUS); |
1350 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); | 1373 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); |
1351 | if (!G_008010_GUI_ACTIVE(grbm_status)) { | 1374 | if (!G_008010_GUI_ACTIVE(grbm_status)) { |
1352 | r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); | 1375 | r100_gpu_lockup_update(lockup, &rdev->cp); |
1353 | return false; | 1376 | return false; |
1354 | } | 1377 | } |
1355 | /* force CP activities */ | 1378 | /* force CP activities */ |
@@ -1361,7 +1384,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) | |||
1361 | radeon_ring_unlock_commit(rdev); | 1384 | radeon_ring_unlock_commit(rdev); |
1362 | } | 1385 | } |
1363 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | 1386 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); |
1364 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); | 1387 | return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); |
1365 | } | 1388 | } |
1366 | 1389 | ||
1367 | int r600_asic_reset(struct radeon_device *rdev) | 1390 | int r600_asic_reset(struct radeon_device *rdev) |
@@ -1608,8 +1631,11 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
1608 | rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; | 1631 | rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; |
1609 | rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | 1632 | rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
1610 | tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | 1633 | tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
1611 | tiling_config |= GROUP_SIZE(0); | 1634 | tiling_config |= GROUP_SIZE((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); |
1612 | rdev->config.r600.tiling_group_size = 256; | 1635 | if ((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) |
1636 | rdev->config.r600.tiling_group_size = 512; | ||
1637 | else | ||
1638 | rdev->config.r600.tiling_group_size = 256; | ||
1613 | tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; | 1639 | tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; |
1614 | if (tmp > 3) { | 1640 | if (tmp > 3) { |
1615 | tiling_config |= ROW_TILING(3); | 1641 | tiling_config |= ROW_TILING(3); |
@@ -1918,8 +1944,9 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1918 | */ | 1944 | */ |
1919 | void r600_cp_stop(struct radeon_device *rdev) | 1945 | void r600_cp_stop(struct radeon_device *rdev) |
1920 | { | 1946 | { |
1921 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1947 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
1922 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1948 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
1949 | WREG32(SCRATCH_UMSK, 0); | ||
1923 | } | 1950 | } |
1924 | 1951 | ||
1925 | int r600_init_microcode(struct radeon_device *rdev) | 1952 | int r600_init_microcode(struct radeon_device *rdev) |
@@ -2000,6 +2027,18 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2000 | chip_name = "CYPRESS"; | 2027 | chip_name = "CYPRESS"; |
2001 | rlc_chip_name = "CYPRESS"; | 2028 | rlc_chip_name = "CYPRESS"; |
2002 | break; | 2029 | break; |
2030 | case CHIP_PALM: | ||
2031 | chip_name = "PALM"; | ||
2032 | rlc_chip_name = "SUMO"; | ||
2033 | break; | ||
2034 | case CHIP_SUMO: | ||
2035 | chip_name = "SUMO"; | ||
2036 | rlc_chip_name = "SUMO"; | ||
2037 | break; | ||
2038 | case CHIP_SUMO2: | ||
2039 | chip_name = "SUMO2"; | ||
2040 | rlc_chip_name = "SUMO"; | ||
2041 | break; | ||
2003 | default: BUG(); | 2042 | default: BUG(); |
2004 | } | 2043 | } |
2005 | 2044 | ||
@@ -2081,7 +2120,11 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) | |||
2081 | 2120 | ||
2082 | r600_cp_stop(rdev); | 2121 | r600_cp_stop(rdev); |
2083 | 2122 | ||
2084 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | 2123 | WREG32(CP_RB_CNTL, |
2124 | #ifdef __BIG_ENDIAN | ||
2125 | BUF_SWAP_32BIT | | ||
2126 | #endif | ||
2127 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
2085 | 2128 | ||
2086 | /* Reset cp */ | 2129 | /* Reset cp */ |
2087 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | 2130 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); |
@@ -2152,7 +2195,7 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2152 | 2195 | ||
2153 | /* Set ring buffer size */ | 2196 | /* Set ring buffer size */ |
2154 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | 2197 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); |
2155 | tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | 2198 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; |
2156 | #ifdef __BIG_ENDIAN | 2199 | #ifdef __BIG_ENDIAN |
2157 | tmp |= BUF_SWAP_32BIT; | 2200 | tmp |= BUF_SWAP_32BIT; |
2158 | #endif | 2201 | #endif |
@@ -2166,8 +2209,23 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2166 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 2209 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
2167 | WREG32(CP_RB_RPTR_WR, 0); | 2210 | WREG32(CP_RB_RPTR_WR, 0); |
2168 | WREG32(CP_RB_WPTR, 0); | 2211 | WREG32(CP_RB_WPTR, 0); |
2169 | WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF); | 2212 | |
2170 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr)); | 2213 | /* set the wb address whether it's enabled or not */ |
2214 | WREG32(CP_RB_RPTR_ADDR, | ||
2215 | #ifdef __BIG_ENDIAN | ||
2216 | RB_RPTR_SWAP(2) | | ||
2217 | #endif | ||
2218 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | ||
2219 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | ||
2220 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | ||
2221 | |||
2222 | if (rdev->wb.enabled) | ||
2223 | WREG32(SCRATCH_UMSK, 0xff); | ||
2224 | else { | ||
2225 | tmp |= RB_NO_UPDATE; | ||
2226 | WREG32(SCRATCH_UMSK, 0); | ||
2227 | } | ||
2228 | |||
2171 | mdelay(1); | 2229 | mdelay(1); |
2172 | WREG32(CP_RB_CNTL, tmp); | 2230 | WREG32(CP_RB_CNTL, tmp); |
2173 | 2231 | ||
@@ -2219,9 +2277,10 @@ void r600_scratch_init(struct radeon_device *rdev) | |||
2219 | int i; | 2277 | int i; |
2220 | 2278 | ||
2221 | rdev->scratch.num_reg = 7; | 2279 | rdev->scratch.num_reg = 7; |
2280 | rdev->scratch.reg_base = SCRATCH_REG0; | ||
2222 | for (i = 0; i < rdev->scratch.num_reg; i++) { | 2281 | for (i = 0; i < rdev->scratch.num_reg; i++) { |
2223 | rdev->scratch.free[i] = true; | 2282 | rdev->scratch.free[i] = true; |
2224 | rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4); | 2283 | rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); |
2225 | } | 2284 | } |
2226 | } | 2285 | } |
2227 | 2286 | ||
@@ -2265,88 +2324,34 @@ int r600_ring_test(struct radeon_device *rdev) | |||
2265 | return r; | 2324 | return r; |
2266 | } | 2325 | } |
2267 | 2326 | ||
2268 | void r600_wb_disable(struct radeon_device *rdev) | ||
2269 | { | ||
2270 | int r; | ||
2271 | |||
2272 | WREG32(SCRATCH_UMSK, 0); | ||
2273 | if (rdev->wb.wb_obj) { | ||
2274 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | ||
2275 | if (unlikely(r != 0)) | ||
2276 | return; | ||
2277 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
2278 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
2279 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
2280 | } | ||
2281 | } | ||
2282 | |||
2283 | void r600_wb_fini(struct radeon_device *rdev) | ||
2284 | { | ||
2285 | r600_wb_disable(rdev); | ||
2286 | if (rdev->wb.wb_obj) { | ||
2287 | radeon_bo_unref(&rdev->wb.wb_obj); | ||
2288 | rdev->wb.wb = NULL; | ||
2289 | rdev->wb.wb_obj = NULL; | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | int r600_wb_enable(struct radeon_device *rdev) | ||
2294 | { | ||
2295 | int r; | ||
2296 | |||
2297 | if (rdev->wb.wb_obj == NULL) { | ||
2298 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, | ||
2299 | RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); | ||
2300 | if (r) { | ||
2301 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); | ||
2302 | return r; | ||
2303 | } | ||
2304 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | ||
2305 | if (unlikely(r != 0)) { | ||
2306 | r600_wb_fini(rdev); | ||
2307 | return r; | ||
2308 | } | ||
2309 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | ||
2310 | &rdev->wb.gpu_addr); | ||
2311 | if (r) { | ||
2312 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
2313 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | ||
2314 | r600_wb_fini(rdev); | ||
2315 | return r; | ||
2316 | } | ||
2317 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | ||
2318 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
2319 | if (r) { | ||
2320 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); | ||
2321 | r600_wb_fini(rdev); | ||
2322 | return r; | ||
2323 | } | ||
2324 | } | ||
2325 | WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF); | ||
2326 | WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC); | ||
2327 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF); | ||
2328 | WREG32(SCRATCH_UMSK, 0xff); | ||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | void r600_fence_ring_emit(struct radeon_device *rdev, | 2327 | void r600_fence_ring_emit(struct radeon_device *rdev, |
2333 | struct radeon_fence *fence) | 2328 | struct radeon_fence *fence) |
2334 | { | 2329 | { |
2335 | /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ | 2330 | if (rdev->wb.use_event) { |
2336 | 2331 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + | |
2337 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | 2332 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); |
2338 | radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); | 2333 | /* EVENT_WRITE_EOP - flush caches, send int */ |
2339 | /* wait for 3D idle clean */ | 2334 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); |
2340 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2335 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); |
2341 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2336 | radeon_ring_write(rdev, addr & 0xffffffff); |
2342 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | 2337 | radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); |
2343 | /* Emit fence sequence & fire IRQ */ | 2338 | radeon_ring_write(rdev, fence->seq); |
2344 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2339 | radeon_ring_write(rdev, 0); |
2345 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 2340 | } else { |
2346 | radeon_ring_write(rdev, fence->seq); | 2341 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); |
2347 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | 2342 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); |
2348 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | 2343 | /* wait for 3D idle clean */ |
2349 | radeon_ring_write(rdev, RB_INT_STAT); | 2344 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2345 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
2346 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | ||
2347 | /* Emit fence sequence & fire IRQ */ | ||
2348 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
2349 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | ||
2350 | radeon_ring_write(rdev, fence->seq); | ||
2351 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | ||
2352 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | ||
2353 | radeon_ring_write(rdev, RB_INT_STAT); | ||
2354 | } | ||
2350 | } | 2355 | } |
2351 | 2356 | ||
2352 | int r600_copy_blit(struct radeon_device *rdev, | 2357 | int r600_copy_blit(struct radeon_device *rdev, |
@@ -2383,28 +2388,13 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) | |||
2383 | /* FIXME: implement */ | 2388 | /* FIXME: implement */ |
2384 | } | 2389 | } |
2385 | 2390 | ||
2386 | |||
2387 | bool r600_card_posted(struct radeon_device *rdev) | ||
2388 | { | ||
2389 | uint32_t reg; | ||
2390 | |||
2391 | /* first check CRTCs */ | ||
2392 | reg = RREG32(D1CRTC_CONTROL) | | ||
2393 | RREG32(D2CRTC_CONTROL); | ||
2394 | if (reg & CRTC_EN) | ||
2395 | return true; | ||
2396 | |||
2397 | /* then check MEM_SIZE, in case the crtcs are off */ | ||
2398 | if (RREG32(CONFIG_MEMSIZE)) | ||
2399 | return true; | ||
2400 | |||
2401 | return false; | ||
2402 | } | ||
2403 | |||
2404 | int r600_startup(struct radeon_device *rdev) | 2391 | int r600_startup(struct radeon_device *rdev) |
2405 | { | 2392 | { |
2406 | int r; | 2393 | int r; |
2407 | 2394 | ||
2395 | /* enable pcie gen2 link */ | ||
2396 | r600_pcie_gen2_enable(rdev); | ||
2397 | |||
2408 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2398 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
2409 | r = r600_init_microcode(rdev); | 2399 | r = r600_init_microcode(rdev); |
2410 | if (r) { | 2400 | if (r) { |
@@ -2428,19 +2418,12 @@ int r600_startup(struct radeon_device *rdev) | |||
2428 | rdev->asic->copy = NULL; | 2418 | rdev->asic->copy = NULL; |
2429 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 2419 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
2430 | } | 2420 | } |
2431 | /* pin copy shader into vram */ | 2421 | |
2432 | if (rdev->r600_blit.shader_obj) { | 2422 | /* allocate wb buffer */ |
2433 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 2423 | r = radeon_wb_init(rdev); |
2434 | if (unlikely(r != 0)) | 2424 | if (r) |
2435 | return r; | 2425 | return r; |
2436 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | 2426 | |
2437 | &rdev->r600_blit.shader_gpu_addr); | ||
2438 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
2439 | if (r) { | ||
2440 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
2441 | return r; | ||
2442 | } | ||
2443 | } | ||
2444 | /* Enable IRQ */ | 2427 | /* Enable IRQ */ |
2445 | r = r600_irq_init(rdev); | 2428 | r = r600_irq_init(rdev); |
2446 | if (r) { | 2429 | if (r) { |
@@ -2459,8 +2442,7 @@ int r600_startup(struct radeon_device *rdev) | |||
2459 | r = r600_cp_resume(rdev); | 2442 | r = r600_cp_resume(rdev); |
2460 | if (r) | 2443 | if (r) |
2461 | return r; | 2444 | return r; |
2462 | /* write back buffer are not vital so don't worry about failure */ | 2445 | |
2463 | r600_wb_enable(rdev); | ||
2464 | return 0; | 2446 | return 0; |
2465 | } | 2447 | } |
2466 | 2448 | ||
@@ -2497,7 +2479,7 @@ int r600_resume(struct radeon_device *rdev) | |||
2497 | 2479 | ||
2498 | r = r600_ib_test(rdev); | 2480 | r = r600_ib_test(rdev); |
2499 | if (r) { | 2481 | if (r) { |
2500 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 2482 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
2501 | return r; | 2483 | return r; |
2502 | } | 2484 | } |
2503 | 2485 | ||
@@ -2519,7 +2501,7 @@ int r600_suspend(struct radeon_device *rdev) | |||
2519 | r600_cp_stop(rdev); | 2501 | r600_cp_stop(rdev); |
2520 | rdev->cp.ready = false; | 2502 | rdev->cp.ready = false; |
2521 | r600_irq_suspend(rdev); | 2503 | r600_irq_suspend(rdev); |
2522 | r600_wb_disable(rdev); | 2504 | radeon_wb_disable(rdev); |
2523 | r600_pcie_gart_disable(rdev); | 2505 | r600_pcie_gart_disable(rdev); |
2524 | /* unpin shaders bo */ | 2506 | /* unpin shaders bo */ |
2525 | if (rdev->r600_blit.shader_obj) { | 2507 | if (rdev->r600_blit.shader_obj) { |
@@ -2542,9 +2524,6 @@ int r600_init(struct radeon_device *rdev) | |||
2542 | { | 2524 | { |
2543 | int r; | 2525 | int r; |
2544 | 2526 | ||
2545 | r = radeon_dummy_page_init(rdev); | ||
2546 | if (r) | ||
2547 | return r; | ||
2548 | if (r600_debugfs_mc_info_init(rdev)) { | 2527 | if (r600_debugfs_mc_info_init(rdev)) { |
2549 | DRM_ERROR("Failed to register debugfs file for mc !\n"); | 2528 | DRM_ERROR("Failed to register debugfs file for mc !\n"); |
2550 | } | 2529 | } |
@@ -2566,7 +2545,7 @@ int r600_init(struct radeon_device *rdev) | |||
2566 | if (r) | 2545 | if (r) |
2567 | return r; | 2546 | return r; |
2568 | /* Post card if necessary */ | 2547 | /* Post card if necessary */ |
2569 | if (!r600_card_posted(rdev)) { | 2548 | if (!radeon_card_posted(rdev)) { |
2570 | if (!rdev->bios) { | 2549 | if (!rdev->bios) { |
2571 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | 2550 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); |
2572 | return -EINVAL; | 2551 | return -EINVAL; |
@@ -2616,8 +2595,8 @@ int r600_init(struct radeon_device *rdev) | |||
2616 | if (r) { | 2595 | if (r) { |
2617 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 2596 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2618 | r600_cp_fini(rdev); | 2597 | r600_cp_fini(rdev); |
2619 | r600_wb_fini(rdev); | ||
2620 | r600_irq_fini(rdev); | 2598 | r600_irq_fini(rdev); |
2599 | radeon_wb_fini(rdev); | ||
2621 | radeon_irq_kms_fini(rdev); | 2600 | radeon_irq_kms_fini(rdev); |
2622 | r600_pcie_gart_fini(rdev); | 2601 | r600_pcie_gart_fini(rdev); |
2623 | rdev->accel_working = false; | 2602 | rdev->accel_working = false; |
@@ -2647,8 +2626,9 @@ void r600_fini(struct radeon_device *rdev) | |||
2647 | r600_audio_fini(rdev); | 2626 | r600_audio_fini(rdev); |
2648 | r600_blit_fini(rdev); | 2627 | r600_blit_fini(rdev); |
2649 | r600_cp_fini(rdev); | 2628 | r600_cp_fini(rdev); |
2650 | r600_wb_fini(rdev); | ||
2651 | r600_irq_fini(rdev); | 2629 | r600_irq_fini(rdev); |
2630 | radeon_wb_fini(rdev); | ||
2631 | radeon_ib_pool_fini(rdev); | ||
2652 | radeon_irq_kms_fini(rdev); | 2632 | radeon_irq_kms_fini(rdev); |
2653 | r600_pcie_gart_fini(rdev); | 2633 | r600_pcie_gart_fini(rdev); |
2654 | radeon_agp_fini(rdev); | 2634 | radeon_agp_fini(rdev); |
@@ -2658,7 +2638,6 @@ void r600_fini(struct radeon_device *rdev) | |||
2658 | radeon_atombios_fini(rdev); | 2638 | radeon_atombios_fini(rdev); |
2659 | kfree(rdev->bios); | 2639 | kfree(rdev->bios); |
2660 | rdev->bios = NULL; | 2640 | rdev->bios = NULL; |
2661 | radeon_dummy_page_fini(rdev); | ||
2662 | } | 2641 | } |
2663 | 2642 | ||
2664 | 2643 | ||
@@ -2669,7 +2648,11 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
2669 | { | 2648 | { |
2670 | /* FIXME: implement */ | 2649 | /* FIXME: implement */ |
2671 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 2650 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
2672 | radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); | 2651 | radeon_ring_write(rdev, |
2652 | #ifdef __BIG_ENDIAN | ||
2653 | (2 << 0) | | ||
2654 | #endif | ||
2655 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
2673 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | 2656 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); |
2674 | radeon_ring_write(rdev, ib->length_dw); | 2657 | radeon_ring_write(rdev, ib->length_dw); |
2675 | } | 2658 | } |
@@ -2769,8 +2752,8 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev) | |||
2769 | 2752 | ||
2770 | /* Allocate ring buffer */ | 2753 | /* Allocate ring buffer */ |
2771 | if (rdev->ih.ring_obj == NULL) { | 2754 | if (rdev->ih.ring_obj == NULL) { |
2772 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, | 2755 | r = radeon_bo_create(rdev, rdev->ih.ring_size, |
2773 | true, | 2756 | PAGE_SIZE, true, |
2774 | RADEON_GEM_DOMAIN_GTT, | 2757 | RADEON_GEM_DOMAIN_GTT, |
2775 | &rdev->ih.ring_obj); | 2758 | &rdev->ih.ring_obj); |
2776 | if (r) { | 2759 | if (r) { |
@@ -2850,13 +2833,20 @@ static int r600_rlc_init(struct radeon_device *rdev) | |||
2850 | WREG32(RLC_HB_CNTL, 0); | 2833 | WREG32(RLC_HB_CNTL, 0); |
2851 | WREG32(RLC_HB_RPTR, 0); | 2834 | WREG32(RLC_HB_RPTR, 0); |
2852 | WREG32(RLC_HB_WPTR, 0); | 2835 | WREG32(RLC_HB_WPTR, 0); |
2853 | WREG32(RLC_HB_WPTR_LSB_ADDR, 0); | 2836 | if (rdev->family <= CHIP_CAICOS) { |
2854 | WREG32(RLC_HB_WPTR_MSB_ADDR, 0); | 2837 | WREG32(RLC_HB_WPTR_LSB_ADDR, 0); |
2838 | WREG32(RLC_HB_WPTR_MSB_ADDR, 0); | ||
2839 | } | ||
2855 | WREG32(RLC_MC_CNTL, 0); | 2840 | WREG32(RLC_MC_CNTL, 0); |
2856 | WREG32(RLC_UCODE_CNTL, 0); | 2841 | WREG32(RLC_UCODE_CNTL, 0); |
2857 | 2842 | ||
2858 | fw_data = (const __be32 *)rdev->rlc_fw->data; | 2843 | fw_data = (const __be32 *)rdev->rlc_fw->data; |
2859 | if (rdev->family >= CHIP_CEDAR) { | 2844 | if (rdev->family >= CHIP_CAYMAN) { |
2845 | for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) { | ||
2846 | WREG32(RLC_UCODE_ADDR, i); | ||
2847 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
2848 | } | ||
2849 | } else if (rdev->family >= CHIP_CEDAR) { | ||
2860 | for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { | 2850 | for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { |
2861 | WREG32(RLC_UCODE_ADDR, i); | 2851 | WREG32(RLC_UCODE_ADDR, i); |
2862 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | 2852 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); |
@@ -2915,6 +2905,8 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
2915 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2905 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
2916 | WREG32(GRBM_INT_CNTL, 0); | 2906 | WREG32(GRBM_INT_CNTL, 0); |
2917 | WREG32(DxMODE_INT_MASK, 0); | 2907 | WREG32(DxMODE_INT_MASK, 0); |
2908 | WREG32(D1GRPH_INTERRUPT_CONTROL, 0); | ||
2909 | WREG32(D2GRPH_INTERRUPT_CONTROL, 0); | ||
2918 | if (ASIC_IS_DCE3(rdev)) { | 2910 | if (ASIC_IS_DCE3(rdev)) { |
2919 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | 2911 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); |
2920 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | 2912 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); |
@@ -2983,10 +2975,13 @@ int r600_irq_init(struct radeon_device *rdev) | |||
2983 | ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | | 2975 | ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | |
2984 | IH_WPTR_OVERFLOW_CLEAR | | 2976 | IH_WPTR_OVERFLOW_CLEAR | |
2985 | (rb_bufsz << 1)); | 2977 | (rb_bufsz << 1)); |
2986 | /* WPTR writeback, not yet */ | 2978 | |
2987 | /*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/ | 2979 | if (rdev->wb.enabled) |
2988 | WREG32(IH_RB_WPTR_ADDR_LO, 0); | 2980 | ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; |
2989 | WREG32(IH_RB_WPTR_ADDR_HI, 0); | 2981 | |
2982 | /* set the writeback address whether it's enabled or not */ | ||
2983 | WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); | ||
2984 | WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); | ||
2990 | 2985 | ||
2991 | WREG32(IH_RB_CNTL, ih_rb_cntl); | 2986 | WREG32(IH_RB_CNTL, ih_rb_cntl); |
2992 | 2987 | ||
@@ -3036,9 +3031,10 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3036 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 3031 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
3037 | u32 grbm_int_cntl = 0; | 3032 | u32 grbm_int_cntl = 0; |
3038 | u32 hdmi1, hdmi2; | 3033 | u32 hdmi1, hdmi2; |
3034 | u32 d1grph = 0, d2grph = 0; | ||
3039 | 3035 | ||
3040 | if (!rdev->irq.installed) { | 3036 | if (!rdev->irq.installed) { |
3041 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 3037 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
3042 | return -EINVAL; | 3038 | return -EINVAL; |
3043 | } | 3039 | } |
3044 | /* don't enable anything if the ih is disabled */ | 3040 | /* don't enable anything if the ih is disabled */ |
@@ -3070,12 +3066,15 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3070 | if (rdev->irq.sw_int) { | 3066 | if (rdev->irq.sw_int) { |
3071 | DRM_DEBUG("r600_irq_set: sw int\n"); | 3067 | DRM_DEBUG("r600_irq_set: sw int\n"); |
3072 | cp_int_cntl |= RB_INT_ENABLE; | 3068 | cp_int_cntl |= RB_INT_ENABLE; |
3069 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | ||
3073 | } | 3070 | } |
3074 | if (rdev->irq.crtc_vblank_int[0]) { | 3071 | if (rdev->irq.crtc_vblank_int[0] || |
3072 | rdev->irq.pflip[0]) { | ||
3075 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | 3073 | DRM_DEBUG("r600_irq_set: vblank 0\n"); |
3076 | mode_int |= D1MODE_VBLANK_INT_MASK; | 3074 | mode_int |= D1MODE_VBLANK_INT_MASK; |
3077 | } | 3075 | } |
3078 | if (rdev->irq.crtc_vblank_int[1]) { | 3076 | if (rdev->irq.crtc_vblank_int[1] || |
3077 | rdev->irq.pflip[1]) { | ||
3079 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 3078 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
3080 | mode_int |= D2MODE_VBLANK_INT_MASK; | 3079 | mode_int |= D2MODE_VBLANK_INT_MASK; |
3081 | } | 3080 | } |
@@ -3118,6 +3117,8 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3118 | 3117 | ||
3119 | WREG32(CP_INT_CNTL, cp_int_cntl); | 3118 | WREG32(CP_INT_CNTL, cp_int_cntl); |
3120 | WREG32(DxMODE_INT_MASK, mode_int); | 3119 | WREG32(DxMODE_INT_MASK, mode_int); |
3120 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); | ||
3121 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); | ||
3121 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3122 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
3122 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); | 3123 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); |
3123 | if (ASIC_IS_DCE3(rdev)) { | 3124 | if (ASIC_IS_DCE3(rdev)) { |
@@ -3140,32 +3141,35 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3140 | return 0; | 3141 | return 0; |
3141 | } | 3142 | } |
3142 | 3143 | ||
3143 | static inline void r600_irq_ack(struct radeon_device *rdev, | 3144 | static inline void r600_irq_ack(struct radeon_device *rdev) |
3144 | u32 *disp_int, | ||
3145 | u32 *disp_int_cont, | ||
3146 | u32 *disp_int_cont2) | ||
3147 | { | 3145 | { |
3148 | u32 tmp; | 3146 | u32 tmp; |
3149 | 3147 | ||
3150 | if (ASIC_IS_DCE3(rdev)) { | 3148 | if (ASIC_IS_DCE3(rdev)) { |
3151 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 3149 | rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); |
3152 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | 3150 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); |
3153 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | 3151 | rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); |
3154 | } else { | 3152 | } else { |
3155 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | 3153 | rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
3156 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 3154 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
3157 | *disp_int_cont2 = 0; | 3155 | rdev->irq.stat_regs.r600.disp_int_cont2 = 0; |
3158 | } | 3156 | } |
3159 | 3157 | rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); | |
3160 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | 3158 | rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); |
3159 | |||
3160 | if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
3161 | WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
3162 | if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
3163 | WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
3164 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) | ||
3161 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3165 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
3162 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | 3166 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) |
3163 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3167 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
3164 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) | 3168 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) |
3165 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3169 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
3166 | if (*disp_int & LB_D2_VLINE_INTERRUPT) | 3170 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) |
3167 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3171 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
3168 | if (*disp_int & DC_HPD1_INTERRUPT) { | 3172 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
3169 | if (ASIC_IS_DCE3(rdev)) { | 3173 | if (ASIC_IS_DCE3(rdev)) { |
3170 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 3174 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
3171 | tmp |= DC_HPDx_INT_ACK; | 3175 | tmp |= DC_HPDx_INT_ACK; |
@@ -3176,7 +3180,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3176 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | 3180 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); |
3177 | } | 3181 | } |
3178 | } | 3182 | } |
3179 | if (*disp_int & DC_HPD2_INTERRUPT) { | 3183 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
3180 | if (ASIC_IS_DCE3(rdev)) { | 3184 | if (ASIC_IS_DCE3(rdev)) { |
3181 | tmp = RREG32(DC_HPD2_INT_CONTROL); | 3185 | tmp = RREG32(DC_HPD2_INT_CONTROL); |
3182 | tmp |= DC_HPDx_INT_ACK; | 3186 | tmp |= DC_HPDx_INT_ACK; |
@@ -3187,7 +3191,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3187 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | 3191 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
3188 | } | 3192 | } |
3189 | } | 3193 | } |
3190 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | 3194 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
3191 | if (ASIC_IS_DCE3(rdev)) { | 3195 | if (ASIC_IS_DCE3(rdev)) { |
3192 | tmp = RREG32(DC_HPD3_INT_CONTROL); | 3196 | tmp = RREG32(DC_HPD3_INT_CONTROL); |
3193 | tmp |= DC_HPDx_INT_ACK; | 3197 | tmp |= DC_HPDx_INT_ACK; |
@@ -3198,18 +3202,18 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3198 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | 3202 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); |
3199 | } | 3203 | } |
3200 | } | 3204 | } |
3201 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | 3205 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
3202 | tmp = RREG32(DC_HPD4_INT_CONTROL); | 3206 | tmp = RREG32(DC_HPD4_INT_CONTROL); |
3203 | tmp |= DC_HPDx_INT_ACK; | 3207 | tmp |= DC_HPDx_INT_ACK; |
3204 | WREG32(DC_HPD4_INT_CONTROL, tmp); | 3208 | WREG32(DC_HPD4_INT_CONTROL, tmp); |
3205 | } | 3209 | } |
3206 | if (ASIC_IS_DCE32(rdev)) { | 3210 | if (ASIC_IS_DCE32(rdev)) { |
3207 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3211 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
3208 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3212 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
3209 | tmp |= DC_HPDx_INT_ACK; | 3213 | tmp |= DC_HPDx_INT_ACK; |
3210 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 3214 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
3211 | } | 3215 | } |
3212 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3216 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
3213 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3217 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
3214 | tmp |= DC_HPDx_INT_ACK; | 3218 | tmp |= DC_HPDx_INT_ACK; |
3215 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 3219 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
@@ -3231,12 +3235,10 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3231 | 3235 | ||
3232 | void r600_irq_disable(struct radeon_device *rdev) | 3236 | void r600_irq_disable(struct radeon_device *rdev) |
3233 | { | 3237 | { |
3234 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
3235 | |||
3236 | r600_disable_interrupts(rdev); | 3238 | r600_disable_interrupts(rdev); |
3237 | /* Wait and acknowledge irq */ | 3239 | /* Wait and acknowledge irq */ |
3238 | mdelay(1); | 3240 | mdelay(1); |
3239 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3241 | r600_irq_ack(rdev); |
3240 | r600_disable_interrupt_state(rdev); | 3242 | r600_disable_interrupt_state(rdev); |
3241 | } | 3243 | } |
3242 | 3244 | ||
@@ -3244,8 +3246,10 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3244 | { | 3246 | { |
3245 | u32 wptr, tmp; | 3247 | u32 wptr, tmp; |
3246 | 3248 | ||
3247 | /* XXX use writeback */ | 3249 | if (rdev->wb.enabled) |
3248 | wptr = RREG32(IH_RB_WPTR); | 3250 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
3251 | else | ||
3252 | wptr = RREG32(IH_RB_WPTR); | ||
3249 | 3253 | ||
3250 | if (wptr & RB_OVERFLOW) { | 3254 | if (wptr & RB_OVERFLOW) { |
3251 | /* When a ring buffer overflow happen start parsing interrupt | 3255 | /* When a ring buffer overflow happen start parsing interrupt |
@@ -3294,54 +3298,57 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3294 | 3298 | ||
3295 | int r600_irq_process(struct radeon_device *rdev) | 3299 | int r600_irq_process(struct radeon_device *rdev) |
3296 | { | 3300 | { |
3297 | u32 wptr = r600_get_ih_wptr(rdev); | 3301 | u32 wptr; |
3298 | u32 rptr = rdev->ih.rptr; | 3302 | u32 rptr; |
3299 | u32 src_id, src_data; | 3303 | u32 src_id, src_data; |
3300 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | 3304 | u32 ring_index; |
3301 | unsigned long flags; | 3305 | unsigned long flags; |
3302 | bool queue_hotplug = false; | 3306 | bool queue_hotplug = false; |
3303 | 3307 | ||
3304 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 3308 | if (!rdev->ih.enabled || rdev->shutdown) |
3305 | if (!rdev->ih.enabled) | ||
3306 | return IRQ_NONE; | 3309 | return IRQ_NONE; |
3307 | 3310 | ||
3311 | wptr = r600_get_ih_wptr(rdev); | ||
3312 | rptr = rdev->ih.rptr; | ||
3313 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
3314 | |||
3308 | spin_lock_irqsave(&rdev->ih.lock, flags); | 3315 | spin_lock_irqsave(&rdev->ih.lock, flags); |
3309 | 3316 | ||
3310 | if (rptr == wptr) { | 3317 | if (rptr == wptr) { |
3311 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3318 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
3312 | return IRQ_NONE; | 3319 | return IRQ_NONE; |
3313 | } | 3320 | } |
3314 | if (rdev->shutdown) { | ||
3315 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
3316 | return IRQ_NONE; | ||
3317 | } | ||
3318 | 3321 | ||
3319 | restart_ih: | 3322 | restart_ih: |
3320 | /* display interrupts */ | 3323 | /* display interrupts */ |
3321 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3324 | r600_irq_ack(rdev); |
3322 | 3325 | ||
3323 | rdev->ih.wptr = wptr; | 3326 | rdev->ih.wptr = wptr; |
3324 | while (rptr != wptr) { | 3327 | while (rptr != wptr) { |
3325 | /* wptr/rptr are in bytes! */ | 3328 | /* wptr/rptr are in bytes! */ |
3326 | ring_index = rptr / 4; | 3329 | ring_index = rptr / 4; |
3327 | src_id = rdev->ih.ring[ring_index] & 0xff; | 3330 | src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; |
3328 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | 3331 | src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; |
3329 | 3332 | ||
3330 | switch (src_id) { | 3333 | switch (src_id) { |
3331 | case 1: /* D1 vblank/vline */ | 3334 | case 1: /* D1 vblank/vline */ |
3332 | switch (src_data) { | 3335 | switch (src_data) { |
3333 | case 0: /* D1 vblank */ | 3336 | case 0: /* D1 vblank */ |
3334 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 3337 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { |
3335 | drm_handle_vblank(rdev->ddev, 0); | 3338 | if (rdev->irq.crtc_vblank_int[0]) { |
3336 | rdev->pm.vblank_sync = true; | 3339 | drm_handle_vblank(rdev->ddev, 0); |
3337 | wake_up(&rdev->irq.vblank_queue); | 3340 | rdev->pm.vblank_sync = true; |
3338 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 3341 | wake_up(&rdev->irq.vblank_queue); |
3342 | } | ||
3343 | if (rdev->irq.pflip[0]) | ||
3344 | radeon_crtc_handle_flip(rdev, 0); | ||
3345 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
3339 | DRM_DEBUG("IH: D1 vblank\n"); | 3346 | DRM_DEBUG("IH: D1 vblank\n"); |
3340 | } | 3347 | } |
3341 | break; | 3348 | break; |
3342 | case 1: /* D1 vline */ | 3349 | case 1: /* D1 vline */ |
3343 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | 3350 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { |
3344 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | 3351 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
3345 | DRM_DEBUG("IH: D1 vline\n"); | 3352 | DRM_DEBUG("IH: D1 vline\n"); |
3346 | } | 3353 | } |
3347 | break; | 3354 | break; |
@@ -3353,17 +3360,21 @@ restart_ih: | |||
3353 | case 5: /* D2 vblank/vline */ | 3360 | case 5: /* D2 vblank/vline */ |
3354 | switch (src_data) { | 3361 | switch (src_data) { |
3355 | case 0: /* D2 vblank */ | 3362 | case 0: /* D2 vblank */ |
3356 | if (disp_int & LB_D2_VBLANK_INTERRUPT) { | 3363 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { |
3357 | drm_handle_vblank(rdev->ddev, 1); | 3364 | if (rdev->irq.crtc_vblank_int[1]) { |
3358 | rdev->pm.vblank_sync = true; | 3365 | drm_handle_vblank(rdev->ddev, 1); |
3359 | wake_up(&rdev->irq.vblank_queue); | 3366 | rdev->pm.vblank_sync = true; |
3360 | disp_int &= ~LB_D2_VBLANK_INTERRUPT; | 3367 | wake_up(&rdev->irq.vblank_queue); |
3368 | } | ||
3369 | if (rdev->irq.pflip[1]) | ||
3370 | radeon_crtc_handle_flip(rdev, 1); | ||
3371 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; | ||
3361 | DRM_DEBUG("IH: D2 vblank\n"); | 3372 | DRM_DEBUG("IH: D2 vblank\n"); |
3362 | } | 3373 | } |
3363 | break; | 3374 | break; |
3364 | case 1: /* D1 vline */ | 3375 | case 1: /* D1 vline */ |
3365 | if (disp_int & LB_D2_VLINE_INTERRUPT) { | 3376 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { |
3366 | disp_int &= ~LB_D2_VLINE_INTERRUPT; | 3377 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; |
3367 | DRM_DEBUG("IH: D2 vline\n"); | 3378 | DRM_DEBUG("IH: D2 vline\n"); |
3368 | } | 3379 | } |
3369 | break; | 3380 | break; |
@@ -3375,43 +3386,43 @@ restart_ih: | |||
3375 | case 19: /* HPD/DAC hotplug */ | 3386 | case 19: /* HPD/DAC hotplug */ |
3376 | switch (src_data) { | 3387 | switch (src_data) { |
3377 | case 0: | 3388 | case 0: |
3378 | if (disp_int & DC_HPD1_INTERRUPT) { | 3389 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
3379 | disp_int &= ~DC_HPD1_INTERRUPT; | 3390 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; |
3380 | queue_hotplug = true; | 3391 | queue_hotplug = true; |
3381 | DRM_DEBUG("IH: HPD1\n"); | 3392 | DRM_DEBUG("IH: HPD1\n"); |
3382 | } | 3393 | } |
3383 | break; | 3394 | break; |
3384 | case 1: | 3395 | case 1: |
3385 | if (disp_int & DC_HPD2_INTERRUPT) { | 3396 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
3386 | disp_int &= ~DC_HPD2_INTERRUPT; | 3397 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; |
3387 | queue_hotplug = true; | 3398 | queue_hotplug = true; |
3388 | DRM_DEBUG("IH: HPD2\n"); | 3399 | DRM_DEBUG("IH: HPD2\n"); |
3389 | } | 3400 | } |
3390 | break; | 3401 | break; |
3391 | case 4: | 3402 | case 4: |
3392 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | 3403 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
3393 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | 3404 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; |
3394 | queue_hotplug = true; | 3405 | queue_hotplug = true; |
3395 | DRM_DEBUG("IH: HPD3\n"); | 3406 | DRM_DEBUG("IH: HPD3\n"); |
3396 | } | 3407 | } |
3397 | break; | 3408 | break; |
3398 | case 5: | 3409 | case 5: |
3399 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | 3410 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
3400 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | 3411 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; |
3401 | queue_hotplug = true; | 3412 | queue_hotplug = true; |
3402 | DRM_DEBUG("IH: HPD4\n"); | 3413 | DRM_DEBUG("IH: HPD4\n"); |
3403 | } | 3414 | } |
3404 | break; | 3415 | break; |
3405 | case 10: | 3416 | case 10: |
3406 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3417 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
3407 | disp_int_cont2 &= ~DC_HPD5_INTERRUPT; | 3418 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; |
3408 | queue_hotplug = true; | 3419 | queue_hotplug = true; |
3409 | DRM_DEBUG("IH: HPD5\n"); | 3420 | DRM_DEBUG("IH: HPD5\n"); |
3410 | } | 3421 | } |
3411 | break; | 3422 | break; |
3412 | case 12: | 3423 | case 12: |
3413 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3424 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
3414 | disp_int_cont2 &= ~DC_HPD6_INTERRUPT; | 3425 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; |
3415 | queue_hotplug = true; | 3426 | queue_hotplug = true; |
3416 | DRM_DEBUG("IH: HPD6\n"); | 3427 | DRM_DEBUG("IH: HPD6\n"); |
3417 | } | 3428 | } |
@@ -3433,9 +3444,10 @@ restart_ih: | |||
3433 | break; | 3444 | break; |
3434 | case 181: /* CP EOP event */ | 3445 | case 181: /* CP EOP event */ |
3435 | DRM_DEBUG("IH: CP EOP\n"); | 3446 | DRM_DEBUG("IH: CP EOP\n"); |
3447 | radeon_fence_process(rdev); | ||
3436 | break; | 3448 | break; |
3437 | case 233: /* GUI IDLE */ | 3449 | case 233: /* GUI IDLE */ |
3438 | DRM_DEBUG("IH: CP EOP\n"); | 3450 | DRM_DEBUG("IH: GUI idle\n"); |
3439 | rdev->pm.gui_idle = true; | 3451 | rdev->pm.gui_idle = true; |
3440 | wake_up(&rdev->irq.idle_queue); | 3452 | wake_up(&rdev->irq.idle_queue); |
3441 | break; | 3453 | break; |
@@ -3453,7 +3465,7 @@ restart_ih: | |||
3453 | if (wptr != rdev->ih.wptr) | 3465 | if (wptr != rdev->ih.wptr) |
3454 | goto restart_ih; | 3466 | goto restart_ih; |
3455 | if (queue_hotplug) | 3467 | if (queue_hotplug) |
3456 | queue_work(rdev->wq, &rdev->hotplug_work); | 3468 | schedule_work(&rdev->hotplug_work); |
3457 | rdev->ih.rptr = rptr; | 3469 | rdev->ih.rptr = rptr; |
3458 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3470 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3459 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3471 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
@@ -3528,10 +3540,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
3528 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | 3540 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) |
3529 | { | 3541 | { |
3530 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3542 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3531 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3543 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. |
3544 | * This seems to cause problems on some AGP cards. Just use the old | ||
3545 | * method for them. | ||
3532 | */ | 3546 | */ |
3533 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 3547 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3534 | rdev->vram_scratch.ptr) { | 3548 | rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { |
3535 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3549 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3536 | u32 tmp; | 3550 | u32 tmp; |
3537 | 3551 | ||
@@ -3540,3 +3554,222 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3540 | } else | 3554 | } else |
3541 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 3555 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); |
3542 | } | 3556 | } |
3557 | |||
3558 | void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes) | ||
3559 | { | ||
3560 | u32 link_width_cntl, mask, target_reg; | ||
3561 | |||
3562 | if (rdev->flags & RADEON_IS_IGP) | ||
3563 | return; | ||
3564 | |||
3565 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3566 | return; | ||
3567 | |||
3568 | /* x2 cards have a special sequence */ | ||
3569 | if (ASIC_IS_X2(rdev)) | ||
3570 | return; | ||
3571 | |||
3572 | /* FIXME wait for idle */ | ||
3573 | |||
3574 | switch (lanes) { | ||
3575 | case 0: | ||
3576 | mask = RADEON_PCIE_LC_LINK_WIDTH_X0; | ||
3577 | break; | ||
3578 | case 1: | ||
3579 | mask = RADEON_PCIE_LC_LINK_WIDTH_X1; | ||
3580 | break; | ||
3581 | case 2: | ||
3582 | mask = RADEON_PCIE_LC_LINK_WIDTH_X2; | ||
3583 | break; | ||
3584 | case 4: | ||
3585 | mask = RADEON_PCIE_LC_LINK_WIDTH_X4; | ||
3586 | break; | ||
3587 | case 8: | ||
3588 | mask = RADEON_PCIE_LC_LINK_WIDTH_X8; | ||
3589 | break; | ||
3590 | case 12: | ||
3591 | mask = RADEON_PCIE_LC_LINK_WIDTH_X12; | ||
3592 | break; | ||
3593 | case 16: | ||
3594 | default: | ||
3595 | mask = RADEON_PCIE_LC_LINK_WIDTH_X16; | ||
3596 | break; | ||
3597 | } | ||
3598 | |||
3599 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3600 | |||
3601 | if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == | ||
3602 | (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) | ||
3603 | return; | ||
3604 | |||
3605 | if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS) | ||
3606 | return; | ||
3607 | |||
3608 | link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | | ||
3609 | RADEON_PCIE_LC_RECONFIG_NOW | | ||
3610 | R600_PCIE_LC_RENEGOTIATE_EN | | ||
3611 | R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3612 | link_width_cntl |= mask; | ||
3613 | |||
3614 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3615 | |||
3616 | /* some northbridges can renegotiate the link rather than requiring | ||
3617 | * a complete re-config. | ||
3618 | * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) | ||
3619 | */ | ||
3620 | if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT) | ||
3621 | link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT; | ||
3622 | else | ||
3623 | link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; | ||
3624 | |||
3625 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | | ||
3626 | RADEON_PCIE_LC_RECONFIG_NOW)); | ||
3627 | |||
3628 | if (rdev->family >= CHIP_RV770) | ||
3629 | target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3630 | else | ||
3631 | target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3632 | |||
3633 | /* wait for lane set to complete */ | ||
3634 | link_width_cntl = RREG32(target_reg); | ||
3635 | while (link_width_cntl == 0xffffffff) | ||
3636 | link_width_cntl = RREG32(target_reg); | ||
3637 | |||
3638 | } | ||
3639 | |||
3640 | int r600_get_pcie_lanes(struct radeon_device *rdev) | ||
3641 | { | ||
3642 | u32 link_width_cntl; | ||
3643 | |||
3644 | if (rdev->flags & RADEON_IS_IGP) | ||
3645 | return 0; | ||
3646 | |||
3647 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3648 | return 0; | ||
3649 | |||
3650 | /* x2 cards have a special sequence */ | ||
3651 | if (ASIC_IS_X2(rdev)) | ||
3652 | return 0; | ||
3653 | |||
3654 | /* FIXME wait for idle */ | ||
3655 | |||
3656 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3657 | |||
3658 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | ||
3659 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | ||
3660 | return 0; | ||
3661 | case RADEON_PCIE_LC_LINK_WIDTH_X1: | ||
3662 | return 1; | ||
3663 | case RADEON_PCIE_LC_LINK_WIDTH_X2: | ||
3664 | return 2; | ||
3665 | case RADEON_PCIE_LC_LINK_WIDTH_X4: | ||
3666 | return 4; | ||
3667 | case RADEON_PCIE_LC_LINK_WIDTH_X8: | ||
3668 | return 8; | ||
3669 | case RADEON_PCIE_LC_LINK_WIDTH_X16: | ||
3670 | default: | ||
3671 | return 16; | ||
3672 | } | ||
3673 | } | ||
3674 | |||
3675 | static void r600_pcie_gen2_enable(struct radeon_device *rdev) | ||
3676 | { | ||
3677 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; | ||
3678 | u16 link_cntl2; | ||
3679 | |||
3680 | if (radeon_pcie_gen2 == 0) | ||
3681 | return; | ||
3682 | |||
3683 | if (rdev->flags & RADEON_IS_IGP) | ||
3684 | return; | ||
3685 | |||
3686 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3687 | return; | ||
3688 | |||
3689 | /* x2 cards have a special sequence */ | ||
3690 | if (ASIC_IS_X2(rdev)) | ||
3691 | return; | ||
3692 | |||
3693 | /* only RV6xx+ chips are supported */ | ||
3694 | if (rdev->family <= CHIP_R600) | ||
3695 | return; | ||
3696 | |||
3697 | /* 55 nm r6xx asics */ | ||
3698 | if ((rdev->family == CHIP_RV670) || | ||
3699 | (rdev->family == CHIP_RV620) || | ||
3700 | (rdev->family == CHIP_RV635)) { | ||
3701 | /* advertise upconfig capability */ | ||
3702 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3703 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3704 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3705 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3706 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
3707 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
3708 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
3709 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3710 | link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN; | ||
3711 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3712 | } else { | ||
3713 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3714 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3715 | } | ||
3716 | } | ||
3717 | |||
3718 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3719 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
3720 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
3721 | |||
3722 | /* 55 nm r6xx asics */ | ||
3723 | if ((rdev->family == CHIP_RV670) || | ||
3724 | (rdev->family == CHIP_RV620) || | ||
3725 | (rdev->family == CHIP_RV635)) { | ||
3726 | WREG32(MM_CFGREGS_CNTL, 0x8); | ||
3727 | link_cntl2 = RREG32(0x4088); | ||
3728 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3729 | /* not supported yet */ | ||
3730 | if (link_cntl2 & SELECTABLE_DEEMPHASIS) | ||
3731 | return; | ||
3732 | } | ||
3733 | |||
3734 | speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK; | ||
3735 | speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT); | ||
3736 | speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK; | ||
3737 | speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE; | ||
3738 | speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE; | ||
3739 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3740 | |||
3741 | tmp = RREG32(0x541c); | ||
3742 | WREG32(0x541c, tmp | 0x8); | ||
3743 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
3744 | link_cntl2 = RREG16(0x4088); | ||
3745 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
3746 | link_cntl2 |= 0x2; | ||
3747 | WREG16(0x4088, link_cntl2); | ||
3748 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3749 | |||
3750 | if ((rdev->family == CHIP_RV670) || | ||
3751 | (rdev->family == CHIP_RV620) || | ||
3752 | (rdev->family == CHIP_RV635)) { | ||
3753 | training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL); | ||
3754 | training_cntl &= ~LC_POINT_7_PLUS_EN; | ||
3755 | WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl); | ||
3756 | } else { | ||
3757 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3758 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
3759 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3760 | } | ||
3761 | |||
3762 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3763 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
3764 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3765 | |||
3766 | } else { | ||
3767 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3768 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
3769 | if (1) | ||
3770 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3771 | else | ||
3772 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3773 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3774 | } | ||
3775 | } | ||