diff options
| author | Alex Deucher <alexdeucher@gmail.com> | 2010-03-18 01:04:01 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-03-30 23:11:29 -0400 |
| commit | a084e6ee6e64a76f1a9665d527203cdab7d6048f (patch) | |
| tree | ebc1f90b7111b39bee17ff3f1e2ee02452dc1bf7 | |
| parent | c1bcad9d16831859373d8f579fa1e146409f9960 (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>
| -rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 32 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atom.h | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 367 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 74 |
7 files changed, 272 insertions, 242 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index b7fe660985c4..247f8ee7e940 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 | ||
| 1298 | void atom_parse_data_header(struct atom_context *ctx, int index, | 1298 | bool 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 | ||
| 1315 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | 1319 | bool 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 | ||
| 1328 | int atom_allocate_fb_scratch(struct atom_context *ctx) | 1336 | int 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 1b2626314804..cd1b64ab5ca7 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 *); | |||
| 143 | int atom_execute_table(struct atom_context *, int, uint32_t *); | 143 | int atom_execute_table(struct atom_context *, int, uint32_t *); |
| 144 | int atom_asic_init(struct atom_context *); | 144 | int atom_asic_init(struct atom_context *); |
| 145 | void atom_destroy(struct atom_context *); | 145 | void atom_destroy(struct atom_context *); |
| 146 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); | 146 | bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, |
| 147 | void 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); |
| 148 | bool atom_parse_cmd_header(struct atom_context *ctx, int index, | ||
| 149 | uint8_t *frev, uint8_t *crev); | ||
| 148 | int atom_allocate_fb_scratch(struct atom_context *ctx); | 150 | int 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 94aa6b293e0f..56107b3a997f 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 3733cb787798..f0ea7f8da678 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 d65931d2e77a..eca714c381de 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 a236c75496c4..fd4052f71bf3 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 e356935b0283..f758d5cc1160 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 | ||
| 61 | union igp_info { | ||
| 62 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | ||
| 63 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2; | ||
| 64 | }; | ||
| 65 | |||
| 61 | void rs690_pm_info(struct radeon_device *rdev) | 66 | void 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 */ |
