Message ID | 20250325-wip-obbardc-qcom-t14s-oled-panel-v2-4-e9bc7c9d30cc@linaro.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support for OLED panel used on Snapdragon Lenovo T14s Gen6 | expand |
On 25/03/2025 21:21, Christopher Obbard wrote: > Some eDP devices report DP_EDP_PWMGEN_BIT_COUNT as 0, but still provide > valid non-zero MIN and MAX values. This patch reworks the logic to > fallback to the max value in such cases, ensuring correct backlight PWM > configuration even when the bit count value is not explicitly set. I don't think this matches the eDP standard. It tells to use MIN if BIT_COUNT is less than MIN, if I understand it correctly. > > This improves compatibility with eDP panels (e.g. Samsung ATNA40YK20 > used on the Lenovo T14s Gen6 Snapdragon with OLED panel) which reports > DP_EDP_PWMGEN_BIT_COUNT as 0 but still provides valid non-zero MIN/MAX > values. > > Co-developed-by: Rui Miguel Silva <rui.silva@linaro.org> > Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> > Signed-off-by: Christopher Obbard <christopher.obbard@linaro.org> > --- > drivers/gpu/drm/display/drm_dp_helper.c | 51 ++++++++++++++++++++++----------- > 1 file changed, 34 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c > index da3c8521a7fa7d3c9761377363cdd4b44ab1106e..734b7b8e46394de21837cda6ca1b189413b25cd8 100644 > --- a/drivers/gpu/drm/display/drm_dp_helper.c > +++ b/drivers/gpu/drm/display/drm_dp_helper.c > @@ -3964,7 +3964,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf > { > int fxp, fxp_min, fxp_max, fxp_actual, f = 1; > int ret; > - u8 pn, pn_min, pn_max; > + u8 pn, pn_min, pn_max, bl_caps; > > if (!bl->aux_set) > return 0; > @@ -3975,8 +3975,40 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf > aux->name, ret); > return -ENODEV; > } > - > pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK; > + > + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min); > + if (ret != 1) { > + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap min: %d\n", > + aux->name, ret); > + return 0; > + } > + pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; > + > + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max); > + if (ret != 1) { > + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap max: %d\n", > + aux->name, ret); > + return 0; > + } > + pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; > + > + ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP, &bl_caps); > + if (ret != 1) { > + bl_caps = 0; > + drm_dbg_kms(aux->drm_dev, "%s: Failed to read backlight adjustment cap: %d\n", > + aux->name, ret); > + } > + > + /* > + * Some eDP panels report brightness byte count support, but the byte count > + * reading is 0 (e.g. Samsung ATNA40YK20) so in these cases use pn_max > + * for pn. > + */ > + if (!pn && (bl_caps & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) > + && pn_max) > + pn = pn_max; > + > bl->max = (1 << pn) - 1; > if (!driver_pwm_freq_hz) > return 0; > @@ -4003,21 +4035,6 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf > * - FxP is within 25% of desired value. > * Note: 25% is arbitrary value and may need some tweak. > */ > - ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min); > - if (ret != 1) { > - drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap min: %d\n", > - aux->name, ret); > - return 0; > - } > - ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max); > - if (ret != 1) { > - drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap max: %d\n", > - aux->name, ret); > - return 0; > - } > - pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; > - pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; > - > /* Ensure frequency is within 25% of desired value */ > fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); > fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4); >
Hi Dmitry, On Tue, 25 Mar 2025 at 22:53, Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > > On 25/03/2025 21:21, Christopher Obbard wrote: > > Some eDP devices report DP_EDP_PWMGEN_BIT_COUNT as 0, but still provide > > valid non-zero MIN and MAX values. This patch reworks the logic to > > fallback to the max value in such cases, ensuring correct backlight PWM > > configuration even when the bit count value is not explicitly set. > > I don't think this matches the eDP standard. It tells to use MIN if > BIT_COUNT is less than MIN, if I understand it correctly. Thanks for your comment; that's a good point. I need to re-read this section of the spec; but at least on this hardware I printed the values of the registers and it seems like MIN and MAX are the same, so I could switch the patch around to use MIN in the next version. drm_edp_backlight_probe_max: pn=0, pn_min=11, pn_max=11, bl_caps=134 diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 6e519c58c2e84..2be2b00c8a531 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4061,6 +4061,8 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf aux->name, ret); } + pr_info("%s: pn=%d, pn_min=%d, pn_max=%d, bl_caps=%d\n", __func__, pn, pn_min, pn_max, bl_caps); + /* * Some eDP panels report brightness byte count support, but the byte count * reading is 0 (e.g. Samsung ATNA40YK20) so in these cases use pn_max
On Wed, Mar 26, 2025 at 03:08:30PM +0000, Christopher Obbard wrote: > Hi Dmitry, > > On Tue, 25 Mar 2025 at 22:53, Dmitry Baryshkov > <dmitry.baryshkov@oss.qualcomm.com> wrote: > > > > On 25/03/2025 21:21, Christopher Obbard wrote: > > > Some eDP devices report DP_EDP_PWMGEN_BIT_COUNT as 0, but still provide > > > valid non-zero MIN and MAX values. This patch reworks the logic to > > > fallback to the max value in such cases, ensuring correct backlight PWM > > > configuration even when the bit count value is not explicitly set. > > > > I don't think this matches the eDP standard. It tells to use MIN if > > BIT_COUNT is less than MIN, if I understand it correctly. > > Thanks for your comment; that's a good point. > > I need to re-read this section of the spec; but at least on this > hardware I printed the values of the registers and it seems like > MIN and MAX are the same, so I could switch the patch around to use > MIN in the next version. SGTM.
On 25-03-25 19:21:29, Christopher Obbard wrote: > Some eDP devices report DP_EDP_PWMGEN_BIT_COUNT as 0, but still provide > valid non-zero MIN and MAX values. This patch reworks the logic to > fallback to the max value in such cases, ensuring correct backlight PWM > configuration even when the bit count value is not explicitly set. > > This improves compatibility with eDP panels (e.g. Samsung ATNA40YK20 > used on the Lenovo T14s Gen6 Snapdragon with OLED panel) which reports > DP_EDP_PWMGEN_BIT_COUNT as 0 but still provides valid non-zero MIN/MAX > values. > Nit-pick: AFAICT, there is no relationship between this patch and the rest. So it should've probably not be part of this patchset.
Right, the reason this was included in this series is because without this patch the panel's backlight doesn't actually work. So for me it was natural to include it. But happy to split it into its own series. On Thu, 27 Mar 2025 at 08:05, Abel Vesa <abel.vesa@linaro.org> wrote: > > On 25-03-25 19:21:29, Christopher Obbard wrote: > > Some eDP devices report DP_EDP_PWMGEN_BIT_COUNT as 0, but still provide > > valid non-zero MIN and MAX values. This patch reworks the logic to > > fallback to the max value in such cases, ensuring correct backlight PWM > > configuration even when the bit count value is not explicitly set. > > > > This improves compatibility with eDP panels (e.g. Samsung ATNA40YK20 > > used on the Lenovo T14s Gen6 Snapdragon with OLED panel) which reports > > DP_EDP_PWMGEN_BIT_COUNT as 0 but still provides valid non-zero MIN/MAX > > values. > > > > Nit-pick: AFAICT, there is no relationship between this patch and the > rest. So it should've probably not be part of this patchset.
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index da3c8521a7fa7d3c9761377363cdd4b44ab1106e..734b7b8e46394de21837cda6ca1b189413b25cd8 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3964,7 +3964,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf { int fxp, fxp_min, fxp_max, fxp_actual, f = 1; int ret; - u8 pn, pn_min, pn_max; + u8 pn, pn_min, pn_max, bl_caps; if (!bl->aux_set) return 0; @@ -3975,8 +3975,40 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf aux->name, ret); return -ENODEV; } - pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min); + if (ret != 1) { + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap min: %d\n", + aux->name, ret); + return 0; + } + pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max); + if (ret != 1) { + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap max: %d\n", + aux->name, ret); + return 0; + } + pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + + ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP, &bl_caps); + if (ret != 1) { + bl_caps = 0; + drm_dbg_kms(aux->drm_dev, "%s: Failed to read backlight adjustment cap: %d\n", + aux->name, ret); + } + + /* + * Some eDP panels report brightness byte count support, but the byte count + * reading is 0 (e.g. Samsung ATNA40YK20) so in these cases use pn_max + * for pn. + */ + if (!pn && (bl_caps & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) + && pn_max) + pn = pn_max; + bl->max = (1 << pn) - 1; if (!driver_pwm_freq_hz) return 0; @@ -4003,21 +4035,6 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf * - FxP is within 25% of desired value. * Note: 25% is arbitrary value and may need some tweak. */ - ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min); - if (ret != 1) { - drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap min: %d\n", - aux->name, ret); - return 0; - } - ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max); - if (ret != 1) { - drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap max: %d\n", - aux->name, ret); - return 0; - } - pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - /* Ensure frequency is within 25% of desired value */ fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);