diff mbox

[v2,5/7] drm/ltdc: Use the panel-bridge helper.

Message ID 20170511183128.25085-5-eric@anholt.net (mailing list archive)
State New, archived
Headers show

Commit Message

Eric Anholt May 11, 2017, 6:31 p.m. UTC
Another 100 lines of boilerplate gone.  Bridges aren't supported yet,
but will be trivial to add later.

Signed-off-by: Eric Anholt <eric@anholt.net>
---

Also untested.

 drivers/gpu/drm/stm/ltdc.c | 128 +++++----------------------------------------
 drivers/gpu/drm/stm/ltdc.h |   2 +-
 2 files changed, 13 insertions(+), 117 deletions(-)

Comments

Boris BREZILLON May 12, 2017, 8:17 a.m. UTC | #1
On Thu, 11 May 2017 11:31:26 -0700
Eric Anholt <eric@anholt.net> wrote:

> Another 100 lines of boilerplate gone.  Bridges aren't supported yet,
> but will be trivial to add later.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> 

[...]

> @@ -1082,28 +993,13 @@ int ltdc_load(struct drm_device *ddev)
>  
>  	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
>  
> -	if (ldev->panel) {
> +	if (ldev->bridge) {
>  		encoder = ltdc_rgb_encoder_create(ddev);
>  		if (!encoder) {
>  			DRM_ERROR("Failed to create RGB encoder\n");
>  			ret = -EINVAL;
>  			goto err;
>  		}

You should have a call to drm_bridge_attach() somewhere, otherwise your
panel (and its connector) will not be registered.

> -
> -		connector = ltdc_rgb_connector_create(ddev);
> -		if (!connector) {
> -			DRM_ERROR("Failed to create RGB connector\n");
> -			ret = -EINVAL;
> -			goto err;
> -		}
> -
> -		ret = drm_mode_connector_attach_encoder(connector, encoder);
> -		if (ret) {
> -			DRM_ERROR("Failed to attach connector to encoder\n");
> -			goto err;
> -		}
> -
> -		drm_panel_attach(ldev->panel, connector);
>  	}
>
Philippe CORNU May 30, 2017, 4:55 p.m. UTC | #2
Hi Eric,

I took your patch for the panel-bridge and it works perfectly in both 
DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)

~160 lines have been removed from ltdc.c thanks to your panel-bridge code!

Many thanks
Philippe

On 05/11/2017 08:31 PM, Eric Anholt wrote:
> Another 100 lines of boilerplate gone.  Bridges aren't supported yet,

> but will be trivial to add later.

> 

> Signed-off-by: Eric Anholt <eric@anholt.net>

> ---

> 

> Also untested.

> 

>   drivers/gpu/drm/stm/ltdc.c | 128 +++++----------------------------------------

>   drivers/gpu/drm/stm/ltdc.h |   2 +-

>   2 files changed, 13 insertions(+), 117 deletions(-)

> 

> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c

> index a40418cda74a..41a1c5d68f5b 100644

> --- a/drivers/gpu/drm/stm/ltdc.c

> +++ b/drivers/gpu/drm/stm/ltdc.c

> @@ -269,11 +269,6 @@ static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)

>   	return (struct ltdc_device *)enc->dev->dev_private;

>   }

>   

> -static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)

> -{

> -	return (struct ltdc_device *)con->dev->dev_private;

> -}

> -

>   static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)

>   {

>   	enum ltdc_pix_fmt pf;

> @@ -815,22 +810,12 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)

>   

>   static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)

>   {

> -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);

> -

>   	DRM_DEBUG_DRIVER("\n");

> -

> -	drm_panel_prepare(ldev->panel);

> -	drm_panel_enable(ldev->panel);

>   }

>   

>   static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)

>   {

> -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);

> -

>   	DRM_DEBUG_DRIVER("\n");

> -

> -	drm_panel_disable(ldev->panel);

> -	drm_panel_unprepare(ldev->panel);

>   }

>   

>   static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {

> @@ -863,82 +848,6 @@ static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)

>   	return encoder;

>   }

>   

> -/*

> - * DRM_CONNECTOR

> - */

> -

> -static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)

> -{

> -	struct drm_device *ddev = connector->dev;

> -	struct ltdc_device *ldev = ddev->dev_private;

> -	int ret = 0;

> -

> -	DRM_DEBUG_DRIVER("\n");

> -

> -	if (ldev->panel)

> -		ret = drm_panel_get_modes(ldev->panel);

> -

> -	return ret < 0 ? 0 : ret;

> -}

> -

> -static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {

> -	.get_modes = ltdc_rgb_connector_get_modes,

> -};

> -

> -static enum drm_connector_status

> -ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)

> -{

> -	struct ltdc_device *ldev = connector_to_ltdc(connector);

> -

> -	return ldev->panel ? connector_status_connected :

> -	       connector_status_disconnected;

> -}

> -

> -static void ltdc_rgb_connector_destroy(struct drm_connector *connector)

> -{

> -	DRM_DEBUG_DRIVER("\n");

> -

> -	drm_connector_unregister(connector);

> -	drm_connector_cleanup(connector);

> -}

> -

