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 	unsigned long int pixclock;
45 
46 	void __iomem *mmio;
47 	void __iomem *qfprom_mmio;
48 	phys_addr_t mmio_phy_addr;
49 
50 	struct regulator_bulk_data *hpd_regs;
51 	struct regulator_bulk_data *pwr_regs;
52 	struct clk **hpd_clks;
53 	struct clk **pwr_clks;
54 
55 	struct gpio_desc *hpd_gpiod;
56 
57 	struct hdmi_phy *phy;
58 	struct device *phy_dev;
59 
60 	struct i2c_adapter *i2c;
61 	struct drm_connector *connector;
62 	struct drm_bridge *bridge;
63 
64 	struct drm_bridge *next_bridge;
65 
66 	/* the encoder we are hooked to (outside of hdmi block) */
67 	struct drm_encoder *encoder;
68 
69 	int irq;
70 	struct workqueue_struct *workq;
71 
72 	struct hdmi_hdcp_ctrl *hdcp_ctrl;
73 
74 	/*
75 	* spinlock to protect registers shared by different execution
76 	* REG_HDMI_CTRL
77 	* REG_HDMI_DDC_ARBITRATION
78 	* REG_HDMI_HDCP_INT_CTRL
79 	* REG_HDMI_HPD_CTRL
80 	*/
81 	spinlock_t reg_lock;
82 };
83 
84 /* platform config data (ie. from DT, or pdata) */
85 struct hdmi_platform_config {
86 	/* regulators that need to be on for hpd: */
87 	const char **hpd_reg_names;
88 	int hpd_reg_cnt;
89 
90 	/* regulators that need to be on for screen pwr: */
91 	const char **pwr_reg_names;
92 	int pwr_reg_cnt;
93 
94 	/* clks that need to be on for hpd: */
95 	const char **hpd_clk_names;
96 	const long unsigned *hpd_freq;
97 	int hpd_clk_cnt;
98 
99 	/* clks that need to be on for screen pwr (ie pixel clk): */
100 	const char **pwr_clk_names;
101 	int pwr_clk_cnt;
102 };
103 
104 struct hdmi_bridge {
105 	struct drm_bridge base;
106 	struct hdmi *hdmi;
107 	struct work_struct hpd_work;
108 };
109 #define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
110 
111 void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
112 
hdmi_write(struct hdmi * hdmi,u32 reg,u32 data)113 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
114 {
115 	writel(data, hdmi->mmio + reg);
116 }
117 
hdmi_read(struct hdmi * hdmi,u32 reg)118 static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
119 {
120 	return readl(hdmi->mmio + reg);
121 }
122 
hdmi_qfprom_read(struct hdmi * hdmi,u32 reg)123 static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
124 {
125 	return readl(hdmi->qfprom_mmio + reg);
126 }
127 
128 /*
129  * hdmi phy:
130  */
131 
132 enum hdmi_phy_type {
133 	MSM_HDMI_PHY_8x60,
134 	MSM_HDMI_PHY_8960,
135 	MSM_HDMI_PHY_8x74,
136 	MSM_HDMI_PHY_8996,
137 	MSM_HDMI_PHY_8998,
138 	MSM_HDMI_PHY_MAX,
139 };
140 
141 struct hdmi_phy_cfg {
142 	enum hdmi_phy_type type;
143 	void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
144 	void (*powerdown)(struct hdmi_phy *phy);
145 	const char * const *reg_names;
146 	int num_regs;
147 	const char * const *clk_names;
148 	int num_clks;
149 };
150 
151 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg;
152 extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
153 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
154 extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
155 extern const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg;
156 
157 struct hdmi_phy {
158 	struct platform_device *pdev;
159 	void __iomem *mmio;
160 	struct hdmi_phy_cfg *cfg;
161 	const struct hdmi_phy_funcs *funcs;
162 	struct regulator_bulk_data *regs;
163 	struct clk **clks;
164 };
165 
hdmi_phy_write(struct hdmi_phy * phy,u32 reg,u32 data)166 static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
167 {
168 	writel(data, phy->mmio + reg);
169 }
170 
hdmi_phy_read(struct hdmi_phy * phy,u32 reg)171 static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg)
172 {
173 	return readl(phy->mmio + reg);
174 }
175 
176 int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy);
177 void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy);
178 void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock);
179 void msm_hdmi_phy_powerdown(struct hdmi_phy *phy);
180 void __init msm_hdmi_phy_driver_register(void);
181 void __exit msm_hdmi_phy_driver_unregister(void);
182 
183 #ifdef CONFIG_COMMON_CLK
184 int msm_hdmi_pll_8960_init(struct platform_device *pdev);
185 int msm_hdmi_pll_8996_init(struct platform_device *pdev);
186 int msm_hdmi_pll_8998_init(struct platform_device *pdev);
187 #else
msm_hdmi_pll_8960_init(struct platform_device * pdev)188 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
189 {
190 	return -ENODEV;
191 }
192 
msm_hdmi_pll_8996_init(struct platform_device * pdev)193 static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
194 {
195 	return -ENODEV;
196 }
197 
msm_hdmi_pll_8998_init(struct platform_device * pdev)198 static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
199 {
200 	return -ENODEV;
201 }
202 #endif
203 
204 /*
205  * audio:
206  */
207 struct hdmi_codec_daifmt;
208 struct hdmi_codec_params;
209 
210 int msm_hdmi_audio_update(struct hdmi *hdmi);
211 int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
212 				  struct drm_bridge *bridge,
213 				  struct hdmi_codec_daifmt *daifmt,
214 				  struct hdmi_codec_params *params);
215 void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector,
216 				    struct drm_bridge *bridge);
217 
218 /*
219  * hdmi bridge:
220  */
221 
222 int msm_hdmi_bridge_init(struct hdmi *hdmi);
223 
224 void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
225 enum drm_connector_status msm_hdmi_bridge_detect(
226 		struct drm_bridge *bridge);
227 int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
228 void msm_hdmi_hpd_disable(struct hdmi *hdmi);
229 
230 /*
231  * i2c adapter for ddc:
232  */
233 
234 void msm_hdmi_i2c_irq(struct i2c_adapter *i2c);
235 void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c);
236 struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi);
237 
238 /*
239  * hdcp
240  */
241 #ifdef CONFIG_DRM_MSM_HDMI_HDCP
242 struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi);
243 void msm_hdmi_hdcp_destroy(struct hdmi *hdmi);
244 void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl);
245 void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl);
246 void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl);
247 #else
msm_hdmi_hdcp_init(struct hdmi * hdmi)248 static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
249 {
250 	return ERR_PTR(-ENXIO);
251 }
msm_hdmi_hdcp_destroy(struct hdmi * hdmi)252 static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl * hdcp_ctrl)253 static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl * hdcp_ctrl)254 static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl * hdcp_ctrl)255 static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
256 #endif
257 
258 #endif /* __HDMI_CONNECTOR_H__ */
259