radeon: pull in recent fixes from ddx
- fixup atom digital encoder setup - pull in add get edid (currently disabled due to lack of support for atom fb/scratch space)main
parent
4d1031a9f0
commit
e4fa03f7dd
|
@ -72,11 +72,66 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
|
|||
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.hw_line = gpio.sucI2cId.sbfAccess.bfI2C_LineMux;
|
||||
i2c.hw_capable = gpio.sucI2cId.sbfAccess.bfHW_Capable;
|
||||
i2c.valid = true;
|
||||
|
||||
return i2c;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO fix atom FB/scratch space access
|
||||
struct edid *radeon_atom_get_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_radeon_private *dev_priv = radeon_connector->base.dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION edid_param;
|
||||
int i2c_clock = 50;
|
||||
int prescale;
|
||||
unsigned char *raw_edid;
|
||||
struct edid *edid = NULL;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, ReadEDIDFromHWAssistedI2C);
|
||||
|
||||
if (!radeon_connector->ddc_bus)
|
||||
return edid;
|
||||
|
||||
if (!radeon_connector->ddc_bus->rec.hw_capable)
|
||||
return edid;
|
||||
|
||||
if (info->atomBIOS->fbBase)
|
||||
raw_edid = (unsigned char *)info->FB + info->atomBIOS->fbBase;
|
||||
else if (info->atomBIOS->scratchBase)
|
||||
raw_edid = (unsigned char *)info->atomBIOS->scratchBase;
|
||||
else
|
||||
return edid;
|
||||
|
||||
memset(raw_edid, 0, ATOM_EDID_RAW_DATASIZE);
|
||||
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520)
|
||||
prescale = (127 << 8) + (mode_info->sclk * 10) / (4 * 127 * i2c_clock);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600)
|
||||
prescale = (((mode_info->sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
|
||||
else
|
||||
prescale = (mode_info->spll.reference_freq * 10) / i2c_clock;
|
||||
|
||||
edid_param.usPrescale = prescale;
|
||||
edid_param.usVRAMAddress = 0;
|
||||
edid_param.ucSlaveAddr = 0xa0;
|
||||
edid_param.ucLineNumber = radeon_connector->ddc_bus->rec.hw_line;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&edid_param);
|
||||
|
||||
if (raw_edid[1] == 0xff) {
|
||||
edid = kmalloc(size_of(struct edid), GFP_KERNEL);
|
||||
*edid = raw_edid;
|
||||
}
|
||||
|
||||
return edid;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct radeon_i2c_bus_rec radeon_parse_i2c_record(struct drm_device *dev, ATOM_I2C_RECORD *record)
|
||||
{
|
||||
return radeon_lookup_gpio(dev, record->sucI2cId.bfI2C_LineMux);
|
||||
|
@ -591,6 +646,8 @@ void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder)
|
|||
encoder->voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
|
||||
encoder->vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
|
||||
encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs);
|
||||
encoder->lvds_misc = lvds_info->info.ucLVDS_Misc;
|
||||
encoder->lvds_ss_id = lvds_info->info.ucSS_Id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -385,6 +385,8 @@ struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
|
|||
{
|
||||
struct radeon_i2c_bus_rec i2c;
|
||||
|
||||
i2c.hw_line = 0;
|
||||
i2c.hw_capable = false; // actually depends on chip
|
||||
i2c.mask_clk_mask = RADEON_GPIO_EN_1;
|
||||
i2c.mask_data_mask = RADEON_GPIO_EN_0;
|
||||
i2c.a_clk_mask = RADEON_GPIO_A_1;
|
||||
|
|
|
@ -228,58 +228,105 @@ void atombios_set_crtc_source(struct drm_encoder *encoder, int source)
|
|||
|
||||
}
|
||||
|
||||
static void radeon_dfp_disable_dither(struct drm_encoder *encoder, int device)
|
||||
static void atombios_output_digital_mode_set(struct drm_encoder *encoder,
|
||||
int device,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (!radeon_is_avivo(dev_priv))
|
||||
return;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct drm_radeon_private *dev_priv = encoder->dev->dev_private;
|
||||
uint8_t frev, crev;
|
||||
int index;
|
||||
LVDS_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 args2;
|
||||
uint32_t *param = NULL;
|
||||
|
||||
switch (device) {
|
||||
case ATOM_DEVICE_DFP1_INDEX:
|
||||
RADEON_WRITE(AVIVO_TMDSA_BIT_DEPTH_CONTROL, 0); /* TMDSA */
|
||||
index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
|
||||
break;
|
||||
case ATOM_DEVICE_DFP2_INDEX:
|
||||
if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
(dev_priv->chip_family == CHIP_RS740))
|
||||
RADEON_WRITE(AVIVO_DDIA_BIT_DEPTH_CONTROL, 0); /* DDIA */
|
||||
else
|
||||
RADEON_WRITE(AVIVO_DVOA_BIT_DEPTH_CONTROL, 0); /* DVO */
|
||||
case ATOM_DEVICE_LCD1_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
|
||||
break;
|
||||
/*case ATOM_DEVICE_LCD1_INDEX:*/ /* LVDS panels need dither enabled */
|
||||
case ATOM_DEVICE_DFP3_INDEX:
|
||||
RADEON_WRITE(AVIVO_LVTMA_BIT_DEPTH_CONTROL, 0); /* LVTMA */
|
||||
index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev);
|
||||
|
||||
switch (frev) {
|
||||
case 0:
|
||||
case 1:
|
||||
switch (crev) {
|
||||
case 0:
|
||||
case 1:
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = PANEL_ENCODER_ACTION_ENABLE;
|
||||
// TODO HDMI
|
||||
//if (radeon_encoder->type == OUTPUT_HDMI)
|
||||
//disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
if (device == ATOM_DEVICE_LCD1_INDEX) {
|
||||
if (radeon_encoder->lvds_misc & (1 << 0))
|
||||
args.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
if (radeon_encoder->lvds_misc & (1 << 1))
|
||||
args.ucMisc |= (1 << 1);
|
||||
} else {
|
||||
if (mode->clock > 165000)
|
||||
args.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
// TODO 6-bit DAC
|
||||
args.ucMisc |= (1 << 1);
|
||||
}
|
||||
param = (uint32_t *)&args;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
memset(&args2, 0, sizeof(args2));
|
||||
args2.ucAction = PANEL_ENCODER_ACTION_ENABLE;
|
||||
if (crev == 3) {
|
||||
// TODO coherent mode
|
||||
//if (encoder->coherent_mode)
|
||||
//args2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
|
||||
}
|
||||
// TODO HDMI
|
||||
//if (radeon_encoder->type == OUTPUT_HDMI)
|
||||
//args2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
|
||||
if (device == ATOM_DEVICE_LCD1_INDEX) {
|
||||
if (radeon_encoder->lvds_misc & (1 << 0))
|
||||
args2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
if (radeon_encoder->lvds_misc & (1 << 5)) {
|
||||
args2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
|
||||
if (radeon_encoder->lvds_misc & (1 << 1))
|
||||
args2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
|
||||
}
|
||||
if (radeon_encoder->lvds_misc & (1 << 6)) {
|
||||
args2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
|
||||
if (radeon_encoder->lvds_misc & (1 << 1))
|
||||
args2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
|
||||
}
|
||||
} else {
|
||||
if (mode->clock > 165000)
|
||||
args2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
}
|
||||
param = (uint32_t *)&args2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)param);
|
||||
}
|
||||
|
||||
static void radeon_lvtma_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
LVDS_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
atombios_scaler_setup(encoder, mode);
|
||||
atombios_set_crtc_source(encoder, ATOM_DEVICE_LCD1_INDEX);
|
||||
|
||||
args.ucAction = 1;
|
||||
if (adjusted_mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
args.usPixelClock = cpu_to_le16(adjusted_mode->clock / 10);
|
||||
|
||||
printk("executing set LVDS encoder\n");
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
atombios_output_digital_mode_set(encoder, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -287,7 +334,6 @@ static void radeon_lvtma_dpms(struct drm_encoder *encoder, int mode)
|
|||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
|
||||
uint32_t bios_2_scratch, bios_3_scratch;
|
||||
int crtc_id = 0;
|
||||
|
@ -593,7 +639,6 @@ static int atombios_tv1_setup(struct drm_encoder *encoder,
|
|||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TV_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
|
||||
|
||||
|
@ -617,7 +662,6 @@ static void radeon_atom_dac_mode_set(struct drm_encoder *encoder,
|
|||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type = -1;
|
||||
|
||||
|
@ -724,69 +768,22 @@ static const struct drm_encoder_funcs radeon_atom_dac_enc_funcs = {
|
|||
. destroy = radeon_enc_destroy,
|
||||
};
|
||||
|
||||
|
||||
static void atombios_tmds1_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TMDS1_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = 1;
|
||||
if (mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_tmds2_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TMDS2_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = 1;
|
||||
if (mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
|
||||
void atombios_ext_tmds_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.sXTmdsEncoder.ucEnable = 1;
|
||||
args.sXTmdsEncoder.ucEnable = PANEL_ENCODER_ACTION_ENABLE;
|
||||
|
||||
if (mode->clock > 165000)
|
||||
args.sXTmdsEncoder.ucMisc = 1;
|
||||
else
|
||||
args.sXTmdsEncoder.ucMisc = 0;
|
||||
args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
|
||||
|
||||
// TODO 6-bit DAC
|
||||
// args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
args.sXTmdsEncoder.ucMisc |= (1 << 1);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
@ -799,7 +796,8 @@ static void atombios_dig1_setup(struct drm_encoder *encoder,
|
|||
DIG_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
||||
|
||||
args.ucAction = 1;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = ATOM_ENABLE;
|
||||
args.usPixelClock = mode->clock / 10;
|
||||
args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
|
||||
|
||||
|
@ -827,13 +825,12 @@ static void atombios_ddia_setup(struct drm_encoder *encoder,
|
|||
DVO_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
|
||||
|
||||
args.sDVOEncoder.ucAction = ATOM_ENABLE;
|
||||
args.sDVOEncoder.usPixelClock = mode->clock / 10;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.sDVOEncoder.ucAction = PANEL_ENCODER_ACTION_ENABLE;
|
||||
args.sDVOEncoder.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
if (mode->clock > 165000)
|
||||
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
|
||||
else
|
||||
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
@ -846,8 +843,10 @@ struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios
|
|||
struct drm_encoder *encoder;
|
||||
int type = with_tv ? DRM_MODE_ENCODER_TVDAC : DRM_MODE_ENCODER_DAC;
|
||||
int found = 0;
|
||||
int digital_enc_mask = ~(ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT |
|
||||
ATOM_DEVICE_LCD1_SUPPORT);
|
||||
int digital_enc_mask = ~(ATOM_DEVICE_DFP1_SUPPORT |
|
||||
ATOM_DEVICE_DFP2_SUPPORT |
|
||||
ATOM_DEVICE_DFP3_SUPPORT |
|
||||
ATOM_DEVICE_LCD1_SUPPORT);
|
||||
/* we may already have added this encoder */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
|
||||
|
@ -1036,7 +1035,7 @@ static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder,
|
|||
atombios_set_crtc_source(encoder, atom_type);
|
||||
|
||||
if (atom_type == ATOM_DEVICE_DFP1_INDEX)
|
||||
atombios_tmds1_setup(encoder, adjusted_mode);
|
||||
atombios_output_digital_mode_set(encoder, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
|
||||
if (atom_type == ATOM_DEVICE_DFP2_INDEX) {
|
||||
if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
|
@ -1046,10 +1045,7 @@ static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder,
|
|||
atombios_ext_tmds_setup(encoder, adjusted_mode);
|
||||
}
|
||||
if (atom_type == ATOM_DEVICE_DFP3_INDEX)
|
||||
atombios_tmds2_setup(encoder, adjusted_mode);
|
||||
radeon_dfp_disable_dither(encoder, atom_type);
|
||||
|
||||
|
||||
atombios_output_digital_mode_set(encoder, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
|
||||
}
|
||||
|
||||
static void radeon_atom_tmds_prepare(struct drm_encoder *encoder)
|
||||
|
@ -1085,7 +1081,7 @@ struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bio
|
|||
struct drm_encoder *encoder;
|
||||
int analog_enc_mask = ~(ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT);
|
||||
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
if (!radeon_encoder) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ struct radeon_i2c_bus_rec {
|
|||
uint32_t get_data_mask;
|
||||
uint32_t a_clk_mask;
|
||||
uint32_t a_data_mask;
|
||||
int hw_line;
|
||||
bool hw_capable;
|
||||
};
|
||||
|
||||
struct radeon_bios_connector {
|
||||
|
@ -227,6 +229,10 @@ struct radeon_encoder {
|
|||
bool use_bios_dividers;
|
||||
uint32_t lvds_gen_cntl;
|
||||
|
||||
/* atom lvds */
|
||||
int lvds_misc;
|
||||
int lvds_ss_id;
|
||||
|
||||
/* legacy primary dac */
|
||||
uint32_t ps2_pdac_adj;
|
||||
|
||||
|
|
Loading…
Reference in New Issue