Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/atombios_dp.c | 8 ++++---- drivers/gpu/drm/radeon/radeon_mode.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 3e3290c..ed173d3 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -253,7 +253,7 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector) #define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_LEVEL_3 #define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPH_LEVEL_3
-static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], +static void dp_get_adjust_train(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count, u8 train_set[4]) { @@ -311,7 +311,7 @@ static int dp_get_max_dp_pix_clock(int link_rate, /***** radeon specific DP functions *****/
int radeon_dp_get_max_link_rate(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE]) + const u8 dpcd[DP_DPCD_SIZE]) { int max_link_rate;
@@ -328,7 +328,7 @@ int radeon_dp_get_max_link_rate(struct drm_connector *connector, * if the max lane# < low rate lane# then use max lane# instead. */ static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], + const u8 dpcd[DP_DPCD_SIZE], int pix_clock) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); @@ -347,7 +347,7 @@ static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, }
static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], + const u8 dpcd[DP_DPCD_SIZE], int pix_clock) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index fa91a17..6de5459 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -754,7 +754,7 @@ extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_connector *connector); int radeon_dp_get_max_link_rate(struct drm_connector *connector, - u8 *dpcd); + const u8 *dpcd); extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, u8 power_state); extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector);
Retry the dpcd fetch several times. Some eDP panels fail several times before the fetch is successful.
bug: https://bugs.freedesktop.org/show_bug.cgi?id=73530
Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/atombios_dp.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index ed173d3..f81e0d7 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -421,19 +421,21 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) { struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; u8 msg[DP_DPCD_SIZE]; - int ret; + int ret, i;
- ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, - DP_DPCD_SIZE); - if (ret > 0) { - memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); + for (i = 0; i < 7; i++) { + ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, + DP_DPCD_SIZE); + if (ret == DP_DPCD_SIZE) { + memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
- DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), - dig_connector->dpcd); + DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), + dig_connector->dpcd);
- radeon_dp_probe_oui(radeon_connector); + radeon_dp_probe_oui(radeon_connector);
- return true; + return true; + } } dig_connector->dpcd[0] = 0; return false;
Since we are messing with state in the worker.
Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 7162c93..5b12c3f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -79,10 +79,12 @@ static void radeon_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector;
+ mutex_lock(&mode_config->mutex); if (mode_config->num_connector) { list_for_each_entry(connector, &mode_config->connector_list, head) radeon_connector_hotplug(connector); } + mutex_unlock(&mode_config->mutex); /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); } @@ -96,10 +98,12 @@ static void radeon_dp_work_func(struct work_struct *work) struct drm_connector *connector;
/* this should take a mutex */ + mutex_lock(&mode_config->mutex); if (mode_config->num_connector) { list_for_each_entry(connector, &mode_config->connector_list, head) radeon_connector_hotplug(connector); } + mutex_unlock(&mode_config->mutex); } /** * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
On 19.05.2015 01:24, Alex Deucher wrote:
@@ -96,10 +98,12 @@ static void radeon_dp_work_func(struct work_struct *work) struct drm_connector *connector;
/* this should take a mutex */
- mutex_lock(&mode_config->mutex);
This comment can be removed?
On 19 May 2015 at 12:27, Michel Dänzer michel@daenzer.net wrote:
On 19.05.2015 01:24, Alex Deucher wrote:
@@ -96,10 +98,12 @@ static void radeon_dp_work_func(struct work_struct *work) struct drm_connector *connector;
/* this should take a mutex */
mutex_lock(&mode_config->mutex);
This comment can be removed?
I have vague memories of not doing this, because bad things happened.
so keep an eye out for lockdep traces.
Dave.
On Mon, May 18, 2015 at 11:24 PM, Dave Airlie airlied@gmail.com wrote:
On 19 May 2015 at 12:27, Michel Dänzer michel@daenzer.net wrote:
On 19.05.2015 01:24, Alex Deucher wrote:
@@ -96,10 +98,12 @@ static void radeon_dp_work_func(struct work_struct *work) struct drm_connector *connector;
/* this should take a mutex */
mutex_lock(&mode_config->mutex);
This comment can be removed?
I have vague memories of not doing this, because bad things happened.
so keep an eye out for lockdep traces.
I tested the non-MST handling pretty extensively, but I admit I didn't play with mst. Might be better to split this into two patches.
Alex
On Mon, May 18, 2015 at 11:28:47PM -0400, Alex Deucher wrote:
On Mon, May 18, 2015 at 11:24 PM, Dave Airlie airlied@gmail.com wrote:
On 19 May 2015 at 12:27, Michel Dänzer michel@daenzer.net wrote:
On 19.05.2015 01:24, Alex Deucher wrote:
@@ -96,10 +98,12 @@ static void radeon_dp_work_func(struct work_struct *work) struct drm_connector *connector;
/* this should take a mutex */
mutex_lock(&mode_config->mutex);
This comment can be removed?
I have vague memories of not doing this, because bad things happened.
so keep an eye out for lockdep traces.
I tested the non-MST handling pretty extensively, but I admit I didn't play with mst. Might be better to split this into two patches.
Registering a new connector also needs the dev->mode_config.mutex. If you hold that while calling into mst hpd code you'll deadlock. -Daniel
Need to handle DVI where we way end up with an analog encoder in some cases.
Reported-by: Julian Margetson runaway@candw.ms Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_audio.c | 18 ++++++++++-------- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index dcb7796..31b60f6 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -453,22 +453,24 @@ void radeon_audio_enable(struct radeon_device *rdev, void radeon_audio_detect(struct drm_connector *connector, enum drm_connector_status status) { - struct radeon_device *rdev; - struct radeon_encoder *radeon_encoder; + struct drm_device *dev = connector->dev; + struct radeon_device *rdev = dev->dev_private; struct radeon_encoder_atom_dig *dig; + const struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + struct drm_encoder *encoder = connector_funcs->best_encoder(connector); + struct radeon_encoder *radeon_encoder;
- if (!connector || !connector->encoder) + if (!connector || !encoder) return;
- if (!radeon_encoder_is_digital(connector->encoder)) + if (!radeon_encoder_is_digital(encoder)) return;
- rdev = connector->encoder->dev->dev_private; - if (!radeon_audio_chipset_supported(rdev)) return;
- radeon_encoder = to_radeon_encoder(connector->encoder); + radeon_encoder = to_radeon_encoder(encoder); dig = radeon_encoder->enc_priv;
if (!dig->afmt) @@ -484,7 +486,7 @@ void radeon_audio_detect(struct drm_connector *connector, else radeon_encoder->audio = rdev->audio.hdmi_funcs;
- dig->afmt->pin = radeon_audio_get_pin(connector->encoder); + dig->afmt->pin = radeon_audio_get_pin(encoder); if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } else { diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index d17d251..c251eac 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1379,7 +1379,7 @@ out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret);
- if (radeon_audio != 0) { + if ((radeon_audio != 0) && (radeon_connector->use_digital)) { radeon_connector_get_edid(connector); radeon_audio_detect(connector, ret); }
- make it static - fix mask/bool handling for last param
Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vgter.kernel.org --- drivers/gpu/drm/radeon/radeon_audio.c | 18 +++++++++--------- drivers/gpu/drm/radeon/radeon_audio.h | 2 -- 2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 31b60f6..9e9f6a1 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -242,6 +242,13 @@ static struct radeon_audio_funcs dce6_dp_funcs = { .dpms = evergreen_dp_enable, };
+static void radeon_audio_enable(struct radeon_device *rdev, + struct r600_audio_pin *pin, u8 enable_mask) +{ + if (rdev->audio.funcs->enable) + rdev->audio.funcs->enable(rdev, pin, enable_mask); +} + static void radeon_audio_interface_init(struct radeon_device *rdev) { if (ASIC_IS_DCE6(rdev)) { @@ -307,7 +314,7 @@ int radeon_audio_init(struct radeon_device *rdev)
/* disable audio. it will be set up later */ for (i = 0; i < rdev->audio.num_pins; i++) - radeon_audio_enable(rdev, &rdev->audio.pin[i], false); + radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
return 0; } @@ -443,13 +450,6 @@ static void radeon_audio_select_pin(struct drm_encoder *encoder) radeon_encoder->audio->select_pin(encoder); }
-void radeon_audio_enable(struct radeon_device *rdev, - struct r600_audio_pin *pin, u8 enable_mask) -{ - if (rdev->audio.funcs->enable) - rdev->audio.funcs->enable(rdev, pin, enable_mask); -} - void radeon_audio_detect(struct drm_connector *connector, enum drm_connector_status status) { @@ -507,7 +507,7 @@ void radeon_audio_fini(struct radeon_device *rdev) return;
for (i = 0; i < rdev->audio.num_pins; i++) - radeon_audio_enable(rdev, &rdev->audio.pin[i], false); + radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
rdev->audio.enabled = false; } diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index c92d059..8438304 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h @@ -74,8 +74,6 @@ u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, u32 reg, u32 v); struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); -void radeon_audio_enable(struct radeon_device *rdev, - struct r600_audio_pin *pin, u8 enable_mask); void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode);
dri-devel@lists.freedesktop.org