Commit 445282db authored by Dave Airlie's avatar Dave Airlie

drm/radeon/kms: add initial connector properties

This adds:
coherent mode: TMDS coherent mode for atom cards.
scaling mode: LVDS scaler mode
load detect: DAC load detection, DVI-I, VGA, TV
tmds pll: legacy TMDS pll selection
tv standard: TV standard selection.

for later: other TV ones? dvi subconnector selection using std prop

[contains fixes pointed out on dri-devel for atom bios mixups
 by Michel]
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent c88f9f0c
...@@ -719,9 +719,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) ...@@ -719,9 +719,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
return false; return false;
} }
struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
radeon_encoder struct radeon_encoder_int_tmds *tmds)
*encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
...@@ -732,7 +731,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct ...@@ -732,7 +731,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
uint8_t frev, crev; uint8_t frev, crev;
uint16_t maxfreq; uint16_t maxfreq;
int i; int i;
struct radeon_encoder_int_tmds *tmds = NULL;
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
&crev, &data_offset); &crev, &data_offset);
...@@ -742,12 +740,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct ...@@ -742,12 +740,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
data_offset); data_offset);
if (tmds_info) { if (tmds_info) {
tmds =
kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
tmds->tmds_pll[i].freq = tmds->tmds_pll[i].freq =
...@@ -773,8 +765,9 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct ...@@ -773,8 +765,9 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
break; break;
} }
} }
return true;
} }
return tmds; return false;
} }
union lvds_info { union lvds_info {
......
...@@ -998,16 +998,12 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = { ...@@ -998,16 +998,12 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */
}; };
static struct radeon_encoder_int_tmds bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
*radeon_legacy_get_tmds_info_from_table(struct radeon_device *rdev) struct radeon_encoder_int_tmds *tmds)
{ {
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
int i; int i;
struct radeon_encoder_int_tmds *tmds = NULL;
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
tmds->tmds_pll[i].value = tmds->tmds_pll[i].value =
...@@ -1015,31 +1011,24 @@ static struct radeon_encoder_int_tmds ...@@ -1015,31 +1011,24 @@ static struct radeon_encoder_int_tmds
tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq; tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
} }
return tmds; return true;
} }
struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
radeon_encoder struct radeon_encoder_int_tmds *tmds)
*encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
uint16_t tmds_info; uint16_t tmds_info;
int i, n; int i, n;
uint8_t ver; uint8_t ver;
struct radeon_encoder_int_tmds *tmds = NULL;
if (rdev->bios == NULL) if (rdev->bios == NULL)
return radeon_legacy_get_tmds_info_from_table(rdev); return false;
tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
if (tmds_info) { if (tmds_info) {
tmds =
kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
ver = RBIOS8(tmds_info); ver = RBIOS8(tmds_info);
DRM_INFO("DFP table revision: %d\n", ver); DRM_INFO("DFP table revision: %d\n", ver);
...@@ -1077,6 +1066,23 @@ struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct ...@@ -1077,6 +1066,23 @@ struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct
} }
} else } else
DRM_INFO("No TMDS info found in BIOS\n"); DRM_INFO("No TMDS info found in BIOS\n");
return true;
}
struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
{
struct radeon_encoder_int_tmds *tmds = NULL;
bool ret;
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
if (ret == false)
radeon_legacy_get_tmds_info_from_table(encoder, tmds);
return tmds; return tmds;
} }
......
This diff is collapsed.
...@@ -623,6 +623,83 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = { ...@@ -623,6 +623,83 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
.fb_changed = radeonfb_probe, .fb_changed = radeonfb_probe,
}; };
struct drm_prop_enum_list {
int type;
char *name;
};
static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
{ { 0, "driver" },
{ 1, "bios" },
};
static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
{ { TV_STD_NTSC, "ntsc" },
{ TV_STD_PAL, "pal" },
{ TV_STD_PAL_M, "pal-m" },
{ TV_STD_PAL_60, "pal-60" },
{ TV_STD_NTSC_J, "ntsc-j" },
{ TV_STD_SCART_PAL, "scart-pal" },
{ TV_STD_PAL_CN, "pal-cn" },
{ TV_STD_SECAM, "secam" },
};
int radeon_modeset_create_props(struct radeon_device *rdev)
{
int i, sz;
if (rdev->is_atom_bios) {
rdev->mode_info.coherent_mode_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"coherent", 2);
if (!rdev->mode_info.coherent_mode_property)
return -ENOMEM;
rdev->mode_info.coherent_mode_property->values[0] = 0;
rdev->mode_info.coherent_mode_property->values[0] = 1;
}
if (!ASIC_IS_AVIVO(rdev)) {
sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
rdev->mode_info.tmds_pll_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_ENUM,
"tmds_pll", sz);
for (i = 0; i < sz; i++) {
drm_property_add_enum(rdev->mode_info.tmds_pll_property,
i,
radeon_tmds_pll_enum_list[i].type,
radeon_tmds_pll_enum_list[i].name);
}
}
rdev->mode_info.load_detect_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"load detection", 2);
if (!rdev->mode_info.load_detect_property)
return -ENOMEM;
rdev->mode_info.load_detect_property->values[0] = 0;
rdev->mode_info.load_detect_property->values[0] = 1;
drm_mode_create_scaling_mode_property(rdev->ddev);
sz = ARRAY_SIZE(radeon_tv_std_enum_list);
rdev->mode_info.tv_std_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_ENUM,
"tv standard", sz);
for (i = 0; i < sz; i++) {
drm_property_add_enum(rdev->mode_info.tv_std_property,
i,
radeon_tv_std_enum_list[i].type,
radeon_tv_std_enum_list[i].name);
}
return 0;
}
int radeon_modeset_init(struct radeon_device *rdev) int radeon_modeset_init(struct radeon_device *rdev)
{ {
int num_crtc = 2, i; int num_crtc = 2, i;
...@@ -643,6 +720,10 @@ int radeon_modeset_init(struct radeon_device *rdev) ...@@ -643,6 +720,10 @@ int radeon_modeset_init(struct radeon_device *rdev)
rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
ret = radeon_modeset_create_props(rdev);
if (ret) {
return ret;
}
/* allocate crtcs - TODO single crtc */ /* allocate crtcs - TODO single crtc */
for (i = 0; i < num_crtc; i++) { for (i = 0; i < num_crtc; i++) {
radeon_crtc_init(rdev->ddev, i); radeon_crtc_init(rdev->ddev, i);
......
...@@ -241,9 +241,12 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) ...@@ -241,9 +241,12 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
DAC_ENCODER_CONTROL_PS_ALLOCATION args; DAC_ENCODER_CONTROL_PS_ALLOCATION args;
int index = 0, num = 0; int index = 0, num = 0;
/* fixme - fill in enc_priv for atom dac */ struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
enum radeon_tv_std tv_std = TV_STD_NTSC; enum radeon_tv_std tv_std = TV_STD_NTSC;
if (dac_info->tv_std)
tv_std = dac_info->tv_std;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
switch (radeon_encoder->encoder_id) { switch (radeon_encoder->encoder_id) {
...@@ -296,9 +299,12 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) ...@@ -296,9 +299,12 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
TV_ENCODER_CONTROL_PS_ALLOCATION args; TV_ENCODER_CONTROL_PS_ALLOCATION args;
int index = 0; int index = 0;
/* fixme - fill in enc_priv for atom dac */ struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
enum radeon_tv_std tv_std = TV_STD_NTSC; enum radeon_tv_std tv_std = TV_STD_NTSC;
if (dac_info->tv_std)
tv_std = dac_info->tv_std;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
......
...@@ -1271,6 +1271,30 @@ static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = { ...@@ -1271,6 +1271,30 @@ static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_enc_destroy,
}; };
static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder_int_tmds *tmds = NULL;
bool ret;
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
if (rdev->is_atom_bios)
ret = radeon_atombios_get_tmds_info(encoder, tmds);
else
ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
if (ret == false)
radeon_legacy_get_tmds_info_from_table(encoder, tmds);
return tmds;
}
void void
radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{ {
...@@ -1317,10 +1341,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t ...@@ -1317,10 +1341,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
case ENCODER_OBJECT_ID_INTERNAL_TMDS1: case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
if (rdev->is_atom_bios) radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder);
radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder);
else
radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1: case ENCODER_OBJECT_ID_INTERNAL_DAC1:
drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
......
...@@ -175,6 +175,15 @@ struct radeon_mode_info { ...@@ -175,6 +175,15 @@ struct radeon_mode_info {
enum radeon_connector_table connector_table; enum radeon_connector_table connector_table;
bool mode_config_initialized; bool mode_config_initialized;
struct radeon_crtc *crtcs[2]; struct radeon_crtc *crtcs[2];
/* DVI-I properties */
struct drm_property *coherent_mode_property;
/* DAC enable load detect */
struct drm_property *load_detect_property;
/* TV standard load detect */
struct drm_property *tv_std_property;
/* legacy TMDS PLL detect */
struct drm_property *tmds_pll_property;
}; };
struct radeon_native_mode { struct radeon_native_mode {
...@@ -304,6 +313,7 @@ struct radeon_connector { ...@@ -304,6 +313,7 @@ struct radeon_connector {
and get modes due to analog/digital/tvencoder */ and get modes due to analog/digital/tvencoder */
struct edid *edid; struct edid *edid;
void *con_priv; void *con_priv;
bool dac_load_detect;
}; };
struct radeon_framebuffer { struct radeon_framebuffer {
...@@ -364,16 +374,18 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev); ...@@ -364,16 +374,18 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
extern bool radeon_combios_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev);
extern struct radeon_encoder_atom_dig * extern struct radeon_encoder_atom_dig *
radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_int_tmds * bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
radeon_atombios_get_tmds_info(struct radeon_encoder *encoder); struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds);
extern struct radeon_encoder_primary_dac * extern struct radeon_encoder_primary_dac *
radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_tv_dac * extern struct radeon_encoder_tv_dac *
radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder); radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_lvds * extern struct radeon_encoder_lvds *
radeon_combios_get_lvds_info(struct radeon_encoder *encoder); radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_int_tmds *
radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder); extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_tv_dac * extern struct radeon_encoder_tv_dac *
radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
......
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