forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
c1bcad9d16
commit
a084e6ee6e
@ -1295,12 +1295,16 @@ void atom_destroy(struct atom_context *ctx)
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
void atom_parse_data_header(struct atom_context *ctx, int index,
|
||||
bool atom_parse_data_header(struct atom_context *ctx, int index,
|
||||
uint16_t * size, uint8_t * frev, uint8_t * crev,
|
||||
uint16_t * data_start)
|
||||
{
|
||||
int offset = index * 2 + 4;
|
||||
int idx = CU16(ctx->data_table + offset);
|
||||
u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
|
||||
|
||||
if (!mdt[index])
|
||||
return false;
|
||||
|
||||
if (size)
|
||||
*size = CU16(idx);
|
||||
@ -1309,38 +1313,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,
|
||||
if (crev)
|
||||
*crev = CU8(idx + 3);
|
||||
*data_start = idx;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
|
||||
bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
|
||||
uint8_t * crev)
|
||||
{
|
||||
int offset = index * 2 + 4;
|
||||
int idx = CU16(ctx->cmd_table + offset);
|
||||
u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
|
||||
|
||||
if (!mct[index])
|
||||
return false;
|
||||
|
||||
if (frev)
|
||||
*frev = CU8(idx + 2);
|
||||
if (crev)
|
||||
*crev = CU8(idx + 3);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
int atom_allocate_fb_scratch(struct atom_context *ctx)
|
||||
{
|
||||
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
|
||||
uint16_t data_offset;
|
||||
int usage_bytes;
|
||||
int usage_bytes = 0;
|
||||
struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
|
||||
|
||||
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
|
||||
if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
|
||||
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
|
||||
|
||||
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
|
||||
DRM_DEBUG("atom firmware requested %08x %dkb\n",
|
||||
firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
|
||||
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
|
||||
|
||||
DRM_DEBUG("atom firmware requested %08x %dkb\n",
|
||||
firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
|
||||
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
|
||||
|
||||
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
|
||||
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
|
||||
}
|
||||
if (usage_bytes == 0)
|
||||
usage_bytes = 20 * 1024;
|
||||
/* allocate some scratch memory */
|
||||
|
@ -143,8 +143,10 @@ struct atom_context *atom_parse(struct card_info *, void *);
|
||||
int atom_execute_table(struct atom_context *, int, uint32_t *);
|
||||
int atom_asic_init(struct atom_context *);
|
||||
void atom_destroy(struct atom_context *);
|
||||
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
|
||||
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
|
||||
bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
|
||||
uint8_t *frev, uint8_t *crev, uint16_t *data_start);
|
||||
bool atom_parse_cmd_header(struct atom_context *ctx, int index,
|
||||
uint8_t *frev, uint8_t *crev);
|
||||
int atom_allocate_fb_scratch(struct atom_context *ctx);
|
||||
#include "atom-types.h"
|
||||
#include "atombios.h"
|
||||
|
@ -541,8 +541,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||
int index;
|
||||
|
||||
index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev))
|
||||
return adjusted_clock;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
@ -630,8 +631,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev))
|
||||
return;
|
||||
|
||||
switch (frev) {
|
||||
case 1:
|
||||
@ -705,8 +707,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
|
||||
&ref_div, &post_div);
|
||||
|
||||
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev))
|
||||
return;
|
||||
|
||||
switch (frev) {
|
||||
case 1:
|
||||
|
@ -75,46 +75,45 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
|
||||
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
|
||||
i2c.valid = false;
|
||||
|
||||
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
|
||||
if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
|
||||
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
|
||||
|
||||
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
gpio = &i2c_info->asGPIO_Info[i];
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == id) {
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
|
||||
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
|
||||
i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
|
||||
i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
|
||||
i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
|
||||
i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
|
||||
i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
|
||||
i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
|
||||
i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
|
||||
i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
|
||||
i2c.en_data_mask = (1 << gpio->ucDataEnShift);
|
||||
i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
|
||||
i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
|
||||
i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
|
||||
i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
|
||||
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
gpio = &i2c_info->asGPIO_Info[i];
|
||||
if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
|
||||
i2c.hw_capable = true;
|
||||
else
|
||||
i2c.hw_capable = false;
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == id) {
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
|
||||
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
|
||||
i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
|
||||
i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
|
||||
i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
|
||||
i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
|
||||
i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
|
||||
i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
|
||||
i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
|
||||
i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
|
||||
i2c.en_data_mask = (1 << gpio->ucDataEnShift);
|
||||
i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
|
||||
i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
|
||||
i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
|
||||
i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
|
||||
if (gpio->sucI2cId.ucAccess == 0xa0)
|
||||
i2c.mm_i2c = true;
|
||||
else
|
||||
i2c.mm_i2c = false;
|
||||
|
||||
if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
|
||||
i2c.hw_capable = true;
|
||||
else
|
||||
i2c.hw_capable = false;
|
||||
i2c.i2c_id = gpio->sucI2cId.ucAccess;
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == 0xa0)
|
||||
i2c.mm_i2c = true;
|
||||
else
|
||||
i2c.mm_i2c = false;
|
||||
|
||||
i2c.i2c_id = gpio->sucI2cId.ucAccess;
|
||||
|
||||
i2c.valid = true;
|
||||
break;
|
||||
i2c.valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,20 +134,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd
|
||||
memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
|
||||
gpio.valid = false;
|
||||
|
||||
atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
|
||||
if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
|
||||
gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
|
||||
|
||||
gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
|
||||
num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
|
||||
sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
|
||||
|
||||
num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
|
||||
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
pin = &gpio_info->asGPIO_Pin[i];
|
||||
if (id == pin->ucGPIO_ID) {
|
||||
gpio.id = pin->ucGPIO_ID;
|
||||
gpio.reg = pin->usGpioPin_AIndex * 4;
|
||||
gpio.mask = (1 << pin->ucGpioPinBitShift);
|
||||
gpio.valid = true;
|
||||
break;
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
pin = &gpio_info->asGPIO_Pin[i];
|
||||
if (id == pin->ucGPIO_ID) {
|
||||
gpio.id = pin->ucGPIO_ID;
|
||||
gpio.reg = pin->usGpioPin_AIndex * 4;
|
||||
gpio.mask = (1 << pin->ucGpioPinBitShift);
|
||||
gpio.valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,9 +395,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
|
||||
struct radeon_gpio_rec gpio;
|
||||
struct radeon_hpd hpd;
|
||||
|
||||
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
|
||||
|
||||
if (data_offset == 0)
|
||||
if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
|
||||
return false;
|
||||
|
||||
if (crev < 2)
|
||||
@ -449,37 +447,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
|
||||
GetIndexIntoMasterTable(DATA,
|
||||
IntegratedSystemInfo);
|
||||
|
||||
atom_parse_data_header(ctx, index, &size, &frev,
|
||||
&crev, &igp_offset);
|
||||
if (atom_parse_data_header(ctx, index, &size, &frev,
|
||||
&crev, &igp_offset)) {
|
||||
|
||||
if (crev >= 2) {
|
||||
igp_obj =
|
||||
(ATOM_INTEGRATED_SYSTEM_INFO_V2
|
||||
*) (ctx->bios + igp_offset);
|
||||
if (crev >= 2) {
|
||||
igp_obj =
|
||||
(ATOM_INTEGRATED_SYSTEM_INFO_V2
|
||||
*) (ctx->bios + igp_offset);
|
||||
|
||||
if (igp_obj) {
|
||||
uint32_t slot_config, ct;
|
||||
if (igp_obj) {
|
||||
uint32_t slot_config, ct;
|
||||
|
||||
if (con_obj_num == 1)
|
||||
slot_config =
|
||||
igp_obj->
|
||||
ulDDISlot1Config;
|
||||
else
|
||||
slot_config =
|
||||
igp_obj->
|
||||
ulDDISlot2Config;
|
||||
if (con_obj_num == 1)
|
||||
slot_config =
|
||||
igp_obj->
|
||||
ulDDISlot1Config;
|
||||
else
|
||||
slot_config =
|
||||
igp_obj->
|
||||
ulDDISlot2Config;
|
||||
|
||||
ct = (slot_config >> 16) & 0xff;
|
||||
connector_type =
|
||||
object_connector_convert
|
||||
[ct];
|
||||
connector_object_id = ct;
|
||||
igp_lane_info =
|
||||
slot_config & 0xffff;
|
||||
ct = (slot_config >> 16) & 0xff;
|
||||
connector_type =
|
||||
object_connector_convert
|
||||
[ct];
|
||||
connector_object_id = ct;
|
||||
igp_lane_info =
|
||||
slot_config & 0xffff;
|
||||
} else
|
||||
continue;
|
||||
} else
|
||||
continue;
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
igp_lane_info = 0;
|
||||
connector_type =
|
||||
object_connector_convert[con_obj_id];
|
||||
connector_object_id = con_obj_id;
|
||||
}
|
||||
} else {
|
||||
igp_lane_info = 0;
|
||||
connector_type =
|
||||
@ -627,20 +631,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
|
||||
uint8_t frev, crev;
|
||||
ATOM_XTMDS_INFO *xtmds;
|
||||
|
||||
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
|
||||
xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
|
||||
if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {
|
||||
xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
|
||||
|
||||
if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DVII)
|
||||
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
|
||||
else
|
||||
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
|
||||
} else {
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DVII)
|
||||
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
|
||||
else
|
||||
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
|
||||
}
|
||||
if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DVII)
|
||||
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
|
||||
else
|
||||
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
|
||||
} else {
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DVII)
|
||||
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
|
||||
else
|
||||
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
|
||||
}
|
||||
} else
|
||||
return supported_devices_connector_object_id_convert
|
||||
[connector_type];
|
||||
} else {
|
||||
return supported_devices_connector_object_id_convert
|
||||
[connector_type];
|
||||
@ -672,7 +679,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
|
||||
int i, j, max_device;
|
||||
struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
|
||||
|
||||
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
|
||||
if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
|
||||
return false;
|
||||
|
||||
supported_devices =
|
||||
(union atom_supported_devices *)(ctx->bios + data_offset);
|
||||
@ -865,14 +873,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
|
||||
struct radeon_pll *mpll = &rdev->clock.mpll;
|
||||
uint16_t data_offset;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
|
||||
&crev, &data_offset);
|
||||
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
|
||||
if (firmware_info) {
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
/* pixel clocks */
|
||||
p1pll->reference_freq =
|
||||
le16_to_cpu(firmware_info->info.usReferenceClock);
|
||||
@ -1006,13 +1011,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
|
||||
&crev, &data_offset);
|
||||
|
||||
igp_info = (union igp_info *)(mode_info->atom_context->bios +
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
igp_info = (union igp_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
|
||||
if (igp_info) {
|
||||
switch (crev) {
|
||||
case 1:
|
||||
if (igp_info->info.ucMemoryType & 0xf0)
|
||||
@ -1043,14 +1045,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
|
||||
uint16_t maxfreq;
|
||||
int i;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
|
||||
&crev, &data_offset);
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
tmds_info =
|
||||
(struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
|
||||
tmds_info =
|
||||
(struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
|
||||
if (tmds_info) {
|
||||
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
|
||||
for (i = 0; i < 4; i++) {
|
||||
tmds->tmds_pll[i].freq =
|
||||
@ -1099,13 +1099,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
|
||||
if (id > ATOM_MAX_SS_ENTRY)
|
||||
return NULL;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
|
||||
&crev, &data_offset);
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
ss_info =
|
||||
(struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
ss_info =
|
||||
(struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
if (ss_info) {
|
||||
ss =
|
||||
kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
|
||||
|
||||
@ -1146,13 +1144,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
|
||||
uint8_t frev, crev;
|
||||
struct radeon_encoder_atom_dig *lvds = NULL;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
|
||||
&crev, &data_offset);
|
||||
|
||||
lvds_info =
|
||||
(union lvds_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
if (lvds_info) {
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
lvds_info =
|
||||
(union lvds_info *)(mode_info->atom_context->bios + data_offset);
|
||||
lvds =
|
||||
kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
|
||||
|
||||
@ -1228,11 +1223,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
|
||||
uint8_t bg, dac;
|
||||
struct radeon_encoder_primary_dac *p_dac = NULL;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
dac_info = (struct _COMPASSIONATE_DATA *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
if (dac_info) {
|
||||
p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
|
||||
|
||||
if (!p_dac)
|
||||
@ -1257,7 +1252,9 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
|
||||
u8 frev, crev;
|
||||
u16 data_offset, misc;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
|
||||
if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
|
||||
&frev, &crev, &data_offset))
|
||||
return false;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
@ -1349,47 +1346,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)
|
||||
struct _ATOM_ANALOG_TV_INFO *tv_info;
|
||||
enum radeon_tv_std tv_std = TV_STD_NTSC;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
|
||||
tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
|
||||
tv_info = (struct _ATOM_ANALOG_TV_INFO *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
switch (tv_info->ucTV_BootUpDefaultStandard) {
|
||||
case ATOM_TV_NTSC:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Default TV standard: NTSC\n");
|
||||
break;
|
||||
case ATOM_TV_NTSCJ:
|
||||
tv_std = TV_STD_NTSC_J;
|
||||
DRM_INFO("Default TV standard: NTSC-J\n");
|
||||
break;
|
||||
case ATOM_TV_PAL:
|
||||
tv_std = TV_STD_PAL;
|
||||
DRM_INFO("Default TV standard: PAL\n");
|
||||
break;
|
||||
case ATOM_TV_PALM:
|
||||
tv_std = TV_STD_PAL_M;
|
||||
DRM_INFO("Default TV standard: PAL-M\n");
|
||||
break;
|
||||
case ATOM_TV_PALN:
|
||||
tv_std = TV_STD_PAL_N;
|
||||
DRM_INFO("Default TV standard: PAL-N\n");
|
||||
break;
|
||||
case ATOM_TV_PALCN:
|
||||
tv_std = TV_STD_PAL_CN;
|
||||
DRM_INFO("Default TV standard: PAL-CN\n");
|
||||
break;
|
||||
case ATOM_TV_PAL60:
|
||||
tv_std = TV_STD_PAL_60;
|
||||
DRM_INFO("Default TV standard: PAL-60\n");
|
||||
break;
|
||||
case ATOM_TV_SECAM:
|
||||
tv_std = TV_STD_SECAM;
|
||||
DRM_INFO("Default TV standard: SECAM\n");
|
||||
break;
|
||||
default:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
|
||||
break;
|
||||
switch (tv_info->ucTV_BootUpDefaultStandard) {
|
||||
case ATOM_TV_NTSC:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Default TV standard: NTSC\n");
|
||||
break;
|
||||
case ATOM_TV_NTSCJ:
|
||||
tv_std = TV_STD_NTSC_J;
|
||||
DRM_INFO("Default TV standard: NTSC-J\n");
|
||||
break;
|
||||
case ATOM_TV_PAL:
|
||||
tv_std = TV_STD_PAL;
|
||||
DRM_INFO("Default TV standard: PAL\n");
|
||||
break;
|
||||
case ATOM_TV_PALM:
|
||||
tv_std = TV_STD_PAL_M;
|
||||
DRM_INFO("Default TV standard: PAL-M\n");
|
||||
break;
|
||||
case ATOM_TV_PALN:
|
||||
tv_std = TV_STD_PAL_N;
|
||||
DRM_INFO("Default TV standard: PAL-N\n");
|
||||
break;
|
||||
case ATOM_TV_PALCN:
|
||||
tv_std = TV_STD_PAL_CN;
|
||||
DRM_INFO("Default TV standard: PAL-CN\n");
|
||||
break;
|
||||
case ATOM_TV_PAL60:
|
||||
tv_std = TV_STD_PAL_60;
|
||||
DRM_INFO("Default TV standard: PAL-60\n");
|
||||
break;
|
||||
case ATOM_TV_SECAM:
|
||||
tv_std = TV_STD_SECAM;
|
||||
DRM_INFO("Default TV standard: SECAM\n");
|
||||
break;
|
||||
default:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tv_std;
|
||||
}
|
||||
@ -1407,11 +1407,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
|
||||
uint8_t bg, dac;
|
||||
struct radeon_encoder_tv_dac *tv_dac = NULL;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
|
||||
dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
|
||||
dac_info = (struct _COMPASSIONATE_DATA *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
if (dac_info) {
|
||||
tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
|
||||
|
||||
if (!tv_dac)
|
||||
@ -1479,13 +1480,11 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
int state_index = 0, mode_index = 0;
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
rdev->pm.default_power_state = NULL;
|
||||
|
||||
if (power_info) {
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
if (frev < 4) {
|
||||
/* add the i2c bus for thermal/fan chip */
|
||||
if (power_info->info.ucOverdriveThermalController > 0) {
|
||||
|
@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
|
||||
|
||||
if (rdev->bios) {
|
||||
if (rdev->is_atom_bios) {
|
||||
if (rdev->family >= CHIP_R600)
|
||||
ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
|
||||
if (ret == false)
|
||||
ret = radeon_get_atom_connector_info_from_object_table(dev);
|
||||
else
|
||||
ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
|
||||
} else {
|
||||
ret = radeon_get_legacy_connector_info_from_bios(dev);
|
||||
if (ret == false)
|
||||
|
@ -519,7 +519,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
|
||||
break;
|
||||
}
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
switch (frev) {
|
||||
case 1:
|
||||
@ -725,7 +726,8 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
||||
}
|
||||
num = dig->dig_encoder + 1;
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
args.v1.ucAction = action;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
args.v1.ucAction = action;
|
||||
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
|
||||
@ -1103,7 +1106,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
switch (frev) {
|
||||
case 1:
|
||||
@ -1411,7 +1415,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return false;
|
||||
|
||||
args.sDacload.ucMisc = 0;
|
||||
|
||||
|
@ -58,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
union igp_info {
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO info;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2;
|
||||
};
|
||||
|
||||
void rs690_pm_info(struct radeon_device *rdev)
|
||||
{
|
||||
int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO *info;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
|
||||
void *ptr;
|
||||
union igp_info *info;
|
||||
uint16_t data_offset;
|
||||
uint8_t frev, crev;
|
||||
fixed20_12 tmp;
|
||||
|
||||
atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset);
|
||||
ptr = rdev->mode_info.atom_context->bios + data_offset;
|
||||
info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr;
|
||||
info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr;
|
||||
/* Get various system informations from bios */
|
||||
switch (crev) {
|
||||
case 1:
|
||||
tmp.full = rfixed_const(100);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock));
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock));
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth);
|
||||
break;
|
||||
case 2:
|
||||
tmp.full = rfixed_const(100);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq);
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth));
|
||||
break;
|
||||
default:
|
||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
|
||||
|
||||
/* Get various system informations from bios */
|
||||
switch (crev) {
|
||||
case 1:
|
||||
tmp.full = rfixed_const(100);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock));
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth);
|
||||
break;
|
||||
case 2:
|
||||
tmp.full = rfixed_const(100);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock);
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq);
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
|
||||
break;
|
||||
default:
|
||||
tmp.full = rfixed_const(100);
|
||||
/* We assume the slower possible clock ie worst case */
|
||||
/* DDR 333Mhz */
|
||||
rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
|
||||
/* FIXME: system clock ? */
|
||||
rdev->pm.igp_system_mclk.full = rfixed_const(100);
|
||||
rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(8);
|
||||
DRM_ERROR("No integrated system info for your GPU, using safe default\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tmp.full = rfixed_const(100);
|
||||
/* We assume the slower possible clock ie worst case */
|
||||
/* DDR 333Mhz */
|
||||
@ -104,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev)
|
||||
rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
|
||||
rdev->pm.igp_ht_link_width.full = rfixed_const(8);
|
||||
DRM_ERROR("No integrated system info for your GPU, using safe default\n");
|
||||
break;
|
||||
}
|
||||
/* Compute various bandwidth */
|
||||
/* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */
|
||||
|
Loading…
Reference in New Issue
Block a user