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
hdmi_write(struct hdmi * hdmi,u32 reg,u32 data)105 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
106 {
107 writel(data, hdmi->mmio + reg);
108 }
109
hdmi_read(struct hdmi * hdmi,u32 reg)110 static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
111 {
112 return readl(hdmi->mmio + reg);
113 }
114
hdmi_clear_bits(struct hdmi * hdmi,u32 reg,u32 mask)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
hdmi_update_bits(struct hdmi * hdmi,u32 reg,u32 mask,u32 data)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
hdmi_qfprom_read(struct hdmi * hdmi,u32 reg)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
hdmi_phy_write(struct hdmi_phy * phy,u32 reg,u32 data)177 static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
178 {
179 writel(data, phy->mmio + reg);
180 }
181
hdmi_phy_read(struct hdmi_phy * phy,u32 reg)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
msm_hdmi_pll_8960_init(struct platform_device * pdev)199 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
200 {
201 return -ENODEV;
202 }
203
msm_hdmi_pll_8996_init(struct platform_device * pdev)204 static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
205 {
206 return -ENODEV;
207 }
208
msm_hdmi_pll_8998_init(struct platform_device * pdev)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
msm_hdmi_hdcp_init(struct hdmi * hdmi)259 static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
260 {
261 return ERR_PTR(-ENXIO);
262 }
msm_hdmi_hdcp_destroy(struct hdmi * hdmi)263 static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl * hdcp_ctrl)264 static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl * hdcp_ctrl)265 static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_irq(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