47,8 → 47,7 |
int connector_type, |
struct radeon_i2c_bus_rec *i2c_bus, |
bool linkb, uint32_t igp_lane_info, |
uint16_t connector_object_id, |
struct radeon_hpd *hpd); |
uint16_t connector_object_id); |
|
/* from radeon_legacy_encoder.c */ |
extern void |
61,16 → 60,16 |
struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
}; |
|
static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
uint8_t id) |
static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device |
*dev, uint8_t id) |
{ |
struct radeon_device *rdev = dev->dev_private; |
struct atom_context *ctx = rdev->mode_info.atom_context; |
ATOM_GPIO_I2C_ASSIGMENT *gpio; |
ATOM_GPIO_I2C_ASSIGMENT gpio; |
struct radeon_i2c_bus_rec i2c; |
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
struct _ATOM_GPIO_I2C_INFO *i2c_info; |
uint16_t data_offset; |
int i; |
|
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); |
i2c.valid = false; |
79,121 → 78,34 |
|
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
|
gpio = i2c_info->asGPIO_Info[id]; |
|
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); |
|
if (gpio->sucI2cId.sbfAccess.bfHW_Capable) |
i2c.hw_capable = true; |
else |
i2c.hw_capable = false; |
|
if (gpio->sucI2cId.ucAccess == 0xa0) |
i2c.mm_i2c = true; |
else |
i2c.mm_i2c = false; |
|
i2c.i2c_id = gpio->sucI2cId.ucAccess; |
|
i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; |
i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; |
i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; |
i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; |
i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; |
i2c.get_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.put_clk_mask = (1 << gpio.ucClkEnShift); |
i2c.put_data_mask = (1 << gpio.ucDataEnShift); |
i2c.get_clk_mask = (1 << gpio.ucClkY_Shift); |
i2c.get_data_mask = (1 << gpio.ucDataY_Shift); |
i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); |
i2c.a_data_mask = (1 << gpio.ucDataA_Shift); |
i2c.valid = true; |
} |
} |
|
return i2c; |
} |
|
static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, |
u8 id) |
{ |
struct atom_context *ctx = rdev->mode_info.atom_context; |
struct radeon_gpio_rec gpio; |
int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); |
struct _ATOM_GPIO_PIN_LUT *gpio_info; |
ATOM_GPIO_PIN_ASSIGNMENT *pin; |
u16 data_offset, size; |
int i, num_indices; |
|
memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); |
gpio.valid = false; |
|
atom_parse_data_header(ctx, index, &size, NULL, NULL, &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); |
|
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; |
} |
} |
|
return gpio; |
} |
|
static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, |
struct radeon_gpio_rec *gpio) |
{ |
struct radeon_hpd hpd; |
hpd.gpio = *gpio; |
if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { |
switch(gpio->mask) { |
case (1 << 0): |
hpd.hpd = RADEON_HPD_1; |
break; |
case (1 << 8): |
hpd.hpd = RADEON_HPD_2; |
break; |
case (1 << 16): |
hpd.hpd = RADEON_HPD_3; |
break; |
case (1 << 24): |
hpd.hpd = RADEON_HPD_4; |
break; |
case (1 << 26): |
hpd.hpd = RADEON_HPD_5; |
break; |
case (1 << 28): |
hpd.hpd = RADEON_HPD_6; |
break; |
default: |
hpd.hpd = RADEON_HPD_NONE; |
break; |
} |
} else |
hpd.hpd = RADEON_HPD_NONE; |
return hpd; |
} |
|
static bool radeon_atom_apply_quirks(struct drm_device *dev, |
uint32_t supported_device, |
int *connector_type, |
struct radeon_i2c_bus_rec *i2c_bus, |
uint16_t *line_mux, |
struct radeon_hpd *hpd) |
uint16_t *line_mux) |
{ |
|
/* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
223,23 → 135,6 |
} |
} |
|
/* HIS X1300 is DVI+VGA, not DVI+DVI */ |
if ((dev->pdev->device == 0x7146) && |
(dev->pdev->subsystem_vendor == 0x17af) && |
(dev->pdev->subsystem_device == 0x2058)) { |
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) |
return false; |
} |
|
/* Gigabyte X1300 is DVI+VGA, not DVI+DVI */ |
if ((dev->pdev->device == 0x7142) && |
(dev->pdev->subsystem_vendor == 0x1458) && |
(dev->pdev->subsystem_device == 0x2134)) { |
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) |
return false; |
} |
|
|
/* Funky macbooks */ |
if ((dev->pdev->device == 0x71C5) && |
(dev->pdev->subsystem_vendor == 0x106b) && |
277,15 → 172,6 |
} |
} |
|
/* Acer laptop reports DVI-D as DVI-I */ |
if ((dev->pdev->device == 0x95c4) && |
(dev->pdev->subsystem_vendor == 0x1025) && |
(dev->pdev->subsystem_device == 0x013c)) { |
if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && |
(supported_device == ATOM_DEVICE_DFP1_SUPPORT)) |
*connector_type = DRM_MODE_CONNECTOR_DVID; |
} |
|
return true; |
} |
|
354,18 → 240,16 |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
struct atom_context *ctx = mode_info->atom_context; |
int index = GetIndexIntoMasterTable(DATA, Object_Header); |
u16 size, data_offset; |
u8 frev, crev; |
uint16_t size, data_offset; |
uint8_t frev, crev, line_mux = 0; |
ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
ATOM_OBJECT_HEADER *obj_header; |
int i, j, path_size, device_support; |
int connector_type; |
u16 igp_lane_info, conn_id, connector_object_id; |
uint16_t igp_lane_info, conn_id, connector_object_id; |
bool linkb; |
struct radeon_i2c_bus_rec ddc_bus; |
struct radeon_gpio_rec gpio; |
struct radeon_hpd hpd; |
|
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
|
392,6 → 276,7 |
path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
path_size += le16_to_cpu(path->usSize); |
linkb = false; |
|
if (device_support & le16_to_cpu(path->usDeviceTag)) { |
uint8_t con_obj_id, con_obj_num, con_obj_type; |
|
492,9 → 377,10 |
} |
} |
|
/* look up gpio for ddc, hpd */ |
/* look up gpio for ddc */ |
if ((le16_to_cpu(path->usDeviceTag) & |
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { |
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
== 0) { |
for (j = 0; j < con_obj->ucNumberOfObjects; j++) { |
if (le16_to_cpu(path->usConnObjectId) == |
le16_to_cpu(con_obj->asObjects[j]. |
508,35 → 394,22 |
asObjects[j]. |
usRecordOffset)); |
ATOM_I2C_RECORD *i2c_record; |
ATOM_HPD_INT_RECORD *hpd_record; |
ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; |
hpd.hpd = RADEON_HPD_NONE; |
|
while (record->ucRecordType > 0 |
&& record-> |
ucRecordType <= |
ATOM_MAX_OBJECT_RECORD_NUMBER) { |
switch (record->ucRecordType) { |
switch (record-> |
ucRecordType) { |
case ATOM_I2C_RECORD_TYPE: |
i2c_record = |
(ATOM_I2C_RECORD *) |
record; |
i2c_config = |
(ATOM_I2C_ID_CONFIG_ACCESS *) |
&i2c_record->sucI2cId; |
ddc_bus = radeon_lookup_i2c_gpio(rdev, |
i2c_config-> |
ucAccess); |
(ATOM_I2C_RECORD |
*) record; |
line_mux = |
i2c_record-> |
sucI2cId. |
bfI2C_LineMux; |
break; |
case ATOM_HPD_INT_RECORD_TYPE: |
hpd_record = |
(ATOM_HPD_INT_RECORD *) |
record; |
gpio = radeon_lookup_gpio(rdev, |
hpd_record->ucHPDIntGPIOID); |
hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); |
hpd.plugged_state = hpd_record->ucPlugged_PinState; |
break; |
} |
record = |
(ATOM_COMMON_RECORD_HEADER |
548,16 → 421,24 |
break; |
} |
} |
} else { |
hpd.hpd = RADEON_HPD_NONE; |
} else |
line_mux = 0; |
|
if ((le16_to_cpu(path->usDeviceTag) == |
ATOM_DEVICE_TV1_SUPPORT) |
|| (le16_to_cpu(path->usDeviceTag) == |
ATOM_DEVICE_TV2_SUPPORT) |
|| (le16_to_cpu(path->usDeviceTag) == |
ATOM_DEVICE_CV_SUPPORT)) |
ddc_bus.valid = false; |
} |
else |
ddc_bus = radeon_lookup_gpio(dev, line_mux); |
|
conn_id = le16_to_cpu(path->usConnObjectId); |
|
if (!radeon_atom_apply_quirks |
(dev, le16_to_cpu(path->usDeviceTag), &connector_type, |
&ddc_bus, &conn_id, &hpd)) |
&ddc_bus, &conn_id)) |
continue; |
|
radeon_add_atom_connector(dev, |
566,8 → 447,7 |
usDeviceTag), |
connector_type, &ddc_bus, |
linkb, igp_lane_info, |
connector_object_id, |
&hpd); |
connector_object_id); |
|
} |
} |
622,7 → 502,6 |
uint16_t devices; |
int connector_type; |
struct radeon_i2c_bus_rec ddc_bus; |
struct radeon_hpd hpd; |
}; |
|
bool radeon_get_atom_connector_info_from_supported_devices_table(struct |
638,7 → 517,7 |
uint16_t device_support; |
uint8_t dac; |
union atom_supported_devices *supported_devices; |
int i, j, max_device; |
int i, j; |
struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
|
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
648,12 → 527,7 |
|
device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); |
|
if (frev > 1) |
max_device = ATOM_MAX_SUPPORTED_DEVICE; |
else |
max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; |
|
for (i = 0; i < max_device; i++) { |
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
ATOM_CONNECTOR_INFO_I2C ci = |
supported_devices->info.asConnInfo[i]; |
|
679,8 → 553,22 |
|
dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; |
|
if ((rdev->family == CHIP_RS690) || |
(rdev->family == CHIP_RS740)) { |
if ((i == ATOM_DEVICE_DFP2_INDEX) |
&& (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2)) |
bios_connectors[i].line_mux = |
ci.sucI2cId.ucAccess; |
ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; |
else if ((i == ATOM_DEVICE_DFP3_INDEX) |
&& (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1)) |
bios_connectors[i].line_mux = |
ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; |
else |
bios_connectors[i].line_mux = |
ci.sucI2cId.sbfAccess.bfI2C_LineMux; |
} else |
bios_connectors[i].line_mux = |
ci.sucI2cId.sbfAccess.bfI2C_LineMux; |
|
/* give tv unique connector ids */ |
if (i == ATOM_DEVICE_TV1_INDEX) { |
694,31 → 582,9 |
bios_connectors[i].line_mux = 52; |
} else |
bios_connectors[i].ddc_bus = |
radeon_lookup_i2c_gpio(rdev, |
radeon_lookup_gpio(dev, |
bios_connectors[i].line_mux); |
|
if ((crev > 1) && (frev > 1)) { |
u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; |
switch (isb) { |
case 0x4: |
bios_connectors[i].hpd.hpd = RADEON_HPD_1; |
break; |
case 0xa: |
bios_connectors[i].hpd.hpd = RADEON_HPD_2; |
break; |
default: |
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; |
break; |
} |
} else { |
if (i == ATOM_DEVICE_DFP1_INDEX) |
bios_connectors[i].hpd.hpd = RADEON_HPD_1; |
else if (i == ATOM_DEVICE_DFP2_INDEX) |
bios_connectors[i].hpd.hpd = RADEON_HPD_2; |
else |
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; |
} |
|
/* Always set the connector type to VGA for CRT1/CRT2. if they are |
* shared with a DVI port, we'll pick up the DVI connector when we |
* merge the outputs. Some bioses incorrectly list VGA ports as DVI. |
729,8 → 595,7 |
|
if (!radeon_atom_apply_quirks |
(dev, (1 << i), &bios_connectors[i].connector_type, |
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, |
&bios_connectors[i].hpd)) |
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) |
continue; |
|
bios_connectors[i].valid = true; |
752,9 → 617,9 |
} |
|
/* combine shared connectors */ |
for (i = 0; i < max_device; i++) { |
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
if (bios_connectors[i].valid) { |
for (j = 0; j < max_device; j++) { |
for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { |
if (bios_connectors[j].valid && (i != j)) { |
if (bios_connectors[i].line_mux == |
bios_connectors[j].line_mux) { |
778,10 → 643,6 |
bios_connectors[i]. |
connector_type = |
DRM_MODE_CONNECTOR_DVII; |
if (bios_connectors[j].devices & |
(ATOM_DEVICE_DFP_SUPPORT)) |
bios_connectors[i].hpd = |
bios_connectors[j].hpd; |
bios_connectors[j]. |
valid = false; |
} |
792,7 → 653,7 |
} |
|
/* add the connectors */ |
for (i = 0; i < max_device; i++) { |
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
if (bios_connectors[i].valid) { |
uint16_t connector_object_id = |
atombios_get_connector_object_id(dev, |
805,8 → 666,7 |
connector_type, |
&bios_connectors[i].ddc_bus, |
false, 0, |
connector_object_id, |
&bios_connectors[i].hpd); |
connector_object_id); |
} |
} |
|
871,7 → 731,6 |
* pre-DCE 3.0 r6xx hardware. This might need to be adjusted per |
* family. |
*/ |
if (!radeon_new_pll) |
p1pll->pll_out_min = 64800; |
} |
|
1002,7 → 861,6 |
struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
uint8_t frev, crev; |
struct radeon_atom_ss *ss = NULL; |
int i; |
|
if (id > ATOM_MAX_SS_ENTRY) |
return NULL; |
1020,18 → 878,13 |
if (!ss) |
return NULL; |
|
for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) { |
if (ss_info->asSS_Info[i].ucSS_Id == id) { |
ss->percentage = |
le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); |
ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; |
ss->step = ss_info->asSS_Info[i].ucSS_Step; |
ss->delay = ss_info->asSS_Info[i].ucSS_Delay; |
ss->range = ss_info->asSS_Info[i].ucSS_Range; |
ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; |
ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage); |
ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType; |
ss->step = ss_info->asSS_Info[id].ucSS_Step; |
ss->delay = ss_info->asSS_Info[id].ucSS_Delay; |
ss->range = ss_info->asSS_Info[id].ucSS_Range; |
ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div; |
} |
} |
} |
return ss; |
} |
|
1048,7 → 901,7 |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
int index = GetIndexIntoMasterTable(DATA, LVDS_Info); |
uint16_t data_offset, misc; |
uint16_t data_offset; |
union lvds_info *lvds_info; |
uint8_t frev, crev; |
struct radeon_encoder_atom_dig *lvds = NULL; |
1087,19 → 940,6 |
lvds->panel_pwr_delay = |
le16_to_cpu(lvds_info->info.usOffDelayInMs); |
lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; |
|
misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess); |
if (misc & ATOM_VSYNC_POLARITY) |
lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC; |
if (misc & ATOM_HSYNC_POLARITY) |
lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC; |
if (misc & ATOM_COMPOSITESYNC) |
lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC; |
if (misc & ATOM_INTERLACE) |
lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE; |
if (misc & ATOM_DOUBLE_CLOCK_MODE) |
lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; |
|
/* set crtc values */ |
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
|