Message ID | 20220629160550.433980-5-hsinyi@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | anx7625: Cleanup, fixes, and implement wait_hpd_asserted | expand |
Hi Hsin-Yi, thanks for your patch, it looks good to me. Reviewed-by: Xin Ji <xji@analogixsemi.com> Thanks, Xin On Thu, Jun 30, 2022 at 12:05:50AM +0800, Hsin-Yi Wang wrote: > 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@chromium.org> > --- > 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 59ddeba33652b..ea5a0b86fe52a 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
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 59ddeba33652b..ea5a0b86fe52a 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 */
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@chromium.org> --- drivers/gpu/drm/bridge/analogix/anx7625.c | 33 ++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-)