Move hpd polling check into wait_hpd_asserted() callback. For the cases that aux transfer function wasn't used, do hpd polling check after pm runtime resume, which will power on the bridge. Signed-off-by: Hsin-Yi Wang <hsinyi@xxxxxxxxxxxx> Reviewed-by: Xin Ji <xji@xxxxxxxxxxxxxxxx> --- v1->v2: fix indent. --- drivers/gpu/drm/bridge/analogix/anx7625.c | 33 ++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index aded20b9e25b1..d1f1d525aeb6d 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1443,23 +1443,24 @@ static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); } -static void anx7625_hpd_polling(struct anx7625_data *ctx) +static int _anx7625_hpd_polling(struct anx7625_data *ctx, + unsigned long wait_us) { int ret, val; struct device *dev = &ctx->client->dev; /* Interrupt mode, no need poll HPD status, just return */ if (ctx->pdata.intp_irq) - return; + return 0; ret = readx_poll_timeout(anx7625_read_hpd_status_p0, ctx, val, ((val & HPD_STATUS) || (val < 0)), - 5000, - 5000 * 100); + wait_us / 100, + wait_us); if (ret) { DRM_DEV_ERROR(dev, "no hpd.\n"); - return; + return ret; } DRM_DEV_DEBUG_DRIVER(dev, "system status: 0x%x. HPD raise up.\n", val); @@ -1472,6 +1473,23 @@ static void anx7625_hpd_polling(struct anx7625_data *ctx) if (!ctx->pdata.panel_bridge && ctx->bridge_attached) drm_helper_hpd_irq_event(ctx->bridge.dev); + + return 0; +} + +static int anx7625_wait_hpd_asserted(struct drm_dp_aux *aux, + unsigned long wait_us) +{ + struct anx7625_data *ctx = container_of(aux, struct anx7625_data, aux); + struct device *dev = &ctx->client->dev; + int ret; + + pm_runtime_get_sync(dev); + ret = _anx7625_hpd_polling(ctx, wait_us); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; } static void anx7625_remove_edid(struct anx7625_data *ctx) @@ -1741,6 +1759,7 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx) } pm_runtime_get_sync(dev); + _anx7625_hpd_polling(ctx, 5000 * 100); edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data); pm_runtime_put_sync(dev); @@ -2378,6 +2397,7 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, ctx->connector = connector; pm_runtime_get_sync(dev); + _anx7625_hpd_polling(ctx, 5000 * 100); anx7625_dp_start(ctx); } @@ -2497,7 +2517,6 @@ static int __maybe_unused anx7625_runtime_pm_resume(struct device *dev) mutex_lock(&ctx->lock); anx7625_power_on_init(ctx); - anx7625_hpd_polling(ctx); mutex_unlock(&ctx->lock); @@ -2589,6 +2608,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, platform->aux.name = "anx7625-aux"; platform->aux.dev = dev; platform->aux.transfer = anx7625_aux_transfer; + platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted; drm_dp_aux_init(&platform->aux); if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { @@ -2617,6 +2637,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, if (!platform->pdata.low_power_mode) { anx7625_disable_pd_protocol(platform); pm_runtime_get_sync(dev); + _anx7625_hpd_polling(platform, 5000 * 100); } /* Add work function */ -- 2.37.0.rc0.161.g10f37bed90-goog