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 int 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_qfprom_read(struct hdmi * hdmi,u32 reg)115 static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
116 {
117 return readl(hdmi->qfprom_mmio + reg);
118 }
119
120 /*
121 * hdmi phy:
122 */
123
124 enum hdmi_phy_type {
125 MSM_HDMI_PHY_8x60,
126 MSM_HDMI_PHY_8960,
127 MSM_HDMI_PHY_8x74,
128 MSM_HDMI_PHY_8996,
129 MSM_HDMI_PHY_8998,
130 MSM_HDMI_PHY_MAX,
131 };
132
133 struct hdmi_phy_cfg {
134 enum hdmi_phy_type type;
135 void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
136 void (*powerdown)(struct hdmi_phy *phy);
137 const char * const *reg_names;
138 int num_regs;
139 const char * const *clk_names;
140 int num_clks;
141 };
142
143 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg;
144 extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
145 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
146 extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
147 extern const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg;
148
149 struct hdmi_phy {
150 struct platform_device *pdev;
151 void __iomem *mmio;
152 struct hdmi_phy_cfg *cfg;
153 const struct hdmi_phy_funcs *funcs;
154 struct regulator_bulk_data *regs;
155 struct clk **clks;
156 };
157
hdmi_phy_write(struct hdmi_phy * phy,u32 reg,u32 data)158 static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
159 {
160 writel(data, phy->mmio + reg);
161 }
162
hdmi_phy_read(struct hdmi_phy * phy,u32 reg)163 static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg)
164 {
165 return readl(phy->mmio + reg);
166 }
167
168 int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy);
169 void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy);
170 void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock);
171 void msm_hdmi_phy_powerdown(struct hdmi_phy *phy);
172 void __init msm_hdmi_phy_driver_register(void);
173 void __exit msm_hdmi_phy_driver_unregister(void);
174
175 #ifdef CONFIG_COMMON_CLK
176 int msm_hdmi_pll_8960_init(struct platform_device *pdev);
177 int msm_hdmi_pll_8996_init(struct platform_device *pdev);
178 int msm_hdmi_pll_8998_init(struct platform_device *pdev);
179 #else
msm_hdmi_pll_8960_init(struct platform_device * pdev)180 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
181 {
182 return -ENODEV;
183 }
184
msm_hdmi_pll_8996_init(struct platform_device * pdev)185 static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
186 {
187 return -ENODEV;
188 }
189
msm_hdmi_pll_8998_init(struct platform_device * pdev)190 static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
191 {
192 return -ENODEV;
193 }
194 #endif
195
196 /*
197 * audio:
198 */
199 struct hdmi_codec_daifmt;
200 struct hdmi_codec_params;
201
202 int msm_hdmi_audio_update(struct hdmi *hdmi);
203 int msm_hdmi_bridge_audio_prepare(struct drm_bridge *bridge,
204 struct drm_connector *connector,
205 struct hdmi_codec_daifmt *daifmt,
206 struct hdmi_codec_params *params);
207 void msm_hdmi_bridge_audio_shutdown(struct drm_bridge *bridge,
208 struct drm_connector *connector);
209
210 /*
211 * hdmi bridge:
212 */
213
214 int msm_hdmi_bridge_init(struct hdmi *hdmi);
215
216 void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
217 enum drm_connector_status msm_hdmi_bridge_detect(
218 struct drm_bridge *bridge, struct drm_connector *connector);
219 void msm_hdmi_hpd_enable(struct drm_bridge *bridge);
220 void msm_hdmi_hpd_disable(struct drm_bridge *bridge);
221
222 /*
223 * i2c adapter for ddc:
224 */
225
226 void msm_hdmi_i2c_irq(struct i2c_adapter *i2c);
227 void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c);
228 struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi);
229
230 /*
231 * hdcp
232 */
233 #ifdef CONFIG_DRM_MSM_HDMI_HDCP
234 struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi);
235 void msm_hdmi_hdcp_destroy(struct hdmi *hdmi);
236 void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl);
237 void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl);
238 void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl);
239 #else
msm_hdmi_hdcp_init(struct hdmi * hdmi)240 static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
241 {
242 return ERR_PTR(-ENXIO);
243 }
msm_hdmi_hdcp_destroy(struct hdmi * hdmi)244 static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl * hdcp_ctrl)245 static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl * hdcp_ctrl)246 static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl * hdcp_ctrl)247 static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
248 #endif
249
250 #endif /* __HDMI_CONNECTOR_H__ */
251