radeon legacy chips: tv dac bg/dac adj updates

COMBIOS - fallback to table values if there are no tv dac or lvds bios tables
ATOMBIOS - add support for looking up these values from the bios table

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 98904de..786632d 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -824,6 +824,78 @@
 	return lvds;
 }
 
+struct radeon_encoder_primary_dac *
+radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, CompassionateData);
+	uint16_t data_offset;
+	struct _COMPASSIONATE_DATA *dac_info;
+	uint8_t frev, crev;
+	uint8_t bg, dac;
+	int i;
+	struct radeon_encoder_primary_dac *p_dac = NULL;
+
+	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+
+	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+
+	if (dac_info) {
+		p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
+
+		if (!p_dac)
+			return NULL;
+
+		bg = dac_info->ucDAC1_BG_Adjustment;
+		dac = dac_info->ucDAC1_DAC_Adjustment;
+		p_dac->ps2_pdac_adj = (bg << 8) | (dac);
+
+	}
+	return p_dac;
+}
+
+struct radeon_encoder_tv_dac *
+radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, CompassionateData);
+	uint16_t data_offset;
+	struct _COMPASSIONATE_DATA *dac_info;
+	uint8_t frev, crev;
+	uint8_t bg, dac;
+	int i;
+	struct radeon_encoder_tv_dac *tv_dac = NULL;
+
+	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+
+	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+
+	if (dac_info) {
+		tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
+
+		if (!tv_dac)
+			return NULL;
+
+		bg = dac_info->ucDAC2_CRT2_BG_Adjustment;
+		dac = dac_info->ucDAC2_CRT2_DAC_Adjustment;
+		tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = dac_info->ucDAC2_PAL_BG_Adjustment;
+		dac = dac_info->ucDAC2_PAL_DAC_Adjustment;
+		tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = dac_info->ucDAC2_NTSC_BG_Adjustment;
+		dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;
+		tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+
+	}
+	return tv_dac;
+}
+
 void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
 {
 	DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index be52198..06e8038 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -783,6 +783,9 @@
 				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
 				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
 			}
+		} else {
+			DRM_INFO("No TV DAC info found in BIOS\n");
+			return radeon_legacy_get_tv_dac_info_from_table(rdev);
 		}
 	}
 
@@ -964,8 +967,10 @@
 			}
 		}
 		encoder->native_mode = lvds->native_mode;
-	} else
+	} else {
 		DRM_INFO("No panel info found in BIOS\n");
+		return radeon_legacy_get_lvds_info_from_regs(rdev);
+	}
 	return lvds;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index c41ab09..2c2f42d 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -1265,13 +1265,17 @@
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 		drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
 		drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs);
-		if (!rdev->is_atom_bios)
+		if (rdev->is_atom_bios)
+			radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder);
+		else
 			radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 		drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC);
 		drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
-		if (!rdev->is_atom_bios)
+		if (rdev->is_atom_bios)
+			radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder);
+		else
 			radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 4b37746..9173b68 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -329,6 +329,10 @@
 radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_int_tmds *
 radeon_atombios_get_tmds_info(struct radeon_encoder *encoder);
+extern struct radeon_encoder_primary_dac *
+radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
+extern struct radeon_encoder_tv_dac *
+radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_lvds *
 radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_int_tmds *