diff options
26 files changed, 320 insertions, 188 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9e6f76fec527..c6fcb5b86a45 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -259,7 +259,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
| 260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
| 261 | /* disable crtc pair power gating before programming */ | 261 | /* disable crtc pair power gating before programming */ |
| 262 | if (ASIC_IS_DCE6(rdev)) | 262 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
| 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
| 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
| @@ -279,7 +279,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
| 280 | radeon_crtc->enabled = false; | 280 | radeon_crtc->enabled = false; |
| 281 | /* power gating is per-pair */ | 281 | /* power gating is per-pair */ |
| 282 | if (ASIC_IS_DCE6(rdev)) { | 282 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { |
| 283 | struct drm_crtc *other_crtc; | 283 | struct drm_crtc *other_crtc; |
| 284 | struct radeon_crtc *other_radeon_crtc; | 284 | struct radeon_crtc *other_radeon_crtc; |
| 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { |
| @@ -1531,12 +1531,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1531 | * crtc virtual pixel clock. | 1531 | * crtc virtual pixel clock. |
| 1532 | */ | 1532 | */ |
| 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
| 1534 | if (ASIC_IS_DCE5(rdev)) | 1534 | if (rdev->clock.dp_extclk) |
| 1535 | return ATOM_DCPLL; | 1535 | return ATOM_PPLL_INVALID; |
| 1536 | else if (ASIC_IS_DCE6(rdev)) | 1536 | else if (ASIC_IS_DCE6(rdev)) |
| 1537 | return ATOM_PPLL0; | 1537 | return ATOM_PPLL0; |
| 1538 | else if (rdev->clock.dp_extclk) | 1538 | else if (ASIC_IS_DCE5(rdev)) |
| 1539 | return ATOM_PPLL_INVALID; | 1539 | return ATOM_DCPLL; |
| 1540 | } | 1540 | } |
| 1541 | } | 1541 | } |
| 1542 | } | 1542 | } |
| @@ -1635,18 +1635,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
| 1636 | { | 1636 | { |
| 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 1638 | struct drm_device *dev = crtc->dev; | ||
| 1639 | struct radeon_device *rdev = dev->dev_private; | ||
| 1638 | 1640 | ||
| 1641 | radeon_crtc->in_mode_set = true; | ||
| 1639 | /* pick pll */ | 1642 | /* pick pll */ |
| 1640 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | 1643 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
| 1641 | 1644 | ||
| 1645 | /* disable crtc pair power gating before programming */ | ||
| 1646 | if (ASIC_IS_DCE6(rdev)) | ||
| 1647 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | ||
| 1648 | |||
| 1642 | atombios_lock_crtc(crtc, ATOM_ENABLE); | 1649 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
| 1643 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1650 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1644 | } | 1651 | } |
| 1645 | 1652 | ||
| 1646 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1653 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
| 1647 | { | 1654 | { |
| 1655 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1656 | |||
| 1648 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1657 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
| 1649 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1658 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
| 1659 | radeon_crtc->in_mode_set = false; | ||
| 1650 | } | 1660 | } |
| 1651 | 1661 | ||
| 1652 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1662 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e585a3b947eb..e93b80a6d4e9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
| 1229 | 1229 | ||
| 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
| 1231 | { | 1231 | { |
| 1232 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
| 1233 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
| 1234 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1232 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
| 1235 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1233 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
| 1236 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
| 1237 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
| 1238 | if (rdev->num_crtc >= 4) { | ||
| 1239 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
| 1240 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
| 1241 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
| 1242 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
| 1243 | } | ||
| 1244 | if (rdev->num_crtc >= 6) { | ||
| 1245 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
| 1246 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
| 1247 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
| 1248 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 1249 | } | ||
| 1250 | 1234 | ||
| 1251 | /* Stop all video */ | 1235 | /* Stop all video */ |
| 1252 | WREG32(VGA_RENDER_CONTROL, 0); | 1236 | WREG32(VGA_RENDER_CONTROL, 0); |
| @@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
| 1357 | /* Unlock host access */ | 1341 | /* Unlock host access */ |
| 1358 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1342 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
| 1359 | mdelay(1); | 1343 | mdelay(1); |
| 1360 | /* Restore video state */ | ||
| 1361 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
| 1362 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
| 1363 | if (rdev->num_crtc >= 4) { | ||
| 1364 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
| 1365 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
| 1366 | } | ||
| 1367 | if (rdev->num_crtc >= 6) { | ||
| 1368 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
| 1369 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
| 1370 | } | ||
| 1371 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
| 1372 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
| 1373 | if (rdev->num_crtc >= 4) { | ||
| 1374 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
| 1375 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
| 1376 | } | ||
| 1377 | if (rdev->num_crtc >= 6) { | ||
| 1378 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
| 1379 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
| 1380 | } | ||
| 1381 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
| 1382 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
| 1383 | if (rdev->num_crtc >= 4) { | ||
| 1384 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
| 1385 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
| 1386 | } | ||
| 1387 | if (rdev->num_crtc >= 6) { | ||
| 1388 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
| 1389 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
| 1390 | } | ||
| 1391 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
| 1392 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
| 1393 | if (rdev->num_crtc >= 4) { | ||
| 1394 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
| 1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
| 1396 | } | ||
| 1397 | if (rdev->num_crtc >= 6) { | ||
| 1398 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
| 1399 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 1400 | } | ||
| 1401 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1344 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
| 1402 | } | 1345 | } |
| 1403 | 1346 | ||
| @@ -1986,10 +1929,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1986 | if (rdev->flags & RADEON_IS_IGP) | 1929 | if (rdev->flags & RADEON_IS_IGP) |
| 1987 | rdev->config.evergreen.tile_config |= 1 << 4; | 1930 | rdev->config.evergreen.tile_config |= 1 << 4; |
| 1988 | else { | 1931 | else { |
| 1989 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1932 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1990 | rdev->config.evergreen.tile_config |= 1 << 4; | 1933 | case 0: /* four banks */ |
| 1991 | else | ||
| 1992 | rdev->config.evergreen.tile_config |= 0 << 4; | 1934 | rdev->config.evergreen.tile_config |= 0 << 4; |
| 1935 | break; | ||
| 1936 | case 1: /* eight banks */ | ||
| 1937 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
| 1938 | break; | ||
| 1939 | case 2: /* sixteen banks */ | ||
| 1940 | default: | ||
| 1941 | rdev->config.evergreen.tile_config |= 2 << 4; | ||
| 1942 | break; | ||
| 1943 | } | ||
| 1993 | } | 1944 | } |
| 1994 | rdev->config.evergreen.tile_config |= 0 << 8; | 1945 | rdev->config.evergreen.tile_config |= 0 << 8; |
| 1995 | rdev->config.evergreen.tile_config |= | 1946 | rdev->config.evergreen.tile_config |= |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index f2e5c545c973..e44a62a07fe3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
| 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: |
| 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: |
| 790 | depth = 1; | 790 | depth = 1; |
| 791 | break; | ||
| 792 | case V_030000_SQ_TEX_DIM_2D_MSAA: | ||
| 793 | case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: | ||
| 794 | surf.nsamples = 1 << llevel; | ||
| 795 | llevel = 0; | ||
| 796 | depth = 1; | ||
| 797 | break; | ||
| 791 | case V_030000_SQ_TEX_DIM_3D: | 798 | case V_030000_SQ_TEX_DIM_3D: |
| 792 | break; | 799 | break; |
| 793 | default: | 800 | default: |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 9945d86d9001..853800e8582f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
| 574 | if (rdev->flags & RADEON_IS_IGP) | 574 | if (rdev->flags & RADEON_IS_IGP) |
| 575 | rdev->config.cayman.tile_config |= 1 << 4; | 575 | rdev->config.cayman.tile_config |= 1 << 4; |
| 576 | else { | 576 | else { |
| 577 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 577 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 578 | rdev->config.cayman.tile_config |= 1 << 4; | 578 | case 0: /* four banks */ |
| 579 | else | ||
| 580 | rdev->config.cayman.tile_config |= 0 << 4; | 579 | rdev->config.cayman.tile_config |= 0 << 4; |
| 580 | break; | ||
| 581 | case 1: /* eight banks */ | ||
| 582 | rdev->config.cayman.tile_config |= 1 << 4; | ||
| 583 | break; | ||
| 584 | case 2: /* sixteen banks */ | ||
| 585 | default: | ||
| 586 | rdev->config.cayman.tile_config |= 2 << 4; | ||
| 587 | break; | ||
| 588 | } | ||
| 581 | } | 589 | } |
| 582 | rdev->config.cayman.tile_config |= | 590 | rdev->config.cayman.tile_config |= |
| 583 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 591 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f541a3..d79c639ae739 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
| 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); |
| 3790 | } | 3790 | } |
| 3791 | } | 3791 | } |
| 3792 | |||
| 3793 | /** | ||
| 3794 | * r600_get_gpu_clock - return GPU clock counter snapshot | ||
| 3795 | * | ||
| 3796 | * @rdev: radeon_device pointer | ||
| 3797 | * | ||
| 3798 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | ||
| 3799 | * Returns the 64 bit clock counter snapshot. | ||
| 3800 | */ | ||
| 3801 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | ||
| 3802 | { | ||
| 3803 | uint64_t clock; | ||
| 3804 | |||
| 3805 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3806 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3807 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3808 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3809 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3810 | return clock; | ||
| 3811 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 1119e31e5c2f..3dab49cb1d4a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -1559,13 +1559,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1559 | u32 tiling_flags) | 1559 | u32 tiling_flags) |
| 1560 | { | 1560 | { |
| 1561 | struct r600_cs_track *track = p->track; | 1561 | struct r600_cs_track *track = p->track; |
| 1562 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1562 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
| 1563 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1563 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
| 1564 | u32 height_align, pitch, pitch_align, depth_align; | 1564 | u32 height_align, pitch, pitch_align, depth_align; |
| 1565 | u32 array, barray, larray; | 1565 | u32 barray, larray; |
| 1566 | u64 base_align; | 1566 | u64 base_align; |
| 1567 | struct array_mode_checker array_check; | 1567 | struct array_mode_checker array_check; |
| 1568 | u32 format; | 1568 | u32 format; |
| 1569 | bool is_array; | ||
| 1569 | 1570 | ||
| 1570 | /* on legacy kernel we don't perform advanced check */ | 1571 | /* on legacy kernel we don't perform advanced check */ |
| 1571 | if (p->rdev == NULL) | 1572 | if (p->rdev == NULL) |
| @@ -1583,12 +1584,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1583 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1584 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
| 1584 | } | 1585 | } |
| 1585 | word1 = radeon_get_ib_value(p, idx + 1); | 1586 | word1 = radeon_get_ib_value(p, idx + 1); |
| 1587 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1588 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1589 | word4 = radeon_get_ib_value(p, idx + 4); | ||
| 1590 | word5 = radeon_get_ib_value(p, idx + 5); | ||
| 1591 | dim = G_038000_DIM(word0); | ||
| 1586 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1592 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
| 1593 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1587 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1594 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
| 1588 | d0 = G_038004_TEX_DEPTH(word1); | 1595 | d0 = G_038004_TEX_DEPTH(word1); |
| 1596 | format = G_038004_DATA_FORMAT(word1); | ||
| 1597 | blevel = G_038010_BASE_LEVEL(word4); | ||
| 1598 | llevel = G_038014_LAST_LEVEL(word5); | ||
| 1599 | /* pitch in texels */ | ||
| 1600 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1601 | array_check.group_size = track->group_size; | ||
| 1602 | array_check.nbanks = track->nbanks; | ||
| 1603 | array_check.npipes = track->npipes; | ||
| 1604 | array_check.nsamples = 1; | ||
| 1605 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1589 | nfaces = 1; | 1606 | nfaces = 1; |
| 1590 | array = 0; | 1607 | is_array = false; |
| 1591 | switch (G_038000_DIM(word0)) { | 1608 | switch (dim) { |
| 1592 | case V_038000_SQ_TEX_DIM_1D: | 1609 | case V_038000_SQ_TEX_DIM_1D: |
| 1593 | case V_038000_SQ_TEX_DIM_2D: | 1610 | case V_038000_SQ_TEX_DIM_2D: |
| 1594 | case V_038000_SQ_TEX_DIM_3D: | 1611 | case V_038000_SQ_TEX_DIM_3D: |
| @@ -1601,29 +1618,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1601 | break; | 1618 | break; |
| 1602 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1619 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
| 1603 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1620 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
| 1604 | array = 1; | 1621 | is_array = true; |
| 1605 | break; | 1622 | break; |
| 1606 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1607 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1623 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
| 1624 | is_array = true; | ||
| 1625 | /* fall through */ | ||
| 1626 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1627 | array_check.nsamples = 1 << llevel; | ||
| 1628 | llevel = 0; | ||
| 1629 | break; | ||
| 1608 | default: | 1630 | default: |
| 1609 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1631 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
| 1610 | return -EINVAL; | 1632 | return -EINVAL; |
| 1611 | } | 1633 | } |
| 1612 | format = G_038004_DATA_FORMAT(word1); | ||
| 1613 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1634 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
| 1614 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1635 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
| 1615 | __func__, __LINE__, format); | 1636 | __func__, __LINE__, format); |
| 1616 | return -EINVAL; | 1637 | return -EINVAL; |
| 1617 | } | 1638 | } |
| 1618 | 1639 | ||
| 1619 | /* pitch in texels */ | ||
| 1620 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1621 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1622 | array_check.group_size = track->group_size; | ||
| 1623 | array_check.nbanks = track->nbanks; | ||
| 1624 | array_check.npipes = track->npipes; | ||
| 1625 | array_check.nsamples = 1; | ||
| 1626 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1627 | if (r600_get_array_mode_alignment(&array_check, | 1640 | if (r600_get_array_mode_alignment(&array_check, |
| 1628 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1641 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| 1629 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1642 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
| @@ -1649,20 +1662,13 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1649 | return -EINVAL; | 1662 | return -EINVAL; |
| 1650 | } | 1663 | } |
| 1651 | 1664 | ||
| 1652 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1653 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1654 | |||
| 1655 | word0 = radeon_get_ib_value(p, idx + 4); | ||
| 1656 | word1 = radeon_get_ib_value(p, idx + 5); | ||
| 1657 | blevel = G_038010_BASE_LEVEL(word0); | ||
| 1658 | llevel = G_038014_LAST_LEVEL(word1); | ||
| 1659 | if (blevel > llevel) { | 1665 | if (blevel > llevel) { |
| 1660 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1666 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
| 1661 | blevel, llevel); | 1667 | blevel, llevel); |
| 1662 | } | 1668 | } |
| 1663 | if (array == 1) { | 1669 | if (is_array) { |
| 1664 | barray = G_038014_BASE_ARRAY(word1); | 1670 | barray = G_038014_BASE_ARRAY(word5); |
| 1665 | larray = G_038014_LAST_ARRAY(word1); | 1671 | larray = G_038014_LAST_ARRAY(word5); |
| 1666 | 1672 | ||
| 1667 | nfaces = larray - barray + 1; | 1673 | nfaces = larray - barray + 1; |
| 1668 | } | 1674 | } |
| @@ -1679,7 +1685,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1679 | return -EINVAL; | 1685 | return -EINVAL; |
| 1680 | } | 1686 | } |
| 1681 | /* using get ib will give us the offset into the mipmap bo */ | 1687 | /* using get ib will give us the offset into the mipmap bo */ |
| 1682 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1683 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1688 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
| 1684 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1689 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
| 1685 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1690 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae75fc2..fd328f4c3ea8 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -602,6 +602,9 @@ | |||
| 602 | #define RLC_HB_WPTR 0x3f1c | 602 | #define RLC_HB_WPTR 0x3f1c |
| 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 |
| 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 |
| 605 | #define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 | ||
| 606 | #define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c | ||
| 607 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 | ||
| 605 | #define RLC_MC_CNTL 0x3f44 | 608 | #define RLC_MC_CNTL 0x3f44 |
| 606 | #define RLC_UCODE_CNTL 0x3f48 | 609 | #define RLC_UCODE_CNTL 0x3f48 |
| 607 | #define RLC_UCODE_ADDR 0x3f2c | 610 | #define RLC_UCODE_ADDR 0x3f2c |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5431af292408..99304194a65c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -300,6 +300,7 @@ struct radeon_bo_va { | |||
| 300 | uint64_t soffset; | 300 | uint64_t soffset; |
| 301 | uint64_t eoffset; | 301 | uint64_t eoffset; |
| 302 | uint32_t flags; | 302 | uint32_t flags; |
| 303 | struct radeon_fence *fence; | ||
| 303 | bool valid; | 304 | bool valid; |
| 304 | }; | 305 | }; |
| 305 | 306 | ||
| @@ -1533,6 +1534,7 @@ struct radeon_device { | |||
| 1533 | unsigned debugfs_count; | 1534 | unsigned debugfs_count; |
| 1534 | /* virtual memory */ | 1535 | /* virtual memory */ |
| 1535 | struct radeon_vm_manager vm_manager; | 1536 | struct radeon_vm_manager vm_manager; |
| 1537 | struct mutex gpu_clock_mutex; | ||
| 1536 | }; | 1538 | }; |
| 1537 | 1539 | ||
| 1538 | int radeon_device_init(struct radeon_device *rdev, | 1540 | int radeon_device_init(struct radeon_device *rdev, |
| @@ -1733,11 +1735,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
| 1733 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) | 1735 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) |
| 1734 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) | 1736 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) |
| 1735 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) | 1737 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) |
| 1736 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) | 1738 | #define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) |
| 1737 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) | 1739 | #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) |
| 1738 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) | 1740 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
| 1739 | #define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) | 1741 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
| 1740 | #define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) | 1742 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
| 1741 | 1743 | ||
| 1742 | /* Common functions */ | 1744 | /* Common functions */ |
| 1743 | /* AGP */ | 1745 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4af24310438..18c38d14c8cd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
| 255 | * rv515 | 255 | * rv515 |
| 256 | */ | 256 | */ |
| 257 | struct rv515_mc_save { | 257 | struct rv515_mc_save { |
| 258 | u32 d1vga_control; | ||
| 259 | u32 d2vga_control; | ||
| 260 | u32 vga_render_control; | 258 | u32 vga_render_control; |
| 261 | u32 vga_hdp_control; | 259 | u32 vga_hdp_control; |
| 262 | u32 d1crtc_control; | ||
| 263 | u32 d2crtc_control; | ||
| 264 | }; | 260 | }; |
| 261 | |||
| 265 | int rv515_init(struct radeon_device *rdev); | 262 | int rv515_init(struct radeon_device *rdev); |
| 266 | void rv515_fini(struct radeon_device *rdev); | 263 | void rv515_fini(struct radeon_device *rdev); |
| 267 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 264 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| @@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
| 371 | unsigned num_gpu_pages, | 368 | unsigned num_gpu_pages, |
| 372 | struct radeon_sa_bo *vb); | 369 | struct radeon_sa_bo *vb); |
| 373 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 370 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
| 371 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | ||
| 374 | 372 | ||
| 375 | /* | 373 | /* |
| 376 | * rv770,rv730,rv710,rv740 | 374 | * rv770,rv730,rv710,rv740 |
| @@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
| 389 | * evergreen | 387 | * evergreen |
| 390 | */ | 388 | */ |
| 391 | struct evergreen_mc_save { | 389 | struct evergreen_mc_save { |
| 392 | u32 vga_control[6]; | ||
| 393 | u32 vga_render_control; | 390 | u32 vga_render_control; |
| 394 | u32 vga_hdp_control; | 391 | u32 vga_hdp_control; |
| 395 | u32 crtc_control[6]; | ||
| 396 | }; | 392 | }; |
| 393 | |||
| 397 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
| 398 | int evergreen_init(struct radeon_device *rdev); | 395 | int evergreen_init(struct radeon_device *rdev); |
| 399 | void evergreen_fini(struct radeon_device *rdev); | 396 | void evergreen_fini(struct radeon_device *rdev); |
| @@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | |||
| 472 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); |
| 473 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); |
| 474 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
| 472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
| 475 | 473 | ||
| 476 | #endif | 474 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1e3820df363..f9c21f9d16bc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1263 | union igp_info { | 1263 | union igp_info { |
| 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
| 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
| 1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
| 1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
| 1266 | }; | 1268 | }; |
| 1267 | 1269 | ||
| 1268 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1270 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
| @@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | |||
| 1390 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1392 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 1391 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | 1393 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); |
| 1392 | u16 data_offset, size; | 1394 | u16 data_offset, size; |
| 1393 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | 1395 | union igp_info *igp_info; |
| 1394 | u8 frev, crev; | 1396 | u8 frev, crev; |
| 1395 | u16 percentage = 0, rate = 0; | 1397 | u16 percentage = 0, rate = 0; |
| 1396 | 1398 | ||
| 1397 | /* get any igp specific overrides */ | 1399 | /* get any igp specific overrides */ |
| 1398 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | 1400 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
| 1399 | &frev, &crev, &data_offset)) { | 1401 | &frev, &crev, &data_offset)) { |
| 1400 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | 1402 | igp_info = (union igp_info *) |
| 1401 | (mode_info->atom_context->bios + data_offset); | 1403 | (mode_info->atom_context->bios + data_offset); |
| 1402 | switch (id) { | 1404 | switch (crev) { |
| 1403 | case ASIC_INTERNAL_SS_ON_TMDS: | 1405 | case 6: |
| 1404 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | 1406 | switch (id) { |
| 1405 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | 1407 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1408 | percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); | ||
| 1409 | rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); | ||
| 1410 | break; | ||
| 1411 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1412 | percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); | ||
| 1413 | rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); | ||
| 1414 | break; | ||
| 1415 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1416 | percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); | ||
| 1417 | rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); | ||
| 1418 | break; | ||
| 1419 | } | ||
| 1406 | break; | 1420 | break; |
| 1407 | case ASIC_INTERNAL_SS_ON_HDMI: | 1421 | case 7: |
| 1408 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | 1422 | switch (id) { |
| 1409 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | 1423 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1424 | percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); | ||
| 1425 | rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); | ||
| 1426 | break; | ||
| 1427 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1428 | percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); | ||
| 1429 | rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); | ||
| 1430 | break; | ||
| 1431 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1432 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); | ||
| 1433 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); | ||
| 1434 | break; | ||
| 1435 | } | ||
| 1410 | break; | 1436 | break; |
| 1411 | case ASIC_INTERNAL_SS_ON_LVDS: | 1437 | default: |
| 1412 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | 1438 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
| 1413 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
| 1414 | break; | 1439 | break; |
| 1415 | } | 1440 | } |
| 1416 | if (percentage) | 1441 | if (percentage) |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..f75247d42ffd 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
| 719 | return i2c; | 719 | return i2c; |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) | ||
| 723 | { | ||
| 724 | struct drm_device *dev = rdev->ddev; | ||
| 725 | struct radeon_i2c_bus_rec i2c; | ||
| 726 | u16 offset; | ||
| 727 | u8 id, blocks, clk, data; | ||
| 728 | int i; | ||
| 729 | |||
| 730 | i2c.valid = false; | ||
| 731 | |||
| 732 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | ||
| 733 | if (offset) { | ||
| 734 | blocks = RBIOS8(offset + 2); | ||
| 735 | for (i = 0; i < blocks; i++) { | ||
| 736 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 737 | if (id == 136) { | ||
| 738 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 739 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 740 | /* gpiopad */ | ||
| 741 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 742 | (1 << clk), (1 << data)); | ||
| 743 | break; | ||
| 744 | } | ||
| 745 | } | ||
| 746 | } | ||
| 747 | return i2c; | ||
| 748 | } | ||
| 749 | |||
| 722 | void radeon_combios_i2c_init(struct radeon_device *rdev) | 750 | void radeon_combios_i2c_init(struct radeon_device *rdev) |
| 723 | { | 751 | { |
| 724 | struct drm_device *dev = rdev->ddev; | 752 | struct drm_device *dev = rdev->ddev; |
| @@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
| 755 | } else if (rdev->family == CHIP_RS300 || | 783 | } else if (rdev->family == CHIP_RS300 || |
| 756 | rdev->family == CHIP_RS400 || | 784 | rdev->family == CHIP_RS400 || |
| 757 | rdev->family == CHIP_RS480) { | 785 | rdev->family == CHIP_RS480) { |
| 758 | u16 offset; | ||
| 759 | u8 id, blocks, clk, data; | ||
| 760 | int i; | ||
| 761 | |||
| 762 | /* 0x68 */ | 786 | /* 0x68 */ |
| 763 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 787 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 764 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 788 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
| 765 | 789 | ||
| 766 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | 790 | /* gpiopad */ |
| 767 | if (offset) { | 791 | i2c = radeon_combios_get_i2c_info_from_table(rdev); |
| 768 | blocks = RBIOS8(offset + 2); | 792 | if (i2c.valid) |
| 769 | for (i = 0; i < blocks; i++) { | 793 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
| 770 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 771 | if (id == 136) { | ||
| 772 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 773 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 774 | /* gpiopad */ | ||
| 775 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 776 | (1 << clk), (1 << data)); | ||
| 777 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | } | ||
| 781 | } | ||
| 782 | } else if ((rdev->family == CHIP_R200) || | 794 | } else if ((rdev->family == CHIP_R200) || |
| 783 | (rdev->family >= CHIP_R300)) { | 795 | (rdev->family >= CHIP_R300)) { |
| 784 | /* 0x68 */ | 796 | /* 0x68 */ |
| @@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2321 | connector = (tmp >> 12) & 0xf; | 2333 | connector = (tmp >> 12) & 0xf; |
| 2322 | 2334 | ||
| 2323 | ddc_type = (tmp >> 8) & 0xf; | 2335 | ddc_type = (tmp >> 8) & 0xf; |
| 2324 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | 2336 | if (ddc_type == 5) |
| 2337 | ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); | ||
| 2338 | else | ||
| 2339 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | ||
| 2325 | 2340 | ||
| 2326 | switch (connector) { | 2341 | switch (connector) { |
| 2327 | case CONNECTOR_PROPRIETARY_LEGACY: | 2342 | case CONNECTOR_PROPRIETARY_LEGACY: |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8a4c49ef0cc4..b4a0db24f4dd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
| 278 | return 0; | 278 | return 0; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
| 282 | struct radeon_fence *fence) | ||
| 283 | { | ||
| 284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
| 285 | struct radeon_vm *vm = &fpriv->vm; | ||
| 286 | struct radeon_bo_list *lobj; | ||
| 287 | |||
| 288 | if (parser->chunk_ib_idx == -1) { | ||
| 289 | return; | ||
| 290 | } | ||
| 291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | |||
| 295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
| 296 | struct radeon_bo_va *bo_va; | ||
| 297 | struct radeon_bo *rbo = lobj->bo; | ||
| 298 | |||
| 299 | bo_va = radeon_bo_va(rbo, vm); | ||
| 300 | radeon_fence_unref(&bo_va->fence); | ||
| 301 | bo_va->fence = radeon_fence_ref(fence); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 281 | /** | 305 | /** |
| 282 | * cs_parser_fini() - clean parser states | 306 | * cs_parser_fini() - clean parser states |
| 283 | * @parser: parser structure holding parsing context. | 307 | * @parser: parser structure holding parsing context. |
| @@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 290 | { | 314 | { |
| 291 | unsigned i; | 315 | unsigned i; |
| 292 | 316 | ||
| 293 | if (!error) | 317 | if (!error) { |
| 318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
| 319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
| 294 | ttm_eu_fence_buffer_objects(&parser->validated, | 320 | ttm_eu_fence_buffer_objects(&parser->validated, |
| 295 | parser->ib.fence); | 321 | parser->ib.fence); |
| 296 | else | 322 | } else { |
| 297 | ttm_eu_backoff_reservation(&parser->validated); | 323 | ttm_eu_backoff_reservation(&parser->validated); |
| 324 | } | ||
| 298 | 325 | ||
| 299 | if (parser->relocs != NULL) { | 326 | if (parser->relocs != NULL) { |
| 300 | for (i = 0; i < parser->nrelocs; i++) { | 327 | for (i = 0; i < parser->nrelocs; i++) { |
| @@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 388 | 415 | ||
| 389 | if (parser->chunk_ib_idx == -1) | 416 | if (parser->chunk_ib_idx == -1) |
| 390 | return 0; | 417 | return 0; |
| 391 | |||
| 392 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 418 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
| 393 | return 0; | 419 | return 0; |
| 394 | 420 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 711e95ad39bf..8794744cdf1a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
| @@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
| 67 | 67 | ||
| 68 | if (ASIC_IS_DCE4(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
| 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 71 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 71 | } else if (ASIC_IS_AVIVO(rdev)) { | 72 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 73 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 74 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
| @@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
| 94 | if (ASIC_IS_DCE4(rdev)) { | 95 | if (ASIC_IS_DCE4(rdev)) { |
| 95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 96 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | 97 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
| 97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 98 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 99 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 98 | } else if (ASIC_IS_AVIVO(rdev)) { | 100 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 101 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 102 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af8244e89..d2e243867ac6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1009 | atomic_set(&rdev->ih.lock, 0); | 1009 | atomic_set(&rdev->ih.lock, 0); |
| 1010 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
| 1011 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
| 1012 | mutex_init(&rdev->gpu_clock_mutex); | ||
| 1012 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
| 1013 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
| 1014 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4b736ecb0aa5..d7269f48d37c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -60,9 +60,11 @@ | |||
| 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation | 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation |
| 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx | 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx |
| 62 | * 2.18.0 - r600-eg: allow "invalid" DB formats | 62 | * 2.18.0 - r600-eg: allow "invalid" DB formats |
| 63 | * 2.19.0 - r600-eg: MSAA textures | ||
| 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | ||
| 63 | */ | 65 | */ |
| 64 | #define KMS_DRIVER_MAJOR 2 | 66 | #define KMS_DRIVER_MAJOR 2 |
| 65 | #define KMS_DRIVER_MINOR 18 | 67 | #define KMS_DRIVER_MINOR 20 |
| 66 | #define KMS_DRIVER_PATCHLEVEL 0 | 68 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 67 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 69 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
| 68 | int radeon_driver_unload_kms(struct drm_device *dev); | 70 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 814 | return -EINVAL; | 814 | return -EINVAL; |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
| 818 | return 0; | 818 | return 0; |
| 819 | 819 | ||
| 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
| @@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
| 859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
| 860 | { | 860 | { |
| 861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
| 862 | int r; | ||
| 862 | 863 | ||
| 863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
| 864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
| 865 | return 0; | 866 | return 0; |
| 866 | 867 | ||
| 868 | /* wait for va use to end */ | ||
| 869 | while (bo_va->fence) { | ||
| 870 | r = radeon_fence_wait(bo_va->fence, false); | ||
| 871 | if (r) { | ||
| 872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
| 873 | } | ||
| 874 | if (r == -EDEADLK) { | ||
| 875 | r = radeon_gpu_reset(rdev); | ||
| 876 | if (!r) | ||
| 877 | continue; | ||
| 878 | } | ||
| 879 | break; | ||
| 880 | } | ||
| 881 | radeon_fence_unref(&bo_va->fence); | ||
| 882 | |||
| 867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
| 868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
| 869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
| @@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 934 | } | 950 | } |
| 935 | 951 | ||
| 936 | /** | 952 | /** |
| 937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
| 938 | * | 954 | * |
| 939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
| 940 | * @vm: requested vm | 956 | * @vm: requested vm |
| @@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
| 953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
| 954 | 970 | ||
| 955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
| 972 | * waited for the last vm fence to signal | ||
| 973 | */ | ||
| 956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
| 957 | if (!r) { | 975 | if (!r) { |
| 958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
| 959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
| 960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
| 979 | radeon_fence_unref(&bo_va->fence); | ||
| 961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
| 962 | kfree(bo_va); | 981 | kfree(bo_va); |
| 963 | } | 982 | } |
| @@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
| 970 | if (!r) { | 989 | if (!r) { |
| 971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
| 991 | radeon_fence_unref(&bo_va->fence); | ||
| 972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
| 973 | kfree(bo_va); | 993 | kfree(bo_va); |
| 974 | } | 994 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d045245739..1b57b0058ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
| 134 | struct radeon_device *rdev = rbo->rdev; | 134 | struct radeon_device *rdev = rbo->rdev; |
| 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
| 136 | struct radeon_vm *vm = &fpriv->vm; | 136 | struct radeon_vm *vm = &fpriv->vm; |
| 137 | struct radeon_bo_va *bo_va, *tmp; | ||
| 138 | 137 | ||
| 139 | if (rdev->family < CHIP_CAYMAN) { | 138 | if (rdev->family < CHIP_CAYMAN) { |
| 140 | return; | 139 | return; |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | if (radeon_bo_reserve(rbo, false)) { | 142 | if (radeon_bo_reserve(rbo, false)) { |
| 143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | ||
| 144 | return; | 144 | return; |
| 145 | } | 145 | } |
| 146 | list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { | 146 | radeon_vm_bo_rmv(rdev, vm, rbo); |
| 147 | if (bo_va->vm == vm) { | ||
| 148 | /* remove from this vm address space */ | ||
| 149 | mutex_lock(&vm->mutex); | ||
| 150 | list_del(&bo_va->vm_list); | ||
| 151 | mutex_unlock(&vm->mutex); | ||
| 152 | list_del(&bo_va->bo_list); | ||
| 153 | kfree(bo_va); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | radeon_bo_unreserve(rbo); | 147 | radeon_bo_unreserve(rbo); |
| 157 | } | 148 | } |
| 158 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 1d73f16b5d97..414b4acf6947 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
| 30 | #include "radeon.h" | 30 | #include "radeon.h" |
| 31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
| 32 | #include "radeon_asic.h" | ||
| 32 | 33 | ||
| 33 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
| 167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 168 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
| 168 | { | 169 | { |
| 169 | struct radeon_device *rdev = dev->dev_private; | 170 | struct radeon_device *rdev = dev->dev_private; |
| 170 | struct drm_radeon_info *info; | 171 | struct drm_radeon_info *info = data; |
| 171 | struct radeon_mode_info *minfo = &rdev->mode_info; | 172 | struct radeon_mode_info *minfo = &rdev->mode_info; |
| 172 | uint32_t *value_ptr; | 173 | uint32_t value, *value_ptr; |
| 173 | uint32_t value; | 174 | uint64_t value64, *value_ptr64; |
| 174 | struct drm_crtc *crtc; | 175 | struct drm_crtc *crtc; |
| 175 | int i, found; | 176 | int i, found; |
| 176 | 177 | ||
| 177 | info = data; | 178 | /* TIMESTAMP is a 64-bit value, needs special handling. */ |
| 179 | if (info->request == RADEON_INFO_TIMESTAMP) { | ||
| 180 | if (rdev->family >= CHIP_R600) { | ||
| 181 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | ||
| 182 | if (rdev->family >= CHIP_TAHITI) { | ||
| 183 | value64 = si_get_gpu_clock(rdev); | ||
| 184 | } else { | ||
| 185 | value64 = r600_get_gpu_clock(rdev); | ||
| 186 | } | ||
| 187 | |||
| 188 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | ||
| 189 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | ||
| 190 | return -EFAULT; | ||
| 191 | } | ||
| 192 | return 0; | ||
| 193 | } else { | ||
| 194 | DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 178 | value_ptr = (uint32_t *)((unsigned long)info->value); | 199 | value_ptr = (uint32_t *)((unsigned long)info->value); |
| 179 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) | 200 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { |
| 201 | DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); | ||
| 180 | return -EFAULT; | 202 | return -EFAULT; |
| 203 | } | ||
| 181 | 204 | ||
| 182 | switch (info->request) { | 205 | switch (info->request) { |
| 183 | case RADEON_INFO_DEVICE_ID: | 206 | case RADEON_INFO_DEVICE_ID: |
| @@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 337 | return -EINVAL; | 360 | return -EINVAL; |
| 338 | } | 361 | } |
| 339 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 362 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
| 340 | DRM_ERROR("copy_to_user\n"); | 363 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
| 341 | return -EFAULT; | 364 | return -EFAULT; |
| 342 | } | 365 | } |
| 343 | return 0; | 366 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index d5fd615897ec..94b4a1c12893 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1025 | 1025 | ||
| 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
| 1027 | { | 1027 | { |
| 1028 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1028 | struct drm_device *dev = crtc->dev; | 1029 | struct drm_device *dev = crtc->dev; |
| 1029 | struct drm_crtc *crtci; | 1030 | struct drm_crtc *crtci; |
| 1030 | 1031 | ||
| 1032 | radeon_crtc->in_mode_set = true; | ||
| 1031 | /* | 1033 | /* |
| 1032 | * The hardware wedges sometimes if you reconfigure one CRTC | 1034 | * The hardware wedges sometimes if you reconfigure one CRTC |
| 1033 | * whilst another is running (see fdo bug #24611). | 1035 | * whilst another is running (see fdo bug #24611). |
| @@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
| 1038 | 1040 | ||
| 1039 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1041 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
| 1040 | { | 1042 | { |
| 1043 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1041 | struct drm_device *dev = crtc->dev; | 1044 | struct drm_device *dev = crtc->dev; |
| 1042 | struct drm_crtc *crtci; | 1045 | struct drm_crtc *crtci; |
| 1043 | 1046 | ||
| @@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
| 1048 | if (crtci->enabled) | 1051 | if (crtci->enabled) |
| 1049 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1052 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
| 1050 | } | 1053 | } |
| 1054 | radeon_crtc->in_mode_set = false; | ||
| 1051 | } | 1055 | } |
| 1052 | 1056 | ||
| 1053 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1057 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f380d59c5763..d56978949f34 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -275,6 +275,7 @@ struct radeon_crtc { | |||
| 275 | u16 lut_r[256], lut_g[256], lut_b[256]; | 275 | u16 lut_r[256], lut_g[256], lut_b[256]; |
| 276 | bool enabled; | 276 | bool enabled; |
| 277 | bool can_tile; | 277 | bool can_tile; |
| 278 | bool in_mode_set; | ||
| 278 | uint32_t crtc_offset; | 279 | uint32_t crtc_offset; |
| 279 | struct drm_gem_object *cursor_bo; | 280 | struct drm_gem_object *cursor_bo; |
| 280 | uint64_t cursor_addr; | 281 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f1a4c803c1d..1cb014b571ab 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
| 52 | 52 | ||
| 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
| 54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
| 55 | mutex_lock(&bo_va->vm->mutex); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); |
| 56 | list_del(&bo_va->vm_list); | ||
| 57 | mutex_unlock(&bo_va->vm->mutex); | ||
| 58 | list_del(&bo_va->bo_list); | ||
| 59 | kfree(bo_va); | ||
| 60 | } | 56 | } |
| 61 | } | 57 | } |
| 62 | 58 | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index a12fbcc8ccb6..aa8ef491ef3c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
| 281 | 281 | ||
| 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
| 283 | { | 283 | { |
| 284 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); | ||
| 285 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); | ||
| 286 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
| 287 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
| 288 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
| 289 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
| 290 | 286 | ||
| 291 | /* Stop all video */ | 287 | /* Stop all video */ |
| 292 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
| @@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
| 311 | /* Unlock host access */ | 307 | /* Unlock host access */ |
| 312 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
| 313 | mdelay(1); | 309 | mdelay(1); |
| 314 | /* Restore video state */ | ||
| 315 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
| 316 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
| 317 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
| 318 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
| 319 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
| 320 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
| 321 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
| 322 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 323 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
| 324 | } | 311 | } |
| 325 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c053f8193771..0139e227e3c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
| 1639 | /* XXX what about 12? */ | 1639 | /* XXX what about 12? */ |
| 1640 | rdev->config.si.tile_config |= (3 << 0); | 1640 | rdev->config.si.tile_config |= (3 << 0); |
| 1641 | break; | 1641 | break; |
| 1642 | } | 1642 | } |
| 1643 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1643 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1644 | rdev->config.si.tile_config |= 1 << 4; | 1644 | case 0: /* four banks */ |
| 1645 | else | ||
| 1646 | rdev->config.si.tile_config |= 0 << 4; | 1645 | rdev->config.si.tile_config |= 0 << 4; |
| 1646 | break; | ||
| 1647 | case 1: /* eight banks */ | ||
| 1648 | rdev->config.si.tile_config |= 1 << 4; | ||
| 1649 | break; | ||
| 1650 | case 2: /* sixteen banks */ | ||
| 1651 | default: | ||
| 1652 | rdev->config.si.tile_config |= 2 << 4; | ||
| 1653 | break; | ||
| 1654 | } | ||
| 1647 | rdev->config.si.tile_config |= | 1655 | rdev->config.si.tile_config |= |
| 1648 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 1656 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
| 1649 | rdev->config.si.tile_config |= | 1657 | rdev->config.si.tile_config |= |
| @@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) | |||
| 3960 | rdev->bios = NULL; | 3968 | rdev->bios = NULL; |
| 3961 | } | 3969 | } |
| 3962 | 3970 | ||
| 3971 | /** | ||
| 3972 | * si_get_gpu_clock - return GPU clock counter snapshot | ||
| 3973 | * | ||
| 3974 | * @rdev: radeon_device pointer | ||
| 3975 | * | ||
| 3976 | * Fetches a GPU clock counter snapshot (SI). | ||
| 3977 | * Returns the 64 bit clock counter snapshot. | ||
| 3978 | */ | ||
| 3979 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | ||
| 3980 | { | ||
| 3981 | uint64_t clock; | ||
| 3982 | |||
| 3983 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3984 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3985 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3986 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3987 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3988 | return clock; | ||
| 3989 | } | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089e8761..ef4815c27b1c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
| @@ -698,6 +698,9 @@ | |||
| 698 | #define RLC_UCODE_ADDR 0xC32C | 698 | #define RLC_UCODE_ADDR 0xC32C |
| 699 | #define RLC_UCODE_DATA 0xC330 | 699 | #define RLC_UCODE_DATA 0xC330 |
| 700 | 700 | ||
| 701 | #define RLC_GPU_CLOCK_COUNT_LSB 0xC338 | ||
| 702 | #define RLC_GPU_CLOCK_COUNT_MSB 0xC33C | ||
| 703 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 | ||
| 701 | #define RLC_MC_CNTL 0xC344 | 704 | #define RLC_MC_CNTL 0xC344 |
| 702 | #define RLC_UCODE_CNTL 0xC348 | 705 | #define RLC_UCODE_CNTL 0xC348 |
| 703 | 706 | ||
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 7ff5c99b1638..c78bb997e2c6 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
| @@ -213,9 +213,12 @@ | |||
| 213 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 213 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
| 214 | {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 214 | {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
| 215 | {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 215 | {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
| 216 | {0x1002, 0x6806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
| 216 | {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 217 | {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
| 217 | {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 218 | {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
| 218 | {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 219 | {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
| 220 | {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
| 221 | {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
| 219 | {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 222 | {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
| 220 | {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 223 | {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
| 221 | {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 224 | {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 58056865b8e9..dc3a8cd7db8a 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h | |||
| @@ -964,6 +964,8 @@ struct drm_radeon_cs { | |||
| 964 | #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f | 964 | #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f |
| 965 | /* max pipes - needed for compute shaders */ | 965 | /* max pipes - needed for compute shaders */ |
| 966 | #define RADEON_INFO_MAX_PIPES 0x10 | 966 | #define RADEON_INFO_MAX_PIPES 0x10 |
| 967 | /* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */ | ||
| 968 | #define RADEON_INFO_TIMESTAMP 0x11 | ||
| 967 | 969 | ||
| 968 | struct drm_radeon_info { | 970 | struct drm_radeon_info { |
| 969 | uint32_t request; | 971 | uint32_t request; |
