diff options
author | Dave Airlie <airlied@redhat.com> | 2013-02-20 16:15:10 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-02-20 16:15:16 -0500 |
commit | 74e1697478ffdee0e12e48db024a9b3677fd8cee (patch) | |
tree | ec6e337139cd9020f7b5adc054b1f6caa09c1b0a | |
parent | e9f211ad7d65b264998928cea822c11c88e5586b (diff) | |
parent | 43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 (diff) |
Merge branch 'drm-next-3.9' of git://people.freedesktop.org/~agd5f/linux into drm-next
More drm-next bits for radeon. Just bug fixes.
* 'drm-next-3.9' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon: properly validate the atpx interface
drm/radeon: switch get_gpu_clock() to a callback (v2)
drm/radeon: add a asic callback to get the xclk
drm/radeon: Avoid NULL pointer dereference from atom_index_iio() allocation failure
drm/radeon: remove overzealous warning in hdmi handling
drm/radeon: fix multi-head power profile stability on BTC+ asics
-rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770d.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 5 |
15 files changed, 212 insertions, 19 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 5ce9bf51a8de..46a9c3772850 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -1238,6 +1238,8 @@ static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; | |||
1238 | static void atom_index_iio(struct atom_context *ctx, int base) | 1238 | static void atom_index_iio(struct atom_context *ctx, int base) |
1239 | { | 1239 | { |
1240 | ctx->iio = kzalloc(2 * 256, GFP_KERNEL); | 1240 | ctx->iio = kzalloc(2 * 256, GFP_KERNEL); |
1241 | if (!ctx->iio) | ||
1242 | return; | ||
1241 | while (CU8(base) == ATOM_IIO_START) { | 1243 | while (CU8(base) == ATOM_IIO_START) { |
1242 | ctx->iio[CU8(base + 1)] = base + 2; | 1244 | ctx->iio[CU8(base + 1)] = base + 2; |
1243 | base += 2; | 1245 | base += 2; |
@@ -1287,6 +1289,10 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) | |||
1287 | ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR); | 1289 | ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR); |
1288 | ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR); | 1290 | ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR); |
1289 | atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4); | 1291 | atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4); |
1292 | if (!ctx->iio) { | ||
1293 | atom_destroy(ctx); | ||
1294 | return NULL; | ||
1295 | } | ||
1290 | 1296 | ||
1291 | str = CSTR(CU16(base + ATOM_ROM_MSG_PTR)); | 1297 | str = CSTR(CU16(base + ATOM_ROM_MSG_PTR)); |
1292 | while (*str && ((*str == '\n') || (*str == '\r'))) | 1298 | while (*str && ((*str == '\n') || (*str == '\r'))) |
@@ -1335,8 +1341,7 @@ int atom_asic_init(struct atom_context *ctx) | |||
1335 | 1341 | ||
1336 | void atom_destroy(struct atom_context *ctx) | 1342 | void atom_destroy(struct atom_context *ctx) |
1337 | { | 1343 | { |
1338 | if (ctx->iio) | 1344 | kfree(ctx->iio); |
1339 | kfree(ctx->iio); | ||
1340 | kfree(ctx); | 1345 | kfree(ctx); |
1341 | } | 1346 | } |
1342 | 1347 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 2916de896a60..3c38ea46531c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -403,6 +403,19 @@ void evergreen_pm_misc(struct radeon_device *rdev) | |||
403 | rdev->pm.current_vddc = voltage->voltage; | 403 | rdev->pm.current_vddc = voltage->voltage; |
404 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); | 404 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); |
405 | } | 405 | } |
406 | |||
407 | /* starting with BTC, there is one state that is used for both | ||
408 | * MH and SH. Difference is that we always use the high clock index for | ||
409 | * mclk and vddci. | ||
410 | */ | ||
411 | if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && | ||
412 | (rdev->family >= CHIP_BARTS) && | ||
413 | rdev->pm.active_crtc_count && | ||
414 | ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || | ||
415 | (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) | ||
416 | voltage = &rdev->pm.power_state[req_ps_idx]. | ||
417 | clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage; | ||
418 | |||
406 | /* 0xff01 is a flag rather then an actual voltage */ | 419 | /* 0xff01 is a flag rather then an actual voltage */ |
407 | if (voltage->vddci == 0xff01) | 420 | if (voltage->vddci == 0xff01) |
408 | return; | 421 | return; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dbcb0752f083..6d4b5611daf4 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -109,6 +109,19 @@ void r600_fini(struct radeon_device *rdev); | |||
109 | void r600_irq_disable(struct radeon_device *rdev); | 109 | void r600_irq_disable(struct radeon_device *rdev); |
110 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | 110 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); |
111 | 111 | ||
112 | /** | ||
113 | * r600_get_xclk - get the xclk | ||
114 | * | ||
115 | * @rdev: radeon_device pointer | ||
116 | * | ||
117 | * Returns the reference clock used by the gfx engine | ||
118 | * (r6xx, IGPs, APUs). | ||
119 | */ | ||
120 | u32 r600_get_xclk(struct radeon_device *rdev) | ||
121 | { | ||
122 | return rdev->clock.spll.reference_freq; | ||
123 | } | ||
124 | |||
112 | /* get temperature in millidegrees */ | 125 | /* get temperature in millidegrees */ |
113 | int rv6xx_get_temp(struct radeon_device *rdev) | 126 | int rv6xx_get_temp(struct radeon_device *rdev) |
114 | { | 127 | { |
@@ -4448,14 +4461,14 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
4448 | } | 4461 | } |
4449 | 4462 | ||
4450 | /** | 4463 | /** |
4451 | * r600_get_gpu_clock - return GPU clock counter snapshot | 4464 | * r600_get_gpu_clock_counter - return GPU clock counter snapshot |
4452 | * | 4465 | * |
4453 | * @rdev: radeon_device pointer | 4466 | * @rdev: radeon_device pointer |
4454 | * | 4467 | * |
4455 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | 4468 | * Fetches a GPU clock counter snapshot (R6xx-cayman). |
4456 | * Returns the 64 bit clock counter snapshot. | 4469 | * Returns the 64 bit clock counter snapshot. |
4457 | */ | 4470 | */ |
4458 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | 4471 | uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev) |
4459 | { | 4472 | { |
4460 | uint64_t clock; | 4473 | uint64_t clock; |
4461 | 4474 | ||
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index ff80efe9cb7d..95970ec47c45 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -544,7 +544,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
544 | 544 | ||
545 | /* Called for ATOM_ENCODER_MODE_HDMI only */ | 545 | /* Called for ATOM_ENCODER_MODE_HDMI only */ |
546 | if (!dig || !dig->afmt) { | 546 | if (!dig || !dig->afmt) { |
547 | WARN_ON(1); | ||
548 | return; | 547 | return; |
549 | } | 548 | } |
550 | if (!dig->afmt->enabled) | 549 | if (!dig->afmt->enabled) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index bb43a849759b..8263af3fd832 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1178,6 +1178,10 @@ struct radeon_asic { | |||
1178 | bool (*gui_idle)(struct radeon_device *rdev); | 1178 | bool (*gui_idle)(struct radeon_device *rdev); |
1179 | /* wait for mc_idle */ | 1179 | /* wait for mc_idle */ |
1180 | int (*mc_wait_for_idle)(struct radeon_device *rdev); | 1180 | int (*mc_wait_for_idle)(struct radeon_device *rdev); |
1181 | /* get the reference clock */ | ||
1182 | u32 (*get_xclk)(struct radeon_device *rdev); | ||
1183 | /* get the gpu clock counter */ | ||
1184 | uint64_t (*get_gpu_clock_counter)(struct radeon_device *rdev); | ||
1181 | /* gart */ | 1185 | /* gart */ |
1182 | struct { | 1186 | struct { |
1183 | void (*tlb_flush)(struct radeon_device *rdev); | 1187 | void (*tlb_flush)(struct radeon_device *rdev); |
@@ -1859,6 +1863,8 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
1859 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) | 1863 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
1860 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) | 1864 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
1861 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) | 1865 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
1866 | #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev)) | ||
1867 | #define radeon_get_gpu_clock_counter(rdev) (rdev)->asic->get_gpu_clock_counter((rdev)) | ||
1862 | 1868 | ||
1863 | /* Common functions */ | 1869 | /* Common functions */ |
1864 | /* AGP */ | 1870 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 67f008febec7..aba0a893ea98 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -934,6 +934,8 @@ static struct radeon_asic r600_asic = { | |||
934 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 934 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
935 | .gui_idle = &r600_gui_idle, | 935 | .gui_idle = &r600_gui_idle, |
936 | .mc_wait_for_idle = &r600_mc_wait_for_idle, | 936 | .mc_wait_for_idle = &r600_mc_wait_for_idle, |
937 | .get_xclk = &r600_get_xclk, | ||
938 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
937 | .gart = { | 939 | .gart = { |
938 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 940 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
939 | .set_page = &rs600_gart_set_page, | 941 | .set_page = &rs600_gart_set_page, |
@@ -1018,6 +1020,8 @@ static struct radeon_asic rs780_asic = { | |||
1018 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1020 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1019 | .gui_idle = &r600_gui_idle, | 1021 | .gui_idle = &r600_gui_idle, |
1020 | .mc_wait_for_idle = &r600_mc_wait_for_idle, | 1022 | .mc_wait_for_idle = &r600_mc_wait_for_idle, |
1023 | .get_xclk = &r600_get_xclk, | ||
1024 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1021 | .gart = { | 1025 | .gart = { |
1022 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 1026 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
1023 | .set_page = &rs600_gart_set_page, | 1027 | .set_page = &rs600_gart_set_page, |
@@ -1102,6 +1106,8 @@ static struct radeon_asic rv770_asic = { | |||
1102 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1106 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1103 | .gui_idle = &r600_gui_idle, | 1107 | .gui_idle = &r600_gui_idle, |
1104 | .mc_wait_for_idle = &r600_mc_wait_for_idle, | 1108 | .mc_wait_for_idle = &r600_mc_wait_for_idle, |
1109 | .get_xclk = &rv770_get_xclk, | ||
1110 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1105 | .gart = { | 1111 | .gart = { |
1106 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 1112 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
1107 | .set_page = &rs600_gart_set_page, | 1113 | .set_page = &rs600_gart_set_page, |
@@ -1186,6 +1192,8 @@ static struct radeon_asic evergreen_asic = { | |||
1186 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1192 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1187 | .gui_idle = &r600_gui_idle, | 1193 | .gui_idle = &r600_gui_idle, |
1188 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1194 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1195 | .get_xclk = &rv770_get_xclk, | ||
1196 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1189 | .gart = { | 1197 | .gart = { |
1190 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1198 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1191 | .set_page = &rs600_gart_set_page, | 1199 | .set_page = &rs600_gart_set_page, |
@@ -1270,6 +1278,8 @@ static struct radeon_asic sumo_asic = { | |||
1270 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1278 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1271 | .gui_idle = &r600_gui_idle, | 1279 | .gui_idle = &r600_gui_idle, |
1272 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1280 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1281 | .get_xclk = &r600_get_xclk, | ||
1282 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1273 | .gart = { | 1283 | .gart = { |
1274 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1284 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1275 | .set_page = &rs600_gart_set_page, | 1285 | .set_page = &rs600_gart_set_page, |
@@ -1354,6 +1364,8 @@ static struct radeon_asic btc_asic = { | |||
1354 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1364 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1355 | .gui_idle = &r600_gui_idle, | 1365 | .gui_idle = &r600_gui_idle, |
1356 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1366 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1367 | .get_xclk = &rv770_get_xclk, | ||
1368 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1357 | .gart = { | 1369 | .gart = { |
1358 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1370 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1359 | .set_page = &rs600_gart_set_page, | 1371 | .set_page = &rs600_gart_set_page, |
@@ -1438,6 +1450,8 @@ static struct radeon_asic cayman_asic = { | |||
1438 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1450 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1439 | .gui_idle = &r600_gui_idle, | 1451 | .gui_idle = &r600_gui_idle, |
1440 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1452 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1453 | .get_xclk = &rv770_get_xclk, | ||
1454 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1441 | .gart = { | 1455 | .gart = { |
1442 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1456 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1443 | .set_page = &rs600_gart_set_page, | 1457 | .set_page = &rs600_gart_set_page, |
@@ -1565,6 +1579,8 @@ static struct radeon_asic trinity_asic = { | |||
1565 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1579 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1566 | .gui_idle = &r600_gui_idle, | 1580 | .gui_idle = &r600_gui_idle, |
1567 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1581 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1582 | .get_xclk = &r600_get_xclk, | ||
1583 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | ||
1568 | .gart = { | 1584 | .gart = { |
1569 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1585 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1570 | .set_page = &rs600_gart_set_page, | 1586 | .set_page = &rs600_gart_set_page, |
@@ -1692,6 +1708,8 @@ static struct radeon_asic si_asic = { | |||
1692 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 1708 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
1693 | .gui_idle = &r600_gui_idle, | 1709 | .gui_idle = &r600_gui_idle, |
1694 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, | 1710 | .mc_wait_for_idle = &evergreen_mc_wait_for_idle, |
1711 | .get_xclk = &si_get_xclk, | ||
1712 | .get_gpu_clock_counter = &si_get_gpu_clock_counter, | ||
1695 | .gart = { | 1713 | .gart = { |
1696 | .tlb_flush = &si_pcie_gart_tlb_flush, | 1714 | .tlb_flush = &si_pcie_gart_tlb_flush, |
1697 | .set_page = &rs600_gart_set_page, | 1715 | .set_page = &rs600_gart_set_page, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4134a823958..3535f73ad3e2 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -389,7 +389,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
389 | unsigned num_gpu_pages, | 389 | unsigned num_gpu_pages, |
390 | struct radeon_sa_bo *vb); | 390 | struct radeon_sa_bo *vb); |
391 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 391 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
392 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | 392 | u32 r600_get_xclk(struct radeon_device *rdev); |
393 | uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); | ||
393 | 394 | ||
394 | /* | 395 | /* |
395 | * rv770,rv730,rv710,rv740 | 396 | * rv770,rv730,rv710,rv740 |
@@ -407,6 +408,7 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
407 | uint64_t src_offset, uint64_t dst_offset, | 408 | uint64_t src_offset, uint64_t dst_offset, |
408 | unsigned num_gpu_pages, | 409 | unsigned num_gpu_pages, |
409 | struct radeon_fence **fence); | 410 | struct radeon_fence **fence); |
411 | u32 rv770_get_xclk(struct radeon_device *rdev); | ||
410 | 412 | ||
411 | /* | 413 | /* |
412 | * evergreen | 414 | * evergreen |
@@ -515,11 +517,12 @@ void si_vm_set_page(struct radeon_device *rdev, | |||
515 | uint32_t incr, uint32_t flags); | 517 | uint32_t incr, uint32_t flags); |
516 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 518 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
517 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 519 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
518 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
519 | int si_copy_dma(struct radeon_device *rdev, | 520 | int si_copy_dma(struct radeon_device *rdev, |
520 | uint64_t src_offset, uint64_t dst_offset, | 521 | uint64_t src_offset, uint64_t dst_offset, |
521 | unsigned num_gpu_pages, | 522 | unsigned num_gpu_pages, |
522 | struct radeon_fence **fence); | 523 | struct radeon_fence **fence); |
523 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 524 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
525 | u32 si_get_xclk(struct radeon_device *rdev); | ||
526 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); | ||
524 | 527 | ||
525 | #endif | 528 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 15f5ded65e0c..d96070bf8388 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -43,6 +43,12 @@ struct atpx_verify_interface { | |||
43 | u32 function_bits; /* supported functions bit vector */ | 43 | u32 function_bits; /* supported functions bit vector */ |
44 | } __packed; | 44 | } __packed; |
45 | 45 | ||
46 | struct atpx_px_params { | ||
47 | u16 size; /* structure size in bytes (includes size field) */ | ||
48 | u32 valid_flags; /* which flags are valid */ | ||
49 | u32 flags; /* flags */ | ||
50 | } __packed; | ||
51 | |||
46 | struct atpx_power_control { | 52 | struct atpx_power_control { |
47 | u16 size; | 53 | u16 size; |
48 | u8 dgpu_state; | 54 | u8 dgpu_state; |
@@ -123,9 +129,61 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas | |||
123 | } | 129 | } |
124 | 130 | ||
125 | /** | 131 | /** |
132 | * radeon_atpx_validate_functions - validate ATPX functions | ||
133 | * | ||
134 | * @atpx: radeon atpx struct | ||
135 | * | ||
136 | * Validate that required functions are enabled (all asics). | ||
137 | * returns 0 on success, error on failure. | ||
138 | */ | ||
139 | static int radeon_atpx_validate(struct radeon_atpx *atpx) | ||
140 | { | ||
141 | /* make sure required functions are enabled */ | ||
142 | /* dGPU power control is required */ | ||
143 | atpx->functions.power_cntl = true; | ||
144 | |||
145 | if (atpx->functions.px_params) { | ||
146 | union acpi_object *info; | ||
147 | struct atpx_px_params output; | ||
148 | size_t size; | ||
149 | u32 valid_bits; | ||
150 | |||
151 | info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); | ||
152 | if (!info) | ||
153 | return -EIO; | ||
154 | |||
155 | memset(&output, 0, sizeof(output)); | ||
156 | |||
157 | size = *(u16 *) info->buffer.pointer; | ||
158 | if (size < 10) { | ||
159 | printk("ATPX buffer is too small: %zu\n", size); | ||
160 | kfree(info); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | size = min(sizeof(output), size); | ||
164 | |||
165 | memcpy(&output, info->buffer.pointer, size); | ||
166 | |||
167 | valid_bits = output.flags & output.valid_flags; | ||
168 | /* if separate mux flag is set, mux controls are required */ | ||
169 | if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { | ||
170 | atpx->functions.i2c_mux_cntl = true; | ||
171 | atpx->functions.disp_mux_cntl = true; | ||
172 | } | ||
173 | /* if any outputs are muxed, mux controls are required */ | ||
174 | if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | | ||
175 | ATPX_TV_SIGNAL_MUXED | | ||
176 | ATPX_DFP_SIGNAL_MUXED)) | ||
177 | atpx->functions.disp_mux_cntl = true; | ||
178 | |||
179 | kfree(info); | ||
180 | } | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | /** | ||
126 | * radeon_atpx_verify_interface - verify ATPX | 185 | * radeon_atpx_verify_interface - verify ATPX |
127 | * | 186 | * |
128 | * @handle: acpi handle | ||
129 | * @atpx: radeon atpx struct | 187 | * @atpx: radeon atpx struct |
130 | * | 188 | * |
131 | * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function | 189 | * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function |
@@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
406 | */ | 464 | */ |
407 | static int radeon_atpx_init(void) | 465 | static int radeon_atpx_init(void) |
408 | { | 466 | { |
467 | int r; | ||
468 | |||
409 | /* set up the ATPX handle */ | 469 | /* set up the ATPX handle */ |
410 | return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); | 470 | r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); |
471 | if (r) | ||
472 | return r; | ||
473 | |||
474 | /* validate the atpx setup */ | ||
475 | r = radeon_atpx_validate(&radeon_atpx_priv.atpx); | ||
476 | if (r) | ||
477 | return r; | ||
478 | |||
479 | return 0; | ||
411 | } | 480 | } |
412 | 481 | ||
413 | /** | 482 | /** |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 8794de10a6c7..44b8034a400d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -759,6 +759,11 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
759 | atom_card_info->pll_write = cail_pll_write; | 759 | atom_card_info->pll_write = cail_pll_write; |
760 | 760 | ||
761 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | 761 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
762 | if (!rdev->mode_info.atom_context) { | ||
763 | radeon_atombios_fini(rdev); | ||
764 | return -ENOMEM; | ||
765 | } | ||
766 | |||
762 | mutex_init(&rdev->mode_info.atom_context->mutex); | 767 | mutex_init(&rdev->mode_info.atom_context->mutex); |
763 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 768 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
764 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | 769 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); |
@@ -778,9 +783,11 @@ void radeon_atombios_fini(struct radeon_device *rdev) | |||
778 | { | 783 | { |
779 | if (rdev->mode_info.atom_context) { | 784 | if (rdev->mode_info.atom_context) { |
780 | kfree(rdev->mode_info.atom_context->scratch); | 785 | kfree(rdev->mode_info.atom_context->scratch); |
781 | kfree(rdev->mode_info.atom_context); | ||
782 | } | 786 | } |
787 | kfree(rdev->mode_info.atom_context); | ||
788 | rdev->mode_info.atom_context = NULL; | ||
783 | kfree(rdev->mode_info.atom_card_info); | 789 | kfree(rdev->mode_info.atom_card_info); |
790 | rdev->mode_info.atom_card_info = NULL; | ||
784 | } | 791 | } |
785 | 792 | ||
786 | /* COMBIOS */ | 793 | /* COMBIOS */ |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 9c312f9afb68..c75cb2c6ba71 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -185,11 +185,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
185 | if (info->request == RADEON_INFO_TIMESTAMP) { | 185 | if (info->request == RADEON_INFO_TIMESTAMP) { |
186 | if (rdev->family >= CHIP_R600) { | 186 | if (rdev->family >= CHIP_R600) { |
187 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | 187 | value_ptr64 = (uint64_t*)((unsigned long)info->value); |
188 | if (rdev->family >= CHIP_TAHITI) { | 188 | value64 = radeon_get_gpu_clock_counter(rdev); |
189 | value64 = si_get_gpu_clock(rdev); | ||
190 | } else { | ||
191 | value64 = r600_get_gpu_clock(rdev); | ||
192 | } | ||
193 | 189 | ||
194 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | 190 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { |
195 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | 191 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
@@ -282,7 +278,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
282 | break; | 278 | break; |
283 | case RADEON_INFO_CLOCK_CRYSTAL_FREQ: | 279 | case RADEON_INFO_CLOCK_CRYSTAL_FREQ: |
284 | /* return clock value in KHz */ | 280 | /* return clock value in KHz */ |
285 | value = rdev->clock.spll.reference_freq * 10; | 281 | if (rdev->asic->get_xclk) |
282 | value = radeon_get_xclk(rdev) * 10; | ||
283 | else | ||
284 | value = rdev->clock.spll.reference_freq * 10; | ||
286 | break; | 285 | break; |
287 | case RADEON_INFO_NUM_BACKENDS: | 286 | case RADEON_INFO_NUM_BACKENDS: |
288 | if (rdev->family >= CHIP_TAHITI) | 287 | if (rdev->family >= CHIP_TAHITI) |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 0bfa656aa87d..338fd6a74e87 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -169,7 +169,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
169 | 169 | ||
170 | /* starting with BTC, there is one state that is used for both | 170 | /* starting with BTC, there is one state that is used for both |
171 | * MH and SH. Difference is that we always use the high clock index for | 171 | * MH and SH. Difference is that we always use the high clock index for |
172 | * mclk. | 172 | * mclk and vddci. |
173 | */ | 173 | */ |
174 | if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && | 174 | if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && |
175 | (rdev->family >= CHIP_BARTS) && | 175 | (rdev->family >= CHIP_BARTS) && |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 1b2444f4d8f4..d63fe1d0f53f 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -43,6 +43,31 @@ static void rv770_gpu_init(struct radeon_device *rdev); | |||
43 | void rv770_fini(struct radeon_device *rdev); | 43 | void rv770_fini(struct radeon_device *rdev); |
44 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev); | 44 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev); |
45 | 45 | ||
46 | #define PCIE_BUS_CLK 10000 | ||
47 | #define TCLK (PCIE_BUS_CLK / 10) | ||
48 | |||
49 | /** | ||
50 | * rv770_get_xclk - get the xclk | ||
51 | * | ||
52 | * @rdev: radeon_device pointer | ||
53 | * | ||
54 | * Returns the reference clock used by the gfx engine | ||
55 | * (r7xx-cayman). | ||
56 | */ | ||
57 | u32 rv770_get_xclk(struct radeon_device *rdev) | ||
58 | { | ||
59 | u32 reference_clock = rdev->clock.spll.reference_freq; | ||
60 | u32 tmp = RREG32(CG_CLKPIN_CNTL); | ||
61 | |||
62 | if (tmp & MUX_TCLK_TO_XCLK) | ||
63 | return TCLK; | ||
64 | |||
65 | if (tmp & XTALIN_DIVIDE) | ||
66 | return reference_clock / 4; | ||
67 | |||
68 | return reference_clock; | ||
69 | } | ||
70 | |||
46 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | 71 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
47 | { | 72 | { |
48 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 73 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 20e29d23d348..c55f950a4af7 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -128,6 +128,10 @@ | |||
128 | #define GUI_ACTIVE (1<<31) | 128 | #define GUI_ACTIVE (1<<31) |
129 | #define GRBM_STATUS2 0x8014 | 129 | #define GRBM_STATUS2 0x8014 |
130 | 130 | ||
131 | #define CG_CLKPIN_CNTL 0x660 | ||
132 | # define MUX_TCLK_TO_XCLK (1 << 8) | ||
133 | # define XTALIN_DIVIDE (1 << 9) | ||
134 | |||
131 | #define CG_MULT_THERMAL_STATUS 0x740 | 135 | #define CG_MULT_THERMAL_STATUS 0x740 |
132 | #define ASIC_T(x) ((x) << 16) | 136 | #define ASIC_T(x) ((x) << 16) |
133 | #define ASIC_T_MASK 0x3FF0000 | 137 | #define ASIC_T_MASK 0x3FF0000 |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 719f03e061db..80979ed951eb 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -70,6 +70,33 @@ extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); | |||
70 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); | 70 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); |
71 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); | 71 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); |
72 | 72 | ||
73 | #define PCIE_BUS_CLK 10000 | ||
74 | #define TCLK (PCIE_BUS_CLK / 10) | ||
75 | |||
76 | /** | ||
77 | * si_get_xclk - get the xclk | ||
78 | * | ||
79 | * @rdev: radeon_device pointer | ||
80 | * | ||
81 | * Returns the reference clock used by the gfx engine | ||
82 | * (SI). | ||
83 | */ | ||
84 | u32 si_get_xclk(struct radeon_device *rdev) | ||
85 | { | ||
86 | u32 reference_clock = rdev->clock.spll.reference_freq; | ||
87 | u32 tmp; | ||
88 | |||
89 | tmp = RREG32(CG_CLKPIN_CNTL_2); | ||
90 | if (tmp & MUX_TCLK_TO_XCLK) | ||
91 | return TCLK; | ||
92 | |||
93 | tmp = RREG32(CG_CLKPIN_CNTL); | ||
94 | if (tmp & XTALIN_DIVIDE) | ||
95 | return reference_clock / 4; | ||
96 | |||
97 | return reference_clock; | ||
98 | } | ||
99 | |||
73 | /* get temperature in millidegrees */ | 100 | /* get temperature in millidegrees */ |
74 | int si_get_temp(struct radeon_device *rdev) | 101 | int si_get_temp(struct radeon_device *rdev) |
75 | { | 102 | { |
@@ -4582,14 +4609,14 @@ void si_fini(struct radeon_device *rdev) | |||
4582 | } | 4609 | } |
4583 | 4610 | ||
4584 | /** | 4611 | /** |
4585 | * si_get_gpu_clock - return GPU clock counter snapshot | 4612 | * si_get_gpu_clock_counter - return GPU clock counter snapshot |
4586 | * | 4613 | * |
4587 | * @rdev: radeon_device pointer | 4614 | * @rdev: radeon_device pointer |
4588 | * | 4615 | * |
4589 | * Fetches a GPU clock counter snapshot (SI). | 4616 | * Fetches a GPU clock counter snapshot (SI). |
4590 | * Returns the 64 bit clock counter snapshot. | 4617 | * Returns the 64 bit clock counter snapshot. |
4591 | */ | 4618 | */ |
4592 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | 4619 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev) |
4593 | { | 4620 | { |
4594 | uint64_t clock; | 4621 | uint64_t clock; |
4595 | 4622 | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 07fc455e35ae..23fc08fc8e7f 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -58,6 +58,11 @@ | |||
58 | #define VGA_HDP_CONTROL 0x328 | 58 | #define VGA_HDP_CONTROL 0x328 |
59 | #define VGA_MEMORY_DISABLE (1 << 4) | 59 | #define VGA_MEMORY_DISABLE (1 << 4) |
60 | 60 | ||
61 | #define CG_CLKPIN_CNTL 0x660 | ||
62 | # define XTALIN_DIVIDE (1 << 1) | ||
63 | #define CG_CLKPIN_CNTL_2 0x664 | ||
64 | # define MUX_TCLK_TO_XCLK (1 << 8) | ||
65 | |||
61 | #define DMIF_ADDR_CONFIG 0xBD4 | 66 | #define DMIF_ADDR_CONFIG 0xBD4 |
62 | 67 | ||
63 | #define SRBM_STATUS 0xE50 | 68 | #define SRBM_STATUS 0xE50 |