xref: /openbmc/linux/include/drm/bridge/dw_hdmi.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2b21f4b65SAndy Yan /*
3b21f4b65SAndy Yan  * Copyright (C) 2011 Freescale Semiconductor, Inc.
4b21f4b65SAndy Yan  */
5b21f4b65SAndy Yan 
6b21f4b65SAndy Yan #ifndef __DW_HDMI__
7b21f4b65SAndy Yan #define __DW_HDMI__
8b21f4b65SAndy Yan 
9a9c82d63SCheng-Yi Chiang #include <sound/hdmi-codec.h>
10a9c82d63SCheng-Yi Chiang 
11af05bba0SLaurent Pinchart struct drm_display_info;
12428747aeSSam Ravnborg struct drm_display_mode;
13428747aeSSam Ravnborg struct drm_encoder;
14b5814fffSRussell King struct dw_hdmi;
15428747aeSSam Ravnborg struct platform_device;
16b5814fffSRussell King 
17def23aa7SNeil Armstrong /**
18def23aa7SNeil Armstrong  * DOC: Supported input formats and encodings
19def23aa7SNeil Armstrong  *
20def23aa7SNeil Armstrong  * Depending on the Hardware configuration of the Controller IP, it supports
21def23aa7SNeil Armstrong  * a subset of the following input formats and encodings on its internal
22def23aa7SNeil Armstrong  * 48bit bus.
23def23aa7SNeil Armstrong  *
24def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
2538cb266aSJonathan Corbet  * | Format Name          | Format Code                      | Encodings                    |
26def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
2738cb266aSJonathan Corbet  * | RGB 4:4:4 8bit       | ``MEDIA_BUS_FMT_RGB888_1X24``    | ``V4L2_YCBCR_ENC_DEFAULT``   |
28def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
2938cb266aSJonathan Corbet  * | RGB 4:4:4 10bits     | ``MEDIA_BUS_FMT_RGB101010_1X30`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
30def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
3138cb266aSJonathan Corbet  * | RGB 4:4:4 12bits     | ``MEDIA_BUS_FMT_RGB121212_1X36`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
32def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
3338cb266aSJonathan Corbet  * | RGB 4:4:4 16bits     | ``MEDIA_BUS_FMT_RGB161616_1X48`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
34def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
3538cb266aSJonathan Corbet  * | YCbCr 4:4:4 8bit     | ``MEDIA_BUS_FMT_YUV8_1X24``      | ``V4L2_YCBCR_ENC_601``       |
3638cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
3738cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
3838cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
39def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
4038cb266aSJonathan Corbet  * | YCbCr 4:4:4 10bits   | ``MEDIA_BUS_FMT_YUV10_1X30``     | ``V4L2_YCBCR_ENC_601``       |
4138cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
4238cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
4338cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
44def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
4538cb266aSJonathan Corbet  * | YCbCr 4:4:4 12bits   | ``MEDIA_BUS_FMT_YUV12_1X36``     | ``V4L2_YCBCR_ENC_601``       |
4638cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
4738cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
4838cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
49def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
5038cb266aSJonathan Corbet  * | YCbCr 4:4:4 16bits   | ``MEDIA_BUS_FMT_YUV16_1X48``     | ``V4L2_YCBCR_ENC_601``       |
5138cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
5238cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
5338cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
54def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
5538cb266aSJonathan Corbet  * | YCbCr 4:2:2 8bit     | ``MEDIA_BUS_FMT_UYVY8_1X16``     | ``V4L2_YCBCR_ENC_601``       |
5638cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
57def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
5838cb266aSJonathan Corbet  * | YCbCr 4:2:2 10bits   | ``MEDIA_BUS_FMT_UYVY10_1X20``    | ``V4L2_YCBCR_ENC_601``       |
5938cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
60def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
6138cb266aSJonathan Corbet  * | YCbCr 4:2:2 12bits   | ``MEDIA_BUS_FMT_UYVY12_1X24``    | ``V4L2_YCBCR_ENC_601``       |
6238cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
63def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
6438cb266aSJonathan Corbet  * | YCbCr 4:2:0 8bit     | ``MEDIA_BUS_FMT_UYYVYY8_0_5X24`` | ``V4L2_YCBCR_ENC_601``       |
6538cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
66def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
6738cb266aSJonathan Corbet  * | YCbCr 4:2:0 10bits   | ``MEDIA_BUS_FMT_UYYVYY10_0_5X30``| ``V4L2_YCBCR_ENC_601``       |
6838cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
69def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
7038cb266aSJonathan Corbet  * | YCbCr 4:2:0 12bits   | ``MEDIA_BUS_FMT_UYYVYY12_0_5X36``| ``V4L2_YCBCR_ENC_601``       |
7138cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
72def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
7338cb266aSJonathan Corbet  * | YCbCr 4:2:0 16bits   | ``MEDIA_BUS_FMT_UYYVYY16_0_5X48``| ``V4L2_YCBCR_ENC_601``       |
7438cb266aSJonathan Corbet  * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
75def23aa7SNeil Armstrong  * +----------------------+----------------------------------+------------------------------+
76def23aa7SNeil Armstrong  */
77def23aa7SNeil Armstrong 
78b21f4b65SAndy Yan enum {
79b21f4b65SAndy Yan 	DW_HDMI_RES_8,
80b21f4b65SAndy Yan 	DW_HDMI_RES_10,
81b21f4b65SAndy Yan 	DW_HDMI_RES_12,
82b21f4b65SAndy Yan 	DW_HDMI_RES_MAX,
83b21f4b65SAndy Yan };
84b21f4b65SAndy Yan 
85faba6c3cSLaurent Pinchart enum dw_hdmi_phy_type {
86faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00,
87faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2,
88faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_MHL_PHY = 0xc2,
89faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2,
90faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2,
91faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3,
92faba6c3cSLaurent Pinchart 	DW_HDMI_PHY_VENDOR_PHY = 0xfe,
93faba6c3cSLaurent Pinchart };
94faba6c3cSLaurent Pinchart 
95b21f4b65SAndy Yan struct dw_hdmi_mpll_config {
96b21f4b65SAndy Yan 	unsigned long mpixelclock;
97b21f4b65SAndy Yan 	struct {
98b21f4b65SAndy Yan 		u16 cpce;
99b21f4b65SAndy Yan 		u16 gmp;
100b21f4b65SAndy Yan 	} res[DW_HDMI_RES_MAX];
101b21f4b65SAndy Yan };
102b21f4b65SAndy Yan 
103b21f4b65SAndy Yan struct dw_hdmi_curr_ctrl {
104b21f4b65SAndy Yan 	unsigned long mpixelclock;
105b21f4b65SAndy Yan 	u16 curr[DW_HDMI_RES_MAX];
106b21f4b65SAndy Yan };
107b21f4b65SAndy Yan 
108034705a4SYakir Yang struct dw_hdmi_phy_config {
109b21f4b65SAndy Yan 	unsigned long mpixelclock;
110b21f4b65SAndy Yan 	u16 sym_ctr;    /*clock symbol and transmitter control*/
111b21f4b65SAndy Yan 	u16 term;       /*transmission termination value*/
112034705a4SYakir Yang 	u16 vlev_ctr;   /* voltage level control */
113b21f4b65SAndy Yan };
114b21f4b65SAndy Yan 
115f1585f6eSLaurent Pinchart struct dw_hdmi_phy_ops {
116f1585f6eSLaurent Pinchart 	int (*init)(struct dw_hdmi *hdmi, void *data,
1177be390d4SLaurent Pinchart 		    const struct drm_display_info *display,
11835a395f1SLaurent Pinchart 		    const struct drm_display_mode *mode);
119f1585f6eSLaurent Pinchart 	void (*disable)(struct dw_hdmi *hdmi, void *data);
120f1585f6eSLaurent Pinchart 	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
121386d3299SNeil Armstrong 	void (*update_hpd)(struct dw_hdmi *hdmi, void *data,
122386d3299SNeil Armstrong 			   bool force, bool disabled, bool rxsense);
123386d3299SNeil Armstrong 	void (*setup_hpd)(struct dw_hdmi *hdmi, void *data);
124f1585f6eSLaurent Pinchart };
125f1585f6eSLaurent Pinchart 
126b21f4b65SAndy Yan struct dw_hdmi_plat_data {
12780e2f979SNeil Armstrong 	struct regmap *regm;
12896591a4bSLaurent Pinchart 
1295bcc4839SLaurent Pinchart 	unsigned int output_port;
1305bcc4839SLaurent Pinchart 
131def23aa7SNeil Armstrong 	unsigned long input_bus_encoding;
1327cea8559SJonas Karlman 	bool use_drm_infoframe;
133f14d3f6cSNeil Armstrong 	bool ycbcr_420_allowed;
134f1585f6eSLaurent Pinchart 
13596591a4bSLaurent Pinchart 	/*
13696591a4bSLaurent Pinchart 	 * Private data passed to all the .mode_valid() and .configure_phy()
13796591a4bSLaurent Pinchart 	 * callback functions.
13896591a4bSLaurent Pinchart 	 */
13996591a4bSLaurent Pinchart 	void *priv_data;
14096591a4bSLaurent Pinchart 
14196591a4bSLaurent Pinchart 	/* Platform-specific mode validation (optional). */
14296591a4bSLaurent Pinchart 	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
143af05bba0SLaurent Pinchart 					   const struct drm_display_info *info,
14496591a4bSLaurent Pinchart 					   const struct drm_display_mode *mode);
14596591a4bSLaurent Pinchart 
146d970ce30SSandor Yu 	/* Platform-specific audio enable/disable (optional) */
147d970ce30SSandor Yu 	void (*enable_audio)(struct dw_hdmi *hdmi, int channel,
148d970ce30SSandor Yu 			     int width, int rate, int non_pcm);
149d970ce30SSandor Yu 	void (*disable_audio)(struct dw_hdmi *hdmi);
150d970ce30SSandor Yu 
151f1585f6eSLaurent Pinchart 	/* Vendor PHY support */
152f1585f6eSLaurent Pinchart 	const struct dw_hdmi_phy_ops *phy_ops;
153f1585f6eSLaurent Pinchart 	const char *phy_name;
154f1585f6eSLaurent Pinchart 	void *phy_data;
1558faff374SHeiko Stuebner 	unsigned int phy_force_vendor;
156f1585f6eSLaurent Pinchart 
157f1585f6eSLaurent Pinchart 	/* Synopsys PHY support */
158b21f4b65SAndy Yan 	const struct dw_hdmi_mpll_config *mpll_cfg;
159b21f4b65SAndy Yan 	const struct dw_hdmi_curr_ctrl *cur_ctr;
160034705a4SYakir Yang 	const struct dw_hdmi_phy_config *phy_config;
16149da7e5dSLaurent Pinchart 	int (*configure_phy)(struct dw_hdmi *hdmi, void *data,
1622ef9dfedSKieran Bingham 			     unsigned long mpixelclock);
163cd7f72e6SJernej Skrabec 
164cd7f72e6SJernej Skrabec 	unsigned int disable_cec : 1;
165b21f4b65SAndy Yan };
166b21f4b65SAndy Yan 
167eea034afSJernej Skrabec struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
16869497eb9SLaurent Pinchart 			      const struct dw_hdmi_plat_data *plat_data);
169eea034afSJernej Skrabec void dw_hdmi_remove(struct dw_hdmi *hdmi);
170eea034afSJernej Skrabec void dw_hdmi_unbind(struct dw_hdmi *hdmi);
171eea034afSJernej Skrabec struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
172eea034afSJernej Skrabec 			     struct drm_encoder *encoder,
173b21f4b65SAndy Yan 			     const struct dw_hdmi_plat_data *plat_data);
174b5814fffSRussell King 
17599d02ed5SDouglas Anderson void dw_hdmi_resume(struct dw_hdmi *hdmi);
17699d02ed5SDouglas Anderson 
177c32048d9SNeil Armstrong void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
178386d3299SNeil Armstrong 
179a9c82d63SCheng-Yi Chiang int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn,
180a9c82d63SCheng-Yi Chiang 			   struct device *codec_dev);
181d970ce30SSandor Yu void dw_hdmi_set_sample_non_pcm(struct dw_hdmi *hdmi, unsigned int non_pcm);
182d970ce30SSandor Yu void dw_hdmi_set_sample_width(struct dw_hdmi *hdmi, unsigned int width);
183b5814fffSRussell King void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
1842a2a3d2fSJerome Brunet void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
1853250cdf9SYakir Yang void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
1862a2a3d2fSJerome Brunet void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
187b90120a9SRussell King void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
188b90120a9SRussell King void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
1897be390d4SLaurent Pinchart void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
1907be390d4SLaurent Pinchart 				       const struct drm_display_info *display);
191b5814fffSRussell King 
1922ef9dfedSKieran Bingham /* PHY configuration */
1935765916aSJernej Skrabec void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);
1942ef9dfedSKieran Bingham void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
1952ef9dfedSKieran Bingham 			   unsigned char addr);
1962ef9dfedSKieran Bingham 
1978fb241e2SSandor Yu void dw_hdmi_phy_gen1_reset(struct dw_hdmi *hdmi);
1988fb241e2SSandor Yu 
1995765916aSJernej Skrabec void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable);
2005765916aSJernej Skrabec void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable);
2018fb241e2SSandor Yu void dw_hdmi_phy_gen2_reset(struct dw_hdmi *hdmi);
2025765916aSJernej Skrabec 
2035765916aSJernej Skrabec enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
2045765916aSJernej Skrabec 					       void *data);
2055765916aSJernej Skrabec void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
2065765916aSJernej Skrabec 			    bool force, bool disabled, bool rxsense);
2075765916aSJernej Skrabec void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data);
2085765916aSJernej Skrabec 
209*7ed40ff1SAdrián Larumbe bool dw_hdmi_bus_fmt_is_420(struct dw_hdmi *hdmi);
210*7ed40ff1SAdrián Larumbe 
211b21f4b65SAndy Yan #endif /* __IMX_HDMI_H__ */
212