Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1402 → Rev 1403

/drivers/video/drm/radeon/radeon_encoders.c
156,6 → 156,26
return ret;
}
 
static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
return true;
default:
return false;
}
}
void
radeon_link_encoder_connector(struct drm_device *dev)
{
202,7 → 222,7
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
radeon_connector = to_radeon_connector(connector);
if (radeon_encoder->devices & radeon_connector->devices)
if (radeon_encoder->active_device & radeon_connector->devices)
return connector;
}
return NULL;
233,6 → 253,8
if (!ASIC_IS_AVIVO(rdev)) {
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
adjusted_mode->crtc_hdisplay = mode->hdisplay;
adjusted_mode->crtc_vdisplay = mode->vdisplay;
}
adjusted_mode->base.id = mode_id;
}
438,6 → 460,7
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
union lvds_encoder_control args;
int index = 0;
int hdmi_detected = 0;
uint8_t frev, crev;
struct radeon_encoder_atom_dig *dig;
struct drm_connector *connector;
458,6 → 481,9
if (!radeon_connector->con_priv)
return;
 
if (drm_detect_hdmi_monitor(radeon_connector->edid))
hdmi_detected = 1;
 
dig_connector = radeon_connector->con_priv;
 
memset(&args, 0, sizeof(args));
487,13 → 513,13
case 1:
args.v1.ucMisc = 0;
args.v1.ucAction = action;
if (drm_detect_hdmi_monitor(radeon_connector->edid))
if (hdmi_detected)
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
if (dig->lvds_misc & (1 << 0))
if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
if (dig->lvds_misc & (1 << 1))
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
args.v1.ucMisc |= (1 << 1);
} else {
if (dig_connector->linkb)
512,7 → 538,7
if (dig->coherent_mode)
args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
}
if (drm_detect_hdmi_monitor(radeon_connector->edid))
if (hdmi_detected)
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
args.v2.ucTruncate = 0;
520,18 → 546,18
args.v2.ucTemporal = 0;
args.v2.ucFRC = 0;
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
if (dig->lvds_misc & (1 << 0))
if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
if (dig->lvds_misc & (1 << 5)) {
if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) {
args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
if (dig->lvds_misc & (1 << 1))
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
}
if (dig->lvds_misc & (1 << 6)) {
if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) {
args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
if (dig->lvds_misc & (1 << 1))
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
if (((dig->lvds_misc >> 2) & 0x3) == 2)
if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)
args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
}
} else {
552,7 → 578,7
}
 
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
r600_hdmi_enable(encoder, hdmi_detected);
}
 
int
590,8 → 616,10
return ATOM_ENCODER_MODE_LVDS;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
radeon_dig_connector = radeon_connector->con_priv;
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP;
else if (drm_detect_hdmi_monitor(radeon_connector->edid))
return ATOM_ENCODER_MODE_HDMI;
598,13 → 626,13
else
return ATOM_ENCODER_MODE_DVI;
break;
case CONNECTOR_DVI_A:
case CONNECTOR_VGA:
case DRM_MODE_CONNECTOR_DVIA:
case DRM_MODE_CONNECTOR_VGA:
return ATOM_ENCODER_MODE_CRT;
break;
case CONNECTOR_STV:
case CONNECTOR_CTV:
case CONNECTOR_DIN:
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_9PinDIN:
/* fix me */
return ATOM_ENCODER_MODE_TV;
/*return ATOM_ENCODER_MODE_CV;*/
668,31 → 696,11
 
memset(&args, 0, sizeof(args));
 
if (ASIC_IS_DCE32(rdev)) {
if (dig->dig_block)
if (dig->dig_encoder)
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
num = dig->dig_block + 1;
} else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
num = 1;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
num = 2;
break;
}
}
num = dig->dig_encoder + 1;
 
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
 
814,7 → 822,7
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
}
if (ASIC_IS_DCE32(rdev)) {
if (dig->dig_block)
if (dig->dig_encoder == 1)
args.v2.acConfig.ucEncoderSel = 1;
if (dig_connector->linkb)
args.v2.acConfig.ucLinkSel = 1;
841,17 → 849,16
args.v2.acConfig.fCoherentMode = 1;
}
} else {
 
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
if (dig->dig_encoder)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
if (rdev->flags & RADEON_IS_IGP) {
if (radeon_encoder->pixel_clock > 165000) {
if (dig_connector->igp_lane_info & 0x3)
870,10 → 877,6
}
}
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
break;
}
 
if (radeon_encoder->pixel_clock > 165000)
893,7 → 896,6
}
 
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
}
 
static void
1039,6 → 1041,7
union crtc_sourc_param args;
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
uint8_t frev, crev;
struct radeon_encoder_atom_dig *dig;
 
memset(&args, 0, sizeof(args));
 
1102,40 → 1105,16
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
if (ASIC_IS_DCE32(rdev)) {
if (radeon_crtc->crtc_id)
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
dig = radeon_encoder->enc_priv;
if (dig->dig_encoder)
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
else
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
} else {
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *dig_connector;
 
connector = radeon_get_connector_for_encoder(encoder);
if (!connector)
return;
radeon_connector = to_radeon_connector(connector);
if (!radeon_connector->con_priv)
return;
dig_connector = radeon_connector->con_priv;
 
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
else
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
}
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1162,7 → 1141,6
}
 
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
}
 
static void
1196,6 → 1174,47
}
}
 
static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *test_encoder;
struct radeon_encoder_atom_dig *dig;
uint32_t dig_enc_in_use = 0;
/* on DCE32 and encoder can driver any block so just crtc id */
if (ASIC_IS_DCE32(rdev)) {
return radeon_crtc->crtc_id;
}
 
/* on DCE3 - LVTMA can only be driven by DIGB */
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
struct radeon_encoder *radeon_test_encoder;
 
if (encoder == test_encoder)
continue;
 
if (!radeon_encoder_is_digital(test_encoder))
continue;
 
radeon_test_encoder = to_radeon_encoder(test_encoder);
dig = radeon_test_encoder->enc_priv;
 
if (dig->dig_encoder >= 0)
dig_enc_in_use |= (1 << dig->dig_encoder);
}
 
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {
if (dig_enc_in_use & 0x2)
DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");
return 1;
}
if (!(dig_enc_in_use & 1))
return 0;
return 1;
}
 
static void
radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
1208,13 → 1227,10
 
if (radeon_encoder->active_device &
(ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
if (radeon_encoder->enc_priv) {
struct radeon_encoder_atom_dig *dig;
 
dig = radeon_encoder->enc_priv;
dig->dig_block = radeon_crtc->crtc_id;
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
if (dig)
dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
}
}
radeon_encoder->pixel_clock = adjusted_mode->clock;
 
radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
1265,6 → 1281,8
break;
}
atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
r600_hdmi_setmode(encoder, adjusted_mode);
}
 
static bool
1371,7 → 1389,13
static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig;
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
if (radeon_encoder_is_digital(encoder)) {
dig = radeon_encoder->enc_priv;
dig->dig_encoder = -1;
}
radeon_encoder->active_device = 0;
}
 
1428,6 → 1452,7
 
/* coherent mode by default */
dig->coherent_mode = true;
dig->dig_encoder = -1;
 
return dig;
}
1510,4 → 1535,6
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
break;
}
 
r600_hdmi_init(encoder);
}