lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAAOTY_9VL6U5TM6hnMZ8sJKO5rDUHuMPtNwOs_B7LwJQt7_-VQ@mail.gmail.com>
Date: Tue, 30 Dec 2025 16:13:30 +0000
From: Chun-Kuang Hu <chunkuang.hu@...nel.org>
To: Liankun Yang <liankun.yang@...iatek.com>
Cc: chunkuang.hu@...nel.org, p.zabel@...gutronix.de, airlied@...il.com, 
	simona@...ll.ch, matthias.bgg@...il.com, 
	angelogioacchino.delregno@...labora.com, mac.shen@...iatek.com, 
	peng.liu@...iatek.com, Project_Global_Chrome_Upstream_Group@...iatek.com, 
	dri-devel@...ts.freedesktop.org, linux-mediatek@...ts.infradead.org, 
	linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v8 1/1] drm/mediatek: Move DP training to hotplug thread

Hi, Liankun:

Liankun Yang <liankun.yang@...iatek.com> 於 2025年12月23日週二 上午6:34寫道:
>
> By adjusting the order of link training and relocating it to HPD,
> link training can identify the usability of each lane in the current link.
>
> It also supports handling signal instability and weakness due to
> environmental issues, enabling the acquisition of a stable bandwidth
> for the current link. Subsequently, DP work can proceed based on
> the actual maximum bandwidth.
>
> It should training in the hpd event thread.
> Check the mode with lane count and link rate of training.
>
> If we're eDP and capabilities were already parsed we can skip
> reading again because eDP panels aren't hotpluggable hence the
> caps and training information won't ever change in a boot life
>
> Therefore, bridge typec judgment is required for edp training in
> atomic_enable function.
>
> `mtk_dp_parse_capabilities` is related to DP training, it is
> used in `mtk_dp_hpd_event_thread` before DP training, and then only
> used by eDP when read edid.
>
> -Modify part of in `mtk_dp_bridge_atomic_disable`
>     if (mtk_dp->train_info.cable_plugged_in) {
>        drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
>        usleep_range(2000, 3000);
>     }
>
>     /* power off aux */
>     mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
>                 DP_PWR_STATE_BANDGAP_TPLL,
>                 DP_PWR_STATE_MASK);
>
> -Modify part of in `mtk_dp_aux_panel_poweron(mtk_dp, false);`
>     if (pwron) {
>        ....
>     } else {
>        /* power off panel */
>        drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
>        usleep_range(2000, 3000);
>
>        /* power off aux */
>        mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
>                         DP_PWR_STATE_BANDGAP_TPLL,
>                         DP_PWR_STATE_MASK);
>     }
>
> The `mtk_dp_aux_panel_poweron` function fails to align.
> Within the `mtk_dp_hpd_event_thread`, if DP is disconnected,
> the `mtk_dp_aux_panel_poweron` function will write from `aux`
> to `DPRX`, causing a failure and thus preventing symmetry.
>
> This shows the current timings after the DP cable is plugged in,
> as well as the modified timings.
>
> current timings:                Fix timings:
>
> mtk_dp_hpd_event_thread()       mtk_dp_hpd_event_thread()
>                                 (including DP link training)
>         |                               |
>        ...                             ...
> mtk_dp_bridge_mode_valid()      mtk_dp_bridge_mode_valid()
>         |
>        ...                             ...
> mtk_dp_bridge_atomic_check()    mtk_dp_bridge_atomic_check()
>         |
>        ...                             ...
> mtk_dp_bridge_atomic_enable()   mtk_dp_bridge_atomic_enable()
> (including DP link training)
>
> PS:
> 1. "..." represents ommited steps;
>
> 2. `mtk_dp_bridge_mode_valid()` calculates the bandwidth using the
> current lane count and link rate, and then filters each mode to
> determine if it supports returning a status.
>
> 3. In the `drm_display_mode_to_videomode(&crtc_state->adjusted_mode,
> &mtk_dp->info.vm);` function, within the `mtk_dp_bridge_atomic_check()`
> function, `adjusted_mode` sets the currently selected display mode for
> the DRM.
>
> 4. DP link training tests the signal conditions of the link between
> DPTX and DPRX, and selects the lane count and link rate that meet
> the signal conditions.
>
> 5. For example, the platform support DP 4lane 5.4G,
> but panel A support DP 2lane 5.4G.
>
>    This is a time sequence:
>
>    a).Plug in panel A. According to the platform, it can output 4K60Hz.
>    b).Timing mode set 4K 60Hz(Including in mtk_dp_bridge_atomic_check
>    function).
>    c).Atomic enable(Based on panel A ability, training pass 2lane
>    5.4G).
>    d).Finally, due to 2lane 5.4G bandwidth limitation, the platform
>    cannot output 4K 60Hz, resulting in a black sreen.
>
>    If apply this patch.
>
>    a).Plug in panel A.
>    b).Training pass 2lane 5.4G
>    c).Timing mode set 2K 60Hz(Based on the 2lane 5.4G bandwidth limit
>    and including in mtk_dp_bridge_atomic_che

Applied to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> Signed-off-by: Liankun Yang <liankun.yang@...iatek.com>
> ---
> Change in V8:
> - Update the commit message.
> - Update the commit title.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20251104085957.1175-2-liankun.yang@mediatek.com/
>
> Change in V7:
> - Separate the edp part.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20250822120506.15486-1-liankun.yang@mediatek.com/
>
> Change in V6:
> - Fixed power on in atomic enable.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20250630080824.7107-1-liankun.yang@mediatek.com/
>
> Change in V5:
> - Fixed the issue that the 4th version of the patch caused DP to have no screen.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20250625095446.31726-1-liankun.yang@mediatek.com/
>
> Change in V4:
> - Tested the internal eDP display on MT8195 Tomato and it is fine.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20250318140236.13650-2-liankun.yang@mediatek.com/
>
> Change in V3:
> - Remove 'mtk_dp->enabled = false" in atomic disable.
> - Remove 'mtk_dp->enabled = true" in atomic enable.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20241025083036.8829-4-liankun.yang@mediatek.com/
>
> Change in V2:
> - Adjust DP training timing.
> - Adjust parse capabilities timing.
> - Add power on/off for connect/disconnect.
> Per suggestion from the previous thread:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20240315015233.2023-1-liankun.yang@mediatek.com/
> ---
>  drivers/gpu/drm/mediatek/mtk_dp.c | 57 ++++++++++++++++++++-----------
>  1 file changed, 38 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
> index b0b1e158600f..5e67dab6e2e9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -1976,6 +1976,7 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
>         struct mtk_dp *mtk_dp = dev;
>         unsigned long flags;
>         u32 status;
> +       int ret;
>
>         if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
>                 msleep(100);
> @@ -1994,9 +1995,28 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
>                         memset(&mtk_dp->info.audio_cur_cfg, 0,
>                                sizeof(mtk_dp->info.audio_cur_cfg));
>
> +                       mtk_dp->enabled = false;
> +                       /* power off aux */
> +                       mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
> +                                          DP_PWR_STATE_BANDGAP_TPLL,
> +                                          DP_PWR_STATE_MASK);
> +
>                         mtk_dp->need_debounce = false;
>                         mod_timer(&mtk_dp->debounce_timer,
>                                   jiffies + msecs_to_jiffies(100) - 1);
> +               } else {
> +                       mtk_dp_aux_panel_poweron(mtk_dp, true);
> +
> +                       ret = mtk_dp_parse_capabilities(mtk_dp);
> +                       if (ret)
> +                               drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
> +
> +                       /* Training */
> +                       ret = mtk_dp_training(mtk_dp);
> +                       if (ret)
> +                               drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret);
> +
> +                       mtk_dp->enabled = true;
>                 }
>         }
>
> @@ -2168,7 +2188,8 @@ static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge,
>          * Parse capability here to let atomic_get_input_bus_fmts and
>          * mode_valid use the capability to calculate sink bitrates.
>          */
> -       if (mtk_dp_parse_capabilities(mtk_dp)) {
> +       if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP &&
> +           mtk_dp_parse_capabilities(mtk_dp)) {
>                 drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
>                 drm_edid_free(drm_edid);
>                 drm_edid = NULL;
> @@ -2366,13 +2387,15 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
>                 return;
>         }
>
> -       mtk_dp_aux_panel_poweron(mtk_dp, true);
> +       if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP) {
> +               mtk_dp_aux_panel_poweron(mtk_dp, true);
>
> -       /* Training */
> -       ret = mtk_dp_training(mtk_dp);
> -       if (ret) {
> -               drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret);
> -               goto power_off_aux;
> +               /* Training */
> +               ret = mtk_dp_training(mtk_dp);
> +               if (ret) {
> +                       drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret);
> +                       goto power_off_aux;
> +               }
>         }
>
>         ret = mtk_dp_video_config(mtk_dp);
> @@ -2392,7 +2415,9 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
>                        sizeof(mtk_dp->info.audio_cur_cfg));
>         }
>
> -       mtk_dp->enabled = true;
> +       if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP)
> +               mtk_dp->enabled = true;
> +
>         mtk_dp_update_plugged_status(mtk_dp);
>
>         return;
> @@ -2407,21 +2432,15 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
>  {
>         struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
>
> -       mtk_dp->enabled = false;
> +       if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP) {
> +               mtk_dp->enabled = false;
> +               mtk_dp_aux_panel_poweron(mtk_dp, false);
> +       }
> +
>         mtk_dp_update_plugged_status(mtk_dp);
>         mtk_dp_video_enable(mtk_dp, false);
>         mtk_dp_audio_mute(mtk_dp, true);
>
> -       if (mtk_dp->train_info.cable_plugged_in) {
> -               drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
> -               usleep_range(2000, 3000);
> -       }
> -
> -       /* power off aux */
> -       mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
> -                          DP_PWR_STATE_BANDGAP_TPLL,
> -                          DP_PWR_STATE_MASK);
> -
>         /* SDP path reset sw*/
>         mtk_dp_sdp_path_reset(mtk_dp);
>
> --
> 2.45.2
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