Angelo Dureghello
2024-Apr-12 19:49 UTC
[PATCH v2 1/2] drm/nouveau/disp: add backlight for ada lovelace
Add working backlight for "ada lovelace" missing case. The nvif method is actually not working for this chipset so used the drm apis. Also, by dpcd, drm layer is calculating a max brightness of 255, but to get a real correct max brightnes the maximum must be multiplied by a factor of 16. Tested to work properly in Legion Lenovo Pro 5 Lenovo Legion 5 Pro 16ARX8 Bios ver LPCN49WW LPEC49WW SN PF4T63AZ Nvidia RTX4060 MaxQ/Mobile rev a1 (ADA LOVELACE AD107M) AMD Ryzen 9 7945HX + Radeon and wayland. --- Changes for v2: - add some comments - remove x16 multiplication (hack) - remove forgot debug printk Signed-off-by: Angelo Dureghello <angelo at kernel-space.org> --- drivers/gpu/drm/nouveau/nouveau_backlight.c | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index d47442125fa1..7b7306d18ad7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -286,6 +286,56 @@ nv50_backlight_init(struct nouveau_backlight *bl, return 0; } +static int +nv19x_backlight_init(struct nouveau_backlight *bl, + struct nouveau_connector *nv_conn, + struct nouveau_encoder *nv_encoder, + struct backlight_properties *props, + const struct backlight_ops **ops) +{ + int ret; + u16 current_level; + u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; + u8 current_mode; + struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); + + /* + * nvif functions, so also nvif_outp_bl_get, are not working with this + * connector (return -22), using only drm layer. + */ + if (nv_conn->type == DCB_CONNECTOR_eDP) { + + ret = drm_dp_dpcd_read(&nv_conn->aux, DP_EDP_DPCD_REV, edp_dpcd, + EDP_DISPLAY_CTL_CAP_SIZE); + if (ret < 0) + return ret; + if (!drm_edp_backlight_supported(edp_dpcd)) + return -ENODEV; + + ret = drm_edp_backlight_init(&nv_conn->aux, &bl->edp_info, 0, edp_dpcd, + ¤t_level, ¤t_mode); + if (ret < 0) + return ret; + + ret = drm_edp_backlight_enable(&nv_conn->aux, &bl->edp_info, current_level); + if (ret < 0) { + NV_ERROR(drm, "Failed to enable backlight on %s: %d\n", + nv_conn->base.name, ret); + return ret; + } + + *ops = &nv50_edp_bl_ops; + + props->max_brightness = bl->edp_info.max; + props->brightness = current_level; + bl->uses_dpcd = true; + + return 0; + } + + return -ENODEV; +} + int nouveau_backlight_init(struct drm_connector *connector) { @@ -332,6 +382,10 @@ nouveau_backlight_init(struct drm_connector *connector) ret = nv50_backlight_init(bl, nouveau_connector(connector), nv_encoder, &props, &ops); break; + case NV_DEVICE_INFO_V0_ADA: + ret = nv19x_backlight_init(bl, nouveau_connector(connector), + nv_encoder, &props, &ops); + break; default: ret = 0; goto fail_alloc; -- 2.44.0
Angelo Dureghello
2024-Apr-12 19:49 UTC
[PATCH v2 2/2] drm/dp: set pwm bit count when pwm hz is not set
Set pwmgen_bit_count to have proper brightness inc/dec steps even when driver_pwm_freq_hz (optional) is zero. cat /sys/class/backlight/nv_backlight/max_brightness 255 Can now tune properly backlight from 0 to 255. --- Changes for v2: none Signed-off-by: Angelo Dureghello <angelo at kernel-space.org> --- drivers/gpu/drm/display/drm_dp_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index f5d4be897866..30c4ed0f2ff1 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3768,6 +3768,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf } pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + bl->pwmgen_bit_count = pn; bl->max = (1 << pn) - 1; if (!driver_pwm_freq_hz) return 0; -- 2.44.0
Lyude Paul
2024-Apr-15 16:54 UTC
[PATCH v2 1/2] drm/nouveau/disp: add backlight for ada lovelace
Hm. Could you share some logs with drm.debug=0x116? I'm a bit confused because I would have thought that we were already probing for eDP backlights seeing as I added support for them at one point? (I hope this isn't the point I learn I actually forgot to add support for them :P) On Fri, 2024-04-12 at 21:49 +0200, Angelo Dureghello wrote:> Add working backlight for "ada lovelace" missing case. > > The nvif method is actually not working for this chipset so > used the drm apis. Also, by dpcd, drm layer is calculating a > max brightness of 255, but to get a real correct max brightnes > the maximum must be multiplied by a factor of 16. > > Tested to work properly in Legion Lenovo Pro 5 > > Lenovo Legion 5 Pro 16ARX8 > Bios ver LPCN49WW > LPEC49WW > SN PF4T63AZ > Nvidia RTX4060 MaxQ/Mobile rev a1 (ADA LOVELACE AD107M) > AMD Ryzen 9 7945HX + Radeon > > and wayland. > > --- > Changes for v2: > - add some comments > - remove x16 multiplication (hack) > - remove forgot debug printk > > Signed-off-by: Angelo Dureghello <angelo at kernel-space.org> > --- > ?drivers/gpu/drm/nouveau/nouveau_backlight.c | 54 > +++++++++++++++++++++ > ?1 file changed, 54 insertions(+) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c > b/drivers/gpu/drm/nouveau/nouveau_backlight.c > index d47442125fa1..7b7306d18ad7 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c > +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c > @@ -286,6 +286,56 @@ nv50_backlight_init(struct nouveau_backlight > *bl, > ? return 0; > ?} > ? > +static int > +nv19x_backlight_init(struct nouveau_backlight *bl, > + ???? struct nouveau_connector *nv_conn, > + ???? struct nouveau_encoder *nv_encoder, > + ???? struct backlight_properties *props, > + ???? const struct backlight_ops **ops) > +{ > + int ret; > + u16 current_level; > + u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; > + u8 current_mode; > + struct nouveau_drm *drm = nouveau_drm(nv_encoder- > >base.base.dev); > + > + /* > + * nvif functions, so also nvif_outp_bl_get, are not working > with this > + * connector (return -22), using only drm layer. > + */ > + if (nv_conn->type == DCB_CONNECTOR_eDP) { > + > + ret = drm_dp_dpcd_read(&nv_conn->aux, > DP_EDP_DPCD_REV, edp_dpcd, > + ?????? EDP_DISPLAY_CTL_CAP_SIZE); > + if (ret < 0) > + return ret; > + if (!drm_edp_backlight_supported(edp_dpcd)) > + return -ENODEV; > + > + ret = drm_edp_backlight_init(&nv_conn->aux, &bl- > >edp_info, 0, edp_dpcd, > + ¤t_level, > ¤t_mode); > + if (ret < 0) > + return ret; > + > + ret = drm_edp_backlight_enable(&nv_conn->aux, &bl- > >edp_info, current_level); > + if (ret < 0) { > + NV_ERROR(drm, "Failed to enable backlight on > %s: %d\n", > + nv_conn->base.name, ret); > + return ret; > + } > + > + *ops = &nv50_edp_bl_ops; > + > + props->max_brightness = bl->edp_info.max; > + props->brightness = current_level; > + bl->uses_dpcd = true; > + > + return 0; > + } > + > + return -ENODEV; > +} > + > ?int > ?nouveau_backlight_init(struct drm_connector *connector) > ?{ > @@ -332,6 +382,10 @@ nouveau_backlight_init(struct drm_connector > *connector) > ? ret = nv50_backlight_init(bl, > nouveau_connector(connector), > ? ? nv_encoder, &props, &ops); > ? break; > + case NV_DEVICE_INFO_V0_ADA: > + ret = nv19x_backlight_init(bl, > nouveau_connector(connector), > + ?? nv_encoder, &props, > &ops); > + break; > ? default: > ? ret = 0; > ? goto fail_alloc;-- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat