aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-02-20 16:15:10 -0500
committerDave Airlie <airlied@redhat.com>2013-02-20 16:15:16 -0500
commit74e1697478ffdee0e12e48db024a9b3677fd8cee (patch)
treeec6e337139cd9020f7b5adc054b1f6caa09c1b0a
parente9f211ad7d65b264998928cea822c11c88e5586b (diff)
parent43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 (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.c9
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c13
-rw-r--r--drivers/gpu/drm/radeon/r600.c17
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c73
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c25
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h4
-rw-r--r--drivers/gpu/drm/radeon/si.c31
-rw-r--r--drivers/gpu/drm/radeon/sid.h5
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 };
1238static void atom_index_iio(struct atom_context *ctx, int base) 1238static 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
1336void atom_destroy(struct atom_context *ctx) 1342void 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);
109void r600_irq_disable(struct radeon_device *rdev); 109void r600_irq_disable(struct radeon_device *rdev);
110static void r600_pcie_gen2_enable(struct radeon_device *rdev); 110static 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 */
120u32 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 */
113int rv6xx_get_temp(struct radeon_device *rdev) 126int 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 */
4458uint64_t r600_get_gpu_clock(struct radeon_device *rdev) 4471uint64_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);
391int r600_mc_wait_for_idle(struct radeon_device *rdev); 391int r600_mc_wait_for_idle(struct radeon_device *rdev);
392uint64_t r600_get_gpu_clock(struct radeon_device *rdev); 392u32 r600_get_xclk(struct radeon_device *rdev);
393uint64_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);
411u32 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);
516void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); 518void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
517int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); 519int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
518uint64_t si_get_gpu_clock(struct radeon_device *rdev);
519int si_copy_dma(struct radeon_device *rdev, 520int 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);
523void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); 524void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
525u32 si_get_xclk(struct radeon_device *rdev);
526uint64_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
46struct 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
46struct atpx_power_control { 52struct 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 */
139static 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 */
407static int radeon_atpx_init(void) 465static 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);
43void rv770_fini(struct radeon_device *rdev); 43void rv770_fini(struct radeon_device *rdev);
44static void rv770_pcie_gen2_enable(struct radeon_device *rdev); 44static 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 */
57u32 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
46u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) 71u32 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);
70extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); 70extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
71extern bool evergreen_is_display_hung(struct radeon_device *rdev); 71extern 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 */
84u32 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 */
74int si_get_temp(struct radeon_device *rdev) 101int 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 */
4592uint64_t si_get_gpu_clock(struct radeon_device *rdev) 4619uint64_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