xf86-video-ati: Branch 'master' - 6 commits
Dave Airlie
airlied at kemper.freedesktop.org
Mon Aug 9 20:27:14 PDT 2010
src/atombios_crtc.c | 426 +++++++++++++++++++++++++-------------------------
src/atombios_output.c | 331 ++++++++++++++++----------------------
src/radeon.h | 2
src/radeon_atombios.c | 7
src/radeon_atombios.h | 2
src/radeon_output.c | 3
6 files changed, 369 insertions(+), 402 deletions(-)
New commits:
commit 94bc1b7156cd0866566dc44a823c7e051bb45175
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:24:52 2010 +1000
atombios: fixup set crtc source like KMS
This removes a bunch of strict aliasing warnings and fixes the
codepaths up like the latest KMS code, including a workaround for a bug
on evergreen.
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 2feacde..8d640be 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -67,8 +67,6 @@ const char *device_name[12] = {
static void do_displayport_link_train(xf86OutputPtr output);
-static void atombios_set_output_crtc_source(xf86OutputPtr output);
-
static int
atombios_output_dac_setup(xf86OutputPtr output, int action)
{
@@ -1409,7 +1407,12 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
}
}
-static void
+union crtc_source_param {
+ SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
+ SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
+};
+
+void
atombios_set_output_crtc_source(xf86OutputPtr output)
{
RADEONOutputPrivatePtr radeon_output = output->driver_private;
@@ -1418,16 +1421,15 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
AtomBiosArgRec data;
unsigned char *space;
- SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
- SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2;
+ union crtc_source_param args;
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
int major, minor;
if (radeon_encoder == NULL)
return;
- memset(&crtc_src_param, 0, sizeof(crtc_src_param));
- memset(&crtc_src_param2, 0, sizeof(crtc_src_param2));
+ memset(&args, 0, sizeof(args));
+
atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
/*ErrorF("select crtc source table is %d %d\n", major, minor);*/
@@ -1439,55 +1441,54 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
case 1:
default:
if (IS_AVIVO_VARIANT)
- crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
+ args.v1.ucCRTC = radeon_crtc->crtc_id;
else {
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)
- crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
+ args.v1.ucCRTC = radeon_crtc->crtc_id;
else
- crtc_src_param.ucCRTC = radeon_crtc->crtc_id << 2;
+ args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
}
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- crtc_src_param.ucDevice = ATOM_DEVICE_DFP1_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
break;
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT)
- crtc_src_param.ucDevice = ATOM_DEVICE_LCD1_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
else
- crtc_src_param.ucDevice = ATOM_DEVICE_DFP3_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
- crtc_src_param.ucDevice = ATOM_DEVICE_DFP2_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
else
- crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
else
- crtc_src_param.ucDevice = ATOM_DEVICE_CRT2_INDEX;
+ args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
break;
}
- data.exec.pspace = &crtc_src_param;
- /*ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);*/
+ /*ErrorF("device sourced: 0x%x\n", args.v1.ucDevice);*/
break;
case 2:
- crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
- crtc_src_param2.ucEncodeMode = atombios_get_encoder_mode(output);
+ args.v2.ucCRTC = radeon_crtc->crtc_id;
+ args.v2.ucEncodeMode = atombios_get_encoder_mode(output);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
@@ -1495,44 +1496,46 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
switch (radeon_output->dig_encoder) {
case 0:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
break;
case 1:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
break;
case 2:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
break;
case 3:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
break;
case 4:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
break;
case 5:
- crtc_src_param2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
break;
}
break;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
+ break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
else
- crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
else
- crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
+ args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
break;
}
- data.exec.pspace = &crtc_src_param2;
- /*ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);*/
+ /*ErrorF("device sourced: 0x%x\n", args.v2.ucEncoderID);*/
break;
}
break;
@@ -1541,6 +1544,7 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
exit(-1);
}
+ data.exec.pspace = &args;
data.exec.index = index;
data.exec.dataSpace = (void *)&space;
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index 67f65ca..866c4bf 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -288,4 +288,5 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
extern uint32_t
radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supported_device, int dac);
+void atombios_set_output_crtc_source(xf86OutputPtr output);
#endif /* RHD_ATOMBIOS_H_ */
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 172b871..42aa3ca 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -734,6 +734,9 @@ radeon_mode_prepare(xf86OutputPtr output)
radeon_dpms(output, DPMSModeOff);
radeon_crtc_dpms(output->crtc, DPMSModeOff);
+ if (IS_AVIVO_VARIANT || info->r4xx_atom)
+ atombios_set_output_crtc_source(output);
+
}
static void
commit 9bc716eb62d4e0eed2902b92437a42634eef6ba1
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:23:21 2010 +1000
atombios: move adjust pixel clock around to follow KMS code flow
This reworks the pixel clock adjusting code to follow the KMS style,
also fixes warnings in this code.
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 6f083b4..d0ffa07 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -347,6 +347,164 @@ atombios_pick_pll(xf86CrtcPtr crtc)
}
}
+union adjust_pixel_clock {
+ ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
+ ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
+};
+
+static uint32_t atombios_adjust_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int *pll_flags_p)
+{
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ uint32_t adjusted_clock = mode->Clock;
+ RADEONOutputPrivatePtr radeon_output = NULL;
+ radeon_encoder_ptr radeon_encoder = NULL;
+ xf86OutputPtr output;
+ int pll_flags = 0;
+ int i;
+
+ if (IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ } else {
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ }
+
+ if (IS_AVIVO_VARIANT) {
+ if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
+ (info->ChipFamily == CHIP_FAMILY_RS690) ||
+ (info->ChipFamily == CHIP_FAMILY_RS740))
+ pll_flags |= /*RADEON_PLL_USE_FRAC_FB_DIV |*/
+ RADEON_PLL_PREFER_CLOSEST_LOWER;
+ if (IS_DCE32_VARIANT && mode->Clock > 200000) /* range limits??? */
+ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ } else {
+ pll_flags |= RADEON_PLL_LEGACY;
+
+ if (mode->Clock > 200000) /* range limits??? */
+ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ output = xf86_config->output[i];
+ if (output->crtc == crtc) {
+ radeon_output = output->driver_private;
+ radeon_encoder = radeon_get_encoder(output);
+ if (IS_AVIVO_VARIANT) {
+ /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
+ if (radeon_encoder &&
+ (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) &&
+ !IS_DCE3_VARIANT)
+ adjusted_clock *= 2;
+ if (radeon_output->active_device &
+ (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) {
+ pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ }
+ } else {
+ if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT |
+ ATOM_DEVICE_DFP_SUPPORT))
+ pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+ if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+ pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
+ }
+ if (IS_DCE3_VARIANT)
+ break;
+ }
+ }
+
+ if (IS_DCE3_VARIANT) {
+ union adjust_pixel_clock args;
+ int major, minor, index;
+ AtomBiosArgRec data;
+ unsigned char *space;
+
+ memset(&args, 0, sizeof(args));
+
+ index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+
+ atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
+
+ data.exec.index = index;
+ data.exec.dataSpace = (void *)&space;
+ data.exec.pspace = &args;
+
+ switch(major) {
+ case 1:
+ switch(minor) {
+ case 1:
+ case 2:
+ args.v1.usPixelClock = cpu_to_le16(adjusted_clock / 10);
+ args.v1.ucTransmitterID = radeon_encoder->encoder_id;
+ args.v1.ucEncodeMode = atombios_get_encoder_mode(output);
+
+ ErrorF("before %d\n", args.v1.usPixelClock);
+ if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+ adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
+ }
+ ErrorF("after %d\n", args.v1.usPixelClock);
+ break;
+ case 3:
+ args.v3.sInput.usPixelClock = cpu_to_le16(adjusted_clock / 10);
+ args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
+ args.v3.sInput.ucEncodeMode = atombios_get_encoder_mode(output);
+ args.v3.sInput.ucDispPllConfig = 0;
+ if (radeon_output->coherent_mode || (args.v3.sInput.ucEncodeMode == ATOM_ENCODER_MODE_DP))
+ args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE;
+ if (adjusted_clock > 165000)
+ args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
+ // if SS
+ // args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
+
+ ErrorF("before %d 0x%x\n", args.v3.sInput.usPixelClock, args.v3.sInput.ucDispPllConfig);
+ if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+ adjusted_clock = args.v3.sOutput.ulDispPllFreq * 10;
+ if (args.v3.sOutput.ucRefDiv) {
+ pll_flags |= RADEON_PLL_USE_REF_DIV;
+ info->pll.reference_div = args.v3.sOutput.ucRefDiv;
+ }
+ if (args.v3.sOutput.ucPostDiv) {
+ pll_flags |= RADEON_PLL_USE_POST_DIV;
+ info->pll.post_div = args.v3.sOutput.ucPostDiv;
+ }
+ ErrorF("after %d %d %d\n", args.v3.sOutput.ulDispPllFreq,
+ args.v3.sOutput.ucRefDiv, args.v3.sOutput.ucPostDiv);
+ }
+ break;
+ default:
+ ErrorF("%s: Unknown table version %d %d\n", __func__, major, minor);
+ goto out;
+ }
+ break;
+ default:
+ ErrorF("%s: Unknown table version %d %d\n", __func__, major, minor);
+ goto out;
+ }
+ }
+out:
+ *pll_flags_p = pll_flags;
+ return adjusted_clock;
+}
+
+union set_pixel_clock {
+ SET_PIXEL_CLOCK_PS_ALLOCATION base;
+ PIXEL_CLOCK_PARAMETERS v1;
+ PIXEL_CLOCK_PARAMETERS_V2 v2;
+ PIXEL_CLOCK_PARAMETERS_V3 v3;
+ PIXEL_CLOCK_PARAMETERS_V5 v5;
+};
+
static void
atombios_crtc_set_dcpll(xf86CrtcPtr crtc)
{
@@ -357,7 +515,7 @@ atombios_crtc_set_dcpll(xf86CrtcPtr crtc)
radeon_encoder_ptr radeon_encoder = NULL;
int index;
int major, minor, i;
- PIXEL_CLOCK_PARAMETERS_V5 args;
+ union set_pixel_clock args;
AtomBiosArgRec data;
unsigned char *space;
@@ -390,25 +548,10 @@ atombios_crtc_set_dcpll(xf86CrtcPtr crtc)
case 1:
switch(minor) {
case 5:
- args.ucCRTC = ATOM_CRTC_INVALID;
+ args.v5.ucCRTC = ATOM_CRTC_INVALID;
/* XXX: get this from the firmwareinfo table */
- args.usPixelClock = 60000; // 600 Mhz
- args.ucPostDiv = info->pll.pll_out_max / 60000;
- if (info->pll.reference_freq == 10000) {
- // 100 Mhz ref clock
- args.ucRefDiv = 7;
- args.usFbDiv = cpu_to_le16(84);
- args.ulFbDivDecFrac = cpu_to_le32(0);
- } else {
- // 27 Mhz ref clock
- args.ucRefDiv = 2;
- args.usFbDiv = cpu_to_le16(88);
- args.ulFbDivDecFrac = cpu_to_le32(888889);
- }
- args.ucPpll = ATOM_DCPLL;
- args.ucMiscInfo = 0; //HDMI depth
- args.ucTransmitterID = radeon_encoder->encoder_id;
- args.ucEncoderMode = atombios_get_encoder_mode(output);
+ args.v5.usPixelClock = info->default_dispclk;
+ args.v5.ucPpll = ATOM_DCPLL;
break;
default:
ErrorF("Unknown table version\n");
@@ -439,200 +582,66 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
unsigned char *RADEONMMIO = info->MMIO;
int index;
- uint32_t sclock = mode->Clock;
+ uint32_t sclock;
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
- int major, minor, i;
- SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
- PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
- PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
- PIXEL_CLOCK_PARAMETERS_V5 *spc5_ptr;
+ int major, minor;
+ union set_pixel_clock args;
xf86OutputPtr output = NULL;
- RADEONOutputPrivatePtr radeon_output = NULL;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
radeon_encoder_ptr radeon_encoder = NULL;
int pll_flags = 0;
uint32_t temp;
AtomBiosArgRec data;
unsigned char *space;
+ int i;
- memset(&spc_param, 0, sizeof(spc_param));
-
- if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE))
- radeon_crtc->pll_algo = RADEON_PLL_NEW;
- else
- radeon_crtc->pll_algo = RADEON_PLL_OLD;
- } else {
- if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
- radeon_crtc->pll_algo = RADEON_PLL_NEW;
- else
- radeon_crtc->pll_algo = RADEON_PLL_OLD;
- }
-
- if (IS_AVIVO_VARIANT) {
- if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
- (info->ChipFamily == CHIP_FAMILY_RS690) ||
- (info->ChipFamily == CHIP_FAMILY_RS740))
- pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV | RADEON_PLL_PREFER_CLOSEST_LOWER;
- if (IS_DCE3_VARIANT && mode->Clock > 200000) /* range limits??? */
- pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
- else
- pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- if (output->crtc == crtc) {
- radeon_output = output->driver_private;
- radeon_encoder = radeon_get_encoder(output);
- /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
- /* AdjustDisplayPll handles this on DCE3.x */
- if (radeon_encoder &&
- (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) &&
- !IS_DCE3_VARIANT)
- sclock *= 2;
- if (radeon_output->active_device &
- (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) {
- pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
- radeon_crtc->pll_algo = RADEON_PLL_OLD;
- }
- }
- }
+ memset(&args, 0, sizeof(args));
- /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
- if (IS_DCE4_VARIANT) {
- /* XXX 6 crtcs, but only 2 plls */
- switch (radeon_crtc->pll_id) {
- case ATOM_PPLL1:
- temp = INREG(EVERGREEN_P1PLL_SS_CNTL);
- OUTREG(EVERGREEN_P1PLL_SS_CNTL, temp & ~EVERGREEN_PxPLL_SS_EN);
- break;
- case ATOM_PPLL2:
- temp = INREG(EVERGREEN_P2PLL_SS_CNTL);
- OUTREG(EVERGREEN_P2PLL_SS_CNTL, temp & ~EVERGREEN_PxPLL_SS_EN);
- break;
- }
- } else {
- if (radeon_crtc->crtc_id == 0) {
- temp = INREG(AVIVO_P1PLL_INT_SS_CNTL);
- OUTREG(AVIVO_P1PLL_INT_SS_CNTL, temp & ~1);
- } else {
- temp = INREG(AVIVO_P2PLL_INT_SS_CNTL);
- OUTREG(AVIVO_P2PLL_INT_SS_CNTL, temp & ~1);
- }
+ if (IS_DCE4_VARIANT) {
+ /* XXX 6 crtcs, but only 2 plls */
+ switch (radeon_crtc->pll_id) {
+ case ATOM_PPLL1:
+ temp = INREG(EVERGREEN_P1PLL_SS_CNTL);
+ OUTREG(EVERGREEN_P1PLL_SS_CNTL, temp & ~EVERGREEN_PxPLL_SS_EN);
+ break;
+ case ATOM_PPLL2:
+ temp = INREG(EVERGREEN_P2PLL_SS_CNTL);
+ OUTREG(EVERGREEN_P2PLL_SS_CNTL, temp & ~EVERGREEN_PxPLL_SS_EN);
+ break;
}
} else {
- pll_flags |= RADEON_PLL_LEGACY;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (output->crtc == crtc) {
- if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT |
- ATOM_DEVICE_DFP_SUPPORT))
- pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
- if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
- pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
- }
+ if (radeon_crtc->crtc_id == 0) {
+ temp = INREG(AVIVO_P1PLL_INT_SS_CNTL);
+ OUTREG(AVIVO_P1PLL_INT_SS_CNTL, temp & ~1);
+ } else {
+ temp = INREG(AVIVO_P2PLL_INT_SS_CNTL);
+ OUTREG(AVIVO_P2PLL_INT_SS_CNTL, temp & ~1);
}
-
- if (mode->Clock > 200000) /* range limits??? */
- pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
- else
- pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
}
if (IS_DCE3_VARIANT) {
- ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_param;
- ADJUST_DISPLAY_PLL_PS_ALLOCATION *adp_ptr;
- ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 *adp3_ptr;
-
- /* Can't really do cloning easily on DCE3 cards */
for (i = 0; i < xf86_config->num_output; i++) {
output = xf86_config->output[i];
if (output->crtc == crtc) {
- radeon_output = output->driver_private;
radeon_encoder = radeon_get_encoder(output);
break;
}
}
- if (radeon_output == NULL) {
+ if (output->driver_private == NULL) {
xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
return;
}
-
if (radeon_encoder == NULL) {
xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No encoder assigned to output!\n");
return;
}
-
- memset(&adjust_pll_param, 0, sizeof(adjust_pll_param));
-
- index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
- atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
-
- data.exec.index = index;
- data.exec.dataSpace = (void *)&space;
- data.exec.pspace = &adjust_pll_param;
-
- switch(major) {
- case 1:
- switch(minor) {
- case 1:
- case 2:
- adp_ptr = (ADJUST_DISPLAY_PLL_PS_ALLOCATION*)&adjust_pll_param.usPixelClock;
- adp_ptr->usPixelClock = cpu_to_le16(sclock / 10);
- adp_ptr->ucTransmitterID = radeon_encoder->encoder_id;
- adp_ptr->ucEncodeMode = atombios_get_encoder_mode(output);
-
- ErrorF("before %d\n", adp_ptr->usPixelClock);
- if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- sclock = le16_to_cpu(adp_ptr->usPixelClock) * 10;
- }
- ErrorF("after %d\n", adp_ptr->usPixelClock);
- break;
- case 3:
- adp3_ptr = (ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3*)&adjust_pll_param.usPixelClock;
- adp3_ptr->sInput.usPixelClock = cpu_to_le16(sclock / 10);
- adp3_ptr->sInput.ucTransmitterID = radeon_encoder->encoder_id;
- adp3_ptr->sInput.ucEncodeMode = atombios_get_encoder_mode(output);
- adp3_ptr->sInput.ucDispPllConfig = 0;
- if (radeon_output->coherent_mode || (adp3_ptr->sInput.ucEncodeMode == ATOM_ENCODER_MODE_DP))
- adp3_ptr->sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE;
- if (sclock > 165000)
- adp3_ptr->sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
- // if SS
- // adp3_ptr->sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
-
- ErrorF("before %d 0x%x\n", adp3_ptr->sInput.usPixelClock, adp3_ptr->sInput.ucDispPllConfig);
- if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- sclock = adp3_ptr->sOutput.ulDispPllFreq * 10;
- if (adp3_ptr->sOutput.ucRefDiv) {
- pll_flags |= RADEON_PLL_USE_REF_DIV;
- info->pll.reference_div = adp3_ptr->sOutput.ucRefDiv;
- }
- if (adp3_ptr->sOutput.ucPostDiv) {
- pll_flags |= RADEON_PLL_USE_POST_DIV;
- info->pll.post_div = adp3_ptr->sOutput.ucPostDiv;
- }
- ErrorF("after %d %d %d\n", adp3_ptr->sOutput.ulDispPllFreq,
- adp3_ptr->sOutput.ucRefDiv, adp3_ptr->sOutput.ucPostDiv);
- }
- break;
- default:
- ErrorF("Unknown table version\n");
- exit(-1);
- }
- break;
- default:
- ErrorF("Unknown table version\n");
- exit(-1);
- }
}
+ sclock = atombios_adjust_pll(crtc, mode, &pll_flags);
+
RADEONComputePLL(crtc, &info->pll, sclock, &temp,
&fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags);
sclock = temp; /* 10 khz */
@@ -654,40 +663,37 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
switch(minor) {
case 1:
case 2:
- spc2_ptr = (PIXEL_CLOCK_PARAMETERS_V2*)&spc_param.sPCLKInput;
- spc2_ptr->usPixelClock = cpu_to_le16(mode->Clock / 10);
- spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
- spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
- spc2_ptr->ucFracFbDiv = frac_fb_div;
- spc2_ptr->ucPostDiv = post_div;
- spc2_ptr->ucPpll = radeon_crtc->pll_id;
- spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
- spc2_ptr->ucRefDivSrc = 1;
+ args.v2.usPixelClock = cpu_to_le16(mode->Clock / 10);
+ args.v2.usRefDiv = cpu_to_le16(ref_div);
+ args.v2.usFbDiv = cpu_to_le16(fb_div);
+ args.v2.ucFracFbDiv = frac_fb_div;
+ args.v2.ucPostDiv = post_div;
+ args.v2.ucPpll = radeon_crtc->pll_id;
+ args.v2.ucCRTC = radeon_crtc->crtc_id;
+ args.v2.ucRefDivSrc = 1;
break;
case 3:
- spc3_ptr = (PIXEL_CLOCK_PARAMETERS_V3*)&spc_param.sPCLKInput;
- spc3_ptr->usPixelClock = cpu_to_le16(mode->Clock / 10);
- spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
- spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
- spc3_ptr->ucFracFbDiv = frac_fb_div;
- spc3_ptr->ucPostDiv = post_div;
- spc3_ptr->ucPpll = radeon_crtc->pll_id;
- spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
- spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id;
- spc3_ptr->ucEncoderMode = atombios_get_encoder_mode(output);
+ args.v3.usPixelClock = cpu_to_le16(mode->Clock / 10);
+ args.v3.usRefDiv = cpu_to_le16(ref_div);
+ args.v3.usFbDiv = cpu_to_le16(fb_div);
+ args.v3.ucFracFbDiv = frac_fb_div;
+ args.v3.ucPostDiv = post_div;
+ args.v3.ucPpll = radeon_crtc->pll_id;
+ args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
+ args.v3.ucTransmitterId = radeon_encoder->encoder_id;
+ args.v3.ucEncoderMode = atombios_get_encoder_mode(output);
break;
case 5:
- spc5_ptr = (PIXEL_CLOCK_PARAMETERS_V5*)&spc_param.sPCLKInput;
- spc5_ptr->ucCRTC = radeon_crtc->crtc_id;
- spc5_ptr->usPixelClock = cpu_to_le16(mode->Clock / 10);
- spc5_ptr->ucRefDiv = ref_div;
- spc5_ptr->usFbDiv = cpu_to_le16(fb_div);
- spc5_ptr->ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
- spc5_ptr->ucPostDiv = post_div;
- spc5_ptr->ucPpll = radeon_crtc->pll_id;
- spc5_ptr->ucMiscInfo = 0; //HDMI depth
- spc5_ptr->ucTransmitterID = radeon_encoder->encoder_id;
- spc5_ptr->ucEncoderMode = atombios_get_encoder_mode(output);
+ args.v5.ucCRTC = radeon_crtc->crtc_id;
+ args.v5.usPixelClock = cpu_to_le16(mode->Clock / 10);
+ args.v5.ucRefDiv = ref_div;
+ args.v5.usFbDiv = cpu_to_le16(fb_div);
+ args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
+ args.v5.ucPostDiv = post_div;
+ args.v5.ucPpll = radeon_crtc->pll_id;
+ args.v5.ucMiscInfo = 0; //HDMI depth
+ args.v5.ucTransmitterID = radeon_encoder->encoder_id;
+ args.v5.ucEncoderMode = atombios_get_encoder_mode(output);
break;
default:
ErrorF("Unknown table version\n");
@@ -701,7 +707,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
data.exec.index = index;
data.exec.dataSpace = (void *)&space;
- data.exec.pspace = &spc_param;
+ data.exec.pspace = &args;
if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
ErrorF("Set CRTC %d PLL success\n", radeon_crtc->crtc_id);
commit 31de43bf9d9eb93cc2b2150474ea7404beabe49d
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:21:39 2010 +1000
displayport: retry on timeout
this is ported from KMS
diff --git a/src/atombios_output.c b/src/atombios_output.c
index ee024a6..2feacde 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -2002,6 +2002,7 @@ RADEONProcessAuxCH(xf86OutputPtr output, uint8_t *req_bytes, uint8_t num_bytes,
AtomBiosArgRec data;
unsigned char *space;
unsigned char *base;
+ int retry_count = 0;
memset(&args, 0, sizeof(args));
if (info->atomBIOS->fbBase)
@@ -2011,6 +2012,7 @@ RADEONProcessAuxCH(xf86OutputPtr output, uint8_t *req_bytes, uint8_t num_bytes,
else
return FALSE;
+retry:
memcpy(base, req_bytes, num_bytes);
args.v1.lpAuxRequest = 0;
@@ -2026,9 +2028,11 @@ RADEONProcessAuxCH(xf86OutputPtr output, uint8_t *req_bytes, uint8_t num_bytes,
data.exec.pspace = &args;
RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data);
- if (args.v1.ucReplyStatus) {
- ErrorF("failed to get auxch %02x%02x %02x %02x %02x\n",
- req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], args.v1.ucReplyStatus);
+ if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
+ if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
+ goto retry;
+ ErrorF("failed to get auxch %02x%02x %02x %02x %02x after %d retries\n",
+ req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], args.v1.ucReplyStatus, retry_count);
return FALSE;
}
if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
@@ -2066,7 +2070,7 @@ RADEONDPEncoderService(xf86OutputPtr output, int action, uint8_t ucconfig, uint8
RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data);
- ErrorF("%s: %d\n", __func__, args.ucStatus);
+ ErrorF("%s: %d %d\n", __func__, action, args.ucStatus);
return args.ucStatus;
}
commit 9ef67335583d36080d227e8bce1966afe08e0486
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:21:01 2010 +1000
evergreen: don't call YUV table on evergreen
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 5ccf50d..ee024a6 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -1693,7 +1693,7 @@ atombios_output_mode_set(xf86OutputPtr output,
atombios_output_scaler_setup(output);
atombios_set_output_crtc_source(output);
- if (IS_AVIVO_VARIANT) {
+ if (IS_AVIVO_VARIANT && !IS_DCE4_VARIANT) {
if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
atombios_output_yuv_setup(output, TRUE);
else
commit 1cce55e8ba43e7958cb67147aeaeb068826ab99f
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:20:13 2010 +1000
evergreen: add support to parse firmware info for ext dp clk
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 003b8f8..5ccf50d 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -729,7 +729,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
}
// select the PLL for the UNIPHY
- if (radeon_output->MonType == MT_DP)
+ if (radeon_output->MonType == MT_DP && info->dp_extclk)
disp_data.v3.acConfig.ucRefClkSource = 2; /* ext clk */
else
disp_data.v3.acConfig.ucRefClkSource = radeon_output->pll_id;
diff --git a/src/radeon.h b/src/radeon.h
index d66cdd9..134a4cf 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -872,6 +872,8 @@ typedef struct {
Bool ddc2;
RADEONPLLRec pll;
+ int default_dispclk;
+ int dp_extclk;
int RamWidth;
float sclk; /* in MHz */
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 996e6ee..61b5372 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2307,6 +2307,13 @@ RADEONGetATOMClockInfo(ScrnInfoPtr pScrn)
pll->pll_out_min = 64800;
}
+ if (IS_DCE4_VARIANT) {
+ info->default_dispclk =
+ le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_2_1->ulDefaultDispEngineClkFreq);
+ if (info->default_dispclk == 0)
+ info->default_dispclk = 60000;
+ info->dp_extclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_2_1->usUniphyDPModeExtClkFreq);
+ }
return TRUE;
}
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index 1f21c46..67f65ca 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -194,6 +194,7 @@ typedef struct _atomDataTables
ATOM_FIRMWARE_INFO_V1_2 *FirmwareInfo_V_1_2;
ATOM_FIRMWARE_INFO_V1_3 *FirmwareInfo_V_1_3;
ATOM_FIRMWARE_INFO_V1_4 *FirmwareInfo_V_1_4;
+ ATOM_FIRMWARE_INFO_V2_1 *FirmwareInfo_V_2_1;
} FirmwareInfo;
ATOM_DAC_INFO *DAC_Info;
union {
commit bbffd67d3296344e8735b007cdee83146d38369c
Author: Dave Airlie <airlied at redhat.com>
Date: Tue Aug 10 13:14:54 2010 +1000
atombios: realign digital transmitter/encoder setup with kms
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 3e2d301..003b8f8 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -559,19 +559,40 @@ dp_link_clock_for_mode_clock(RADEONOutputPrivatePtr radeon_output,
* - 2 DIG encoder blocks.
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
*
+ * DCE 4.0
+ * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B).
+ * Supports up to 6 digital outputs
+ * - 6 DIG encoder blocks.
+ * - DIG to PHY mapping is hardcoded
+ * DIG1 drives UNIPHY0 link A, A+B
+ * DIG2 drives UNIPHY0 link B
+ * DIG3 drives UNIPHY1 link A, A+B
+ * DIG4 drives UNIPHY1 link B
+ * DIG5 drives UNIPHY2 link A, A+B
+ * DIG6 drives UNIPHY2 link B
+ *
* Routing
* crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
* Examples:
* crtc0 -> dig2 -> LVTMA links A+B
* crtc1 -> dig1 -> UNIPHY0 link B
+ * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS
+ * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI
*/
+
+union dig_encoder_control {
+ DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
+ DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
+ DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
+};
+
static int
atombios_output_dig_encoder_setup(xf86OutputPtr output, int action)
{
RADEONOutputPrivatePtr radeon_output = output->driver_private;
RADEONInfoPtr info = RADEONPTR(output->scrn);
radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
- DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+ union dig_encoder_control disp_data;
AtomBiosArgRec data;
unsigned char *space;
int index = 0, major, minor;
@@ -582,55 +603,49 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int action)
memset(&disp_data,0, sizeof(disp_data));
- if (radeon_output->dig_encoder)
+ if (IS_DCE4_VARIANT)
+ index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
+ else if (radeon_output->dig_encoder)
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
- disp_data.ucAction = action;
- disp_data.usPixelClock = cpu_to_le16(clock / 10);
+ disp_data.v1.ucAction = action;
+ disp_data.v1.usPixelClock = cpu_to_le16(clock / 10);
+ disp_data.v1.ucEncoderMode = atombios_get_encoder_mode(output);
- if (IS_DCE32_VARIANT) {
+ if (disp_data.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+ if (dp_link_clock_for_mode_clock(radeon_output, clock) == 27000)
+ disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+ disp_data.v1.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
+ } else if (clock > 165000)
+ disp_data.v1.ucLaneNum = 8;
+ else
+ disp_data.v1.ucLaneNum = 4;
+
+ if (IS_DCE4_VARIANT) {
+ disp_data.v3.acConfig.ucDigSel = radeon_output->dig_encoder;
+ disp_data.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+ } else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+ disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+ disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
- break;
- }
- } else {
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_UNIPHY;
- break;
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_LVTMA;
+ disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
break;
}
+ if (radeon_output->linkb)
+ disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+ else
+ disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
}
- disp_data.ucEncoderMode = atombios_get_encoder_mode(output);
-
- if (disp_data.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
- if (dp_link_clock_for_mode_clock(radeon_output, clock) == 27000)
- disp_data.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
- disp_data.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
- } else if (clock > 165000)
- disp_data.ucLaneNum = 8;
- else
- disp_data.ucLaneNum = 4;
-
- if (radeon_output->linkb)
- disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
- else
- disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
-
data.exec.index = index;
data.exec.dataSpace = (void *)&space;
data.exec.pspace = &disp_data;
@@ -645,54 +660,6 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int action)
}
-static int
-atombios_dce4_output_dig_encoder_setup(xf86OutputPtr output, int action)
-{
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- RADEONInfoPtr info = RADEONPTR(output->scrn);
- radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
- DIG_ENCODER_CONTROL_PARAMETERS_V3 disp_data;
- AtomBiosArgRec data;
- unsigned char *space;
- int index;
- int clock = radeon_output->pixel_clock;
-
- if (radeon_encoder == NULL)
- return ATOM_NOT_IMPLEMENTED;
-
- memset(&disp_data,0, sizeof(disp_data));
-
- index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
-
- disp_data.ucAction = action;
- disp_data.usPixelClock = cpu_to_le16(clock / 10);
- disp_data.ucEncoderMode = atombios_get_encoder_mode(output);
- disp_data.acConfig.ucDigSel = radeon_output->dig_encoder;
-
- if (disp_data.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
- if (dp_link_clock_for_mode_clock(radeon_output, clock) == 27000)
- disp_data.acConfig.ucDPLinkRate = 1;
- disp_data.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
- } else if (clock > 165000)
- disp_data.ucLaneNum = 8;
- else
- disp_data.ucLaneNum = 4;
-
- disp_data.ucBitPerColor = PANEL_8BIT_PER_COLOR;
-
- data.exec.index = index;
- data.exec.dataSpace = (void *)&space;
- data.exec.pspace = &disp_data;
-
- if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- ErrorF("Output DIG%d encoder setup success\n", radeon_output->dig_encoder);
- return ATOM_SUCCESS;
- }
-
- ErrorF("Output DIG%d setup failed\n", radeon_output->dig_encoder);
- return ATOM_NOT_IMPLEMENTED;
-}
-
union dig_transmitter_control {
DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
@@ -733,25 +700,22 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
disp_data.v1.ucAction = action;
+ if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+ disp_data.v1.usInitInfo = radeon_output->connector_object_id;
+ } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+ disp_data.v1.asMode.ucLaneSel = lane_num;
+ disp_data.v1.asMode.ucLaneSet = lane_set;
+ } else {
+ if (radeon_output->MonType == MT_DP)
+ disp_data.v1.usPixelClock =
+ cpu_to_le16(dp_link_clock_for_mode_clock(radeon_output, clock));
+ else if (clock > 165000)
+ disp_data.v1.usPixelClock = cpu_to_le16((clock / 2) / 10);
+ else
+ disp_data.v1.usPixelClock = cpu_to_le16(clock / 10);
+ }
if (IS_DCE4_VARIANT) {
- if (action == ATOM_TRANSMITTER_ACTION_INIT) {
- disp_data.v3.usInitInfo = radeon_output->connector_object_id;
- } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
- disp_data.v3.asMode.ucLaneSel = lane_num;
- disp_data.v3.asMode.ucLaneSet = lane_set;
- } else {
- if (radeon_output->MonType == MT_DP) {
- disp_data.v3.usPixelClock =
- cpu_to_le16(dp_link_clock_for_mode_clock(radeon_output, clock));
- } else if (clock > 165000) {
- disp_data.v3.usPixelClock = cpu_to_le16((clock / 2) / 10);
- disp_data.v3.acConfig.fDualLinkConnector = 1;
- } else {
- disp_data.v3.usPixelClock = cpu_to_le16(clock / 10);
- }
- }
-
if (radeon_output->MonType == MT_DP)
disp_data.v3.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
else if (clock > 165000)
@@ -790,25 +754,10 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
else if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
if (radeon_output->coherent_mode)
disp_data.v3.acConfig.fCoherentMode = 1;
+ if (clock > 165000)
+ disp_data.v3.acConfig.fDualLinkConnector = 1;
}
} else if (IS_DCE32_VARIANT) {
- if (action == ATOM_TRANSMITTER_ACTION_INIT) {
- disp_data.v2.usInitInfo = radeon_output->connector_object_id;
- } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
- disp_data.v2.asMode.ucLaneSel = lane_num;
- disp_data.v2.asMode.ucLaneSet = lane_set;
- } else {
- if (radeon_output->MonType == MT_DP) {
- disp_data.v2.usPixelClock =
- cpu_to_le16(dp_link_clock_for_mode_clock(radeon_output, clock));
- disp_data.v2.acConfig.fDPConnector = 1;
- } else if (clock > 165000) {
- disp_data.v2.usPixelClock = cpu_to_le16((clock / 2) / 10);
- disp_data.v2.acConfig.fDualLinkConnector = 1;
- } else {
- disp_data.v2.usPixelClock = cpu_to_le16(clock / 10);
- }
- }
if (radeon_output->dig_encoder)
disp_data.v2.acConfig.ucEncoderSel = 1;
@@ -839,21 +788,6 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
} else {
disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
- if (action == ATOM_TRANSMITTER_ACTION_INIT) {
- disp_data.v1.usInitInfo = radeon_output->connector_object_id;
- } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
- disp_data.v1.asMode.ucLaneSel = lane_num;
- disp_data.v1.asMode.ucLaneSet = lane_set;
- } else {
- if (radeon_output->MonType == MT_DP)
- disp_data.v1.usPixelClock =
- cpu_to_le16(dp_link_clock_for_mode_clock(radeon_output, clock));
- else if (clock > 165000)
- disp_data.v1.usPixelClock = cpu_to_le16((clock / 2) / 10);
- else
- disp_data.v1.usPixelClock = cpu_to_le16(clock / 10);
- }
-
if (radeon_output->dig_encoder)
disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
else
@@ -880,8 +814,6 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
}
break;
}
- if (clock > 165000)
- disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
if (radeon_output->linkb)
disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
else
@@ -892,6 +824,8 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
else if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
if (radeon_output->coherent_mode)
disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+ if (clock > 165000)
+ disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
}
}
@@ -1415,13 +1349,14 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
case DPMSModeOn:
radeon_encoder->devices |= radeon_output->active_device;
if (is_dig) {
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ if (!IS_DCE4_VARIANT)
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
if (((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) ||
(radeon_output->ConnectorType == CONNECTOR_EDP)) &&
(radeon_output->MonType == MT_DP)) {
do_displayport_link_train(output);
if (IS_DCE4_VARIANT)
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_ON);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_ON);
}
}
else {
@@ -1447,13 +1382,14 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
radeon_encoder->devices &= ~(radeon_output->active_device);
if (!radeon_encoder->devices) {
if (is_dig) {
+ if (!IS_DCE4_VARIANT)
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
if (((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) ||
(radeon_output->ConnectorType == CONNECTOR_EDP)) &&
(radeon_output->MonType == MT_DP)) {
if (IS_DCE4_VARIANT)
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
}
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
} else {
disp_data.ucAction = ATOM_DISABLE;
data.exec.index = index;
@@ -1777,17 +1713,20 @@ atombios_output_mode_set(xf86OutputPtr output,
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* disable encoder and transmitter */
/* setup and enable the encoder and transmitter */
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
- if (IS_DCE4_VARIANT)
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_SETUP);
- else {
+ if (IS_DCE4_VARIANT) {
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_SETUP);
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ } else {
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
atombios_output_dig_encoder_setup(output, ATOM_DISABLE);
atombios_output_dig_encoder_setup(output, ATOM_ENABLE);
+
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+ atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
}
- atombios_output_dig_encoder_setup(output, ATOM_ENABLE);
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
- atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
atombios_output_ddia_setup(output, ATOM_ENABLE);
@@ -2683,8 +2622,8 @@ static void do_displayport_link_train(xf86OutputPtr output)
/* start local training start */
if (IS_DCE4_VARIANT) {
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
} else {
RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_START, enc_id, 0);
RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, enc_id, 0);
@@ -2744,7 +2683,7 @@ static void do_displayport_link_train(xf86OutputPtr output)
channel_eq = FALSE;
dp_set_training(output, DP_TRAINING_PATTERN_2);
if (IS_DCE4_VARIANT)
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
else
RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, enc_id, 1);
@@ -2778,7 +2717,7 @@ static void do_displayport_link_train(xf86OutputPtr output)
dp_set_training(output, DP_TRAINING_PATTERN_DISABLE);
if (IS_DCE4_VARIANT)
- atombios_dce4_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
+ atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
else
RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_COMPLETE, enc_id, 0);
More information about the xorg-commit
mailing list