Commit 99999aaa authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms/atom: cleanup and unify DVO handling

Handle all the various asic family specific things for DVO.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8b834852
...@@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); ...@@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
(rdev->family == CHIP_RS400) || \ (rdev->family == CHIP_RS400) || \
(rdev->family == CHIP_RS480)) (rdev->family == CHIP_RS480))
#define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \
(rdev->family == CHIP_RS690) || \
(rdev->family == CHIP_RS740) || \
(rdev->family >= CHIP_R600))
#define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
#define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
......
...@@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) ...@@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
return false; return false;
} }
} }
void void
radeon_link_encoder_connector(struct drm_device *dev) radeon_link_encoder_connector(struct drm_device *dev)
{ {
...@@ -426,52 +427,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) ...@@ -426,52 +427,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
} }
void union dvo_encoder_control {
atombios_external_tmds_setup(struct drm_encoder *encoder, int action) ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
{ DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
struct drm_device *dev = encoder->dev; DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
struct radeon_device *rdev = dev->dev_private; };
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
int index = 0;
memset(&args, 0, sizeof(args));
index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
args.sXTmdsEncoder.ucEnable = action;
if (radeon_encoder->pixel_clock > 165000)
args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8)*/
args.sXTmdsEncoder.ucMisc |= (1 << 1);
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
static void void
atombios_ddia_setup(struct drm_encoder *encoder, int action) atombios_dvo_setup(struct drm_encoder *encoder, int action)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
DVO_ENCODER_CONTROL_PS_ALLOCATION args; union dvo_encoder_control args;
int index = 0; int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); if (ASIC_IS_DCE3(rdev)) {
/* DCE3+ */
args.dvo_v3.ucAction = action;
args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
args.dvo_v3.ucDVOConfig = 0; /* XXX */
} else if (ASIC_IS_DCE2(rdev)) {
/* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
args.dvo.sDVOEncoder.ucAction = action;
args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
/* DFP1, CRT1, TV1 depending on the type of port */
args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
if (radeon_encoder->pixel_clock > 165000)
args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
} else {
/* R4xx, R5xx */
args.ext_tmds.sXTmdsEncoder.ucEnable = action;
args.sDVOEncoder.ucAction = action; if (radeon_encoder->pixel_clock > 165000)
args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
if (radeon_encoder->pixel_clock > 165000) /*if (pScrn->rgbBits == 8)*/
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL; args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
} }
union lvds_encoder_control { union lvds_encoder_control {
...@@ -532,14 +530,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -532,14 +530,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
args.v1.ucMisc |= (1 << 1); args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
} else { } else {
if (dig->linkb) if (dig->linkb)
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (radeon_encoder->pixel_clock > 165000) if (radeon_encoder->pixel_clock > 165000)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8) */ /*if (pScrn->rgbBits == 8) */
args.v1.ucMisc |= (1 << 1); args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
} }
break; break;
case 2: case 2:
...@@ -846,6 +844,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t ...@@ -846,6 +844,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
switch (radeon_encoder->encoder_id) { switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
...@@ -1085,9 +1086,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -1085,9 +1086,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
if (ASIC_IS_DCE3(rdev))
is_dig = true;
else
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVDS: case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
break; break;
...@@ -1317,7 +1323,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) ...@@ -1317,7 +1323,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
break; break;
default: default:
DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
break; return;
} }
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
...@@ -1475,11 +1481,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1475,11 +1481,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
} }
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
atombios_ddia_setup(encoder, ATOM_ENABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
atombios_external_tmds_setup(encoder, ATOM_ENABLE); atombios_dvo_setup(encoder, ATOM_ENABLE);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1: case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
...@@ -1670,11 +1674,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) ...@@ -1670,11 +1674,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
} }
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
atombios_ddia_setup(encoder, ATOM_DISABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
atombios_external_tmds_setup(encoder, ATOM_DISABLE); atombios_dvo_setup(encoder, ATOM_DISABLE);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1: case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
......
...@@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ...@@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
if (rdev->is_atom_bios) { if (rdev->is_atom_bios) {
radeon_encoder->pixel_clock = adjusted_mode->clock; radeon_encoder->pixel_clock = adjusted_mode->clock;
atombios_external_tmds_setup(encoder, ATOM_ENABLE); atombios_dvo_setup(encoder, ATOM_ENABLE);
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
} else { } else {
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
......
...@@ -524,7 +524,7 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev ...@@ -524,7 +524,7 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev
struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); extern void atombios_dvo_setup(struct drm_encoder *encoder, int action);
extern void atombios_digital_setup(struct drm_encoder *encoder, int action); extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
extern int atombios_get_encoder_mode(struct drm_encoder *encoder); extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action); extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment