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