> -static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {

> -	.dpms = drm_atomic_helper_connector_dpms,

> -	.fill_modes = drm_helper_probe_single_connector_modes,

> -	.detect = ltdc_rgb_connector_detect,

> -	.destroy = ltdc_rgb_connector_destroy,

> -	.reset = drm_atomic_helper_connector_reset,

> -	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,

> -	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,

> -};

> -

> -struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)

> -{

> -	struct drm_connector *connector;

> -	int err;

> -

> -	connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);

> -	if (!connector) {

> -		DRM_ERROR("Failed to allocate connector\n");

> -		return NULL;

> -	}

> -

> -	connector->polled = DRM_CONNECTOR_POLL_HPD;

> -

> -	err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,

> -				 DRM_MODE_CONNECTOR_DPI);

> -	if (err) {

> -		DRM_ERROR("Failed to initialize connector\n");

> -		return NULL;

> -	}

> -

> -	drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);

> -

> -	DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);

> -

> -	return connector;

> -}

> -

>   static int ltdc_get_caps(struct drm_device *ddev)

>   {

>   	struct ltdc_device *ldev = ddev->dev_private;

> @@ -972,7 +881,7 @@ static int ltdc_get_caps(struct drm_device *ddev)

>   	return 0;

>   }

>   

> -static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)

> +static struct drm_bridge *ltdc_get_bridge(struct drm_device *ddev)

>   {

>   	struct device *dev = ddev->dev;

>   	struct device_node *np = dev->of_node;

> @@ -1004,7 +913,10 @@ static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)

>   		}

>   	}

>   

> -	return panel;

> +	if (!panel)

> +		return ERR_PTR(-ENODEV);

> +

> +	return drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);

>   }

>   

>   int ltdc_load(struct drm_device *ddev)

> @@ -1014,7 +926,6 @@ int ltdc_load(struct drm_device *ddev)

>   	struct device *dev = ddev->dev;

>   	struct device_node *np = dev->of_node;

>   	struct drm_encoder *encoder;

> -	struct drm_connector *connector = NULL;

>   	struct drm_crtc *crtc;

>   	struct reset_control *rstc;

>   	struct resource res;

> @@ -1022,8 +933,8 @@ int ltdc_load(struct drm_device *ddev)

>   

>   	DRM_DEBUG_DRIVER("\n");

>   

> -	ldev->panel = ltdc_get_panel(ddev);

> -	if (!ldev->panel)

> +	ldev->bridge = ltdc_get_bridge(ddev);

> +	if (!ldev->bridge)

>   		return -EPROBE_DEFER;

>   

>   	rstc = of_reset_control_get(np, NULL);

> @@ -1082,28 +993,13 @@ int ltdc_load(struct drm_device *ddev)

>   

>   	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);

>   

> -	if (ldev->panel) {

> +	if (ldev->bridge) {

>   		encoder = ltdc_rgb_encoder_create(ddev);

>   		if (!encoder) {

>   			DRM_ERROR("Failed to create RGB encoder\n");

>   			ret = -EINVAL;

>   			goto err;

>   		}

> -

> -		connector = ltdc_rgb_connector_create(ddev);

> -		if (!connector) {

> -			DRM_ERROR("Failed to create RGB connector\n");

> -			ret = -EINVAL;

> -			goto err;

> -		}

> -

> -		ret = drm_mode_connector_attach_encoder(connector, encoder);

> -		if (ret) {

> -			DRM_ERROR("Failed to attach connector to encoder\n");

> -			goto err;

> -		}

> -

> -		drm_panel_attach(ldev->panel, connector);

>   	}

>   

>   	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);

> @@ -1130,8 +1026,8 @@ int ltdc_load(struct drm_device *ddev)

>   

>   	return 0;

>   err:

> -	if (ldev->panel)

> -		drm_panel_detach(ldev->panel);

> +	if (ldev->bridge)

> +		drm_panel_bridge_remove(ldev->bridge);

>   

>   	clk_disable_unprepare(ldev->pixel_clk);

>   

> @@ -1146,8 +1042,8 @@ void ltdc_unload(struct drm_device *ddev)

>   

>   	drm_vblank_cleanup(ddev);

>   

> -	if (ldev->panel)

> -		drm_panel_detach(ldev->panel);

> +	if (ldev->bridge)

> +		drm_panel_bridge_remove(ldev->bridge);

>   

>   	clk_disable_unprepare(ldev->pixel_clk);

>   }

> diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h

> index d7a9c736ac1e..d78cb0dd3200 100644

> --- a/drivers/gpu/drm/stm/ltdc.h

> +++ b/drivers/gpu/drm/stm/ltdc.h

> @@ -24,7 +24,7 @@ struct ltdc_device {

>   	struct drm_fbdev_cma *fbdev;

>   	void __iomem *regs;

>   	struct clk *pixel_clk;	/* lcd pixel clock */

> -	struct drm_panel *panel;

> +	struct drm_bridge *bridge;

>   	struct mutex err_lock;	/* protecting error_status */

>   	struct ltdc_caps caps;

>   	u32 clut[256];		/* color look up table */

>
Boris BREZILLON May 31, 2017, 6:26 a.m. UTC | #3
Hi Philippe,

Le Tue, 30 May 2017 16:55:42 +0000,
Philippe CORNU <philippe.cornu@st.com> a écrit :

> Hi Eric,
> 
> I took your patch for the panel-bridge and it works perfectly in both 
> DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)

I still don't understand how it can work without a call to
drm_bridge_attach() (which is used to link the RGB encoder to the DPI
connector). I'm probably missing something obvious. Maybe someone can
point it out :-).

Thanks,

Boris

> 
> ~160 lines have been removed from ltdc.c thanks to your panel-bridge code!
> 
> Many thanks
> Philippe
> 
> On 05/11/2017 08:31 PM, Eric Anholt wrote:
> > Another 100 lines of boilerplate gone.  Bridges aren't supported yet,
> > but will be trivial to add later.
> > 
> > Signed-off-by: Eric Anholt <eric@anholt.net>
> > ---
> > 
> > Also untested.
> > 
> >   drivers/gpu/drm/stm/ltdc.c | 128 +++++----------------------------------------
> >   drivers/gpu/drm/stm/ltdc.h |   2 +-
> >   2 files changed, 13 insertions(+), 117 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> > index a40418cda74a..41a1c5d68f5b 100644
> > --- a/drivers/gpu/drm/stm/ltdc.c
> > +++ b/drivers/gpu/drm/stm/ltdc.c
> > @@ -269,11 +269,6 @@ static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
> >   	return (struct ltdc_device *)enc->dev->dev_private;
> >   }
> >   
> > -static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
> > -{
> > -	return (struct ltdc_device *)con->dev->dev_private;
> > -}
> > -
> >   static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
> >   {
> >   	enum ltdc_pix_fmt pf;
> > @@ -815,22 +810,12 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
> >   
> >   static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
> >   {
> > -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
> > -
> >   	DRM_DEBUG_DRIVER("\n");
> > -
> > -	drm_panel_prepare(ldev->panel);
> > -	drm_panel_enable(ldev->panel);
> >   }
> >   
> >   static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
> >   {
> > -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
> > -
> >   	DRM_DEBUG_DRIVER("\n");
> > -
> > -	drm_panel_disable(ldev->panel);
> > -	drm_panel_unprepare(ldev->panel);
> >   }
> >   
> >   static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
> > @@ -863,82 +848,6 @@ static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
> >   	return encoder;
> >   }
> >   
> > -/*
> > - * DRM_CONNECTOR
> > - */
> > -
> > -static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
> > -{
> > -	struct drm_device *ddev = connector->dev;
> > -	struct ltdc_device *ldev = ddev->dev_private;
> > -	int ret = 0;
> > -
> > -	DRM_DEBUG_DRIVER("\n");
> > -
> > -	if (ldev->panel)
> > -		ret = drm_panel_get_modes(ldev->panel);
> > -
> > -	return ret < 0 ? 0 : ret;
> > -}
> > -
> > -static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
> > -	.get_modes = ltdc_rgb_connector_get_modes,
> > -};
> > -
> > -static enum drm_connector_status
> > -ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
> > -{
> > -	struct ltdc_device *ldev = connector_to_ltdc(connector);
> > -
> > -	return ldev->panel ? connector_status_connected :
> > -	       connector_status_disconnected;
> > -}
> > -
> > -static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
> > -{
> > -	DRM_DEBUG_DRIVER("\n");
> > -
> > -	drm_connector_unregister(connector);
> > -	drm_connector_cleanup(connector);
> > -}
> > -
> > -static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
> > -	.dpms = drm_atomic_helper_connector_dpms,
> > -	.fill_modes = drm_helper_probe_single_connector_modes,
> > -	.detect = ltdc_rgb_connector_detect,
> > -	.destroy = ltdc_rgb_connector_destroy,
> > -	.reset = drm_atomic_helper_connector_reset,
> > -	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> > -	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> > -};
> > -
> > -struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
> > -{
> > -	struct drm_connector *connector;
> > -	int err;
> > -
> > -	connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
> > -	if (!connector) {
> > -		DRM_ERROR("Failed to allocate connector\n");
> > -		return NULL;
> > -	}
> > -
> > -	connector->polled = DRM_CONNECTOR_POLL_HPD;
> > -
> > -	err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
> > -				 DRM_MODE_CONNECTOR_DPI);
> > -	if (err) {
> > -		DRM_ERROR("Failed to initialize connector\n");
> > -		return NULL;
> > -	}
> > -
> > -	drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
> > -
> > -	DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
> > -
> > -	return connector;
> > -}
> > -
> >   static int ltdc_get_caps(struct drm_device *ddev)
> >   {
> >   	struct ltdc_device *ldev = ddev->dev_private;
> > @@ -972,7 +881,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
> >   	return 0;
> >   }
> >   
> > -static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
> > +static struct drm_bridge *ltdc_get_bridge(struct drm_device *ddev)
> >   {
> >   	struct device *dev = ddev->dev;
> >   	struct device_node *np = dev->of_node;
> > @@ -1004,7 +913,10 @@ static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
> >   		}
> >   	}
> >   
> > -	return panel;
> > +	if (!panel)
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	return drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
> >   }
> >   
> >   int ltdc_load(struct drm_device *ddev)
> > @@ -1014,7 +926,6 @@ int ltdc_load(struct drm_device *ddev)
> >   	struct device *dev = ddev->dev;
> >   	struct device_node *np = dev->of_node;
> >   	struct drm_encoder *encoder;
> > -	struct drm_connector *connector = NULL;
> >   	struct drm_crtc *crtc;
> >   	struct reset_control *rstc;
> >   	struct resource res;
> > @@ -1022,8 +933,8 @@ int ltdc_load(struct drm_device *ddev)
> >   
> >   	DRM_DEBUG_DRIVER("\n");
> >   
> > -	ldev->panel = ltdc_get_panel(ddev);
> > -	if (!ldev->panel)
> > +	ldev->bridge = ltdc_get_bridge(ddev);
> > +	if (!ldev->bridge)
> >   		return -EPROBE_DEFER;
> >   
> >   	rstc = of_reset_control_get(np, NULL);
> > @@ -1082,28 +993,13 @@ int ltdc_load(struct drm_device *ddev)
> >   
> >   	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
> >   
> > -	if (ldev->panel) {
> > +	if (ldev->bridge) {
> >   		encoder = ltdc_rgb_encoder_create(ddev);
> >   		if (!encoder) {
> >   			DRM_ERROR("Failed to create RGB encoder\n");
> >   			ret = -EINVAL;
> >   			goto err;
> >   		}
> > -
> > -		connector = ltdc_rgb_connector_create(ddev);
> > -		if (!connector) {
> > -			DRM_ERROR("Failed to create RGB connector\n");
> > -			ret = -EINVAL;
> > -			goto err;
> > -		}
> > -
> > -		ret = drm_mode_connector_attach_encoder(connector, encoder);
> > -		if (ret) {
> > -			DRM_ERROR("Failed to attach connector to encoder\n");
> > -			goto err;
> > -		}
> > -
> > -		drm_panel_attach(ldev->panel, connector);
> >   	}
> >   
> >   	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
> > @@ -1130,8 +1026,8 @@ int ltdc_load(struct drm_device *ddev)
> >   
> >   	return 0;
> >   err:
> > -	if (ldev->panel)
> > -		drm_panel_detach(ldev->panel);
> > +	if (ldev->bridge)
> > +		drm_panel_bridge_remove(ldev->bridge);
> >   
> >   	clk_disable_unprepare(ldev->pixel_clk);
> >   
> > @@ -1146,8 +1042,8 @@ void ltdc_unload(struct drm_device *ddev)
> >   
> >   	drm_vblank_cleanup(ddev);
> >   
> > -	if (ldev->panel)
> > -		drm_panel_detach(ldev->panel);
> > +	if (ldev->bridge)
> > +		drm_panel_bridge_remove(ldev->bridge);
> >   
> >   	clk_disable_unprepare(ldev->pixel_clk);
> >   }
> > diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
> > index d7a9c736ac1e..d78cb0dd3200 100644
> > --- a/drivers/gpu/drm/stm/ltdc.h
> > +++ b/drivers/gpu/drm/stm/ltdc.h
> > @@ -24,7 +24,7 @@ struct ltdc_device {
> >   	struct drm_fbdev_cma *fbdev;
> >   	void __iomem *regs;
> >   	struct clk *pixel_clk;	/* lcd pixel clock */
> > -	struct drm_panel *panel;
> > +	struct drm_bridge *bridge;
> >   	struct mutex err_lock;	/* protecting error_status */
> >   	struct ltdc_caps caps;
> >   	u32 clut[256];		/* color look up table */
> >
Archit Taneja May 31, 2017, 8:01 a.m. UTC | #4
Hi Boris,

On 05/31/2017 11:56 AM, Boris Brezillon wrote:
> Hi Philippe,
>
> Le Tue, 30 May 2017 16:55:42 +0000,
> Philippe CORNU <philippe.cornu@st.com> a écrit :
>
>> Hi Eric,
>>
>> I took your patch for the panel-bridge and it works perfectly in both
>> DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)
>
> I still don't understand how it can work without a call to
> drm_bridge_attach() (which is used to link the RGB encoder to the DPI
> connector). I'm probably missing something obvious. Maybe someone can
> point it out :-).

I think the expectation is that there will be a follow-up patch that
would add bridge support. Philippe had posted a patch for adding bridges
to ltdc before:

https://patchwork.kernel.org/patch/9724835/

He can now redo his patch over Eric's panel-bridge patch-set.

Thanks,
Archit

>
> Thanks,
>
> Boris
>
>>
>> ~160 lines have been removed from ltdc.c thanks to your panel-bridge code!
>>
>> Many thanks
>> Philippe
>>
>> On 05/11/2017 08:31 PM, Eric Anholt wrote:
>>> Another 100 lines of boilerplate gone.  Bridges aren't supported yet,
>>> but will be trivial to add later.
>>>
>>> Signed-off-by: Eric Anholt <eric@anholt.net>
>>> ---
>>>
>>> Also untested.
>>>
>>>   drivers/gpu/drm/stm/ltdc.c | 128 +++++----------------------------------------
>>>   drivers/gpu/drm/stm/ltdc.h |   2 +-
>>>   2 files changed, 13 insertions(+), 117 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
>>> index a40418cda74a..41a1c5d68f5b 100644
>>> --- a/drivers/gpu/drm/stm/ltdc.c
>>> +++ b/drivers/gpu/drm/stm/ltdc.c
>>> @@ -269,11 +269,6 @@ static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
>>>   	return (struct ltdc_device *)enc->dev->dev_private;
>>>   }
>>>
>>> -static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
>>> -{
>>> -	return (struct ltdc_device *)con->dev->dev_private;
>>> -}
>>> -
>>>   static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
>>>   {
>>>   	enum ltdc_pix_fmt pf;
>>> @@ -815,22 +810,12 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
>>>
>>>   static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
>>>   {
>>> -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
>>> -
>>>   	DRM_DEBUG_DRIVER("\n");
>>> -
>>> -	drm_panel_prepare(ldev->panel);
>>> -	drm_panel_enable(ldev->panel);
>>>   }
>>>
>>>   static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
>>>   {
>>> -	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
>>> -
>>>   	DRM_DEBUG_DRIVER("\n");
>>> -
>>> -	drm_panel_disable(ldev->panel);
>>> -	drm_panel_unprepare(ldev->panel);
>>>   }
>>>
>>>   static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
>>> @@ -863,82 +848,6 @@ static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
>>>   	return encoder;
>>>   }
>>>
>>> -/*
>>> - * DRM_CONNECTOR
>>> - */
>>> -
>>> -static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
>>> -{
>>> -	struct drm_device *ddev = connector->dev;
>>> -	struct ltdc_device *ldev = ddev->dev_private;
>>> -	int ret = 0;
>>> -
>>> -	DRM_DEBUG_DRIVER("\n");
>>> -
>>> -	if (ldev->panel)
>>> -		ret = drm_panel_get_modes(ldev->panel);
>>> -
>>> -	return ret < 0 ? 0 : ret;
>>> -}
>>> -
>>> -static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
>>> -	.get_modes = ltdc_rgb_connector_get_modes,
>>> -};
>>> -
>>> -static enum drm_connector_status
>>> -ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
>>> -{
>>> -	struct ltdc_device *ldev = connector_to_ltdc(connector);
>>> -
>>> -	return ldev->panel ? connector_status_connected :
>>> -	       connector_status_disconnected;
>>> -}
>>> -
>>> -static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
>>> -{
>>> -	DRM_DEBUG_DRIVER("\n");
>>> -
>>> -	drm_connector_unregister(connector);
>>> -	drm_connector_cleanup(connector);
>>> -}
>>> -
>>> -static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
>>> -	.dpms = drm_atomic_helper_connector_dpms,
>>> -	.fill_modes = drm_helper_probe_single_connector_modes,
>>> -	.detect = ltdc_rgb_connector_detect,
>>> -	.destroy = ltdc_rgb_connector_destroy,
>>> -	.reset = drm_atomic_helper_connector_reset,
>>> -	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
>>> -	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
>>> -};
>>> -
>>> -struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
>>> -{
>>> -	struct drm_connector *connector;
>>> -	int err;
>>> -
>>> -	connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
>>> -	if (!connector) {
>>> -		DRM_ERROR("Failed to allocate connector\n");
>>> -		return NULL;
>>> -	}
>>> -
>>> -	connector->polled = DRM_CONNECTOR_POLL_HPD;
>>> -
>>> -	err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
>>> -				 DRM_MODE_CONNECTOR_DPI);
>>> -	if (err) {
>>> -		DRM_ERROR("Failed to initialize connector\n");
>>> -		return NULL;
>>> -	}
>>> -
>>> -	drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
>>> -
>>> -	DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
>>> -
>>> -	return connector;
>>> -}
>>> -
>>>   static int ltdc_get_caps(struct drm_device *ddev)
>>>   {
>>>   	struct ltdc_device *ldev = ddev->dev_private;
>>> @@ -972,7 +881,7 @@ static int ltdc_get_caps(struct drm_device *ddev)
>>>   	return 0;
>>>   }
>>>
>>> -static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
>>> +static struct drm_bridge *ltdc_get_bridge(struct drm_device *ddev)
>>>   {
>>>   	struct device *dev = ddev->dev;
>>>   	struct device_node *np = dev->of_node;
>>> @@ -1004,7 +913,10 @@ static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
>>>   		}
>>>   	}
>>>
>>> -	return panel;
>>> +	if (!panel)
>>> +		return ERR_PTR(-ENODEV);
>>> +
>>> +	return drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
>>>   }
>>>
>>>   int ltdc_load(struct drm_device *ddev)
>>> @@ -1014,7 +926,6 @@ int ltdc_load(struct drm_device *ddev)
>>>   	struct device *dev = ddev->dev;
>>>   	struct device_node *np = dev->of_node;
>>>   	struct drm_encoder *encoder;
>>> -	struct drm_connector *connector = NULL;
>>>   	struct drm_crtc *crtc;
>>>   	struct reset_control *rstc;
>>>   	struct resource res;
>>> @@ -1022,8 +933,8 @@ int ltdc_load(struct drm_device *ddev)
>>>
>>>   	DRM_DEBUG_DRIVER("\n");
>>>
>>> -	ldev->panel = ltdc_get_panel(ddev);
>>> -	if (!ldev->panel)
>>> +	ldev->bridge = ltdc_get_bridge(ddev);
>>> +	if (!ldev->bridge)
>>>   		return -EPROBE_DEFER;
>>>
>>>   	rstc = of_reset_control_get(np, NULL);
>>> @@ -1082,28 +993,13 @@ int ltdc_load(struct drm_device *ddev)
>>>
>>>   	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
>>>
>>> -	if (ldev->panel) {
>>> +	if (ldev->bridge) {
>>>   		encoder = ltdc_rgb_encoder_create(ddev);
>>>   		if (!encoder) {
>>>   			DRM_ERROR("Failed to create RGB encoder\n");
>>>   			ret = -EINVAL;
>>>   			goto err;
>>>   		}
>>> -
>>> -		connector = ltdc_rgb_connector_create(ddev);
>>> -		if (!connector) {
>>> -			DRM_ERROR("Failed to create RGB connector\n");
>>> -			ret = -EINVAL;
>>> -			goto err;
>>> -		}
>>> -
>>> -		ret = drm_mode_connector_attach_encoder(connector, encoder);
>>> -		if (ret) {
>>> -			DRM_ERROR("Failed to attach connector to encoder\n");
>>> -			goto err;
>>> -		}
>>> -
>>> -		drm_panel_attach(ldev->panel, connector);
>>>   	}
>>>
>>>   	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
>>> @@ -1130,8 +1026,8 @@ int ltdc_load(struct drm_device *ddev)
>>>
>>>   	return 0;
>>>   err:
>>> -	if (ldev->panel)
>>> -		drm_panel_detach(ldev->panel);
>>> +	if (ldev->bridge)
>>> +		drm_panel_bridge_remove(ldev->bridge);
>>>
>>>   	clk_disable_unprepare(ldev->pixel_clk);
>>>
>>> @@ -1146,8 +1042,8 @@ void ltdc_unload(struct drm_device *ddev)
>>>
>>>   	drm_vblank_cleanup(ddev);
>>>
>>> -	if (ldev->panel)
>>> -		drm_panel_detach(ldev->panel);
>>> +	if (ldev->bridge)
>>> +		drm_panel_bridge_remove(ldev->bridge);
>>>
>>>   	clk_disable_unprepare(ldev->pixel_clk);
>>>   }
>>> diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
>>> index d7a9c736ac1e..d78cb0dd3200 100644
>>> --- a/drivers/gpu/drm/stm/ltdc.h
>>> +++ b/drivers/gpu/drm/stm/ltdc.h
>>> @@ -24,7 +24,7 @@ struct ltdc_device {
>>>   	struct drm_fbdev_cma *fbdev;
>>>   	void __iomem *regs;
>>>   	struct clk *pixel_clk;	/* lcd pixel clock */
>>> -	struct drm_panel *panel;
>>> +	struct drm_bridge *bridge;
>>>   	struct mutex err_lock;	/* protecting error_status */
>>>   	struct ltdc_caps caps;
>>>   	u32 clut[256];		/* color look up table */
>>>
>
Boris BREZILLON May 31, 2017, 8:07 a.m. UTC | #5
Hi Archit,

Le Wed, 31 May 2017 13:31:16 +0530,
Archit Taneja <architt@codeaurora.org> a écrit :

> Hi Boris,
> 
> On 05/31/2017 11:56 AM, Boris Brezillon wrote:
> > Hi Philippe,
> >
> > Le Tue, 30 May 2017 16:55:42 +0000,
> > Philippe CORNU <philippe.cornu@st.com> a écrit :
> >  
> >> Hi Eric,
> >>
> >> I took your patch for the panel-bridge and it works perfectly in both
> >> DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)  
> >
> > I still don't understand how it can work without a call to
> > drm_bridge_attach() (which is used to link the RGB encoder to the DPI
> > connector). I'm probably missing something obvious. Maybe someone can
> > point it out :-).  
> 
> I think the expectation is that there will be a follow-up patch that
> would add bridge support. Philippe had posted a patch for adding bridges
> to ltdc before:
> 
> https://patchwork.kernel.org/patch/9724835/
> 
> He can now redo his patch over Eric's panel-bridge patch-set.

But by doing that you're breaking bisectability, or is it working when
applying only Eric's patchset?

If applying this patch breaks the driver, why not applying it after
bridge support has been added to this driver?

Regards,

Boris
Archit Taneja May 31, 2017, 8:35 a.m. UTC | #6
On 05/31/2017 01:37 PM, Boris Brezillon wrote:
> Hi Archit,
>
> Le Wed, 31 May 2017 13:31:16 +0530,
> Archit Taneja <architt@codeaurora.org> a écrit :
>
>> Hi Boris,
>>
>> On 05/31/2017 11:56 AM, Boris Brezillon wrote:
>>> Hi Philippe,
>>>
>>> Le Tue, 30 May 2017 16:55:42 +0000,
>>> Philippe CORNU <philippe.cornu@st.com> a écrit :
>>>
>>>> Hi Eric,
>>>>
>>>> I took your patch for the panel-bridge and it works perfectly in both
>>>> DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)
>>>
>>> I still don't understand how it can work without a call to
>>> drm_bridge_attach() (which is used to link the RGB encoder to the DPI
>>> connector). I'm probably missing something obvious. Maybe someone can
>>> point it out :-).
>>
>> I think the expectation is that there will be a follow-up patch that
>> would add bridge support. Philippe had posted a patch for adding bridges
>> to ltdc before:
>>
>> https://patchwork.kernel.org/patch/9724835/
>>
>> He can now redo his patch over Eric's panel-bridge patch-set.
>
> But by doing that you're breaking bisectability, or is it working when
> applying only Eric's patchset?
>
> If applying this patch breaks the driver, why not applying it after
> bridge support has been added to this driver?

Yeah, it would break the driver. Philippe can create a patch that adds
bridge support using the panel-bridge glue layer using Eric's patch as a
reference. In the end, there should only be a single patch.

Thanks,
Archit

>
> Regards,
>
> Boris
>
Philippe CORNU June 1, 2017, 9:53 a.m. UTC | #7
On 05/31/2017 10:35 AM, Archit Taneja wrote:
> 

> 

> On 05/31/2017 01:37 PM, Boris Brezillon wrote:

>> Hi Archit,

>>

>> Le Wed, 31 May 2017 13:31:16 +0530,

>> Archit Taneja <architt@codeaurora.org> a écrit :

>>

>>> Hi Boris,

>>>

>>> On 05/31/2017 11:56 AM, Boris Brezillon wrote:

>>>> Hi Philippe,

>>>>

>>>> Le Tue, 30 May 2017 16:55:42 +0000,

>>>> Philippe CORNU <philippe.cornu@st.com> a écrit :

>>>>

>>>>> Hi Eric,

>>>>>

>>>>> I took your patch for the panel-bridge and it works perfectly in both

>>>>> DPI mode (panel RGB //) and DSI mode (bridge dw mipi dsi), bravo :-)

>>>>

>>>> I still don't understand how it can work without a call to

>>>> drm_bridge_attach() (which is used to link the RGB encoder to the DPI

>>>> connector). I'm probably missing something obvious. Maybe someone can

>>>> point it out :-).

>>>

>>> I think the expectation is that there will be a follow-up patch that

>>> would add bridge support. Philippe had posted a patch for adding bridges

>>> to ltdc before:

>>>

>>> https://patchwork.kernel.org/patch/9724835/

>>>

>>> He can now redo his patch over Eric's panel-bridge patch-set.

>>

>> But by doing that you're breaking bisectability, or is it working when

>> applying only Eric's patchset?

>>

>> If applying this patch breaks the driver, why not applying it after

>> bridge support has been added to this driver?

> 

> Yeah, it would break the driver. Philippe can create a patch that adds

> bridge support using the panel-bridge glue layer using Eric's patch as a

> reference. In the end, there should only be a single patch.

> 

> Thanks,

> Archit

> 

>>

>> Regards,

>>

>> Boris

>>

> 


Hi Boris & Archit,

Sorry, I should have been clearer about what I did. Let me explain more 
below:

1 - I applied Eric's patch named "drm/bridge: Refactor out the panel 
wrapper from the lvds-encoder bridge" (https://lkml.org/lkml/2017/5/11/784)

2 - I did a patch on ltdc.c combining Eric's patch named "drm/ltdc: Use 
the panel-bridge helper" (https://lkml.org/lkml/2017/5/11/783) and my 
own preamble patch for STM32 DSI named "drm/stm: ltdc: Add bridge 
support" (https://patchwork.kernel.org/patch/9738427/)

And tests are successful in both DPI mode (panel RGB //) and DSI mode 
(bridge dw mipi dsi).

As suggested in the last Archit's email, there will be a single patch 
that will add bridge support to ltdc.c and I will send it in the "STM32 
DSI HOST" v3 version, if you all agree of course :)

Many thanks for all your great comments,
Philippe
diff mbox

Patch

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index a40418cda74a..41a1c5d68f5b 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -269,11 +269,6 @@  static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
 	return (struct ltdc_device *)enc->dev->dev_private;
 }
 
-static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
-{
-	return (struct ltdc_device *)con->dev->dev_private;
-}
-
 static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
 {
 	enum ltdc_pix_fmt pf;
@@ -815,22 +810,12 @@  static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 
 static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
 {
-	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
 	DRM_DEBUG_DRIVER("\n");
-
-	drm_panel_prepare(ldev->panel);
-	drm_panel_enable(ldev->panel);
 }
 
 static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
 {
-	struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
 	DRM_DEBUG_DRIVER("\n");
-
-	drm_panel_disable(ldev->panel);
-	drm_panel_unprepare(ldev->panel);
 }
 
 static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
@@ -863,82 +848,6 @@  static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
 	return encoder;
 }
 
-/*
- * DRM_CONNECTOR
- */
-
-static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
-{
-	struct drm_device *ddev = connector->dev;
-	struct ltdc_device *ldev = ddev->dev_private;
-	int ret = 0;
-
-	DRM_DEBUG_DRIVER("\n");
-
-	if (ldev->panel)
-		ret = drm_panel_get_modes(ldev->panel);
-
-	return ret < 0 ? 0 : ret;
-}
-
-static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
-	.get_modes = ltdc_rgb_connector_get_modes,
-};
-
-static enum drm_connector_status
-ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
-{
-	struct ltdc_device *ldev = connector_to_ltdc(connector);
-
-	return ldev->panel ? connector_status_connected :
-	       connector_status_disconnected;
-}
-
-static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
-{
-	DRM_DEBUG_DRIVER("\n");
-
-	drm_connector_unregister(connector);
-	drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
-	.dpms = drm_atomic_helper_connector_dpms,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.detect = ltdc_rgb_connector_detect,
-	.destroy = ltdc_rgb_connector_destroy,
-	.reset = drm_atomic_helper_connector_reset,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
-{
-	struct drm_connector *connector;
-	int err;
-
-	connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
-	if (!connector) {
-		DRM_ERROR("Failed to allocate connector\n");
-		return NULL;
-	}
-
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
-				 DRM_MODE_CONNECTOR_DPI);
-	if (err) {
-		DRM_ERROR("Failed to initialize connector\n");
-		return NULL;
-	}
-
-	drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
-
-	DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
-
-	return connector;
-}
-
 static int ltdc_get_caps(struct drm_device *ddev)
 {
 	struct ltdc_device *ldev = ddev->dev_private;
@@ -972,7 +881,7 @@  static int ltdc_get_caps(struct drm_device *ddev)
 	return 0;
 }
 
-static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
+static struct drm_bridge *ltdc_get_bridge(struct drm_device *ddev)
 {
 	struct device *dev = ddev->dev;
 	struct device_node *np = dev->of_node;
@@ -1004,7 +913,10 @@  static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
 		}
 	}
 
-	return panel;
+	if (!panel)
+		return ERR_PTR(-ENODEV);
+
+	return drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
 }
 
 int ltdc_load(struct drm_device *ddev)
@@ -1014,7 +926,6 @@  int ltdc_load(struct drm_device *ddev)
 	struct device *dev = ddev->dev;
 	struct device_node *np = dev->of_node;
 	struct drm_encoder *encoder;
-	struct drm_connector *connector = NULL;
 	struct drm_crtc *crtc;
 	struct reset_control *rstc;
 	struct resource res;
@@ -1022,8 +933,8 @@  int ltdc_load(struct drm_device *ddev)
 
 	DRM_DEBUG_DRIVER("\n");
 
-	ldev->panel = ltdc_get_panel(ddev);
-	if (!ldev->panel)
+	ldev->bridge = ltdc_get_bridge(ddev);
+	if (!ldev->bridge)
 		return -EPROBE_DEFER;
 
 	rstc = of_reset_control_get(np, NULL);
@@ -1082,28 +993,13 @@  int ltdc_load(struct drm_device *ddev)
 
 	DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
 
-	if (ldev->panel) {
+	if (ldev->bridge) {
 		encoder = ltdc_rgb_encoder_create(ddev);
 		if (!encoder) {
 			DRM_ERROR("Failed to create RGB encoder\n");
 			ret = -EINVAL;
 			goto err;
 		}
-
-		connector = ltdc_rgb_connector_create(ddev);
-		if (!connector) {
-			DRM_ERROR("Failed to create RGB connector\n");
-			ret = -EINVAL;
-			goto err;
-		}
-
-		ret = drm_mode_connector_attach_encoder(connector, encoder);
-		if (ret) {
-			DRM_ERROR("Failed to attach connector to encoder\n");
-			goto err;
-		}
-
-		drm_panel_attach(ldev->panel, connector);
 	}
 
 	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
@@ -1130,8 +1026,8 @@  int ltdc_load(struct drm_device *ddev)
 
 	return 0;
 err:
-	if (ldev->panel)
-		drm_panel_detach(ldev->panel);
+	if (ldev->bridge)
+		drm_panel_bridge_remove(ldev->bridge);
 
 	clk_disable_unprepare(ldev->pixel_clk);
 
@@ -1146,8 +1042,8 @@  void ltdc_unload(struct drm_device *ddev)
 
 	drm_vblank_cleanup(ddev);
 
-	if (ldev->panel)
-		drm_panel_detach(ldev->panel);
+	if (ldev->bridge)
+		drm_panel_bridge_remove(ldev->bridge);
 
 	clk_disable_unprepare(ldev->pixel_clk);
 }
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index d7a9c736ac1e..d78cb0dd3200 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -24,7 +24,7 @@  struct ltdc_device {
 	struct drm_fbdev_cma *fbdev;
 	void __iomem *regs;
 	struct clk *pixel_clk;	/* lcd pixel clock */
-	struct drm_panel *panel;
+	struct drm_bridge *bridge;
 	struct mutex err_lock;	/* protecting error_status */
 	struct ltdc_caps caps;
 	u32 clut[256];		/* color look up table */