Hi Am 12.07.21 um 11:41 schrieb Thomas Zimmermann: > > > Am 26.06.21 um 18:51 schrieb Rajeev Nandan: >> Some panels support backlight control over DP AUX channel using >> VESA's standard backlight control interface. >> Using new DRM eDP backlight helpers, add support to create and >> register a backlight for those panels in drm_panel to simplify >> the panel drivers. >> >> The panel driver with access to "struct drm_dp_aux" can create and >> register a backlight device using following code snippet in its >> probe() function: >> >>     err = drm_panel_dp_aux_backlight(panel, aux); >>     if (err) >>         return err; >> >> Then drm_panel will handle backlight_(enable|disable) calls >> similar to the case when drm_panel_of_backlight() is used. >> >> Currently, we are not supporting one feature where the source >> device can combine the backlight brightness levels set through >> DP AUX and the BL_PWM_DIM eDP connector pin. Since it's not >> required for the basic backlight controls, it can be added later. >> >> Signed-off-by: Rajeev Nandan >> Reviewed-by: Douglas Anderson >> Reviewed-by: Lyude Paul >> --- >> >> Changes in v5: >> - New >> >> Changes in v6: >> - Fixed ordering of memory allocation (Douglas) >> - Updated word wrapping in a comment (Douglas) >> >> Changes in v8: >> - Now using backlight_is_blank() to get the backlight blank status >> (Sam Ravnborg) >> >>   drivers/gpu/drm/drm_panel.c | 108 >> ++++++++++++++++++++++++++++++++++++++++++++ >>   include/drm/drm_panel.h     |  15 ++++-- >>   2 files changed, 119 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c >> index f634371..4fa1e3b 100644 >> --- a/drivers/gpu/drm/drm_panel.c >> +++ b/drivers/gpu/drm/drm_panel.c >> @@ -26,12 +26,20 @@ >>   #include >>   #include >> +#include >>   #include >>   #include >>   static DEFINE_MUTEX(panel_lock); >>   static LIST_HEAD(panel_list); >> +struct dp_aux_backlight { >> +    struct backlight_device *base; >> +    struct drm_dp_aux *aux; >> +    struct drm_edp_backlight_info info; >> +    bool enabled; >> +}; >> + >>   /** >>    * DOC: drm panel >>    * >> @@ -342,6 +350,106 @@ int drm_panel_of_backlight(struct drm_panel *panel) >>       return 0; >>   } >>   EXPORT_SYMBOL(drm_panel_of_backlight); >> + >> +static int dp_aux_backlight_update_status(struct backlight_device *bd) >> +{ >> +    struct dp_aux_backlight *bl = bl_get_data(bd); >> +    u16 brightness = backlight_get_brightness(bd); >> +    int ret = 0; >> + >> +    if (!backlight_is_blank(bd)) { >> +        if (!bl->enabled) { >> +            drm_edp_backlight_enable(bl->aux, &bl->info, brightness); >> +            bl->enabled = true; >> +            return 0; >> +        } >> +        ret = drm_edp_backlight_set_level(bl->aux, &bl->info, >> brightness); >> +    } else { >> +        if (bl->enabled) { >> +            drm_edp_backlight_disable(bl->aux, &bl->info); >> +            bl->enabled = false; >> +        } >> +    } >> + >> +    return ret; >> +} >> + >> +static const struct backlight_ops dp_aux_bl_ops = { >> +    .update_status = dp_aux_backlight_update_status, >> +}; >> + >> +/** >> + * drm_panel_dp_aux_backlight - create and use DP AUX backlight >> + * @panel: DRM panel >> + * @aux: The DP AUX channel to use >> + * >> + * Use this function to create and handle backlight if your panel >> + * supports backlight control over DP AUX channel using DPCD >> + * registers as per VESA's standard backlight control interface. >> + * >> + * When the panel is enabled backlight will be enabled after a >> + * successful call to &drm_panel_funcs.enable() >> + * >> + * When the panel is disabled backlight will be disabled before the >> + * call to &drm_panel_funcs.disable(). >> + * >> + * A typical implementation for a panel driver supporting backlight >> + * control over DP AUX will call this function at probe time. >> + * Backlight will then be handled transparently without requiring >> + * any intervention from the driver. >> + * >> + * drm_panel_dp_aux_backlight() must be called after the call to >> drm_panel_init(). >> + * >> + * Return: 0 on success or a negative error code on failure. >> + */ >> +int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct >> drm_dp_aux *aux) >> +{ >> +    struct dp_aux_backlight *bl; >> +    struct backlight_properties props = { 0 }; >> +    u16 current_level; >> +    u8 current_mode; >> +    u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; >> +    int ret; >> + >> +    if (!panel || !panel->dev || !aux) >> +        return -EINVAL; >> + >> +    ret = drm_dp_dpcd_read(aux, DP_EDP_DPCD_REV, edp_dpcd, >> +                   EDP_DISPLAY_CTL_CAP_SIZE); > > This creates a cyclic dependency between drm_kms_helper-ko and drm.ko. > drm_panel.c is in the latter, while drm_dp_dpcd_read() in > drm_dp_helper.c is in the former. Please fix. FYI, build DRM as modules and the error shows up during make module_install. Best regards Thomas -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer