1 /*
2  * Copyright (C) 2016 BayLibre, SAS
3  * Author: Neil Armstrong <narmstrong@baylibre.com>
4  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/component.h>
23 #include <linux/of_device.h>
24 #include <linux/of_graph.h>
25 #include <linux/reset.h>
26 #include <linux/clk.h>
27 #include <linux/regulator/consumer.h>
28 
29 #include <drm/drmP.h>
30 #include <drm/drm_atomic_helper.h>
31 #include <drm/drm_edid.h>
32 #include <drm/drm_probe_helper.h>
33 #include <drm/bridge/dw_hdmi.h>
34 
35 #include <uapi/linux/media-bus-format.h>
36 #include <uapi/linux/videodev2.h>
37 
38 #include "meson_drv.h"
39 #include "meson_venc.h"
40 #include "meson_vclk.h"
41 #include "meson_dw_hdmi.h"
42 #include "meson_registers.h"
43 
44 #define DRIVER_NAME "meson-dw-hdmi"
45 #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver"
46 
47 /**
48  * DOC: HDMI Output
49  *
50  * HDMI Output is composed of :
51  *
52  * - A Synopsys DesignWare HDMI Controller IP
53  * - A TOP control block controlling the Clocks and PHY
54  * - A custom HDMI PHY in order convert video to TMDS signal
55  *
56  * .. code::
57  *
58  *    ___________________________________
59  *   |            HDMI TOP               |<= HPD
60  *   |___________________________________|
61  *   |                  |                |
62  *   |  Synopsys HDMI   |   HDMI PHY     |=> TMDS
63  *   |    Controller    |________________|
64  *   |___________________________________|<=> DDC
65  *
66  *
67  * The HDMI TOP block only supports HPD sensing.
68  * The Synopsys HDMI Controller interrupt is routed
69  * through the TOP Block interrupt.
70  * Communication to the TOP Block and the Synopsys
71  * HDMI Controller is done a pair of addr+read/write
72  * registers.
73  * The HDMI PHY is configured by registers in the
74  * HHI register block.
75  *
76  * Pixel data arrives in 4:4:4 format from the VENC
77  * block and the VPU HDMI mux selects either the ENCI
78  * encoder for the 576i or 480i formats or the ENCP
79  * encoder for all the other formats including
80  * interlaced HD formats.
81  * The VENC uses a DVI encoder on top of the ENCI
82  * or ENCP encoders to generate DVI timings for the
83  * HDMI controller.
84  *
85  * GXBB, GXL and GXM embeds the Synopsys DesignWare
86  * HDMI TX IP version 2.01a with HDCP and I2C & S/PDIF
87  * audio source interfaces.
88  *
89  * We handle the following features :
90  *
91  * - HPD Rise & Fall interrupt
92  * - HDMI Controller Interrupt
93  * - HDMI PHY Init for 480i to 1080p60
94  * - VENC & HDMI Clock setup for 480i to 1080p60
95  * - VENC Mode setup for 480i to 1080p60
96  *
97  * What is missing :
98  *
99  * - PHY, Clock and Mode setup for 2k && 4k modes
100  * - SDDC Scrambling mode for HDMI 2.0a
101  * - HDCP Setup
102  * - CEC Management
103  */
104 
105 /* TOP Block Communication Channel */
106 #define HDMITX_TOP_ADDR_REG	0x0
107 #define HDMITX_TOP_DATA_REG	0x4
108 #define HDMITX_TOP_CTRL_REG	0x8
109 #define HDMITX_TOP_G12A_OFFSET	0x8000
110 
111 /* Controller Communication Channel */
112 #define HDMITX_DWC_ADDR_REG	0x10
113 #define HDMITX_DWC_DATA_REG	0x14
114 #define HDMITX_DWC_CTRL_REG	0x18
115 
116 /* HHI Registers */
117 #define HHI_MEM_PD_REG0		0x100 /* 0x40 */
118 #define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 */
119 #define HHI_HDMI_PHY_CNTL0	0x3a0 /* 0xe8 */
120 #define HHI_HDMI_PHY_CNTL1	0x3a4 /* 0xe9 */
121 #define HHI_HDMI_PHY_CNTL2	0x3a8 /* 0xea */
122 #define HHI_HDMI_PHY_CNTL3	0x3ac /* 0xeb */
123 #define HHI_HDMI_PHY_CNTL4	0x3b0 /* 0xec */
124 #define HHI_HDMI_PHY_CNTL5	0x3b4 /* 0xed */
125 
126 static DEFINE_SPINLOCK(reg_lock);
127 
128 enum meson_venc_source {
129 	MESON_VENC_SOURCE_NONE = 0,
130 	MESON_VENC_SOURCE_ENCI = 1,
131 	MESON_VENC_SOURCE_ENCP = 2,
132 };
133 
134 struct meson_dw_hdmi;
135 
136 struct meson_dw_hdmi_data {
137 	unsigned int	(*top_read)(struct meson_dw_hdmi *dw_hdmi,
138 				    unsigned int addr);
139 	void		(*top_write)(struct meson_dw_hdmi *dw_hdmi,
140 				     unsigned int addr, unsigned int data);
141 	unsigned int	(*dwc_read)(struct meson_dw_hdmi *dw_hdmi,
142 				    unsigned int addr);
143 	void		(*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
144 				     unsigned int addr, unsigned int data);
145 };
146 
147 struct meson_dw_hdmi {
148 	struct drm_encoder encoder;
149 	struct dw_hdmi_plat_data dw_plat_data;
150 	struct meson_drm *priv;
151 	struct device *dev;
152 	void __iomem *hdmitx;
153 	const struct meson_dw_hdmi_data *data;
154 	struct reset_control *hdmitx_apb;
155 	struct reset_control *hdmitx_ctrl;
156 	struct reset_control *hdmitx_phy;
157 	struct clk *hdmi_pclk;
158 	struct clk *venci_clk;
159 	struct regulator *hdmi_supply;
160 	u32 irq_stat;
161 	struct dw_hdmi *hdmi;
162 };
163 #define encoder_to_meson_dw_hdmi(x) \
164 	container_of(x, struct meson_dw_hdmi, encoder)
165 
166 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi,
167 					const char *compat)
168 {
169 	return of_device_is_compatible(dw_hdmi->dev->of_node, compat);
170 }
171 
172 /* PHY (via TOP bridge) and Controller dedicated register interface */
173 
174 static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi,
175 				     unsigned int addr)
176 {
177 	unsigned long flags;
178 	unsigned int data;
179 
180 	spin_lock_irqsave(&reg_lock, flags);
181 
182 	/* ADDR must be written twice */
183 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
184 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
185 
186 	/* Read needs a second DATA read */
187 	data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
188 	data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
189 
190 	spin_unlock_irqrestore(&reg_lock, flags);
191 
192 	return data;
193 }
194 
195 static unsigned int dw_hdmi_g12a_top_read(struct meson_dw_hdmi *dw_hdmi,
196 					  unsigned int addr)
197 {
198 	return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2));
199 }
200 
201 static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi,
202 				     unsigned int addr, unsigned int data)
203 {
204 	unsigned long flags;
205 
206 	spin_lock_irqsave(&reg_lock, flags);
207 
208 	/* ADDR must be written twice */
209 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
210 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
211 
212 	/* Write needs single DATA write */
213 	writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
214 
215 	spin_unlock_irqrestore(&reg_lock, flags);
216 }
217 
218 static inline void dw_hdmi_g12a_top_write(struct meson_dw_hdmi *dw_hdmi,
219 					  unsigned int addr, unsigned int data)
220 {
221 	writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2));
222 }
223 
224 /* Helper to change specific bits in PHY registers */
225 static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi,
226 					  unsigned int addr,
227 					  unsigned int mask,
228 					  unsigned int val)
229 {
230 	unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr);
231 
232 	data &= ~mask;
233 	data |= val;
234 
235 	dw_hdmi->data->top_write(dw_hdmi, addr, data);
236 }
237 
238 static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi,
239 				     unsigned int addr)
240 {
241 	unsigned long flags;
242 	unsigned int data;
243 
244 	spin_lock_irqsave(&reg_lock, flags);
245 
246 	/* ADDR must be written twice */
247 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
248 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
249 
250 	/* Read needs a second DATA read */
251 	data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
252 	data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
253 
254 	spin_unlock_irqrestore(&reg_lock, flags);
255 
256 	return data;
257 }
258 
259 static unsigned int dw_hdmi_g12a_dwc_read(struct meson_dw_hdmi *dw_hdmi,
260 					  unsigned int addr)
261 {
262 	return readb(dw_hdmi->hdmitx + addr);
263 }
264 
265 static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi,
266 				     unsigned int addr, unsigned int data)
267 {
268 	unsigned long flags;
269 
270 	spin_lock_irqsave(&reg_lock, flags);
271 
272 	/* ADDR must be written twice */
273 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
274 	writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
275 
276 	/* Write needs single DATA write */
277 	writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
278 
279 	spin_unlock_irqrestore(&reg_lock, flags);
280 }
281 
282 static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi,
283 					  unsigned int addr, unsigned int data)
284 {
285 	writeb(data, dw_hdmi->hdmitx + addr);
286 }
287 
288 /* Helper to change specific bits in controller registers */
289 static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi,
290 					  unsigned int addr,
291 					  unsigned int mask,
292 					  unsigned int val)
293 {
294 	unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr);
295 
296 	data &= ~mask;
297 	data |= val;
298 
299 	dw_hdmi->data->dwc_write(dw_hdmi, addr, data);
300 }
301 
302 /* Bridge */
303 
304 /* Setup PHY bandwidth modes */
305 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
306 				      struct drm_display_mode *mode)
307 {
308 	struct meson_drm *priv = dw_hdmi->priv;
309 	unsigned int pixel_clock = mode->clock;
310 
311 	if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
312 	    dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) {
313 		if (pixel_clock >= 371250) {
314 			/* 5.94Gbps, 3.7125Gbps */
315 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282);
316 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b);
317 		} else if (pixel_clock >= 297000) {
318 			/* 2.97Gbps */
319 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382);
320 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b);
321 		} else if (pixel_clock >= 148500) {
322 			/* 1.485Gbps */
323 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362);
324 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b);
325 		} else {
326 			/* 742.5Mbps, and below */
327 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142);
328 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b);
329 		}
330 	} else if (dw_hdmi_is_compatible(dw_hdmi,
331 					 "amlogic,meson-gxbb-dw-hdmi")) {
332 		if (pixel_clock >= 371250) {
333 			/* 5.94Gbps, 3.7125Gbps */
334 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245);
335 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b);
336 		} else if (pixel_clock >= 297000) {
337 			/* 2.97Gbps */
338 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283);
339 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b);
340 		} else {
341 			/* 1.485Gbps, and below */
342 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122);
343 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b);
344 		}
345 	} else if (dw_hdmi_is_compatible(dw_hdmi,
346 					 "amlogic,meson-g12a-dw-hdmi")) {
347 		if (pixel_clock >= 371250) {
348 			/* 5.94Gbps, 3.7125Gbps */
349 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4);
350 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
351 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b);
352 		} else if (pixel_clock >= 297000) {
353 			/* 2.97Gbps */
354 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262);
355 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
356 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003);
357 		} else {
358 			/* 1.485Gbps, and below */
359 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242);
360 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
361 			regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003);
362 		}
363 	}
364 }
365 
366 static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi)
367 {
368 	struct meson_drm *priv = dw_hdmi->priv;
369 
370 	/* Enable and software reset */
371 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf);
372 
373 	mdelay(2);
374 
375 	/* Enable and unreset */
376 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe);
377 
378 	mdelay(2);
379 }
380 
381 static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
382 			     struct drm_display_mode *mode)
383 {
384 	struct meson_drm *priv = dw_hdmi->priv;
385 	int vic = drm_match_cea_mode(mode);
386 	unsigned int vclk_freq;
387 	unsigned int venc_freq;
388 	unsigned int hdmi_freq;
389 
390 	vclk_freq = mode->clock;
391 
392 	if (!vic) {
393 		meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
394 				 vclk_freq, vclk_freq, false);
395 		return;
396 	}
397 
398 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
399 		vclk_freq *= 2;
400 
401 	venc_freq = vclk_freq;
402 	hdmi_freq = vclk_freq;
403 
404 	if (meson_venc_hdmi_venc_repeat(vic))
405 		venc_freq *= 2;
406 
407 	vclk_freq = max(venc_freq, hdmi_freq);
408 
409 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
410 		venc_freq /= 2;
411 
412 	DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n",
413 		vclk_freq, venc_freq, hdmi_freq,
414 		priv->venc.hdmi_use_enci);
415 
416 	meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq,
417 			 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
418 }
419 
420 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
421 			    struct drm_display_mode *mode)
422 {
423 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
424 	struct meson_drm *priv = dw_hdmi->priv;
425 	unsigned int wr_clk =
426 		readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING));
427 
428 	DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name,
429 			 mode->clock > 340000 ? 40 : 10);
430 
431 	/* Enable clocks */
432 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
433 
434 	/* Bring HDMITX MEM output of power down */
435 	regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
436 
437 	/* Bring out of reset */
438 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET,  0);
439 
440 	/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
441 	dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
442 			       0x3, 0x3);
443 	dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
444 			       0x3 << 4, 0x3 << 4);
445 
446 	/* Enable normal output to PHY */
447 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
448 
449 	/* TMDS pattern setup (TOFIX Handle the YUV420 case) */
450 	if (mode->clock > 340000) {
451 		dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
452 				  0);
453 		dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
454 				  0x03ff03ff);
455 	} else {
456 		dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
457 				  0x001f001f);
458 		dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
459 				  0x001f001f);
460 	}
461 
462 	/* Load TMDS pattern */
463 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1);
464 	msleep(20);
465 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2);
466 
467 	/* Setup PHY parameters */
468 	meson_hdmi_phy_setup_mode(dw_hdmi, mode);
469 
470 	/* Setup PHY */
471 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
472 			   0xffff << 16, 0x0390 << 16);
473 
474 	/* BIT_INVERT */
475 	if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
476 	    dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
477 	    dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
478 		regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
479 				   BIT(17), 0);
480 	else
481 		regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
482 				   BIT(17), BIT(17));
483 
484 	/* Disable clock, fifo, fifo_wr */
485 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
486 
487 	dw_hdmi_set_high_tmds_clock_ratio(hdmi);
488 
489 	msleep(100);
490 
491 	/* Reset PHY 3 times in a row */
492 	meson_dw_hdmi_phy_reset(dw_hdmi);
493 	meson_dw_hdmi_phy_reset(dw_hdmi);
494 	meson_dw_hdmi_phy_reset(dw_hdmi);
495 
496 	/* Temporary Disable VENC video stream */
497 	if (priv->venc.hdmi_use_enci)
498 		writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
499 	else
500 		writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
501 
502 	/* Temporary Disable HDMI video stream to HDMI-TX */
503 	writel_bits_relaxed(0x3, 0,
504 			    priv->io_base + _REG(VPU_HDMI_SETTING));
505 	writel_bits_relaxed(0xf << 8, 0,
506 			    priv->io_base + _REG(VPU_HDMI_SETTING));
507 
508 	/* Re-Enable VENC video stream */
509 	if (priv->venc.hdmi_use_enci)
510 		writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
511 	else
512 		writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
513 
514 	/* Push back HDMI clock settings */
515 	writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8),
516 			    priv->io_base + _REG(VPU_HDMI_SETTING));
517 
518 	/* Enable and Select HDMI video source for HDMI-TX */
519 	if (priv->venc.hdmi_use_enci)
520 		writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI,
521 				    priv->io_base + _REG(VPU_HDMI_SETTING));
522 	else
523 		writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP,
524 				    priv->io_base + _REG(VPU_HDMI_SETTING));
525 
526 	return 0;
527 }
528 
529 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
530 				void *data)
531 {
532 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
533 	struct meson_drm *priv = dw_hdmi->priv;
534 
535 	DRM_DEBUG_DRIVER("\n");
536 
537 	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
538 }
539 
540 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
541 			     void *data)
542 {
543 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
544 
545 	return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ?
546 		connector_status_connected : connector_status_disconnected;
547 }
548 
549 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi,
550 			      void *data)
551 {
552 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
553 
554 	/* Setup HPD Filter */
555 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER,
556 			  (0xa << 12) | 0xa0);
557 
558 	/* Clear interrupts */
559 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
560 			  HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL);
561 
562 	/* Unmask interrupts */
563 	dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN,
564 			HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL,
565 			HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL);
566 }
567 
568 static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = {
569 	.init = dw_hdmi_phy_init,
570 	.disable = dw_hdmi_phy_disable,
571 	.read_hpd = dw_hdmi_read_hpd,
572 	.setup_hpd = dw_hdmi_setup_hpd,
573 };
574 
575 static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id)
576 {
577 	struct meson_dw_hdmi *dw_hdmi = dev_id;
578 	u32 stat;
579 
580 	stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT);
581 	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat);
582 
583 	/* HPD Events, handle in the threaded interrupt handler */
584 	if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) {
585 		dw_hdmi->irq_stat = stat;
586 		return IRQ_WAKE_THREAD;
587 	}
588 
589 	/* HDMI Controller Interrupt */
590 	if (stat & 1)
591 		return IRQ_NONE;
592 
593 	/* TOFIX Handle HDCP Interrupts */
594 
595 	return IRQ_HANDLED;
596 }
597 
598 /* Threaded interrupt handler to manage HPD events */
599 static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
600 {
601 	struct meson_dw_hdmi *dw_hdmi = dev_id;
602 	u32 stat = dw_hdmi->irq_stat;
603 
604 	/* HPD Events */
605 	if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) {
606 		bool hpd_connected = false;
607 
608 		if (stat & HDMITX_TOP_INTR_HPD_RISE)
609 			hpd_connected = true;
610 
611 		dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected,
612 				       hpd_connected);
613 
614 		drm_helper_hpd_irq_event(dw_hdmi->encoder.dev);
615 	}
616 
617 	return IRQ_HANDLED;
618 }
619 
620 static enum drm_mode_status
621 dw_hdmi_mode_valid(struct drm_connector *connector,
622 		   const struct drm_display_mode *mode)
623 {
624 	struct meson_drm *priv = connector->dev->dev_private;
625 	unsigned int vclk_freq;
626 	unsigned int venc_freq;
627 	unsigned int hdmi_freq;
628 	int vic = drm_match_cea_mode(mode);
629 	enum drm_mode_status status;
630 
631 	DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
632 
633 	/* If sink max TMDS clock, we reject the mode */
634 	if (connector->display_info.max_tmds_clock &&
635 	    mode->clock > connector->display_info.max_tmds_clock)
636 		return MODE_BAD;
637 
638 	/* Check against non-VIC supported modes */
639 	if (!vic) {
640 		status = meson_venc_hdmi_supported_mode(mode);
641 		if (status != MODE_OK)
642 			return status;
643 
644 		return meson_vclk_dmt_supported_freq(priv, mode->clock);
645 	/* Check against supported VIC modes */
646 	} else if (!meson_venc_hdmi_supported_vic(vic))
647 		return MODE_BAD;
648 
649 	vclk_freq = mode->clock;
650 
651 	/* 480i/576i needs global pixel doubling */
652 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
653 		vclk_freq *= 2;
654 
655 	venc_freq = vclk_freq;
656 	hdmi_freq = vclk_freq;
657 
658 	/* VENC double pixels for 1080i and 720p modes */
659 	if (meson_venc_hdmi_venc_repeat(vic))
660 		venc_freq *= 2;
661 
662 	vclk_freq = max(venc_freq, hdmi_freq);
663 
664 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
665 		venc_freq /= 2;
666 
667 	dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
668 		vclk_freq, venc_freq, hdmi_freq);
669 
670 	return meson_vclk_vic_supported_freq(vclk_freq);
671 }
672 
673 /* Encoder */
674 
675 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder)
676 {
677 	drm_encoder_cleanup(encoder);
678 }
679 
680 static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = {
681 	.destroy        = meson_venc_hdmi_encoder_destroy,
682 };
683 
684 static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
685 					struct drm_crtc_state *crtc_state,
686 					struct drm_connector_state *conn_state)
687 {
688 	return 0;
689 }
690 
691 static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder)
692 {
693 	struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
694 	struct meson_drm *priv = dw_hdmi->priv;
695 
696 	DRM_DEBUG_DRIVER("\n");
697 
698 	writel_bits_relaxed(0x3, 0,
699 			    priv->io_base + _REG(VPU_HDMI_SETTING));
700 
701 	writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
702 	writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
703 }
704 
705 static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder)
706 {
707 	struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
708 	struct meson_drm *priv = dw_hdmi->priv;
709 
710 	DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP");
711 
712 	if (priv->venc.hdmi_use_enci)
713 		writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
714 	else
715 		writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
716 }
717 
718 static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
719 				   struct drm_display_mode *mode,
720 				   struct drm_display_mode *adjusted_mode)
721 {
722 	struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
723 	struct meson_drm *priv = dw_hdmi->priv;
724 	int vic = drm_match_cea_mode(mode);
725 
726 	DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic);
727 
728 	/* VENC + VENC-DVI Mode setup */
729 	meson_venc_hdmi_mode_set(priv, vic, mode);
730 
731 	/* VCLK Set clock */
732 	dw_hdmi_set_vclk(dw_hdmi, mode);
733 
734 	/* Setup YUV444 to HDMI-TX, no 10bit diphering */
735 	writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
736 }
737 
738 static const struct drm_encoder_helper_funcs
739 				meson_venc_hdmi_encoder_helper_funcs = {
740 	.atomic_check	= meson_venc_hdmi_encoder_atomic_check,
741 	.disable	= meson_venc_hdmi_encoder_disable,
742 	.enable		= meson_venc_hdmi_encoder_enable,
743 	.mode_set	= meson_venc_hdmi_encoder_mode_set,
744 };
745 
746 /* DW HDMI Regmap */
747 
748 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg,
749 				  unsigned int *result)
750 {
751 	struct meson_dw_hdmi *dw_hdmi = context;
752 
753 	*result = dw_hdmi->data->dwc_read(dw_hdmi, reg);
754 
755 	return 0;
756 
757 }
758 
759 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg,
760 				   unsigned int val)
761 {
762 	struct meson_dw_hdmi *dw_hdmi = context;
763 
764 	dw_hdmi->data->dwc_write(dw_hdmi, reg, val);
765 
766 	return 0;
767 }
768 
769 static const struct regmap_config meson_dw_hdmi_regmap_config = {
770 	.reg_bits = 32,
771 	.val_bits = 8,
772 	.reg_read = meson_dw_hdmi_reg_read,
773 	.reg_write = meson_dw_hdmi_reg_write,
774 	.max_register = 0x10000,
775 	.fast_io = true,
776 };
777 
778 static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
779 	.top_read = dw_hdmi_top_read,
780 	.top_write = dw_hdmi_top_write,
781 	.dwc_read = dw_hdmi_dwc_read,
782 	.dwc_write = dw_hdmi_dwc_write,
783 };
784 
785 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
786 	.top_read = dw_hdmi_g12a_top_read,
787 	.top_write = dw_hdmi_g12a_top_write,
788 	.dwc_read = dw_hdmi_g12a_dwc_read,
789 	.dwc_write = dw_hdmi_g12a_dwc_write,
790 };
791 
792 static bool meson_hdmi_connector_is_available(struct device *dev)
793 {
794 	struct device_node *ep, *remote;
795 
796 	/* HDMI Connector is on the second port, first endpoint */
797 	ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0);
798 	if (!ep)
799 		return false;
800 
801 	/* If the endpoint node exists, consider it enabled */
802 	remote = of_graph_get_remote_port(ep);
803 	if (remote) {
804 		of_node_put(ep);
805 		return true;
806 	}
807 
808 	of_node_put(ep);
809 	of_node_put(remote);
810 
811 	return false;
812 }
813 
814 static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
815 				void *data)
816 {
817 	struct platform_device *pdev = to_platform_device(dev);
818 	const struct meson_dw_hdmi_data *match;
819 	struct meson_dw_hdmi *meson_dw_hdmi;
820 	struct drm_device *drm = data;
821 	struct meson_drm *priv = drm->dev_private;
822 	struct dw_hdmi_plat_data *dw_plat_data;
823 	struct drm_encoder *encoder;
824 	struct resource *res;
825 	int irq;
826 	int ret;
827 
828 	DRM_DEBUG_DRIVER("\n");
829 
830 	if (!meson_hdmi_connector_is_available(dev)) {
831 		dev_info(drm->dev, "HDMI Output connector not available\n");
832 		return -ENODEV;
833 	}
834 
835 	match = of_device_get_match_data(&pdev->dev);
836 	if (!match) {
837 		dev_err(&pdev->dev, "failed to get match data\n");
838 		return -ENODEV;
839 	}
840 
841 	meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi),
842 				     GFP_KERNEL);
843 	if (!meson_dw_hdmi)
844 		return -ENOMEM;
845 
846 	meson_dw_hdmi->priv = priv;
847 	meson_dw_hdmi->dev = dev;
848 	meson_dw_hdmi->data = match;
849 	dw_plat_data = &meson_dw_hdmi->dw_plat_data;
850 	encoder = &meson_dw_hdmi->encoder;
851 
852 	meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi");
853 	if (IS_ERR(meson_dw_hdmi->hdmi_supply)) {
854 		if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER)
855 			return -EPROBE_DEFER;
856 		meson_dw_hdmi->hdmi_supply = NULL;
857 	} else {
858 		ret = regulator_enable(meson_dw_hdmi->hdmi_supply);
859 		if (ret)
860 			return ret;
861 	}
862 
863 	meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,
864 						"hdmitx_apb");
865 	if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) {
866 		dev_err(dev, "Failed to get hdmitx_apb reset\n");
867 		return PTR_ERR(meson_dw_hdmi->hdmitx_apb);
868 	}
869 
870 	meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev,
871 						"hdmitx");
872 	if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) {
873 		dev_err(dev, "Failed to get hdmitx reset\n");
874 		return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl);
875 	}
876 
877 	meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev,
878 						"hdmitx_phy");
879 	if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) {
880 		dev_err(dev, "Failed to get hdmitx_phy reset\n");
881 		return PTR_ERR(meson_dw_hdmi->hdmitx_phy);
882 	}
883 
884 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
885 	meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res);
886 	if (IS_ERR(meson_dw_hdmi->hdmitx))
887 		return PTR_ERR(meson_dw_hdmi->hdmitx);
888 
889 	meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr");
890 	if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) {
891 		dev_err(dev, "Unable to get HDMI pclk\n");
892 		return PTR_ERR(meson_dw_hdmi->hdmi_pclk);
893 	}
894 	clk_prepare_enable(meson_dw_hdmi->hdmi_pclk);
895 
896 	meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci");
897 	if (IS_ERR(meson_dw_hdmi->venci_clk)) {
898 		dev_err(dev, "Unable to get venci clk\n");
899 		return PTR_ERR(meson_dw_hdmi->venci_clk);
900 	}
901 	clk_prepare_enable(meson_dw_hdmi->venci_clk);
902 
903 	dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi,
904 					      &meson_dw_hdmi_regmap_config);
905 	if (IS_ERR(dw_plat_data->regm))
906 		return PTR_ERR(dw_plat_data->regm);
907 
908 	irq = platform_get_irq(pdev, 0);
909 	if (irq < 0) {
910 		dev_err(dev, "Failed to get hdmi top irq\n");
911 		return irq;
912 	}
913 
914 	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq,
915 					dw_hdmi_top_thread_irq, IRQF_SHARED,
916 					"dw_hdmi_top_irq", meson_dw_hdmi);
917 	if (ret) {
918 		dev_err(dev, "Failed to request hdmi top irq\n");
919 		return ret;
920 	}
921 
922 	/* Encoder */
923 
924 	drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs);
925 
926 	ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs,
927 			       DRM_MODE_ENCODER_TMDS, "meson_hdmi");
928 	if (ret) {
929 		dev_err(priv->dev, "Failed to init HDMI encoder\n");
930 		return ret;
931 	}
932 
933 	encoder->possible_crtcs = BIT(0);
934 
935 	DRM_DEBUG_DRIVER("encoder initialized\n");
936 
937 	/* Enable clocks */
938 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
939 
940 	/* Bring HDMITX MEM output of power down */
941 	regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
942 
943 	/* Reset HDMITX APB & TX & PHY */
944 	reset_control_reset(meson_dw_hdmi->hdmitx_apb);
945 	reset_control_reset(meson_dw_hdmi->hdmitx_ctrl);
946 	reset_control_reset(meson_dw_hdmi->hdmitx_phy);
947 
948 	/* Enable APB3 fail on error */
949 	if (!meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
950 		writel_bits_relaxed(BIT(15), BIT(15),
951 				    meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG);
952 		writel_bits_relaxed(BIT(15), BIT(15),
953 				    meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG);
954 	}
955 
956 	/* Bring out of reset */
957 	meson_dw_hdmi->data->top_write(meson_dw_hdmi,
958 				       HDMITX_TOP_SW_RESET,  0);
959 
960 	msleep(20);
961 
962 	meson_dw_hdmi->data->top_write(meson_dw_hdmi,
963 				       HDMITX_TOP_CLK_CNTL, 0xff);
964 
965 	/* Enable HDMI-TX Interrupt */
966 	meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
967 				       HDMITX_TOP_INTR_CORE);
968 
969 	meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN,
970 				       HDMITX_TOP_INTR_CORE);
971 
972 	/* Bridge / Connector */
973 
974 	dw_plat_data->mode_valid = dw_hdmi_mode_valid;
975 	dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
976 	dw_plat_data->phy_name = "meson_dw_hdmi_phy";
977 	dw_plat_data->phy_data = meson_dw_hdmi;
978 	dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
979 	dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
980 
981 	platform_set_drvdata(pdev, meson_dw_hdmi);
982 
983 	meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder,
984 					   &meson_dw_hdmi->dw_plat_data);
985 	if (IS_ERR(meson_dw_hdmi->hdmi))
986 		return PTR_ERR(meson_dw_hdmi->hdmi);
987 
988 	DRM_DEBUG_DRIVER("HDMI controller initialized\n");
989 
990 	return 0;
991 }
992 
993 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master,
994 				   void *data)
995 {
996 	struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev);
997 
998 	dw_hdmi_unbind(meson_dw_hdmi->hdmi);
999 }
1000 
1001 static const struct component_ops meson_dw_hdmi_ops = {
1002 	.bind	= meson_dw_hdmi_bind,
1003 	.unbind	= meson_dw_hdmi_unbind,
1004 };
1005 
1006 static int meson_dw_hdmi_probe(struct platform_device *pdev)
1007 {
1008 	return component_add(&pdev->dev, &meson_dw_hdmi_ops);
1009 }
1010 
1011 static int meson_dw_hdmi_remove(struct platform_device *pdev)
1012 {
1013 	component_del(&pdev->dev, &meson_dw_hdmi_ops);
1014 
1015 	return 0;
1016 }
1017 
1018 static const struct of_device_id meson_dw_hdmi_of_table[] = {
1019 	{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
1020 	  .data = &meson_dw_hdmi_gx_data },
1021 	{ .compatible = "amlogic,meson-gxl-dw-hdmi",
1022 	  .data = &meson_dw_hdmi_gx_data },
1023 	{ .compatible = "amlogic,meson-gxm-dw-hdmi",
1024 	  .data = &meson_dw_hdmi_gx_data },
1025 	{ .compatible = "amlogic,meson-g12a-dw-hdmi",
1026 	  .data = &meson_dw_hdmi_g12a_data },
1027 	{ }
1028 };
1029 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table);
1030 
1031 static struct platform_driver meson_dw_hdmi_platform_driver = {
1032 	.probe		= meson_dw_hdmi_probe,
1033 	.remove		= meson_dw_hdmi_remove,
1034 	.driver		= {
1035 		.name		= DRIVER_NAME,
1036 		.of_match_table	= meson_dw_hdmi_of_table,
1037 	},
1038 };
1039 module_platform_driver(meson_dw_hdmi_platform_driver);
1040 
1041 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
1042 MODULE_DESCRIPTION(DRIVER_DESC);
1043 MODULE_LICENSE("GPL");
1044