From 3277fb894f93e826f05a5f092c4faa4b7fab97bb Mon Sep 17 00:00:00 2001 From: "wenping.zhang" Date: Thu, 22 Dec 2016 09:44:55 +0800 Subject: [PATCH] video: rockchip: dp: fix dp fw load error. Do dptx/apb/core reset on every dp clock enabling, otherwise dp will fail to load the firmware sometimes. Change-Id: Ied0caad99d865ec86162dead2b4769a53f8db12a Signed-off-by: wenping.zhang --- drivers/video/rockchip/dp/cdn-dp-reg.h | 1 + drivers/video/rockchip/dp/rockchip_dp_core.c | 66 ++++++++++---------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/video/rockchip/dp/cdn-dp-reg.h b/drivers/video/rockchip/dp/cdn-dp-reg.h index 29a45714e50b..83419bcbf338 100644 --- a/drivers/video/rockchip/dp/cdn-dp-reg.h +++ b/drivers/video/rockchip/dp/cdn-dp-reg.h @@ -536,6 +536,7 @@ struct cdn_dp_device { struct reset_control *spdif_rst; struct reset_control *dptx_rst; struct reset_control *apb_rst; + struct reset_control *core_rst; struct audio_info audio_info; struct video_info video_info; struct drm_dp_link link; diff --git a/drivers/video/rockchip/dp/rockchip_dp_core.c b/drivers/video/rockchip/dp/rockchip_dp_core.c index 9bfd2fc8d4b7..985b21e0fa30 100644 --- a/drivers/video/rockchip/dp/rockchip_dp_core.c +++ b/drivers/video/rockchip/dp/rockchip_dp_core.c @@ -103,6 +103,14 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp) return ret; } + reset_control_assert(dp->apb_rst); + reset_control_assert(dp->core_rst); + reset_control_assert(dp->dptx_rst); + udelay(1); + reset_control_deassert(dp->dptx_rst); + reset_control_deassert(dp->core_rst); + reset_control_deassert(dp->apb_rst); + ret = cdn_dp_set_fw_rate(dp); if (ret < 0) { dev_err(dp->dev, "cannot get set fw rate %d\n", ret); @@ -402,18 +410,17 @@ static int cdn_dp_init(struct cdn_dp_device *dp) return PTR_ERR(dp->apb_rst); } + dp->core_rst = devm_reset_control_get(dev, "core"); + if (IS_ERR(dp->core_rst)) { + DRM_DEV_ERROR(dev, "no core reset control found\n"); + return PTR_ERR(dp->core_rst); + } + dp->dpms_mode = DRM_MODE_DPMS_OFF; dp->fw_clk_enabled = false; pm_runtime_enable(dev); - reset_control_assert(dp->dptx_rst); - udelay(15); - reset_control_deassert(dp->dptx_rst); - reset_control_assert(dp->apb_rst); - udelay(15); - reset_control_deassert(dp->apb_rst); - mutex_init(&dp->lock); wake_lock_init(&dp->wake_lock, WAKE_LOCK_SUSPEND, "cdn_dp_fb"); return 0; @@ -578,10 +585,12 @@ static void cdn_dp_enter_standy(struct cdn_dp_device *dp, { int i, ret; - ret = phy_power_off(port->phy); - if (ret) { - dev_err(dp->dev, "phy power off failed: %d", ret); - return; + if (port->phy_status) { + ret = phy_power_off(port->phy); + if (ret) { + dev_err(dp->dev, "phy power off failed: %d", ret); + return; + } } port->phy_status = false; @@ -591,9 +600,12 @@ static void cdn_dp_enter_standy(struct cdn_dp_device *dp, return; memset(dp->dpcd, 0, DP_RECEIVER_CAP_SIZE); - if (dp->fw_loaded) + if (dp->fw_actived) cdn_dp_set_firmware_active(dp, false); - cdn_dp_clk_disable(dp); + if (dp->fw_clk_enabled) { + cdn_dp_clk_disable(dp); + dp->fw_clk_enabled = false; + } dp->hpd_status = connector_status_disconnected; hpd_change(dp->dev, 0); @@ -624,7 +636,8 @@ static int cdn_dp_start_work(struct cdn_dp_device *dp, } return ret; - } + } else + dp->fw_loaded = true; } ret = cdn_dp_clk_enable(dp); @@ -632,8 +645,6 @@ static int cdn_dp_start_work(struct cdn_dp_device *dp, dev_err(dp->dev, "failed to enable clock for dp: %d\n", ret); return ret; } - if (dp->fw_loaded) - cdn_dp_set_firmware_active(dp, true); ret = phy_power_on(port->phy); if (ret) { @@ -643,12 +654,10 @@ static int cdn_dp_start_work(struct cdn_dp_device *dp, port->phy_status = true; - if (!dp->fw_loaded) { - ret = cdn_dp_firmware_init(dp); - if (ret) { - dev_err(dp->dev, "firmware init failed: %d", ret); - goto err_firmware; - } + ret = cdn_dp_firmware_init(dp); + if (ret) { + dev_err(dp->dev, "firmware init failed: %d", ret); + goto err_firmware; } ret = cdn_dp_grf_write(dp, GRF_SOC_CON26, @@ -687,7 +696,8 @@ err_hpd: DPTX_HPD_SEL_MASK | DPTX_HPD_DEL); err_grf: - cdn_dp_set_firmware_active(dp, false); + if (dp->fw_actived) + cdn_dp_set_firmware_active(dp, false); err_firmware: if (phy_power_off(port->phy)) @@ -696,9 +706,8 @@ err_firmware: port->phy_status = false; err_phy: - if (dp->fw_loaded) - cdn_dp_set_firmware_active(dp, false); cdn_dp_clk_disable(dp); + dp->fw_clk_enabled = false; return ret; } @@ -854,13 +863,6 @@ int cdn_dp_resume(void *dp_dev) int i; if (dp->suspend) { dp->suspend = false; - reset_control_assert(dp->dptx_rst); - udelay(15); - reset_control_deassert(dp->dptx_rst); - reset_control_assert(dp->apb_rst); - udelay(15); - reset_control_deassert(dp->apb_rst); - for (i = 0; i < dp->ports; i++) { port = dp->port[i]; schedule_delayed_work(&port->event_wq, 0); -- 2.34.1