[v2,2/3] drm/bridge: it6505: Setup links in it6505_irq_hpd
Commit Message
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(-)
Comments
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>
@@ -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",