Message ID | 20221013110411.1674359-3-treapking@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Clean up it6505 driver and improve synchronization | expand |
On Thu, 13 Oct 2022 at 13:04, Pin-yen Lin <treapking@chromium.org> wrote: > > Move the DPCD read and link setup steps to HPD IRQ handler to remove > an unnecessary dependency between .detect callback and the HPD IRQ > handler before registering it6505 as a DRM bridge. This is safe because > there is always a .detect call after each HPD IRQ handler triggered by > the drm_helper_hpd_irq_event call. > > Signed-off-by: Pin-yen Lin <treapking@chromium.org> > --- > > Changes in v2: > - Remove redundant spaces in it6505_detect > - Read sink count in it6505_irq_hpd > > drivers/gpu/drm/bridge/ite-it6505.c | 80 +++++++++++++---------------- > 1 file changed, 35 insertions(+), 45 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c > index f7f6c3e20fae..4b6061272599 100644 > --- a/drivers/gpu/drm/bridge/ite-it6505.c > +++ b/drivers/gpu/drm/bridge/ite-it6505.c > @@ -725,28 +725,6 @@ static void it6505_calc_video_info(struct it6505 *it6505) > DRM_MODE_ARG(&it6505->video_info)); > } > > -static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux, > - struct it6505_drm_dp_link *link) > -{ > - u8 values[3]; > - int err; > - > - memset(link, 0, sizeof(*link)); > - > - err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values)); > - if (err < 0) > - return err; > - > - link->revision = values[0]; > - link->rate = drm_dp_bw_code_to_link_rate(values[1]); > - link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK; > - > - if (values[2] & DP_ENHANCED_FRAME_CAP) > - link->capabilities = DP_ENHANCED_FRAME_CAP; > - > - return 0; > -} > - > static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux, > struct it6505_drm_dp_link *link, > u8 mode) > @@ -1456,11 +1434,19 @@ static void it6505_parse_link_capabilities(struct it6505 *it6505) > int bcaps; > > if (it6505->dpcd[0] == 0) { > - it6505_aux_on(it6505); > - it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, > - ARRAY_SIZE(it6505->dpcd)); > + dev_err(dev, "DPCD is not initialized"); > + return; > } > > + memset(link, 0, sizeof(*link)); > + > + link->revision = it6505->dpcd[0]; > + link->rate = drm_dp_bw_code_to_link_rate(it6505->dpcd[1]); > + link->num_lanes = it6505->dpcd[2] & DP_MAX_LANE_COUNT_MASK; > + > + if (it6505->dpcd[2] & DP_ENHANCED_FRAME_CAP) > + link->capabilities = DP_ENHANCED_FRAME_CAP; > + > DRM_DEV_DEBUG_DRIVER(dev, "DPCD Rev.: %d.%d", > link->revision >> 4, link->revision & 0x0F); > > @@ -2323,19 +2309,32 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) > static void it6505_irq_hpd(struct it6505 *it6505) > { > struct device *dev = &it6505->client->dev; > + int dp_sink_count; > > it6505->hpd_state = it6505_get_sink_hpd_status(it6505); > DRM_DEV_DEBUG_DRIVER(dev, "hpd change interrupt, change to %s", > it6505->hpd_state ? "high" : "low"); > > - if (it6505->bridge.dev) > - drm_helper_hpd_irq_event(it6505->bridge.dev); > - DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", > - it6505->sink_count); > - > if (it6505->hpd_state) { > wait_for_completion_timeout(&it6505->wait_edid_complete, > msecs_to_jiffies(6000)); > + it6505_aux_on(it6505); > + if (it6505->dpcd[0] == 0) { > + it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, > + ARRAY_SIZE(it6505->dpcd)); > + it6505_variable_config(it6505); > + it6505_parse_link_capabilities(it6505); > + } > + it6505->auto_train_retry = AUTO_TRAIN_RETRY; > + > + it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, > + DP_SET_POWER_D0); > + dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT); > + it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count); > + > + DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", > + it6505->sink_count); > + > it6505_lane_termination_on(it6505); > it6505_lane_power_on(it6505); > > @@ -2363,6 +2362,9 @@ static void it6505_irq_hpd(struct it6505 *it6505) > it6505_lane_off(it6505); > it6505_link_reset_step_train(it6505); > } > + > + if (it6505->bridge.dev) > + drm_helper_hpd_irq_event(it6505->bridge.dev); > } > > static void it6505_irq_hpd_irq(struct it6505 *it6505) > @@ -2625,26 +2627,14 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505) > goto unlock; > > if (it6505->enable_drv_hold) { > - status = it6505_get_sink_hpd_status(it6505) ? > - connector_status_connected : > - connector_status_disconnected; > + status = it6505->hpd_state ? connector_status_connected : > + connector_status_disconnected; > goto unlock; > } > > - if (it6505_get_sink_hpd_status(it6505)) { > - it6505_aux_on(it6505); > - it6505_drm_dp_link_probe(&it6505->aux, &it6505->link); > + if (it6505->hpd_state) { > it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, > DP_SET_POWER_D0); > - it6505->auto_train_retry = AUTO_TRAIN_RETRY; > - > - if (it6505->dpcd[0] == 0) { > - it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, > - ARRAY_SIZE(it6505->dpcd)); > - it6505_variable_config(it6505); > - it6505_parse_link_capabilities(it6505); > - } > - > dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT); > it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count); > DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d branch:%d", > -- > 2.38.0.rc1.362.ged0d419d3c-goog > Reviewed-by: Robert Foss <robert.foss@linaro.org>
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index f7f6c3e20fae..4b6061272599 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -725,28 +725,6 @@ static void it6505_calc_video_info(struct it6505 *it6505) DRM_MODE_ARG(&it6505->video_info)); } -static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux, - struct it6505_drm_dp_link *link) -{ - u8 values[3]; - int err; - - memset(link, 0, sizeof(*link)); - - err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values)); - if (err < 0) - return err; - - link->revision = values[0]; - link->rate = drm_dp_bw_code_to_link_rate(values[1]); - link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK; - - if (values[2] & DP_ENHANCED_FRAME_CAP) - link->capabilities = DP_ENHANCED_FRAME_CAP; - - return 0; -} - static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux, struct it6505_drm_dp_link *link, u8 mode) @@ -1456,11 +1434,19 @@ static void it6505_parse_link_capabilities(struct it6505 *it6505) int bcaps; if (it6505->dpcd[0] == 0) { - it6505_aux_on(it6505); - it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, - ARRAY_SIZE(it6505->dpcd)); + dev_err(dev, "DPCD is not initialized"); + return; } + memset(link, 0, sizeof(*link)); + + link->revision = it6505->dpcd[0]; + link->rate = drm_dp_bw_code_to_link_rate(it6505->dpcd[1]); + link->num_lanes = it6505->dpcd[2] & DP_MAX_LANE_COUNT_MASK; + + if (it6505->dpcd[2] & DP_ENHANCED_FRAME_CAP) + link->capabilities = DP_ENHANCED_FRAME_CAP; + DRM_DEV_DEBUG_DRIVER(dev, "DPCD Rev.: %d.%d", link->revision >> 4, link->revision & 0x0F); @@ -2323,19 +2309,32 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) static void it6505_irq_hpd(struct it6505 *it6505) { struct device *dev = &it6505->client->dev; + int dp_sink_count; it6505->hpd_state = it6505_get_sink_hpd_status(it6505); DRM_DEV_DEBUG_DRIVER(dev, "hpd change interrupt, change to %s", it6505->hpd_state ? "high" : "low"); - if (it6505->bridge.dev) - drm_helper_hpd_irq_event(it6505->bridge.dev); - DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", - it6505->sink_count); - if (it6505->hpd_state) { wait_for_completion_timeout(&it6505->wait_edid_complete, msecs_to_jiffies(6000)); + it6505_aux_on(it6505); + if (it6505->dpcd[0] == 0) { + it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, + ARRAY_SIZE(it6505->dpcd)); + it6505_variable_config(it6505); + it6505_parse_link_capabilities(it6505); + } + it6505->auto_train_retry = AUTO_TRAIN_RETRY; + + it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, + DP_SET_POWER_D0); + dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT); + it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count); + + DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", + it6505->sink_count); + it6505_lane_termination_on(it6505); it6505_lane_power_on(it6505); @@ -2363,6 +2362,9 @@ static void it6505_irq_hpd(struct it6505 *it6505) it6505_lane_off(it6505); it6505_link_reset_step_train(it6505); } + + if (it6505->bridge.dev) + drm_helper_hpd_irq_event(it6505->bridge.dev); } static void it6505_irq_hpd_irq(struct it6505 *it6505) @@ -2625,26 +2627,14 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505) goto unlock; if (it6505->enable_drv_hold) { - status = it6505_get_sink_hpd_status(it6505) ? - connector_status_connected : - connector_status_disconnected; + status = it6505->hpd_state ? connector_status_connected : + connector_status_disconnected; goto unlock; } - if (it6505_get_sink_hpd_status(it6505)) { - it6505_aux_on(it6505); - it6505_drm_dp_link_probe(&it6505->aux, &it6505->link); + if (it6505->hpd_state) { it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, DP_SET_POWER_D0); - it6505->auto_train_retry = AUTO_TRAIN_RETRY; - - if (it6505->dpcd[0] == 0) { - it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd, - ARRAY_SIZE(it6505->dpcd)); - it6505_variable_config(it6505); - it6505_parse_link_capabilities(it6505); - } - dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT); it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count); DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d branch:%d",
Move the DPCD read and link setup steps to HPD IRQ handler to remove an unnecessary dependency between .detect callback and the HPD IRQ handler before registering it6505 as a DRM bridge. This is safe because there is always a .detect call after each HPD IRQ handler triggered by the drm_helper_hpd_irq_event call. Signed-off-by: Pin-yen Lin <treapking@chromium.org> --- Changes in v2: - Remove redundant spaces in it6505_detect - Read sink count in it6505_irq_hpd drivers/gpu/drm/bridge/ite-it6505.c | 80 +++++++++++++---------------- 1 file changed, 35 insertions(+), 45 deletions(-)