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