103,7 → 103,8 |
static bool radeon_atom_apply_quirks(struct drm_device *dev, |
uint32_t supported_device, |
int *connector_type, |
struct radeon_i2c_bus_rec *i2c_bus) |
struct radeon_i2c_bus_rec *i2c_bus, |
uint16_t *line_mux) |
{ |
|
/* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
127,9 → 128,11 |
if ((dev->pdev->device == 0x5653) && |
(dev->pdev->subsystem_vendor == 0x1462) && |
(dev->pdev->subsystem_device == 0x0291)) { |
if (*connector_type == DRM_MODE_CONNECTOR_LVDS) |
if (*connector_type == DRM_MODE_CONNECTOR_LVDS) { |
i2c_bus->valid = false; |
*line_mux = 53; |
} |
} |
|
/* Funky macbooks */ |
if ((dev->pdev->device == 0x71C5) && |
140,23 → 143,34 |
return false; |
} |
|
/* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */ |
if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) || |
(*connector_type == DRM_MODE_CONNECTOR_HDMIB)) { |
if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) { |
return false; |
} |
} |
|
/* ASUS HD 3600 XT board lists the DVI port as HDMI */ |
if ((dev->pdev->device == 0x9598) && |
(dev->pdev->subsystem_vendor == 0x1043) && |
(dev->pdev->subsystem_device == 0x01da)) { |
if (*connector_type == DRM_MODE_CONNECTOR_HDMIB) { |
*connector_type = DRM_MODE_CONNECTOR_DVID; |
if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { |
*connector_type = DRM_MODE_CONNECTOR_DVII; |
} |
} |
|
/* ASUS HD 3450 board lists the DVI port as HDMI */ |
if ((dev->pdev->device == 0x95C5) && |
(dev->pdev->subsystem_vendor == 0x1043) && |
(dev->pdev->subsystem_device == 0x01e2)) { |
if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { |
*connector_type = DRM_MODE_CONNECTOR_DVII; |
} |
} |
|
/* some BIOSes seem to report DAC on HDMI - usually this is a board with |
* HDMI + VGA reporting as HDMI |
*/ |
if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { |
if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) { |
*connector_type = DRM_MODE_CONNECTOR_VGA; |
*line_mux = 0; |
} |
} |
|
return true; |
} |
|
189,11 → 203,11 |
DRM_MODE_CONNECTOR_Composite, |
DRM_MODE_CONNECTOR_SVIDEO, |
DRM_MODE_CONNECTOR_Unknown, |
DRM_MODE_CONNECTOR_Unknown, |
DRM_MODE_CONNECTOR_9PinDIN, |
DRM_MODE_CONNECTOR_Unknown, |
DRM_MODE_CONNECTOR_HDMIA, |
DRM_MODE_CONNECTOR_HDMIB, |
DRM_MODE_CONNECTOR_HDMIB, |
DRM_MODE_CONNECTOR_LVDS, |
DRM_MODE_CONNECTOR_9PinDIN, |
DRM_MODE_CONNECTOR_Unknown, |
215,7 → 229,7 |
ATOM_OBJECT_HEADER *obj_header; |
int i, j, path_size, device_support; |
int connector_type; |
uint16_t igp_lane_info; |
uint16_t igp_lane_info, conn_id; |
bool linkb; |
struct radeon_i2c_bus_rec ddc_bus; |
|
367,10 → 381,6 |
&& record-> |
ucRecordType <= |
ATOM_MAX_OBJECT_RECORD_NUMBER) { |
DRM_ERROR |
("record type %d\n", |
record-> |
ucRecordType); |
switch (record-> |
ucRecordType) { |
case ATOM_I2C_RECORD_TYPE: |
406,10 → 416,16 |
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)) |
continue; |
|
radeon_add_atom_connector(dev, |
conn_id, |
le16_to_cpu(path-> |
usConnObjectId), |
le16_to_cpu(path-> |
usDeviceTag), |
connector_type, &ddc_bus, |
linkb, igp_lane_info); |
424,7 → 440,7 |
|
struct bios_connector { |
bool valid; |
uint8_t line_mux; |
uint16_t line_mux; |
uint16_t devices; |
int connector_type; |
struct radeon_i2c_bus_rec ddc_bus; |
468,11 → 484,6 |
continue; |
} |
|
if (i == ATOM_DEVICE_TV1_INDEX) { |
DRM_DEBUG("Skipping TV Out\n"); |
continue; |
} |
|
bios_connectors[i].connector_type = |
supported_devices_connector_convert[ci.sucConnectorInfo. |
sbfAccess. |
526,7 → 537,7 |
|
if (!radeon_atom_apply_quirks |
(dev, (1 << i), &bios_connectors[i].connector_type, |
&bios_connectors[i].ddc_bus)) |
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) |
continue; |
|
bios_connectors[i].valid = true; |
708,9 → 719,8 |
return false; |
} |
|
struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct |
radeon_encoder |
*encoder) |
bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, |
struct radeon_encoder_int_tmds *tmds) |
{ |
struct drm_device *dev = encoder->base.dev; |
struct radeon_device *rdev = dev->dev_private; |
721,7 → 731,6 |
uint8_t frev, crev; |
uint16_t maxfreq; |
int i; |
struct radeon_encoder_int_tmds *tmds = NULL; |
|
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, |
&crev, &data_offset); |
731,12 → 740,6 |
data_offset); |
|
if (tmds_info) { |
tmds = |
kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); |
|
if (!tmds) |
return NULL; |
|
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); |
for (i = 0; i < 4; i++) { |
tmds->tmds_pll[i].freq = |
762,8 → 765,9 |
break; |
} |
} |
return true; |
} |
return tmds; |
return false; |
} |
|
union lvds_info { |
855,6 → 859,72 |
return p_dac; |
} |
|
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, |
int32_t *pixel_clock) |
{ |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
ATOM_ANALOG_TV_INFO *tv_info; |
ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2; |
ATOM_DTD_FORMAT *dtd_timings; |
int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); |
u8 frev, crev; |
uint16_t data_offset; |
|
atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); |
|
switch (crev) { |
case 1: |
tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); |
if (index > MAX_SUPPORTED_TV_TIMING) |
return false; |
|
crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); |
|
crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
|
crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; |
|
crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); |
crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); |
crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); |
crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); |
*pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; |
|
if (index == 1) { |
/* PAL timings appear to have wrong values for totals */ |
crtc_timing->usH_Total -= 1; |
crtc_timing->usV_Total -= 1; |
} |
break; |
case 2: |
tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); |
if (index > MAX_SUPPORTED_TV_TIMING_V1_2) |
return false; |
|
dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); |
crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); |
crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); |
crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); |
crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); |
crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); |
crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); |
crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); |
|
crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); |
*pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; |
break; |
} |
return true; |
} |
|
struct radeon_encoder_tv_dac * |
radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) |
{ |
945,10 → 1015,10 |
uint32_t bios_2_scratch, bios_6_scratch; |
|
if (rdev->family >= CHIP_R600) { |
bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH); |
bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); |
bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); |
} else { |
bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH); |
bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); |
bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); |
} |
|
968,6 → 1038,34 |
|
} |
|
void radeon_save_bios_scratch_regs(struct radeon_device *rdev) |
{ |
uint32_t scratch_reg; |
int i; |
|
if (rdev->family >= CHIP_R600) |
scratch_reg = R600_BIOS_0_SCRATCH; |
else |
scratch_reg = RADEON_BIOS_0_SCRATCH; |
|
for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) |
rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4)); |
} |
|
void radeon_restore_bios_scratch_regs(struct radeon_device *rdev) |
{ |
uint32_t scratch_reg; |
int i; |
|
if (rdev->family >= CHIP_R600) |
scratch_reg = R600_BIOS_0_SCRATCH; |
else |
scratch_reg = RADEON_BIOS_0_SCRATCH; |
|
for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) |
WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]); |
} |
|
void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) |
{ |
struct drm_device *dev = encoder->dev; |