提交 8666c076 编写于 作者: A Alex Deucher

drm/radeon: add a connector property for audio

This provides a connector property to enable/disable hdmi
audio on the fly.  The default is disabled, but you can select
auto (let the driver detect an audio capable monitor and enable it)
or enabled (force audio enabled).  This also enables audio by
default so you no longer need a module parameter to enable audio.
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 7cc0a3d8
...@@ -707,8 +707,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -707,8 +707,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) { switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
if (drm_detect_hdmi_monitor(radeon_connector->edid) && if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
radeon_audio) (drm_detect_hdmi_monitor(radeon_connector->edid) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO)))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital) else if (radeon_connector->use_digital)
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
...@@ -718,8 +719,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -718,8 +719,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA: case DRM_MODE_CONNECTOR_HDMIA:
default: default:
if (drm_detect_hdmi_monitor(radeon_connector->edid) && if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
radeon_audio) (drm_detect_hdmi_monitor(radeon_connector->edid) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO)))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else else
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
...@@ -732,8 +734,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -732,8 +734,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP; return ATOM_ENCODER_MODE_DP;
else if (drm_detect_hdmi_monitor(radeon_connector->edid) && else if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
radeon_audio) (drm_detect_hdmi_monitor(radeon_connector->edid) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO)))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else else
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
......
...@@ -396,6 +396,21 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct ...@@ -396,6 +396,21 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
} }
} }
if (property == rdev->mode_info.audio_property) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
/* need to find digital encoder on connector */
encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
if (!encoder)
return 0;
radeon_encoder = to_radeon_encoder(encoder);
if (radeon_connector->audio != val) {
radeon_connector->audio = val;
radeon_property_change_mode(&radeon_encoder->base);
}
}
if (property == rdev->mode_info.underscan_property) { if (property == rdev->mode_info.underscan_property) {
/* need to find digital encoder on connector */ /* need to find digital encoder on connector */
encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
...@@ -1619,6 +1634,9 @@ radeon_add_atom_connector(struct drm_device *dev, ...@@ -1619,6 +1634,9 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
subpixel_order = SubPixelHorizontalRGB; subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true; connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB) if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
...@@ -1708,6 +1726,11 @@ radeon_add_atom_connector(struct drm_device *dev, ...@@ -1708,6 +1726,11 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
if (connector_type == DRM_MODE_CONNECTOR_DVII) { if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true; radeon_connector->dac_load_detect = true;
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
...@@ -1748,6 +1771,11 @@ radeon_add_atom_connector(struct drm_device *dev, ...@@ -1748,6 +1771,11 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
subpixel_order = SubPixelHorizontalRGB; subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true; connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB) if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
...@@ -1787,6 +1815,11 @@ radeon_add_atom_connector(struct drm_device *dev, ...@@ -1787,6 +1815,11 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
connector->interlace_allowed = true; connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */ /* in theory with a DP to VGA converter... */
connector->doublescan_allowed = false; connector->doublescan_allowed = false;
......
...@@ -1172,6 +1172,12 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] = ...@@ -1172,6 +1172,12 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] =
{ UNDERSCAN_AUTO, "auto" }, { UNDERSCAN_AUTO, "auto" },
}; };
static struct drm_prop_enum_list radeon_audio_enum_list[] =
{ { RADEON_AUDIO_DISABLE, "off" },
{ RADEON_AUDIO_ENABLE, "on" },
{ RADEON_AUDIO_AUTO, "auto" },
};
static int radeon_modeset_create_props(struct radeon_device *rdev) static int radeon_modeset_create_props(struct radeon_device *rdev)
{ {
int sz; int sz;
...@@ -1222,6 +1228,12 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) ...@@ -1222,6 +1228,12 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
if (!rdev->mode_info.underscan_vborder_property) if (!rdev->mode_info.underscan_vborder_property)
return -ENOMEM; return -ENOMEM;
sz = ARRAY_SIZE(radeon_audio_enum_list);
rdev->mode_info.audio_property =
drm_property_create_enum(rdev->ddev, 0,
"audio",
radeon_audio_enum_list, sz);
return 0; return 0;
} }
......
...@@ -153,7 +153,7 @@ int radeon_benchmarking = 0; ...@@ -153,7 +153,7 @@ int radeon_benchmarking = 0;
int radeon_testing = 0; int radeon_testing = 0;
int radeon_connector_table = 0; int radeon_connector_table = 0;
int radeon_tv = 1; int radeon_tv = 1;
int radeon_audio = 0; int radeon_audio = 1;
int radeon_disp_priority = 0; int radeon_disp_priority = 0;
int radeon_hw_i2c = 0; int radeon_hw_i2c = 0;
int radeon_pcie_gen2 = -1; int radeon_pcie_gen2 = -1;
......
...@@ -247,6 +247,8 @@ struct radeon_mode_info { ...@@ -247,6 +247,8 @@ struct radeon_mode_info {
struct drm_property *underscan_property; struct drm_property *underscan_property;
struct drm_property *underscan_hborder_property; struct drm_property *underscan_hborder_property;
struct drm_property *underscan_vborder_property; struct drm_property *underscan_vborder_property;
/* audio */
struct drm_property *audio_property;
/* hardcoded DFP edid from BIOS */ /* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid; struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size; int bios_hardcoded_edid_size;
...@@ -471,6 +473,12 @@ struct radeon_router { ...@@ -471,6 +473,12 @@ struct radeon_router {
u8 cd_mux_state; u8 cd_mux_state;
}; };
enum radeon_connector_audio {
RADEON_AUDIO_DISABLE = 0,
RADEON_AUDIO_ENABLE = 1,
RADEON_AUDIO_AUTO = 2
};
struct radeon_connector { struct radeon_connector {
struct drm_connector base; struct drm_connector base;
uint32_t connector_id; uint32_t connector_id;
...@@ -489,6 +497,7 @@ struct radeon_connector { ...@@ -489,6 +497,7 @@ struct radeon_connector {
struct radeon_hpd hpd; struct radeon_hpd hpd;
struct radeon_router router; struct radeon_router router;
struct radeon_i2c_chan *router_bus; struct radeon_i2c_chan *router_bus;
enum radeon_connector_audio audio;
}; };
struct radeon_framebuffer { struct radeon_framebuffer {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册