Hi Jitao. On Wed, Nov 06, 2019 at 02:40:05PM +0800, Jitao Shi wrote: > Some dsi panels require the dsi lanes keeping low before panel power > on. So seperate the panel power control and the communication with panel. > > And put the power control in drm_panel_prepare_power and > drm_panel_unprepare_power. Put the communication with panel in > drm_panel_prepare and drm_panel_unprepare. > > Signed-off-by: Jitao Shi <jitao.shi@xxxxxxxxxxxx> Panels that requires power before communicating often/always have some timing constraints. Power need to be applied in XYZ micro seconds before it is safe to communicate with the panel. To support this a typical pattern is: panel_xxx_prepare() { // power on the panel using one or a few regulators // wait until panel is known to be ready // Communicate with the panel } first driver I looked at (panel-feiyang-fy07024di26a30d.c) follows this pattern. So we have the timing spelled out in the enable() function and the sequence is obvious. What will the benefit be from a separate drm_panel_prepare_power() function pointer? Sam > --- > drivers/gpu/drm/drm_panel.c | 38 +++++++++++++++++++++++++++++++++++++ > include/drm/drm_panel.h | 17 +++++++++++++++++ > 2 files changed, 55 insertions(+) > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c > index 6b0bf42039cf..e57f6385d2cc 100644 > --- a/drivers/gpu/drm/drm_panel.c > +++ b/drivers/gpu/drm/drm_panel.c > @@ -131,6 +131,24 @@ void drm_panel_detach(struct drm_panel *panel) > } > EXPORT_SYMBOL(drm_panel_detach); > > +/** > + * drm_panel_prepare_power - power on a panel's power > + * @panel: DRM panel > + * > + * Calling this function will enable power and deassert any reset signals to > + * the panel. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int drm_panel_prepare_power(struct drm_panel *panel) > +{ > + if (panel && panel->funcs && panel->funcs->prepare_power) > + return panel->funcs->prepare_power(panel); > + > + return panel ? -ENOSYS : -EINVAL; > +} > +EXPORT_SYMBOL(drm_panel_prepare_power); > + > /** > * drm_panel_prepare - power on a panel > * @panel: DRM panel > @@ -170,6 +188,26 @@ int drm_panel_unprepare(struct drm_panel *panel) > } > EXPORT_SYMBOL(drm_panel_unprepare); > > +/** > + * drm_panel_unprepare_power - power off a panel > + * @panel: DRM panel > + * > + * Calling this function will completely power off a panel (assert the panel's > + * reset, turn off power supplies, ...). After this function has completed, it > + * is usually no longer possible to communicate with the panel until another > + * call to drm_panel_prepare_power and drm_panel_prepare(). > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int drm_panel_unprepare_power(struct drm_panel *panel) > +{ > + if (panel && panel->funcs && panel->funcs->unprepare_power) > + return panel->funcs->unprepare_power(panel); > + > + return panel ? -ENOSYS : -EINVAL; > +} > +EXPORT_SYMBOL(drm_panel_unprepare_power); > + > /** > * drm_panel_enable - enable a panel > * @panel: DRM panel > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h > index 624bd15ecfab..0d8c4855405c 100644 > --- a/include/drm/drm_panel.h > +++ b/include/drm/drm_panel.h > @@ -61,6 +61,13 @@ struct display_timing; > * the panel. This is the job of the .unprepare() function. > */ > struct drm_panel_funcs { > + /** > + * @prepare_power: > + * > + * Turn on panel power. > + */ > + int (*prepare_power)(struct drm_panel *panel); > + > /** > * @prepare: > * > @@ -89,6 +96,13 @@ struct drm_panel_funcs { > */ > int (*unprepare)(struct drm_panel *panel); > > + /** > + * @unprepare_power: > + * > + * Turn off panel_power. > + */ > + int (*unprepare_power)(struct drm_panel *panel); > + > /** > * @get_modes: > * > @@ -155,6 +169,9 @@ void drm_panel_remove(struct drm_panel *panel); > int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector); > void drm_panel_detach(struct drm_panel *panel); > > +int drm_panel_prepare_power(struct drm_panel *panel); > +int drm_panel_unprepare_power(struct drm_panel *panel); > + > int drm_panel_prepare(struct drm_panel *panel); > int drm_panel_unprepare(struct drm_panel *panel); > > -- > 2.21.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel