aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-03-18 01:04:01 -0400
committerDave Airlie <airlied@redhat.com>2010-03-30 23:11:29 -0400
commita084e6ee6e64a76f1a9665d527203cdab7d6048f (patch)
treeebc1f90b7111b39bee17ff3f1e2ee02452dc1bf7 /drivers
parentc1bcad9d16831859373d8f579fa1e146409f9960 (diff)
drm/radeon/kms/atom: make sure tables are valid (v2)
Check that atom cmd and data tables are valid before using them. (v2) - fix some whitespace errors noticed by Rafał Miłecki - check a few more cases Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/atom.c32
-rw-r--r--drivers/gpu/drm/radeon/atom.h6
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c367
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c15
-rw-r--r--drivers/gpu/drm/radeon/rs690.c74
7 files changed, 272 insertions, 242 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index b7fe660985c..247f8ee7e94 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -1295,12 +1295,16 @@ void atom_destroy(struct atom_context *ctx)
1295 kfree(ctx); 1295 kfree(ctx);
1296} 1296}
1297 1297
1298void atom_parse_data_header(struct atom_context *ctx, int index, 1298bool atom_parse_data_header(struct atom_context *ctx, int index,
1299 uint16_t * size, uint8_t * frev, uint8_t * crev, 1299 uint16_t * size, uint8_t * frev, uint8_t * crev,
1300 uint16_t * data_start) 1300 uint16_t * data_start)
1301{ 1301{
1302 int offset = index * 2 + 4; 1302 int offset = index * 2 + 4;
1303 int idx = CU16(ctx->data_table + offset); 1303 int idx = CU16(ctx->data_table + offset);
1304 u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
1305
1306 if (!mdt[index])
1307 return false;
1304 1308
1305 if (size) 1309 if (size)
1306 *size = CU16(idx); 1310 *size = CU16(idx);
@@ -1309,38 +1313,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,
1309 if (crev) 1313 if (crev)
1310 *crev = CU8(idx + 3); 1314 *crev = CU8(idx + 3);
1311 *data_start = idx; 1315 *data_start = idx;
1312 return; 1316 return true;
1313} 1317}
1314 1318
1315void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, 1319bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
1316 uint8_t * crev) 1320 uint8_t * crev)
1317{ 1321{
1318 int offset = index * 2 + 4; 1322 int offset = index * 2 + 4;
1319 int idx = CU16(ctx->cmd_table + offset); 1323 int idx = CU16(ctx->cmd_table + offset);
1324 u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
1325
1326 if (!mct[index])
1327 return false;
1320 1328
1321 if (frev) 1329 if (frev)
1322 *frev = CU8(idx + 2); 1330 *frev = CU8(idx + 2);
1323 if (crev) 1331 if (crev)
1324 *crev = CU8(idx + 3); 1332 *crev = CU8(idx + 3);
1325 return; 1333 return true;
1326} 1334}
1327 1335
1328int atom_allocate_fb_scratch(struct atom_context *ctx) 1336int atom_allocate_fb_scratch(struct atom_context *ctx)
1329{ 1337{
1330 int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); 1338 int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
1331 uint16_t data_offset; 1339 uint16_t data_offset;
1332 int usage_bytes; 1340 int usage_bytes = 0;
1333 struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; 1341 struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
1334 1342
1335 atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); 1343 if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
1344 firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
1336 1345
1337 firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); 1346 DRM_DEBUG("atom firmware requested %08x %dkb\n",
1347 firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
1348 firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
1338 1349
1339 DRM_DEBUG("atom firmware requested %08x %dkb\n", 1350 usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
1340 firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, 1351 }
1341 firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
1342
1343 usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
1344 if (usage_bytes == 0) 1352 if (usage_bytes == 0)
1345 usage_bytes = 20 * 1024; 1353 usage_bytes = 20 * 1024;
1346 /* allocate some scratch memory */ 1354 /* allocate some scratch memory */
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index 1b262631480..cd1b64ab5ca 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -143,8 +143,10 @@ struct atom_context *atom_parse(struct card_info *, void *);
143int atom_execute_table(struct atom_context *, int, uint32_t *); 143int atom_execute_table(struct atom_context *, int, uint32_t *);
144int atom_asic_init(struct atom_context *); 144int atom_asic_init(struct atom_context *);
145void atom_destroy(struct atom_context *); 145void atom_destroy(struct atom_context *);
146void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); 146bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
147void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); 147 uint8_t *frev, uint8_t *crev, uint16_t *data_start);
148bool atom_parse_cmd_header(struct atom_context *ctx, int index,
149 uint8_t *frev, uint8_t *crev);
148int atom_allocate_fb_scratch(struct atom_context *ctx); 150int atom_allocate_fb_scratch(struct atom_context *ctx);
149#include "atom-types.h" 151#include "atom-types.h"
150#include "atombios.h" 152#include "atombios.h"
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 94aa6b293e0..56107b3a997 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -541,8 +541,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
541 int index; 541 int index;
542 542
543 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); 543 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
544 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 544 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
545 &crev); 545 &crev))
546 return adjusted_clock;
546 547
547 memset(&args, 0, sizeof(args)); 548 memset(&args, 0, sizeof(args));
548 549
@@ -630,8 +631,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
630 memset(&args, 0, sizeof(args)); 631 memset(&args, 0, sizeof(args));
631 632
632 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 633 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
633 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 634 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
634 &crev); 635 &crev))
636 return;
635 637
636 switch (frev) { 638 switch (frev) {
637 case 1: 639 case 1:
@@ -705,8 +707,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
705 &ref_div, &post_div); 707 &ref_div, &post_div);
706 708
707 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 709 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
708 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 710 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
709 &crev); 711 &crev))
712 return;
710 713
711 switch (frev) { 714 switch (frev) {
712 case 1: 715 case 1:
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 3733cb78779..f0ea7f8da67 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -75,46 +75,45 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
75 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); 75 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
76 i2c.valid = false; 76 i2c.valid = false;
77 77
78 atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); 78 if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
79 79 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
80 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); 80
81 81 for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
82 82 gpio = &i2c_info->asGPIO_Info[i];
83 for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { 83
84 gpio = &i2c_info->asGPIO_Info[i]; 84 if (gpio->sucI2cId.ucAccess == id) {
85 85 i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
86 if (gpio->sucI2cId.ucAccess == id) { 86 i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
87 i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; 87 i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
88 i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; 88 i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
89 i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; 89 i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
90 i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; 90 i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
91 i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; 91 i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
92 i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; 92 i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
93 i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; 93 i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
94 i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; 94 i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
95 i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); 95 i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
96 i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); 96 i2c.en_data_mask = (1 << gpio->ucDataEnShift);
97 i2c.en_clk_mask = (1 << gpio->ucClkEnShift); 97 i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
98 i2c.en_data_mask = (1 << gpio->ucDataEnShift); 98 i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
99 i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); 99 i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
100 i2c.y_data_mask = (1 << gpio->ucDataY_Shift); 100 i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
101 i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); 101
102 i2c.a_data_mask = (1 << gpio->ucDataA_Shift); 102 if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
103 103 i2c.hw_capable = true;
104 if (gpio->sucI2cId.sbfAccess.bfHW_Capable) 104 else
105 i2c.hw_capable = true; 105 i2c.hw_capable = false;
106 else 106
107 i2c.hw_capable = false; 107 if (gpio->sucI2cId.ucAccess == 0xa0)
108 108 i2c.mm_i2c = true;
109 if (gpio->sucI2cId.ucAccess == 0xa0) 109 else
110 i2c.mm_i2c = true; 110 i2c.mm_i2c = false;
111 else 111
112 i2c.mm_i2c = false; 112 i2c.i2c_id = gpio->sucI2cId.ucAccess;
113 113
114 i2c.i2c_id = gpio->sucI2cId.ucAccess; 114 i2c.valid = true;
115 115 break;
116 i2c.valid = true; 116 }
117 break;
118 } 117 }
119 } 118 }
120 119
@@ -135,20 +134,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd
135 memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); 134 memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
136 gpio.valid = false; 135 gpio.valid = false;
137 136
138 atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); 137 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
138 gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
139 139
140 gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); 140 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
141 sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
141 142
142 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); 143 for (i = 0; i < num_indices; i++) {
143 144 pin = &gpio_info->asGPIO_Pin[i];
144 for (i = 0; i < num_indices; i++) { 145 if (id == pin->ucGPIO_ID) {
145 pin = &gpio_info->asGPIO_Pin[i]; 146 gpio.id = pin->ucGPIO_ID;
146 if (id == pin->ucGPIO_ID) { 147 gpio.reg = pin->usGpioPin_AIndex * 4;
147 gpio.id = pin->ucGPIO_ID; 148 gpio.mask = (1 << pin->ucGpioPinBitShift);
148 gpio.reg = pin->usGpioPin_AIndex * 4; 149 gpio.valid = true;
149 gpio.mask = (1 << pin->ucGpioPinBitShift); 150 break;
150 gpio.valid = true; 151 }
151 break;
152 } 152 }
153 } 153 }
154 154
@@ -395,9 +395,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
395 struct radeon_gpio_rec gpio; 395 struct radeon_gpio_rec gpio;
396 struct radeon_hpd hpd; 396 struct radeon_hpd hpd;
397 397
398 atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); 398 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
399
400 if (data_offset == 0)
401 return false; 399 return false;
402 400
403 if (crev < 2) 401 if (crev < 2)
@@ -449,37 +447,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
449 GetIndexIntoMasterTable(DATA, 447 GetIndexIntoMasterTable(DATA,
450 IntegratedSystemInfo); 448 IntegratedSystemInfo);
451 449
452 atom_parse_data_header(ctx, index, &size, &frev, 450 if (atom_parse_data_header(ctx, index, &size, &frev,
453 &crev, &igp_offset); 451 &crev, &igp_offset)) {
454 452
455 if (crev >= 2) { 453 if (crev >= 2) {
456 igp_obj = 454 igp_obj =
457 (ATOM_INTEGRATED_SYSTEM_INFO_V2 455 (ATOM_INTEGRATED_SYSTEM_INFO_V2
458 *) (ctx->bios + igp_offset); 456 *) (ctx->bios + igp_offset);
459 457
460 if (igp_obj) { 458 if (igp_obj) {
461 uint32_t slot_config, ct; 459 uint32_t slot_config, ct;
462 460
463 if (con_obj_num == 1) 461 if (con_obj_num == 1)
464 slot_config = 462 slot_config =
465 igp_obj-> 463 igp_obj->
466 ulDDISlot1Config; 464 ulDDISlot1Config;
467 else 465 else
468 slot_config = 466 slot_config =
469 igp_obj-> 467 igp_obj->
470 ulDDISlot2Config; 468 ulDDISlot2Config;
471 469
472 ct = (slot_config >> 16) & 0xff; 470 ct = (slot_config >> 16) & 0xff;
473 connector_type = 471 connector_type =
474 object_connector_convert 472 object_connector_convert
475 [ct]; 473 [ct];
476 connector_object_id = ct; 474 connector_object_id = ct;
477 igp_lane_info = 475 igp_lane_info =
478 slot_config & 0xffff; 476 slot_config & 0xffff;
477 } else
478 continue;
479 } else 479 } else
480 continue; 480 continue;
481 } else 481 } else {
482 continue; 482 igp_lane_info = 0;
483 connector_type =
484 object_connector_convert[con_obj_id];
485 connector_object_id = con_obj_id;
486 }
483 } else { 487 } else {
484 igp_lane_info = 0; 488 igp_lane_info = 0;
485 connector_type = 489 connector_type =
@@ -627,20 +631,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
627 uint8_t frev, crev; 631 uint8_t frev, crev;
628 ATOM_XTMDS_INFO *xtmds; 632 ATOM_XTMDS_INFO *xtmds;
629 633
630 atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); 634 if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {
631 xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); 635 xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
632 636
633 if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { 637 if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
634 if (connector_type == DRM_MODE_CONNECTOR_DVII) 638 if (connector_type == DRM_MODE_CONNECTOR_DVII)
635 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; 639 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
636 else 640 else
637 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; 641 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
638 } else { 642 } else {
639 if (connector_type == DRM_MODE_CONNECTOR_DVII) 643 if (connector_type == DRM_MODE_CONNECTOR_DVII)
640 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; 644 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
641 else 645 else
642 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; 646 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
643 } 647 }
648 } else
649 return supported_devices_connector_object_id_convert
650 [connector_type];
644 } else { 651 } else {
645 return supported_devices_connector_object_id_convert 652 return supported_devices_connector_object_id_convert
646 [connector_type]; 653 [connector_type];
@@ -672,7 +679,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
672 int i, j, max_device; 679 int i, j, max_device;
673 struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; 680 struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
674 681
675 atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); 682 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
683 return false;
676 684
677 supported_devices = 685 supported_devices =
678 (union atom_supported_devices *)(ctx->bios + data_offset); 686 (union atom_supported_devices *)(ctx->bios + data_offset);
@@ -865,14 +873,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
865 struct radeon_pll *mpll = &rdev->clock.mpll; 873 struct radeon_pll *mpll = &rdev->clock.mpll;
866 uint16_t data_offset; 874 uint16_t data_offset;
867 875
868 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 876 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
869 &crev, &data_offset); 877 &frev, &crev, &data_offset)) {
870 878 firmware_info =
871 firmware_info = 879 (union firmware_info *)(mode_info->atom_context->bios +
872 (union firmware_info *)(mode_info->atom_context->bios + 880 data_offset);
873 data_offset);
874
875 if (firmware_info) {
876 /* pixel clocks */ 881 /* pixel clocks */
877 p1pll->reference_freq = 882 p1pll->reference_freq =
878 le16_to_cpu(firmware_info->info.usReferenceClock); 883 le16_to_cpu(firmware_info->info.usReferenceClock);
@@ -1006,13 +1011,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
1006 u8 frev, crev; 1011 u8 frev, crev;
1007 u16 data_offset; 1012 u16 data_offset;
1008 1013
1009 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 1014 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1010 &crev, &data_offset); 1015 &frev, &crev, &data_offset)) {
1011 1016 igp_info = (union igp_info *)(mode_info->atom_context->bios +
1012 igp_info = (union igp_info *)(mode_info->atom_context->bios +
1013 data_offset); 1017 data_offset);
1014
1015 if (igp_info) {
1016 switch (crev) { 1018 switch (crev) {
1017 case 1: 1019 case 1:
1018 if (igp_info->info.ucMemoryType & 0xf0) 1020 if (igp_info->info.ucMemoryType & 0xf0)
@@ -1043,14 +1045,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
1043 uint16_t maxfreq; 1045 uint16_t maxfreq;
1044 int i; 1046 int i;
1045 1047
1046 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 1048 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1047 &crev, &data_offset); 1049 &frev, &crev, &data_offset)) {
1050 tmds_info =
1051 (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
1052 data_offset);
1048 1053
1049 tmds_info =
1050 (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
1051 data_offset);
1052
1053 if (tmds_info) {
1054 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); 1054 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
1055 for (i = 0; i < 4; i++) { 1055 for (i = 0; i < 4; i++) {
1056 tmds->tmds_pll[i].freq = 1056 tmds->tmds_pll[i].freq =
@@ -1099,13 +1099,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
1099 if (id > ATOM_MAX_SS_ENTRY) 1099 if (id > ATOM_MAX_SS_ENTRY)
1100 return NULL; 1100 return NULL;
1101 1101
1102 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 1102 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1103 &crev, &data_offset); 1103 &frev, &crev, &data_offset)) {
1104 1104 ss_info =
1105 ss_info = 1105 (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
1106 (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
1107 1106
1108 if (ss_info) {
1109 ss = 1107 ss =
1110 kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); 1108 kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
1111 1109
@@ -1146,13 +1144,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
1146 uint8_t frev, crev; 1144 uint8_t frev, crev;
1147 struct radeon_encoder_atom_dig *lvds = NULL; 1145 struct radeon_encoder_atom_dig *lvds = NULL;
1148 1146
1149 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 1147 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1150 &crev, &data_offset); 1148 &frev, &crev, &data_offset)) {
1151 1149 lvds_info =
1152 lvds_info = 1150 (union lvds_info *)(mode_info->atom_context->bios + data_offset);
1153 (union lvds_info *)(mode_info->atom_context->bios + data_offset);
1154
1155 if (lvds_info) {
1156 lvds = 1151 lvds =
1157 kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); 1152 kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
1158 1153
@@ -1228,11 +1223,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
1228 uint8_t bg, dac; 1223 uint8_t bg, dac;
1229 struct radeon_encoder_primary_dac *p_dac = NULL; 1224 struct radeon_encoder_primary_dac *p_dac = NULL;
1230 1225
1231 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); 1226 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1227 &frev, &crev, &data_offset)) {
1228 dac_info = (struct _COMPASSIONATE_DATA *)
1229 (mode_info->atom_context->bios + data_offset);
1232 1230
1233 dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
1234
1235 if (dac_info) {
1236 p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); 1231 p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
1237 1232
1238 if (!p_dac) 1233 if (!p_dac)
@@ -1257,7 +1252,9 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
1257 u8 frev, crev; 1252 u8 frev, crev;
1258 u16 data_offset, misc; 1253 u16 data_offset, misc;
1259 1254
1260 atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); 1255 if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
1256 &frev, &crev, &data_offset))
1257 return false;
1261 1258
1262 switch (crev) { 1259 switch (crev) {
1263 case 1: 1260 case 1:
@@ -1349,47 +1346,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)
1349 struct _ATOM_ANALOG_TV_INFO *tv_info; 1346 struct _ATOM_ANALOG_TV_INFO *tv_info;
1350 enum radeon_tv_std tv_std = TV_STD_NTSC; 1347 enum radeon_tv_std tv_std = TV_STD_NTSC;
1351 1348
1352 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); 1349 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1350 &frev, &crev, &data_offset)) {
1353 1351
1354 tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); 1352 tv_info = (struct _ATOM_ANALOG_TV_INFO *)
1353 (mode_info->atom_context->bios + data_offset);
1355 1354
1356 switch (tv_info->ucTV_BootUpDefaultStandard) { 1355 switch (tv_info->ucTV_BootUpDefaultStandard) {
1357 case ATOM_TV_NTSC: 1356 case ATOM_TV_NTSC:
1358 tv_std = TV_STD_NTSC; 1357 tv_std = TV_STD_NTSC;
1359 DRM_INFO("Default TV standard: NTSC\n"); 1358 DRM_INFO("Default TV standard: NTSC\n");
1360 break; 1359 break;
1361 case ATOM_TV_NTSCJ: 1360 case ATOM_TV_NTSCJ:
1362 tv_std = TV_STD_NTSC_J; 1361 tv_std = TV_STD_NTSC_J;
1363 DRM_INFO("Default TV standard: NTSC-J\n"); 1362 DRM_INFO("Default TV standard: NTSC-J\n");
1364 break; 1363 break;
1365 case ATOM_TV_PAL: 1364 case ATOM_TV_PAL:
1366 tv_std = TV_STD_PAL; 1365 tv_std = TV_STD_PAL;
1367 DRM_INFO("Default TV standard: PAL\n"); 1366 DRM_INFO("Default TV standard: PAL\n");
1368 break; 1367 break;
1369 case ATOM_TV_PALM: 1368 case ATOM_TV_PALM:
1370 tv_std = TV_STD_PAL_M; 1369 tv_std = TV_STD_PAL_M;
1371 DRM_INFO("Default TV standard: PAL-M\n"); 1370 DRM_INFO("Default TV standard: PAL-M\n");
1372 break; 1371 break;
1373 case ATOM_TV_PALN: 1372 case ATOM_TV_PALN:
1374 tv_std = TV_STD_PAL_N; 1373 tv_std = TV_STD_PAL_N;
1375 DRM_INFO("Default TV standard: PAL-N\n"); 1374 DRM_INFO("Default TV standard: PAL-N\n");
1376 break; 1375 break;
1377 case ATOM_TV_PALCN: 1376 case ATOM_TV_PALCN:
1378 tv_std = TV_STD_PAL_CN; 1377 tv_std = TV_STD_PAL_CN;
1379 DRM_INFO("Default TV standard: PAL-CN\n"); 1378 DRM_INFO("Default TV standard: PAL-CN\n");
1380 break; 1379 break;
1381 case ATOM_TV_PAL60: 1380 case ATOM_TV_PAL60:
1382 tv_std = TV_STD_PAL_60; 1381 tv_std = TV_STD_PAL_60;
1383 DRM_INFO("Default TV standard: PAL-60\n"); 1382 DRM_INFO("Default TV standard: PAL-60\n");
1384 break; 1383 break;
1385 case ATOM_TV_SECAM: 1384 case ATOM_TV_SECAM:
1386 tv_std = TV_STD_SECAM; 1385 tv_std = TV_STD_SECAM;
1387 DRM_INFO("Default TV standard: SECAM\n"); 1386 DRM_INFO("Default TV standard: SECAM\n");
1388 break; 1387 break;
1389 default: 1388 default:
1390 tv_std = TV_STD_NTSC; 1389 tv_std = TV_STD_NTSC;
1391 DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); 1390 DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
1392 break; 1391 break;
1392 }
1393 } 1393 }
1394 return tv_std; 1394 return tv_std;
1395} 1395}
@@ -1407,11 +1407,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
1407 uint8_t bg, dac; 1407 uint8_t bg, dac;
1408 struct radeon_encoder_tv_dac *tv_dac = NULL; 1408 struct radeon_encoder_tv_dac *tv_dac = NULL;
1409 1409
1410 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); 1410 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1411 &frev, &crev, &data_offset)) {
1411 1412
1412 dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); 1413 dac_info = (struct _COMPASSIONATE_DATA *)
1414 (mode_info->atom_context->bios + data_offset);
1413 1415
1414 if (dac_info) {
1415 tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); 1416 tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
1416 1417
1417 if (!tv_dac) 1418 if (!tv_dac)
@@ -1479,13 +1480,11 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1479 int state_index = 0, mode_index = 0; 1480 int state_index = 0, mode_index = 0;
1480 struct radeon_i2c_bus_rec i2c_bus; 1481 struct radeon_i2c_bus_rec i2c_bus;
1481 1482
1482 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
1483
1484 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1485
1486 rdev->pm.default_power_state = NULL; 1483 rdev->pm.default_power_state = NULL;
1487 1484
1488 if (power_info) { 1485 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1486 &frev, &crev, &data_offset)) {
1487 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1489 if (frev < 4) { 1488 if (frev < 4) {
1490 /* add the i2c bus for thermal/fan chip */ 1489 /* add the i2c bus for thermal/fan chip */
1491 if (power_info->info.ucOverdriveThermalController > 0) { 1490 if (power_info->info.ucOverdriveThermalController > 0) {
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index d65931d2e77..eca714c381d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
368 368
369 if (rdev->bios) { 369 if (rdev->bios) {
370 if (rdev->is_atom_bios) { 370 if (rdev->is_atom_bios) {
371 if (rdev->family >= CHIP_R600) 371 ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
372 if (ret == false)
372 ret = radeon_get_atom_connector_info_from_object_table(dev); 373 ret = radeon_get_atom_connector_info_from_object_table(dev);
373 else
374 ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
375 } else { 374 } else {
376 ret = radeon_get_legacy_connector_info_from_bios(dev); 375 ret = radeon_get_legacy_connector_info_from_bios(dev);
377 if (ret == false) 376 if (ret == false)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index a236c75496c..fd4052f71bf 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -519,7 +519,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
519 break; 519 break;
520 } 520 }
521 521
522 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); 522 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
523 return;
523 524
524 switch (frev) { 525 switch (frev) {
525 case 1: 526 case 1:
@@ -725,7 +726,8 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
725 } 726 }
726 num = dig->dig_encoder + 1; 727 num = dig->dig_encoder + 1;
727 728
728 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); 729 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
730 return;
729 731
730 args.v1.ucAction = action; 732 args.v1.ucAction = action;
731 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 733 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -813,7 +815,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
813 } 815 }
814 } 816 }
815 817
816 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); 818 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
819 return;
817 820
818 args.v1.ucAction = action; 821 args.v1.ucAction = action;
819 if (action == ATOM_TRANSMITTER_ACTION_INIT) { 822 if (action == ATOM_TRANSMITTER_ACTION_INIT) {
@@ -1103,7 +1106,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
1103 1106
1104 memset(&args, 0, sizeof(args)); 1107 memset(&args, 0, sizeof(args));
1105 1108
1106 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); 1109 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
1110 return;
1107 1111
1108 switch (frev) { 1112 switch (frev) {
1109 case 1: 1113 case 1:
@@ -1411,7 +1415,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
1411 1415
1412 memset(&args, 0, sizeof(args)); 1416 memset(&args, 0, sizeof(args));
1413 1417
1414 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); 1418 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
1419 return false;
1415 1420
1416 args.sDacload.ucMisc = 0; 1421 args.sDacload.ucMisc = 0;
1417 1422
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index e356935b028..f758d5cc116 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -58,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev)
58 } 58 }
59} 59}
60 60
61union igp_info {
62 struct _ATOM_INTEGRATED_SYSTEM_INFO info;
63 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2;
64};
65
61void rs690_pm_info(struct radeon_device *rdev) 66void rs690_pm_info(struct radeon_device *rdev)
62{ 67{
63 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); 68 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
64 struct _ATOM_INTEGRATED_SYSTEM_INFO *info; 69 union igp_info *info;
65 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
66 void *ptr;
67 uint16_t data_offset; 70 uint16_t data_offset;
68 uint8_t frev, crev; 71 uint8_t frev, crev;
69 fixed20_12 tmp; 72 fixed20_12 tmp;
70 73
71 atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, 74 if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
72 &frev, &crev, &data_offset); 75 &frev, &crev, &data_offset)) {
73 ptr = rdev->mode_info.atom_context->bios + data_offset; 76 info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
74 info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr; 77
75 info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr; 78 /* Get various system informations from bios */
76 /* Get various system informations from bios */ 79 switch (crev) {
77 switch (crev) { 80 case 1:
78 case 1: 81 tmp.full = rfixed_const(100);
79 tmp.full = rfixed_const(100); 82 rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock);
80 rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock); 83 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
81 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); 84 rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
82 rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock)); 85 rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock));
83 rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock)); 86 rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth);
84 rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth); 87 break;
85 break; 88 case 2:
86 case 2: 89 tmp.full = rfixed_const(100);
87 tmp.full = rfixed_const(100); 90 rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock);
88 rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock); 91 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
89 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); 92 rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock);
90 rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock); 93 rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
91 rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); 94 rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq);
92 rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq); 95 rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
93 rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); 96 rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
94 rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth)); 97 break;
95 break; 98 default:
96 default: 99 tmp.full = rfixed_const(100);
100 /* We assume the slower possible clock ie worst case */
101 /* DDR 333Mhz */
102 rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
103 /* FIXME: system clock ? */
104 rdev->pm.igp_system_mclk.full = rfixed_const(100);
105 rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
106 rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
107 rdev->pm.igp_ht_link_width.full = rfixed_const(8);
108 DRM_ERROR("No integrated system info for your GPU, using safe default\n");
109 break;
110 }
111 } else {
97 tmp.full = rfixed_const(100); 112 tmp.full = rfixed_const(100);
98 /* We assume the slower possible clock ie worst case */ 113 /* We assume the slower possible clock ie worst case */
99 /* DDR 333Mhz */ 114 /* DDR 333Mhz */
@@ -104,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev)
104 rdev->pm.igp_ht_link_clk.full = rfixed_const(200); 119 rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
105 rdev->pm.igp_ht_link_width.full = rfixed_const(8); 120 rdev->pm.igp_ht_link_width.full = rfixed_const(8);
106 DRM_ERROR("No integrated system info for your GPU, using safe default\n"); 121 DRM_ERROR("No integrated system info for your GPU, using safe default\n");
107 break;
108 } 122 }
109 /* Compute various bandwidth */ 123 /* Compute various bandwidth */
110 /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */ 124 /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */