diff mbox series

[RFC,v2,5/8] drm/bridge: dw-hdmi: support dynamically get input/out color info

Message ID 20181130134301.17963-6-narmstrong@baylibre.com (mailing list archive)
State Superseded
Headers show
Series drm/meson: Add support for HDMI2.0 4k60 | expand

Commit Message

Neil Armstrong Nov. 30, 2018, 1:42 p.m. UTC
From: Zheng Yang <zhengyang@rock-chips.com>

To get input/output bus_format/enc_format dynamically, this patch
introduce following funstion in plat_data:
	- get_input_bus_format
	- get_output_bus_format
	- get_enc_in_encoding
	- get_enc_out_encoding

Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++++++------
 include/drm/bridge/dw_hdmi.h              |  5 ++++
 2 files changed, 26 insertions(+), 7 deletions(-)

Comments

Heiko Stübner Dec. 14, 2018, 12:13 p.m. UTC | #1
Am Freitag, 30. November 2018, 14:42:58 CET schrieb Neil Armstrong:
> From: Zheng Yang <zhengyang@rock-chips.com>
> 
> To get input/output bus_format/enc_format dynamically, this patch
> introduce following funstion in plat_data:
> 	- get_input_bus_format
> 	- get_output_bus_format
> 	- get_enc_in_encoding
> 	- get_enc_out_encoding
> 
> Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

Please see comments in patch1 for details.

on rk3288 and rk3328
Tested-by: Heiko Stuebner <heiko@sntech.de>
Andrzej Hajda Dec. 19, 2018, 7:26 a.m. UTC | #2
On 30.11.2018 14:42, Neil Armstrong wrote:
> From: Zheng Yang <zhengyang@rock-chips.com>
>
> To get input/output bus_format/enc_format dynamically, this patch
> introduce following funstion in plat_data:
> 	- get_input_bus_format
> 	- get_output_bus_format
> 	- get_enc_in_encoding
> 	- get_enc_out_encoding


It seems fishy. On one side description says about dynamic resolution of
formats and encodings.

On the other side these functions as only argument takes platform_data
which should be rather static.

Where is this "dynamic" thing? The only usage of these callbacks I have
found in next patches is also not dynamic, the functions just return
some static value.

Moreover function takes void* argument, which is again something
suspicious, why cannot you pass know structure?

And finally encoding usually should depend on display mode, it should
not depend only static data.


What kind of problems do you want to solve here?


Regards

Andrzej



>
> Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++++++------
>  include/drm/bridge/dw_hdmi.h              |  5 ++++
>  2 files changed, 26 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4a9a24e854db..bd564ffdf18b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1810,6 +1810,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
>  static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  {
>  	int ret;
> +	void *data = hdmi->plat_data->phy_data;
>  
>  	hdmi_disable_overflow_interrupts(hdmi);
>  
> @@ -1821,10 +1822,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  		dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
>  	}
>  
> -	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
> -	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
> -	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
> -	    (hdmi->vic == 17) || (hdmi->vic == 18))
> +	if (hdmi->plat_data->get_enc_out_encoding)
> +		hdmi->hdmi_data.enc_out_encoding =
> +			hdmi->plat_data->get_enc_out_encoding(data);
> +	else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
> +		 (hdmi->vic == 21) || (hdmi->vic == 22) ||
> +		 (hdmi->vic == 2) || (hdmi->vic == 3) ||
> +		 (hdmi->vic == 17) || (hdmi->vic == 18))
>  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
>  	else
>  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
> @@ -1833,21 +1837,31 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
>  
>  	/* TOFIX: Get input format from plat data or fallback to RGB888 */
> -	if (hdmi->plat_data->input_bus_format)
> +	if (hdmi->plat_data->get_input_bus_format)
> +		hdmi->hdmi_data.enc_in_bus_format =
> +			hdmi->plat_data->get_input_bus_format(data);
> +	else if (hdmi->plat_data->input_bus_format)
>  		hdmi->hdmi_data.enc_in_bus_format =
>  			hdmi->plat_data->input_bus_format;
>  	else
>  		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
>  	/* TOFIX: Get input encoding from plat data or fallback to none */
> -	if (hdmi->plat_data->input_bus_encoding)
> +	if (hdmi->plat_data->get_enc_in_encoding)
> +		hdmi->hdmi_data.enc_in_encoding =
> +			hdmi->plat_data->get_enc_in_encoding(data);
> +	else if (hdmi->plat_data->input_bus_encoding)
>  		hdmi->hdmi_data.enc_in_encoding =
>  			hdmi->plat_data->input_bus_encoding;
>  	else
>  		hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
>  
>  	/* TOFIX: Default to RGB888 output format */
> -	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> +	if (hdmi->plat_data->get_output_bus_format)
> +		hdmi->hdmi_data.enc_out_bus_format =
> +			hdmi->plat_data->get_output_bus_format(data);
> +	else
> +		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
>  	hdmi->hdmi_data.pix_repet_factor = 0;
>  	hdmi->hdmi_data.hdcp_enable = 0;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 7a02744ce0bc..2e797f782c51 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -142,6 +142,11 @@ struct dw_hdmi_plat_data {
>  	int (*configure_phy)(struct dw_hdmi *hdmi,
>  			     const struct dw_hdmi_plat_data *pdata,
>  			     unsigned long mpixelclock);
> +
> +	unsigned long (*get_input_bus_format)(void *data);
> +	unsigned long (*get_output_bus_format)(void *data);
> +	unsigned long (*get_enc_in_encoding)(void *data);
> +	unsigned long (*get_enc_out_encoding)(void *data);
>  };
>  
>  struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
Laurent Pinchart Dec. 19, 2018, 7:50 a.m. UTC | #3
Hello,

On Wednesday, 19 December 2018 09:26:08 EET Andrzej Hajda wrote:
> On 30.11.2018 14:42, Neil Armstrong wrote:
> > From: Zheng Yang <zhengyang@rock-chips.com>
> > 
> > To get input/output bus_format/enc_format dynamically, this patch
> > 
> > introduce following funstion in plat_data:
> > 	- get_input_bus_format
> > 	- get_output_bus_format
> > 	- get_enc_in_encoding
> > 	- get_enc_out_encoding
> 
> It seems fishy. On one side description says about dynamic resolution of
> formats and encodings.
> 
> On the other side these functions as only argument takes platform_data
> which should be rather static.
> 
> Where is this "dynamic" thing? The only usage of these callbacks I have
> found in next patches is also not dynamic, the functions just return
> some static value.
> 
> Moreover function takes void* argument, which is again something
> suspicious, why cannot you pass know structure?
> 
> And finally encoding usually should depend on display mode, it should
> not depend only static data.
> 
> 
> What kind of problems do you want to solve here?

I would add that this doesn't seem to be specific to dw-hdmi in any way. I'd 
prefer an API at the drm_bridge level to handle this.

> > Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
> > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> > ---
> > 
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++++++------
> >  include/drm/bridge/dw_hdmi.h              |  5 ++++
> >  2 files changed, 26 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
> > 4a9a24e854db..bd564ffdf18b 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -1810,6 +1810,7 @@ static void hdmi_disable_overflow_interrupts(struct
> > dw_hdmi *hdmi)> 
> >  static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode
> >  *mode) {
> >  
> >  	int ret;
> > 
> > +	void *data = hdmi->plat_data->phy_data;
> > 
> >  	hdmi_disable_overflow_interrupts(hdmi);
> > 
> > @@ -1821,10 +1822,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
> > struct drm_display_mode *mode)> 
> >  		dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
> >  	
> >  	}
> > 
> > -	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
> > -	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
> > -	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
> > -	    (hdmi->vic == 17) || (hdmi->vic == 18))
> > +	if (hdmi->plat_data->get_enc_out_encoding)
> > +		hdmi->hdmi_data.enc_out_encoding =
> > +			hdmi->plat_data->get_enc_out_encoding(data);
> > +	else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
> > +		 (hdmi->vic == 21) || (hdmi->vic == 22) ||
> > +		 (hdmi->vic == 2) || (hdmi->vic == 3) ||
> > +		 (hdmi->vic == 17) || (hdmi->vic == 18))
> > 
> >  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
> >  	
> >  	else
> >  	
> >  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
> > 
> > @@ -1833,21 +1837,31 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
> > struct drm_display_mode *mode)> 
> >  	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
> >  	
> >  	/* TOFIX: Get input format from plat data or fallback to RGB888 */
> > 
> > -	if (hdmi->plat_data->input_bus_format)
> > +	if (hdmi->plat_data->get_input_bus_format)
> > +		hdmi->hdmi_data.enc_in_bus_format =
> > +			hdmi->plat_data->get_input_bus_format(data);
> > +	else if (hdmi->plat_data->input_bus_format)
> > 
> >  		hdmi->hdmi_data.enc_in_bus_format =
> >  		
> >  			hdmi->plat_data->input_bus_format;
> >  	
> >  	else
> >  	
> >  		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> >  	
> >  	/* TOFIX: Get input encoding from plat data or fallback to none */
> > 
> > -	if (hdmi->plat_data->input_bus_encoding)
> > +	if (hdmi->plat_data->get_enc_in_encoding)
> > +		hdmi->hdmi_data.enc_in_encoding =
> > +			hdmi->plat_data->get_enc_in_encoding(data);
> > +	else if (hdmi->plat_data->input_bus_encoding)
> > 
> >  		hdmi->hdmi_data.enc_in_encoding =
> >  		
> >  			hdmi->plat_data->input_bus_encoding;
> >  	
> >  	else
> >  	
> >  		hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
> >  	
> >  	/* TOFIX: Default to RGB888 output format */
> > 
> > -	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> > +	if (hdmi->plat_data->get_output_bus_format)
> > +		hdmi->hdmi_data.enc_out_bus_format =
> > +			hdmi->plat_data->get_output_bus_format(data);
> > +	else
> > +		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> > 
> >  	hdmi->hdmi_data.pix_repet_factor = 0;
> >  	hdmi->hdmi_data.hdcp_enable = 0;
> > 
> > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > index 7a02744ce0bc..2e797f782c51 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -142,6 +142,11 @@ struct dw_hdmi_plat_data {
> > 
> >  	int (*configure_phy)(struct dw_hdmi *hdmi,
> >  	
> >  			     const struct dw_hdmi_plat_data *pdata,
> >  			     unsigned long mpixelclock);
> > 
> > +
> > +	unsigned long (*get_input_bus_format)(void *data);
> > +	unsigned long (*get_output_bus_format)(void *data);
> > +	unsigned long (*get_enc_in_encoding)(void *data);
> > +	unsigned long (*get_enc_out_encoding)(void *data);
> > 
> >  };
> >  
> >  struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
Neil Armstrong Dec. 20, 2018, 7:37 a.m. UTC | #4
Hi Andrzej, Laurent,

Thanks for your review.

On 19/12/2018 08:50, Laurent Pinchart wrote:
> Hello,
> 
> On Wednesday, 19 December 2018 09:26:08 EET Andrzej Hajda wrote:
>> On 30.11.2018 14:42, Neil Armstrong wrote:
>>> From: Zheng Yang <zhengyang@rock-chips.com>
>>>
>>> To get input/output bus_format/enc_format dynamically, this patch
>>>
>>> introduce following funstion in plat_data:
>>> 	- get_input_bus_format
>>> 	- get_output_bus_format
>>> 	- get_enc_in_encoding
>>> 	- get_enc_out_encoding
>>
>> It seems fishy. On one side description says about dynamic resolution of
>> formats and encodings.
>>
>> On the other side these functions as only argument takes platform_data
>> which should be rather static.

They are callbacks to the "glue" code, similar the PHY and HPD callbacks,
they will return different encodings and formats depending on the current mode
being atomically set.

>>
>> Where is this "dynamic" thing? The only usage of these callbacks I have
>> found in next patches is also not dynamic, the functions just return
>> some static value.

in patch 7 & 8 we return the current glue dw_hdmi->input_bus_format
and dw_hdmi->output_bus_format set during the encoder atomic_check()

>>
>> Moreover function takes void* argument, which is again something
>> suspicious, why cannot you pass know structure?

Yes, we should also pass dw_hdmi along the dw_plat_data->phy_data we
already pass.

>>
>> And finally encoding usually should depend on display mode, it should
>> not depend only static data.

It does not, there are fallbacks already in place, where you can override
with static data (the bus encoding and format can be fixed) or dynamic
to solve the yuv420 format.
Amlogic pipeline can *only* output in YUV (444, 422 or 420) so I pushed
support for statically describing the input format and encoding using
V4L2 definitions.

>>
>>
>> What kind of problems do you want to solve here?

We try to solve 2 things :
- The YUV420 HDMI2.0 mode, but the DW-HDMI CSC cannot convert to/from YUV420, so
it's in passthrought only. So the encoder must output in yuv420 and the controller
must know the input format and the output format, and this dynamically.
- Today the DW-HDMI forces RGB 8bit output, but we may prefer YUV444 or YU422 depending
on the sink and eventually output in 10, 12 or 16bit mode. This logic should
not be in the controller bridge code.

To solve these uses case, we put the logic in the encoder to determine what is
the DW-HDMI input format+encoding and the needed output format+encoding.

Today, the encoding callbacks are not used in this patchset, but they follow the
same scheme.

> 
> I would add that this doesn't seem to be specific to dw-hdmi in any way. I'd 
> prefer an API at the drm_bridge level to handle this.

Can you point me what you have in mind ? I'll be happy to implement it.

These callbacks are only an extension of the hdmi->plat_data->input_bus_format
and hdmi->plat_data->input_bus_encoding I introduced a few times ago.

I'd really like to solve this correctly, but still solve it at some point !
The YUV420 support is handy to easily support 4k60 for cheap and older TVs
without the hassle of SCDC and TMDS scrambling.

Neil

> 
>>> Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>>
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 28 +++++++++++++++++------
>>>  include/drm/bridge/dw_hdmi.h              |  5 ++++
>>>  2 files changed, 26 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
>>> 4a9a24e854db..bd564ffdf18b 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -1810,6 +1810,7 @@ static void hdmi_disable_overflow_interrupts(struct
>>> dw_hdmi *hdmi)> 
>>>  static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode
>>>  *mode) {
>>>  
>>>  	int ret;
>>>
>>> +	void *data = hdmi->plat_data->phy_data;
>>>
>>>  	hdmi_disable_overflow_interrupts(hdmi);
>>>
>>> @@ -1821,10 +1822,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
>>> struct drm_display_mode *mode)> 
>>>  		dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
>>>  	
>>>  	}
>>>
>>> -	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
>>> -	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
>>> -	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
>>> -	    (hdmi->vic == 17) || (hdmi->vic == 18))
>>> +	if (hdmi->plat_data->get_enc_out_encoding)
>>> +		hdmi->hdmi_data.enc_out_encoding =
>>> +			hdmi->plat_data->get_enc_out_encoding(data);
>>> +	else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
>>> +		 (hdmi->vic == 21) || (hdmi->vic == 22) ||
>>> +		 (hdmi->vic == 2) || (hdmi->vic == 3) ||
>>> +		 (hdmi->vic == 17) || (hdmi->vic == 18))
>>>
>>>  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
>>>  	
>>>  	else
>>>  	
>>>  		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
>>>
>>> @@ -1833,21 +1837,31 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
>>> struct drm_display_mode *mode)> 
>>>  	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
>>>  	
>>>  	/* TOFIX: Get input format from plat data or fallback to RGB888 */
>>>
>>> -	if (hdmi->plat_data->input_bus_format)
>>> +	if (hdmi->plat_data->get_input_bus_format)
>>> +		hdmi->hdmi_data.enc_in_bus_format =
>>> +			hdmi->plat_data->get_input_bus_format(data);
>>> +	else if (hdmi->plat_data->input_bus_format)
>>>
>>>  		hdmi->hdmi_data.enc_in_bus_format =
>>>  		
>>>  			hdmi->plat_data->input_bus_format;
>>>  	
>>>  	else
>>>  	
>>>  		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>>>  	
>>>  	/* TOFIX: Get input encoding from plat data or fallback to none */
>>>
>>> -	if (hdmi->plat_data->input_bus_encoding)
>>> +	if (hdmi->plat_data->get_enc_in_encoding)
>>> +		hdmi->hdmi_data.enc_in_encoding =
>>> +			hdmi->plat_data->get_enc_in_encoding(data);
>>> +	else if (hdmi->plat_data->input_bus_encoding)
>>>
>>>  		hdmi->hdmi_data.enc_in_encoding =
>>>  		
>>>  			hdmi->plat_data->input_bus_encoding;
>>>  	
>>>  	else
>>>  	
>>>  		hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
>>>  	
>>>  	/* TOFIX: Default to RGB888 output format */
>>>
>>> -	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>>> +	if (hdmi->plat_data->get_output_bus_format)
>>> +		hdmi->hdmi_data.enc_out_bus_format =
>>> +			hdmi->plat_data->get_output_bus_format(data);
>>> +	else
>>> +		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>>>
>>>  	hdmi->hdmi_data.pix_repet_factor = 0;
>>>  	hdmi->hdmi_data.hdcp_enable = 0;
>>>
>>> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
>>> index 7a02744ce0bc..2e797f782c51 100644
>>> --- a/include/drm/bridge/dw_hdmi.h
>>> +++ b/include/drm/bridge/dw_hdmi.h
>>> @@ -142,6 +142,11 @@ struct dw_hdmi_plat_data {
>>>
>>>  	int (*configure_phy)(struct dw_hdmi *hdmi,
>>>  	
>>>  			     const struct dw_hdmi_plat_data *pdata,
>>>  			     unsigned long mpixelclock);
>>>
>>> +
>>> +	unsigned long (*get_input_bus_format)(void *data);
>>> +	unsigned long (*get_output_bus_format)(void *data);
>>> +	unsigned long (*get_enc_in_encoding)(void *data);
>>> +	unsigned long (*get_enc_out_encoding)(void *data);
>>>
>>>  };
>>>  
>>>  struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
> 
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4a9a24e854db..bd564ffdf18b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1810,6 +1810,7 @@  static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 {
 	int ret;
+	void *data = hdmi->plat_data->phy_data;
 
 	hdmi_disable_overflow_interrupts(hdmi);
 
@@ -1821,10 +1822,13 @@  static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 		dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
 	}
 
-	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
-	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
-	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
-	    (hdmi->vic == 17) || (hdmi->vic == 18))
+	if (hdmi->plat_data->get_enc_out_encoding)
+		hdmi->hdmi_data.enc_out_encoding =
+			hdmi->plat_data->get_enc_out_encoding(data);
+	else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
+		 (hdmi->vic == 21) || (hdmi->vic == 22) ||
+		 (hdmi->vic == 2) || (hdmi->vic == 3) ||
+		 (hdmi->vic == 17) || (hdmi->vic == 18))
 		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
 	else
 		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
@@ -1833,21 +1837,31 @@  static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
 
 	/* TOFIX: Get input format from plat data or fallback to RGB888 */
-	if (hdmi->plat_data->input_bus_format)
+	if (hdmi->plat_data->get_input_bus_format)
+		hdmi->hdmi_data.enc_in_bus_format =
+			hdmi->plat_data->get_input_bus_format(data);
+	else if (hdmi->plat_data->input_bus_format)
 		hdmi->hdmi_data.enc_in_bus_format =
 			hdmi->plat_data->input_bus_format;
 	else
 		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
 	/* TOFIX: Get input encoding from plat data or fallback to none */
-	if (hdmi->plat_data->input_bus_encoding)
+	if (hdmi->plat_data->get_enc_in_encoding)
+		hdmi->hdmi_data.enc_in_encoding =
+			hdmi->plat_data->get_enc_in_encoding(data);
+	else if (hdmi->plat_data->input_bus_encoding)
 		hdmi->hdmi_data.enc_in_encoding =
 			hdmi->plat_data->input_bus_encoding;
 	else
 		hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
 
 	/* TOFIX: Default to RGB888 output format */
-	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+	if (hdmi->plat_data->get_output_bus_format)
+		hdmi->hdmi_data.enc_out_bus_format =
+			hdmi->plat_data->get_output_bus_format(data);
+	else
+		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
 	hdmi->hdmi_data.pix_repet_factor = 0;
 	hdmi->hdmi_data.hdcp_enable = 0;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 7a02744ce0bc..2e797f782c51 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -142,6 +142,11 @@  struct dw_hdmi_plat_data {
 	int (*configure_phy)(struct dw_hdmi *hdmi,
 			     const struct dw_hdmi_plat_data *pdata,
 			     unsigned long mpixelclock);
+
+	unsigned long (*get_input_bus_format)(void *data);
+	unsigned long (*get_output_bus_format)(void *data);
+	unsigned long (*get_enc_in_encoding)(void *data);
+	unsigned long (*get_enc_out_encoding)(void *data);
 };
 
 struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,