mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
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 <wenping.zhang@rock-chips.com>
This commit is contained in:
committed by
Huang, Tao
parent
bd94271915
commit
3277fb894f
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user