xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2013 Red Hat
4*4882a593Smuzhiyun  * Author: Rob Clark <robdclark@gmail.com>
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __HDMI_CONNECTOR_H__
8*4882a593Smuzhiyun #define __HDMI_CONNECTOR_H__
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/i2c.h>
11*4882a593Smuzhiyun #include <linux/clk.h>
12*4882a593Smuzhiyun #include <linux/platform_device.h>
13*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
14*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
15*4882a593Smuzhiyun #include <linux/hdmi.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <drm/drm_bridge.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include "msm_drv.h"
20*4882a593Smuzhiyun #include "hdmi.xml.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define HDMI_MAX_NUM_GPIO	6
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun struct hdmi_phy;
25*4882a593Smuzhiyun struct hdmi_platform_config;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun struct hdmi_gpio_data {
28*4882a593Smuzhiyun 	struct gpio_desc *gpiod;
29*4882a593Smuzhiyun 	bool output;
30*4882a593Smuzhiyun 	int value;
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun struct hdmi_audio {
34*4882a593Smuzhiyun 	bool enabled;
35*4882a593Smuzhiyun 	struct hdmi_audio_infoframe infoframe;
36*4882a593Smuzhiyun 	int rate;
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun struct hdmi_hdcp_ctrl;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun struct hdmi {
42*4882a593Smuzhiyun 	struct drm_device *dev;
43*4882a593Smuzhiyun 	struct platform_device *pdev;
44*4882a593Smuzhiyun 	struct platform_device *audio_pdev;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	const struct hdmi_platform_config *config;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	/* audio state: */
49*4882a593Smuzhiyun 	struct hdmi_audio audio;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	/* video state: */
52*4882a593Smuzhiyun 	bool power_on;
53*4882a593Smuzhiyun 	unsigned long int pixclock;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	void __iomem *mmio;
56*4882a593Smuzhiyun 	void __iomem *qfprom_mmio;
57*4882a593Smuzhiyun 	phys_addr_t mmio_phy_addr;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	struct regulator **hpd_regs;
60*4882a593Smuzhiyun 	struct regulator **pwr_regs;
61*4882a593Smuzhiyun 	struct clk **hpd_clks;
62*4882a593Smuzhiyun 	struct clk **pwr_clks;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	struct hdmi_phy *phy;
65*4882a593Smuzhiyun 	struct device *phy_dev;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	struct i2c_adapter *i2c;
68*4882a593Smuzhiyun 	struct drm_connector *connector;
69*4882a593Smuzhiyun 	struct drm_bridge *bridge;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	/* the encoder we are hooked to (outside of hdmi block) */
72*4882a593Smuzhiyun 	struct drm_encoder *encoder;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	bool hdmi_mode;               /* are we in hdmi mode? */
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	int irq;
77*4882a593Smuzhiyun 	struct workqueue_struct *workq;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	struct hdmi_hdcp_ctrl *hdcp_ctrl;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	/*
82*4882a593Smuzhiyun 	* spinlock to protect registers shared by different execution
83*4882a593Smuzhiyun 	* REG_HDMI_CTRL
84*4882a593Smuzhiyun 	* REG_HDMI_DDC_ARBITRATION
85*4882a593Smuzhiyun 	* REG_HDMI_HDCP_INT_CTRL
86*4882a593Smuzhiyun 	* REG_HDMI_HPD_CTRL
87*4882a593Smuzhiyun 	*/
88*4882a593Smuzhiyun 	spinlock_t reg_lock;
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* platform config data (ie. from DT, or pdata) */
92*4882a593Smuzhiyun struct hdmi_platform_config {
93*4882a593Smuzhiyun 	const char *mmio_name;
94*4882a593Smuzhiyun 	const char *qfprom_mmio_name;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	/* regulators that need to be on for hpd: */
97*4882a593Smuzhiyun 	const char **hpd_reg_names;
98*4882a593Smuzhiyun 	int hpd_reg_cnt;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/* regulators that need to be on for screen pwr: */
101*4882a593Smuzhiyun 	const char **pwr_reg_names;
102*4882a593Smuzhiyun 	int pwr_reg_cnt;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	/* clks that need to be on for hpd: */
105*4882a593Smuzhiyun 	const char **hpd_clk_names;
106*4882a593Smuzhiyun 	const long unsigned *hpd_freq;
107*4882a593Smuzhiyun 	int hpd_clk_cnt;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	/* clks that need to be on for screen pwr (ie pixel clk): */
110*4882a593Smuzhiyun 	const char **pwr_clk_names;
111*4882a593Smuzhiyun 	int pwr_clk_cnt;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	/* gpio's: */
114*4882a593Smuzhiyun 	struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO];
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
118*4882a593Smuzhiyun 
hdmi_write(struct hdmi * hdmi,u32 reg,u32 data)119*4882a593Smuzhiyun static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	msm_writel(data, hdmi->mmio + reg);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun 
hdmi_read(struct hdmi * hdmi,u32 reg)124*4882a593Smuzhiyun static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	return msm_readl(hdmi->mmio + reg);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
hdmi_qfprom_read(struct hdmi * hdmi,u32 reg)129*4882a593Smuzhiyun static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun 	return msm_readl(hdmi->qfprom_mmio + reg);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun /*
135*4882a593Smuzhiyun  * hdmi phy:
136*4882a593Smuzhiyun  */
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun enum hdmi_phy_type {
139*4882a593Smuzhiyun 	MSM_HDMI_PHY_8x60,
140*4882a593Smuzhiyun 	MSM_HDMI_PHY_8960,
141*4882a593Smuzhiyun 	MSM_HDMI_PHY_8x74,
142*4882a593Smuzhiyun 	MSM_HDMI_PHY_8996,
143*4882a593Smuzhiyun 	MSM_HDMI_PHY_MAX,
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun struct hdmi_phy_cfg {
147*4882a593Smuzhiyun 	enum hdmi_phy_type type;
148*4882a593Smuzhiyun 	void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
149*4882a593Smuzhiyun 	void (*powerdown)(struct hdmi_phy *phy);
150*4882a593Smuzhiyun 	const char * const *reg_names;
151*4882a593Smuzhiyun 	int num_regs;
152*4882a593Smuzhiyun 	const char * const *clk_names;
153*4882a593Smuzhiyun 	int num_clks;
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg;
157*4882a593Smuzhiyun extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
158*4882a593Smuzhiyun extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
159*4882a593Smuzhiyun extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun struct hdmi_phy {
162*4882a593Smuzhiyun 	struct platform_device *pdev;
163*4882a593Smuzhiyun 	void __iomem *mmio;
164*4882a593Smuzhiyun 	struct hdmi_phy_cfg *cfg;
165*4882a593Smuzhiyun 	const struct hdmi_phy_funcs *funcs;
166*4882a593Smuzhiyun 	struct regulator **regs;
167*4882a593Smuzhiyun 	struct clk **clks;
168*4882a593Smuzhiyun };
169*4882a593Smuzhiyun 
hdmi_phy_write(struct hdmi_phy * phy,u32 reg,u32 data)170*4882a593Smuzhiyun static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	msm_writel(data, phy->mmio + reg);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
hdmi_phy_read(struct hdmi_phy * phy,u32 reg)175*4882a593Smuzhiyun static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	return msm_readl(phy->mmio + reg);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy);
181*4882a593Smuzhiyun void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy);
182*4882a593Smuzhiyun void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock);
183*4882a593Smuzhiyun void msm_hdmi_phy_powerdown(struct hdmi_phy *phy);
184*4882a593Smuzhiyun void __init msm_hdmi_phy_driver_register(void);
185*4882a593Smuzhiyun void __exit msm_hdmi_phy_driver_unregister(void);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun #ifdef CONFIG_COMMON_CLK
188*4882a593Smuzhiyun int msm_hdmi_pll_8960_init(struct platform_device *pdev);
189*4882a593Smuzhiyun int msm_hdmi_pll_8996_init(struct platform_device *pdev);
190*4882a593Smuzhiyun #else
msm_hdmi_pll_8960_init(struct platform_device * pdev)191*4882a593Smuzhiyun static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	return -ENODEV;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
msm_hdmi_pll_8996_init(struct platform_device * pdev)196*4882a593Smuzhiyun static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	return -ENODEV;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun /*
203*4882a593Smuzhiyun  * audio:
204*4882a593Smuzhiyun  */
205*4882a593Smuzhiyun /* Supported HDMI Audio channels and rates */
206*4882a593Smuzhiyun #define	MSM_HDMI_AUDIO_CHANNEL_2	0
207*4882a593Smuzhiyun #define	MSM_HDMI_AUDIO_CHANNEL_4	1
208*4882a593Smuzhiyun #define	MSM_HDMI_AUDIO_CHANNEL_6	2
209*4882a593Smuzhiyun #define	MSM_HDMI_AUDIO_CHANNEL_8	3
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_32KHZ		0
212*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_44_1KHZ	1
213*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_48KHZ		2
214*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_88_2KHZ	3
215*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_96KHZ		4
216*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_176_4KHZ	5
217*4882a593Smuzhiyun #define	HDMI_SAMPLE_RATE_192KHZ		6
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun int msm_hdmi_audio_update(struct hdmi *hdmi);
220*4882a593Smuzhiyun int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
221*4882a593Smuzhiyun 	uint32_t num_of_channels, uint32_t channel_allocation,
222*4882a593Smuzhiyun 	uint32_t level_shift, bool down_mix);
223*4882a593Smuzhiyun void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /*
227*4882a593Smuzhiyun  * hdmi bridge:
228*4882a593Smuzhiyun  */
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi);
231*4882a593Smuzhiyun void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun /*
234*4882a593Smuzhiyun  * hdmi connector:
235*4882a593Smuzhiyun  */
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun void msm_hdmi_connector_irq(struct drm_connector *connector);
238*4882a593Smuzhiyun struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
239*4882a593Smuzhiyun int msm_hdmi_hpd_enable(struct drm_connector *connector);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun /*
242*4882a593Smuzhiyun  * i2c adapter for ddc:
243*4882a593Smuzhiyun  */
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun void msm_hdmi_i2c_irq(struct i2c_adapter *i2c);
246*4882a593Smuzhiyun void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c);
247*4882a593Smuzhiyun struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun /*
250*4882a593Smuzhiyun  * hdcp
251*4882a593Smuzhiyun  */
252*4882a593Smuzhiyun #ifdef CONFIG_DRM_MSM_HDMI_HDCP
253*4882a593Smuzhiyun struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi);
254*4882a593Smuzhiyun void msm_hdmi_hdcp_destroy(struct hdmi *hdmi);
255*4882a593Smuzhiyun void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl);
256*4882a593Smuzhiyun void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl);
257*4882a593Smuzhiyun void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl);
258*4882a593Smuzhiyun #else
msm_hdmi_hdcp_init(struct hdmi * hdmi)259*4882a593Smuzhiyun static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	return ERR_PTR(-ENXIO);
262*4882a593Smuzhiyun }
msm_hdmi_hdcp_destroy(struct hdmi * hdmi)263*4882a593Smuzhiyun static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl * hdcp_ctrl)264*4882a593Smuzhiyun static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl * hdcp_ctrl)265*4882a593Smuzhiyun static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl * hdcp_ctrl)266*4882a593Smuzhiyun static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun #endif /* __HDMI_CONNECTOR_H__ */
270