1/* $NetBSD: tda19988.c,v 1.8 2021/12/19 12:44:34 riastradh Exp $ */
2
3/*-
4 * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: tda19988.c,v 1.8 2021/12/19 12:44:34 riastradh Exp $");
31
32/*
33* NXP TDA19988 HDMI encoder
34*/
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/time.h>
39#include <sys/bus.h>
40#include <sys/types.h>
41
42#include <dev/i2c/i2cvar.h>
43#include <dev/i2c/ddcvar.h>
44#include <dev/i2c/ddcreg.h>
45
46#include <dev/fdt/fdtvar.h>
47#include <dev/fdt/fdt_port.h>
48
49#include <dev/videomode/videomode.h>
50#include <dev/videomode/edidvar.h>
51
52#include <drm/drm_bridge.h>
53#include <drm/drm_crtc.h>
54#include <drm/drm_crtc_helper.h>
55#include <drm/drm_drv.h>
56#include <drm/drm_edid.h>
57#include <drm/drm_probe_helper.h>
58
59enum {
60	TDA19988_PORT_INPUT = 0
61};
62
63#define	MKREG(page, addr)	(((page) << 8) | (addr))
64
65#define	REGPAGE(reg)		(((reg) >> 8) & 0xff)
66#define	REGADDR(reg)		((reg) & 0xff)
67
68#define TDA_VERSION		MKREG(0x00, 0x00)
69#define TDA_MAIN_CNTRL0		MKREG(0x00, 0x01)
70#define 	MAIN_CNTRL0_SR		(1 << 0)
71#define TDA_VERSION_MSB		MKREG(0x00, 0x02)
72#define	TDA_SOFTRESET		MKREG(0x00, 0x0a)
73#define		SOFTRESET_I2C		(1 << 1)
74#define		SOFTRESET_AUDIO		(1 << 0)
75#define	TDA_DDC_CTRL		MKREG(0x00, 0x0b)
76#define		DDC_ENABLE		0
77#define	TDA_CCLK		MKREG(0x00, 0x0c)
78#define		CCLK_ENABLE		1
79#define	TDA_INT_FLAGS_2		MKREG(0x00, 0x11)
80#define		INT_FLAGS_2_EDID_BLK_RD	(1 << 1)
81
82#define	TDA_VIP_CNTRL_0		MKREG(0x00, 0x20)
83#define	TDA_VIP_CNTRL_1		MKREG(0x00, 0x21)
84#define	TDA_VIP_CNTRL_2		MKREG(0x00, 0x22)
85#define	TDA_VIP_CNTRL_3		MKREG(0x00, 0x23)
86#define		VIP_CNTRL_3_SYNC_HS	(2 << 4)
87#define		VIP_CNTRL_3_V_TGL	(1 << 2)
88#define		VIP_CNTRL_3_H_TGL	(1 << 1)
89
90#define	TDA_VIP_CNTRL_4		MKREG(0x00, 0x24)
91#define		VIP_CNTRL_4_BLANKIT_NDE		(0 << 2)
92#define		VIP_CNTRL_4_BLANKIT_HS_VS	(1 << 2)
93#define		VIP_CNTRL_4_BLANKIT_NHS_VS	(2 << 2)
94#define		VIP_CNTRL_4_BLANKIT_HE_VE	(3 << 2)
95#define		VIP_CNTRL_4_BLC_NONE		(0 << 0)
96#define		VIP_CNTRL_4_BLC_RGB444		(1 << 0)
97#define		VIP_CNTRL_4_BLC_YUV444		(2 << 0)
98#define		VIP_CNTRL_4_BLC_YUV422		(3 << 0)
99#define	TDA_VIP_CNTRL_5		MKREG(0x00, 0x25)
100#define		VIP_CNTRL_5_SP_CNT(n)	(((n) & 3) << 1)
101#define	TDA_MUX_VP_VIP_OUT	MKREG(0x00, 0x27)
102#define TDA_MAT_CONTRL		MKREG(0x00, 0x80)
103#define		MAT_CONTRL_MAT_BP	(1 << 2)
104#define	TDA_VIDFORMAT		MKREG(0x00, 0xa0)
105#define	TDA_REFPIX_MSB		MKREG(0x00, 0xa1)
106#define	TDA_REFPIX_LSB		MKREG(0x00, 0xa2)
107#define	TDA_REFLINE_MSB		MKREG(0x00, 0xa3)
108#define	TDA_REFLINE_LSB		MKREG(0x00, 0xa4)
109#define	TDA_NPIX_MSB		MKREG(0x00, 0xa5)
110#define	TDA_NPIX_LSB		MKREG(0x00, 0xa6)
111#define	TDA_NLINE_MSB		MKREG(0x00, 0xa7)
112#define	TDA_NLINE_LSB		MKREG(0x00, 0xa8)
113#define	TDA_VS_LINE_STRT_1_MSB	MKREG(0x00, 0xa9)
114#define	TDA_VS_LINE_STRT_1_LSB	MKREG(0x00, 0xaa)
115#define	TDA_VS_PIX_STRT_1_MSB	MKREG(0x00, 0xab)
116#define	TDA_VS_PIX_STRT_1_LSB	MKREG(0x00, 0xac)
117#define	TDA_VS_LINE_END_1_MSB	MKREG(0x00, 0xad)
118#define	TDA_VS_LINE_END_1_LSB	MKREG(0x00, 0xae)
119#define	TDA_VS_PIX_END_1_MSB	MKREG(0x00, 0xaf)
120#define	TDA_VS_PIX_END_1_LSB	MKREG(0x00, 0xb0)
121#define	TDA_VS_LINE_STRT_2_MSB	MKREG(0x00, 0xb1)
122#define	TDA_VS_LINE_STRT_2_LSB	MKREG(0x00, 0xb2)
123#define	TDA_VS_PIX_STRT_2_MSB	MKREG(0x00, 0xb3)
124#define	TDA_VS_PIX_STRT_2_LSB	MKREG(0x00, 0xb4)
125#define	TDA_VS_LINE_END_2_MSB	MKREG(0x00, 0xb5)
126#define	TDA_VS_LINE_END_2_LSB	MKREG(0x00, 0xb6)
127#define	TDA_VS_PIX_END_2_MSB	MKREG(0x00, 0xb7)
128#define	TDA_VS_PIX_END_2_LSB	MKREG(0x00, 0xb8)
129#define	TDA_HS_PIX_START_MSB	MKREG(0x00, 0xb9)
130#define	TDA_HS_PIX_START_LSB	MKREG(0x00, 0xba)
131#define	TDA_HS_PIX_STOP_MSB	MKREG(0x00, 0xbb)
132#define	TDA_HS_PIX_STOP_LSB	MKREG(0x00, 0xbc)
133#define	TDA_VWIN_START_1_MSB	MKREG(0x00, 0xbd)
134#define	TDA_VWIN_START_1_LSB	MKREG(0x00, 0xbe)
135#define	TDA_VWIN_END_1_MSB	MKREG(0x00, 0xbf)
136#define	TDA_VWIN_END_1_LSB	MKREG(0x00, 0xc0)
137#define	TDA_VWIN_START_2_MSB	MKREG(0x00, 0xc1)
138#define	TDA_VWIN_START_2_LSB	MKREG(0x00, 0xc2)
139#define	TDA_VWIN_END_2_MSB	MKREG(0x00, 0xc3)
140#define	TDA_VWIN_END_2_LSB	MKREG(0x00, 0xc4)
141#define	TDA_DE_START_MSB	MKREG(0x00, 0xc5)
142#define	TDA_DE_START_LSB	MKREG(0x00, 0xc6)
143#define	TDA_DE_STOP_MSB		MKREG(0x00, 0xc7)
144#define	TDA_DE_STOP_LSB		MKREG(0x00, 0xc8)
145
146#define	TDA_TBG_CNTRL_0		MKREG(0x00, 0xca)
147#define		TBG_CNTRL_0_SYNC_ONCE	(1 << 7)
148#define		TBG_CNTRL_0_SYNC_MTHD	(1 << 6)
149
150#define	TDA_TBG_CNTRL_1		MKREG(0x00, 0xcb)
151#define		TBG_CNTRL_1_DWIN_DIS	(1 << 6)
152#define		TBG_CNTRL_1_TGL_EN	(1 << 2)
153#define		TBG_CNTRL_1_V_TGL	(1 << 1)
154#define		TBG_CNTRL_1_H_TGL	(1 << 0)
155
156#define	TDA_HVF_CNTRL_0		MKREG(0x00, 0xe4)
157#define		HVF_CNTRL_0_PREFIL_NONE		(0 << 2)
158#define		HVF_CNTRL_0_INTPOL_BYPASS	(0 << 0)
159#define	TDA_HVF_CNTRL_1		MKREG(0x00, 0xe5)
160#define		HVF_CNTRL_1_VQR(x)	(((x) & 3) << 2)
161#define		HVF_CNTRL_1_VQR_FULL	HVF_CNTRL_1_VQR(0)
162#define	TDA_ENABLE_SPACE	MKREG(0x00, 0xd6)
163#define	TDA_RPT_CNTRL		MKREG(0x00, 0xf0)
164
165#define	TDA_PLL_SERIAL_1	MKREG(0x02, 0x00)
166#define		PLL_SERIAL_1_SRL_MAN_IP	(1 << 6)
167#define	TDA_PLL_SERIAL_2	MKREG(0x02, 0x01)
168#define		PLL_SERIAL_2_SRL_PR(x)		(((x) & 0xf) << 4)
169#define		PLL_SERIAL_2_SRL_NOSC(x)	(((x) & 0x3) << 0)
170#define	TDA_PLL_SERIAL_3	MKREG(0x02, 0x02)
171#define		PLL_SERIAL_3_SRL_PXIN_SEL	(1 << 4)
172#define		PLL_SERIAL_3_SRL_DE		(1 << 2)
173#define		PLL_SERIAL_3_SRL_CCIR		(1 << 0)
174#define	TDA_SERIALIZER		MKREG(0x02, 0x03)
175#define	TDA_BUFFER_OUT		MKREG(0x02, 0x04)
176#define	TDA_PLL_SCG1		MKREG(0x02, 0x05)
177#define	TDA_PLL_SCG2		MKREG(0x02, 0x06)
178#define	TDA_PLL_SCGN1		MKREG(0x02, 0x07)
179#define	TDA_PLL_SCGN2		MKREG(0x02, 0x08)
180#define	TDA_PLL_SCGR1		MKREG(0x02, 0x09)
181#define	TDA_PLL_SCGR2		MKREG(0x02, 0x0a)
182
183#define	TDA_SEL_CLK		MKREG(0x02, 0x11)
184#define		SEL_CLK_ENA_SC_CLK	(1 << 3)
185#define		SEL_CLK_SEL_VRF_CLK(x)	(((x) & 3) << 1)
186#define		SEL_CLK_SEL_CLK1	(1 << 0)
187#define	TDA_ANA_GENERAL		MKREG(0x02, 0x12)
188
189#define	TDA_EDID_DATA0		MKREG(0x09, 0x00)
190#define	TDA_EDID_CTRL		MKREG(0x09, 0xfa)
191#define	TDA_DDC_ADDR		MKREG(0x09, 0xfb)
192#define	TDA_DDC_OFFS		MKREG(0x09, 0xfc)
193#define	TDA_DDC_SEGM_ADDR	MKREG(0x09, 0xfd)
194#define	TDA_DDC_SEGM		MKREG(0x09, 0xfe)
195
196#define	TDA_IF_VSP		MKREG(0x10, 0x20)
197#define	TDA_IF_AVI		MKREG(0x10, 0x40)
198#define	TDA_IF_SPD		MKREG(0x10, 0x60)
199#define	TDA_IF_AUD		MKREG(0x10, 0x80)
200#define	TDA_IF_MPS		MKREG(0x10, 0xa0)
201
202#define	TDA_ENC_CNTRL		MKREG(0x11, 0x0d)
203#define		ENC_CNTRL_DVI_MODE	(0 << 2)
204#define		ENC_CNTRL_HDMI_MODE	(1 << 2)
205#define	TDA_DIP_IF_FLAGS	MKREG(0x11, 0x0f)
206#define		DIP_IF_FLAGS_IF5	(1 << 5)
207#define		DIP_IF_FLAGS_IF4	(1 << 4)
208#define		DIP_IF_FLAGS_IF3	(1 << 3)
209#define		DIP_IF_FLAGS_IF2	(1 << 2) /* AVI IF on page 10h */
210#define		DIP_IF_FLAGS_IF1	(1 << 1)
211
212#define	TDA_TX3			MKREG(0x12, 0x9a)
213#define	TDA_TX4			MKREG(0x12, 0x9b)
214#define		TX4_PD_RAM		(1 << 1)
215#define	TDA_HDCP_TX33		MKREG(0x12, 0xb8)
216#define		HDCP_TX33_HDMI		(1 << 1)
217
218#define	TDA_CURPAGE_ADDR	0xff
219
220#define	TDA_CEC_RXSHPDLEV	0xfe
221#define		RXSHPDLEV_HPD	__BIT(1)
222
223#define	TDA_CEC_ENAMODS		0xff
224#define		ENAMODS_RXSENS		(1 << 2)
225#define		ENAMODS_HDMI		(1 << 1)
226#define	TDA_CEC_FRO_IM_CLK_CTRL	0xfb
227#define		CEC_FRO_IM_CLK_CTRL_GHOST_DIS	(1 << 7)
228#define		CEC_FRO_IM_CLK_CTRL_IMCLK_SEL	(1 << 1)
229
230/* EDID reading */
231#define	MAX_READ_ATTEMPTS	100
232
233/* EDID fields */
234#define	EDID_MODES0		35
235#define	EDID_MODES1		36
236#define	EDID_TIMING_START	38
237#define	EDID_TIMING_END		54
238#define	EDID_TIMING_X(v)	(((v) + 31) * 8)
239#define	EDID_FREQ(v)		(((v) & 0x3f) + 60)
240#define	EDID_RATIO(v)		(((v) >> 6) & 0x3)
241#define	EDID_RATIO_10x16	0
242#define	EDID_RATIO_3x4		1
243#define	EDID_RATIO_4x5		2
244#define	EDID_RATIO_9x16		3
245
246#define	TDA19988		0x0301
247
248static const struct device_compatible_entry compat_data[] = {
249	{ .compat = "nxp,tda998x" },
250	DEVICE_COMPAT_EOL
251};
252
253struct tda19988_softc;
254
255struct tda19988_connector {
256	struct drm_connector	base;
257	struct tda19988_softc	*sc;
258};
259
260struct tda19988_softc {
261	device_t		sc_dev;
262	int			sc_phandle;
263	i2c_tag_t		sc_i2c;
264	i2c_addr_t		sc_addr;
265	uint32_t		sc_cec_addr;
266	uint16_t		sc_version;
267	int			sc_current_page;
268	uint8_t			*sc_edid;
269	uint32_t		sc_edid_len;
270	bool			sc_edid_valid;
271
272	struct drm_bridge	sc_bridge;
273	struct tda19988_connector sc_connector;
274
275	struct fdt_device_ports	sc_ports;
276
277	enum drm_connector_status sc_last_status;
278};
279
280#define	to_tda_connector(x)	container_of(x, struct tda19988_connector, base)
281
282static int
283tda19988_set_page(struct tda19988_softc *sc, uint8_t page)
284{
285	uint8_t buf[2] = { TDA_CURPAGE_ADDR, page };
286	int result;
287
288	result = iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0, 0);
289	if (result == 0)
290		sc->sc_current_page = page;
291
292	return result;
293}
294
295static int
296tda19988_cec_read(struct tda19988_softc *sc, uint8_t addr, uint8_t *data)
297{
298	return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_cec_addr, &addr, 1, data, 1, 0);
299}
300
301static int
302tda19988_cec_write(struct tda19988_softc *sc, uint8_t addr, uint8_t data)
303{
304	uint8_t buf[2] = { addr, data };
305
306	return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_cec_addr, buf, 2, NULL, 0, 0);
307}
308
309static int
310tda19988_block_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data, int len)
311{
312	uint8_t reg;
313
314	reg = REGADDR(addr);
315
316	if (sc->sc_current_page != REGPAGE(addr))
317		tda19988_set_page(sc, REGPAGE(addr));
318
319	return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, len, 0);
320}
321
322static int
323tda19988_reg_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data)
324{
325	uint8_t reg;
326
327	reg = REGADDR(addr);
328
329	if (sc->sc_current_page != REGPAGE(addr))
330		tda19988_set_page(sc, REGPAGE(addr));
331
332	return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, 1, 0);
333}
334
335static int
336tda19988_reg_write(struct tda19988_softc *sc, uint16_t addr, uint8_t data)
337{
338	uint8_t buf[2] = { REGADDR(addr), data };
339
340	if (sc->sc_current_page != REGPAGE(addr))
341		tda19988_set_page(sc, REGPAGE(addr));
342
343	return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0, 0);
344}
345
346static int
347tda19988_reg_write2(struct tda19988_softc *sc, uint16_t address, uint16_t data)
348{
349	uint8_t buf[3];
350
351	buf[0] = REGADDR(address);
352	buf[1] = (data >> 8);
353	buf[2] = (data & 0xff);
354
355	if (sc->sc_current_page != REGPAGE(address))
356		tda19988_set_page(sc, REGPAGE(address));
357
358	return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, buf, 3, NULL, 0, 0);
359}
360
361static void
362tda19988_reg_set(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
363{
364	uint8_t data;
365
366	tda19988_reg_read(sc, addr, &data);
367	data |= flags;
368	tda19988_reg_write(sc, addr, data);
369}
370
371static void
372tda19988_reg_clear(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
373{
374	uint8_t data;
375
376	tda19988_reg_read(sc, addr, &data);
377	data &= ~flags;
378	tda19988_reg_write(sc, addr, data);
379}
380
381static int
382tda19988_match(device_t parent, cfdata_t match, void *aux)
383{
384	struct i2c_attach_args * const ia = aux;
385	int match_result;
386
387	if (iic_use_direct_match(ia, match, compat_data, &match_result))
388		return match_result;
389
390	return 0;
391}
392
393static void
394tda19988_init_encoder(struct tda19988_softc *sc, const struct drm_display_mode *mode)
395{
396	uint16_t ref_pix, ref_line, n_pix, n_line;
397	uint16_t hs_pix_start, hs_pix_stop;
398	uint16_t vs1_pix_start, vs1_pix_stop;
399	uint16_t vs1_line_start, vs1_line_end;
400	uint16_t vs2_pix_start, vs2_pix_stop;
401	uint16_t vs2_line_start, vs2_line_end;
402	uint16_t vwin1_line_start, vwin1_line_end;
403	uint16_t vwin2_line_start, vwin2_line_end;
404	uint16_t de_start, de_stop;
405	uint8_t reg, div;
406
407	n_pix = mode->crtc_htotal;
408	n_line = mode->crtc_vtotal;
409
410	hs_pix_stop = mode->crtc_hsync_end - mode->crtc_hdisplay;
411	hs_pix_start = mode->crtc_hsync_start - mode->crtc_hdisplay;
412
413	de_stop = mode->crtc_htotal;
414	de_start = mode->crtc_htotal - mode->crtc_hdisplay;
415	ref_pix = hs_pix_start + 3;
416
417	if (mode->flags & DRM_MODE_FLAG_HSKEW)
418		ref_pix += mode->crtc_hskew;
419
420	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0) {
421		ref_line = 1 + mode->crtc_vsync_start - mode->crtc_vdisplay;
422		vwin1_line_start = mode->crtc_vtotal - mode->crtc_vdisplay - 1;
423		vwin1_line_end = vwin1_line_start + mode->crtc_vdisplay;
424
425		vs1_pix_start = vs1_pix_stop = hs_pix_start;
426		vs1_line_start = mode->crtc_vsync_start - mode->crtc_vdisplay;
427		vs1_line_end = vs1_line_start + mode->crtc_vsync_end - mode->crtc_vsync_start;
428
429		vwin2_line_start = vwin2_line_end = 0;
430		vs2_pix_start = vs2_pix_stop = 0;
431		vs2_line_start = vs2_line_end = 0;
432	} else {
433		ref_line = 1 + (mode->crtc_vsync_start - mode->crtc_vdisplay)/2;
434		vwin1_line_start = (mode->crtc_vtotal - mode->crtc_vdisplay)/2;
435		vwin1_line_end = vwin1_line_start + mode->crtc_vdisplay/2;
436
437		vs1_pix_start = vs1_pix_stop = hs_pix_start;
438		vs1_line_start = (mode->crtc_vsync_start - mode->crtc_vdisplay)/2;
439		vs1_line_end = vs1_line_start + (mode->crtc_vsync_end - mode->crtc_vsync_start)/2;
440
441		vwin2_line_start = vwin1_line_start + mode->crtc_vtotal/2;
442		vwin2_line_end = vwin2_line_start + mode->crtc_vdisplay/2;
443
444		vs2_pix_start = vs2_pix_stop = hs_pix_start + mode->crtc_htotal/2;
445		vs2_line_start = vs1_line_start + mode->crtc_vtotal/2 ;
446		vs2_line_end = vs2_line_start + (mode->crtc_vsync_end - mode->crtc_vsync_start)/2;
447	}
448
449	div = 148500 / mode->crtc_clock;
450	if (div != 0) {
451		div--;
452		if (div > 3)
453			div = 3;
454	}
455
456	/* set HDMI HDCP mode off */
457	tda19988_reg_set(sc, TDA_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
458	tda19988_reg_clear(sc, TDA_HDCP_TX33, HDCP_TX33_HDMI);
459	tda19988_reg_write(sc, TDA_ENC_CNTRL, ENC_CNTRL_DVI_MODE);
460
461	/* no pre-filter or interpolator */
462	tda19988_reg_write(sc, TDA_HVF_CNTRL_0,
463	    HVF_CNTRL_0_INTPOL_BYPASS | HVF_CNTRL_0_PREFIL_NONE);
464	tda19988_reg_write(sc, TDA_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0));
465	tda19988_reg_write(sc, TDA_VIP_CNTRL_4,
466	    VIP_CNTRL_4_BLANKIT_NDE | VIP_CNTRL_4_BLC_NONE);
467
468	tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR);
469	tda19988_reg_clear(sc, TDA_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IP);
470	tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE);
471	tda19988_reg_write(sc, TDA_SERIALIZER, 0);
472	tda19988_reg_write(sc, TDA_HVF_CNTRL_1, HVF_CNTRL_1_VQR_FULL);
473
474	tda19988_reg_write(sc, TDA_RPT_CNTRL, 0);
475	tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) |
476			SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
477
478	tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) |
479			PLL_SERIAL_2_SRL_PR(0));
480
481	tda19988_reg_set(sc, TDA_MAT_CONTRL, MAT_CONTRL_MAT_BP);
482
483	tda19988_reg_write(sc, TDA_ANA_GENERAL, 0x09);
484
485	tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD);
486
487	/*
488	 * Sync on rising HSYNC/VSYNC
489	 */
490	reg = VIP_CNTRL_3_SYNC_HS;
491	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
492		reg |= VIP_CNTRL_3_H_TGL;
493	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
494		reg |= VIP_CNTRL_3_V_TGL;
495	tda19988_reg_write(sc, TDA_VIP_CNTRL_3, reg);
496
497	reg = TBG_CNTRL_1_TGL_EN;
498	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
499		reg |= TBG_CNTRL_1_H_TGL;
500	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
501		reg |= TBG_CNTRL_1_V_TGL;
502	tda19988_reg_write(sc, TDA_TBG_CNTRL_1, reg);
503
504	/* Program timing */
505	tda19988_reg_write(sc, TDA_VIDFORMAT, 0x00);
506
507	tda19988_reg_write2(sc, TDA_REFPIX_MSB, ref_pix);
508	tda19988_reg_write2(sc, TDA_REFLINE_MSB, ref_line);
509	tda19988_reg_write2(sc, TDA_NPIX_MSB, n_pix);
510	tda19988_reg_write2(sc, TDA_NLINE_MSB, n_line);
511
512	tda19988_reg_write2(sc, TDA_VS_LINE_STRT_1_MSB, vs1_line_start);
513	tda19988_reg_write2(sc, TDA_VS_PIX_STRT_1_MSB, vs1_pix_start);
514	tda19988_reg_write2(sc, TDA_VS_LINE_END_1_MSB, vs1_line_end);
515	tda19988_reg_write2(sc, TDA_VS_PIX_END_1_MSB, vs1_pix_stop);
516	tda19988_reg_write2(sc, TDA_VS_LINE_STRT_2_MSB, vs2_line_start);
517	tda19988_reg_write2(sc, TDA_VS_PIX_STRT_2_MSB, vs2_pix_start);
518	tda19988_reg_write2(sc, TDA_VS_LINE_END_2_MSB, vs2_line_end);
519	tda19988_reg_write2(sc, TDA_VS_PIX_END_2_MSB, vs2_pix_stop);
520	tda19988_reg_write2(sc, TDA_HS_PIX_START_MSB, hs_pix_start);
521	tda19988_reg_write2(sc, TDA_HS_PIX_STOP_MSB, hs_pix_stop);
522	tda19988_reg_write2(sc, TDA_VWIN_START_1_MSB, vwin1_line_start);
523	tda19988_reg_write2(sc, TDA_VWIN_END_1_MSB, vwin1_line_end);
524	tda19988_reg_write2(sc, TDA_VWIN_START_2_MSB, vwin2_line_start);
525	tda19988_reg_write2(sc, TDA_VWIN_END_2_MSB, vwin2_line_end);
526	tda19988_reg_write2(sc, TDA_DE_START_MSB, de_start);
527	tda19988_reg_write2(sc, TDA_DE_STOP_MSB, de_stop);
528
529	if (sc->sc_version == TDA19988)
530		tda19988_reg_write(sc, TDA_ENABLE_SPACE, 0x00);
531
532	/* must be last register set */
533	tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
534}
535
536static int
537tda19988_read_edid_block(struct tda19988_softc *sc, uint8_t *buf, int block)
538{
539	int attempt, err;
540	uint8_t data;
541
542	err = 0;
543
544	tda19988_reg_set(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
545
546	/* Block 0 */
547	tda19988_reg_write(sc, TDA_DDC_ADDR, 0xa0);
548	tda19988_reg_write(sc, TDA_DDC_OFFS, (block % 2) ? 128 : 0);
549	tda19988_reg_write(sc, TDA_DDC_SEGM_ADDR, 0x60);
550	tda19988_reg_write(sc, TDA_DDC_SEGM, block / 2);
551
552	tda19988_reg_write(sc, TDA_EDID_CTRL, 1);
553	tda19988_reg_write(sc, TDA_EDID_CTRL, 0);
554
555	data = 0;
556	for (attempt = 0; attempt < MAX_READ_ATTEMPTS; attempt++) {
557		tda19988_reg_read(sc, TDA_INT_FLAGS_2, &data);
558		if (data & INT_FLAGS_2_EDID_BLK_RD)
559			break;
560		delay(1000);
561	}
562
563	if (attempt == MAX_READ_ATTEMPTS) {
564		err = -1;
565		goto done;
566	}
567
568	if (tda19988_block_read(sc, TDA_EDID_DATA0, buf, EDID_LENGTH) != 0) {
569		err = -1;
570		goto done;
571	}
572
573done:
574	tda19988_reg_clear(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
575
576	return (err);
577}
578
579static int
580tda19988_read_edid(struct tda19988_softc *sc)
581{
582	int err;
583	int blocks, i;
584	uint8_t *buf, *edid;
585
586	err = 0;
587	if (sc->sc_version == TDA19988)
588		tda19988_reg_clear(sc, TDA_TX4, TX4_PD_RAM);
589
590	err = tda19988_read_edid_block(sc, sc->sc_edid, 0);
591	if (err)
592		goto done;
593
594	blocks = sc->sc_edid[0x7e];
595	if (blocks > 0) {
596		if (sc->sc_edid_len != EDID_LENGTH*(blocks+1)) {
597			edid = kmem_zalloc(EDID_LENGTH*(blocks+1), KM_SLEEP);
598			memcpy(edid, sc->sc_edid, EDID_LENGTH);
599			kmem_free(sc->sc_edid, sc->sc_edid_len);
600			sc->sc_edid = edid;
601			sc->sc_edid_len = EDID_LENGTH*(blocks+1);
602		}
603		for (i = 0; i < blocks; i++) {
604			/* TODO: check validity */
605			buf = sc->sc_edid + EDID_LENGTH*(i+1);
606			err = tda19988_read_edid_block(sc, buf, i);
607			if (err)
608				goto done;
609		}
610	}
611
612done:
613	if (sc->sc_version == TDA19988)
614		tda19988_reg_set(sc, TDA_TX4, TX4_PD_RAM);
615
616	return (err);
617}
618
619static void
620tda19988_start(struct tda19988_softc *sc)
621{
622	device_t dev;
623	uint8_t data;
624	uint16_t ver;
625
626	dev = sc->sc_dev;
627
628	tda19988_cec_write(sc, TDA_CEC_ENAMODS, ENAMODS_RXSENS | ENAMODS_HDMI);
629	DELAY(1000);
630	tda19988_cec_read(sc, TDA_CEC_RXSHPDLEV, &data);
631
632	/* Reset core */
633	tda19988_reg_set(sc, TDA_SOFTRESET, 3);
634	DELAY(100);
635	tda19988_reg_clear(sc, TDA_SOFTRESET, 3);
636	DELAY(100);
637
638	/* reset transmitter: */
639	tda19988_reg_set(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
640	tda19988_reg_clear(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
641
642	/* PLL registers common configuration */
643	tda19988_reg_write(sc, TDA_PLL_SERIAL_1, 0x00);
644	tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1));
645	tda19988_reg_write(sc, TDA_PLL_SERIAL_3, 0x00);
646	tda19988_reg_write(sc, TDA_SERIALIZER, 0x00);
647	tda19988_reg_write(sc, TDA_BUFFER_OUT, 0x00);
648	tda19988_reg_write(sc, TDA_PLL_SCG1, 0x00);
649	tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
650	tda19988_reg_write(sc, TDA_PLL_SCGN1, 0xfa);
651	tda19988_reg_write(sc, TDA_PLL_SCGN2, 0x00);
652	tda19988_reg_write(sc, TDA_PLL_SCGR1, 0x5b);
653	tda19988_reg_write(sc, TDA_PLL_SCGR2, 0x00);
654	tda19988_reg_write(sc, TDA_PLL_SCG2, 0x10);
655
656	/* Write the default value MUX register */
657	tda19988_reg_write(sc, TDA_MUX_VP_VIP_OUT, 0x24);
658
659	ver = 0;
660	tda19988_reg_read(sc, TDA_VERSION, &data);
661	ver |= data;
662	tda19988_reg_read(sc, TDA_VERSION_MSB, &data);
663	ver |= (data << 8);
664
665	/* Clear feature bits */
666	sc->sc_version = ver & ~0x30;
667	switch (sc->sc_version) {
668		case TDA19988:
669			device_printf(dev, "TDA19988\n");
670			break;
671		default:
672			device_printf(dev, "Unknown device: %04x\n", sc->sc_version);
673			return;
674	}
675
676	tda19988_reg_write(sc, TDA_DDC_CTRL, DDC_ENABLE);
677	tda19988_reg_write(sc, TDA_TX3, 39);
678
679    	tda19988_cec_write(sc, TDA_CEC_FRO_IM_CLK_CTRL,
680            CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
681
682	/* Default values for RGB 4:4:4 mapping */
683	tda19988_reg_write(sc, TDA_VIP_CNTRL_0, 0x23);
684	tda19988_reg_write(sc, TDA_VIP_CNTRL_1, 0x01);
685	tda19988_reg_write(sc, TDA_VIP_CNTRL_2, 0x45);
686}
687
688static enum drm_connector_status
689tda19988_connector_detect(struct drm_connector *connector, bool force)
690{
691	struct tda19988_connector *tda_connector = to_tda_connector(connector);
692	struct tda19988_softc * const sc = tda_connector->sc;
693	enum drm_connector_status status;
694	uint8_t data = 0;
695
696	iic_acquire_bus(sc->sc_i2c, 0);
697	tda19988_cec_read(sc, TDA_CEC_RXSHPDLEV, &data);
698	iic_release_bus(sc->sc_i2c, 0);
699
700	status = (data & RXSHPDLEV_HPD) ?
701	    connector_status_connected :
702	    connector_status_disconnected;
703
704	/* On connect, invalidate the last EDID */
705	if (status == connector_status_connected &&
706	    sc->sc_last_status != connector_status_connected)
707		sc->sc_edid_valid = false;
708
709	sc->sc_last_status = status;
710
711	return status;
712}
713
714static void
715tda19988_connector_destroy(struct drm_connector *connector)
716{
717	drm_connector_unregister(connector);
718	drm_connector_cleanup(connector);
719}
720
721static const struct drm_connector_funcs tda19988_connector_funcs = {
722	.dpms = drm_helper_connector_dpms,
723	.detect = tda19988_connector_detect,
724	.fill_modes = drm_helper_probe_single_connector_modes,
725	.destroy = tda19988_connector_destroy,
726};
727
728static int
729tda19988_connector_get_modes(struct drm_connector *connector)
730{
731	struct tda19988_connector *tda_connector = to_tda_connector(connector);
732	struct tda19988_softc * const sc = tda_connector->sc;
733	struct edid *pedid = NULL;
734
735	if (sc->sc_edid_valid) {
736		pedid = (struct edid *)sc->sc_edid;
737	} else {
738		iic_acquire_bus(sc->sc_i2c, 0);
739		if (tda19988_read_edid(sc) == 0)
740			pedid = (struct edid *)sc->sc_edid;
741		iic_release_bus(sc->sc_i2c, 0);
742		sc->sc_edid_valid = true;
743	}
744
745	drm_connector_update_edid_property(connector, pedid);
746	if (pedid == NULL)
747		return 0;
748
749	return drm_add_edid_modes(connector, pedid);
750}
751
752static const struct drm_connector_helper_funcs tda19988_connector_helper_funcs = {
753	.get_modes = tda19988_connector_get_modes,
754};
755
756static int
757tda19988_bridge_attach(struct drm_bridge *bridge)
758{
759	struct tda19988_softc *sc = bridge->driver_private;
760	struct tda19988_connector *tda_connector = &sc->sc_connector;
761	struct drm_connector *connector = &tda_connector->base;
762	int error;
763
764	tda_connector->sc = sc;
765
766	connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
767	connector->interlace_allowed = 1;
768	connector->doublescan_allowed = 0;
769
770	drm_connector_init(bridge->dev, connector, &tda19988_connector_funcs,
771	    DRM_MODE_CONNECTOR_HDMIA);
772	drm_connector_helper_add(connector, &tda19988_connector_helper_funcs);
773
774	error = drm_connector_attach_encoder(connector, bridge->encoder);
775	if (error)
776		return error;
777
778	return drm_connector_register(connector);
779}
780
781static void
782tda19988_bridge_enable(struct drm_bridge *bridge)
783{
784	struct tda19988_softc * const sc = bridge->driver_private;
785
786	fdtbus_pinctrl_set_config(sc->sc_phandle, "default");
787}
788
789static void
790tda19988_bridge_pre_enable(struct drm_bridge *bridge)
791{
792}
793
794static void
795tda19988_bridge_disable(struct drm_bridge *bridge)
796{
797	struct tda19988_softc * const sc = bridge->driver_private;
798
799	fdtbus_pinctrl_set_config(sc->sc_phandle, "off");
800}
801
802static void
803tda19988_bridge_post_disable(struct drm_bridge *bridge)
804{
805}
806
807static void
808tda19988_bridge_mode_set(struct drm_bridge *bridge,
809    const struct drm_display_mode *mode,
810    const struct drm_display_mode *adjusted_mode)
811{
812	struct tda19988_softc * const sc = bridge->driver_private;
813
814	iic_acquire_bus(sc->sc_i2c, 0);
815	tda19988_init_encoder(sc, adjusted_mode);
816	iic_release_bus(sc->sc_i2c, 0);
817}
818
819static bool
820tda19988_bridge_mode_fixup(struct drm_bridge *bridge,
821    const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
822{
823	return true;
824}
825
826static const struct drm_bridge_funcs tda19988_bridge_funcs = {
827	.attach = tda19988_bridge_attach,
828	.enable = tda19988_bridge_enable,
829	.pre_enable = tda19988_bridge_pre_enable,
830	.disable = tda19988_bridge_disable,
831	.post_disable = tda19988_bridge_post_disable,
832	.mode_set = tda19988_bridge_mode_set,
833	.mode_fixup = tda19988_bridge_mode_fixup,
834};
835
836static int
837tda19988_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
838{
839	struct tda19988_softc *sc = device_private(dev);
840	struct fdt_endpoint *in_ep = fdt_endpoint_remote(ep);
841	struct drm_encoder *encoder;
842	int error;
843
844	if (!activate)
845		return EINVAL;
846
847	if (fdt_endpoint_port_index(ep) != TDA19988_PORT_INPUT)
848		return EINVAL;
849
850	switch (fdt_endpoint_type(in_ep)) {
851	case EP_DRM_ENCODER:
852		encoder = fdt_endpoint_get_data(in_ep);
853		break;
854	default:
855		encoder = NULL;
856		break;
857	}
858
859	if (encoder == NULL)
860		return EINVAL;
861
862	sc->sc_bridge.driver_private = sc;
863	sc->sc_bridge.funcs = &tda19988_bridge_funcs;
864	sc->sc_bridge.encoder = encoder;
865	error = drm_bridge_attach(encoder, &sc->sc_bridge, NULL);
866	if (error)
867		return EIO;
868
869	return 0;
870}
871
872static void *
873tda19988_ep_get_data(device_t dev, struct fdt_endpoint *ep)
874{
875	struct tda19988_softc *sc = device_private(dev);
876
877	return &sc->sc_bridge;
878}
879
880static void
881tda19988_attach(device_t parent, device_t self, void *aux)
882{
883	struct tda19988_softc *sc = device_private(self);
884	struct i2c_attach_args * const ia = aux;
885	const int phandle = ia->ia_cookie;
886
887	sc->sc_dev = self;
888	sc->sc_phandle = phandle;
889	sc->sc_i2c = ia->ia_tag;
890	sc->sc_addr = ia->ia_addr;
891	sc->sc_cec_addr = 0x34; /* hardcoded */
892	sc->sc_current_page = 0xff;
893	sc->sc_edid = kmem_zalloc(EDID_LENGTH, KM_SLEEP);
894	sc->sc_edid_len = EDID_LENGTH;
895	sc->sc_edid_valid = false;
896	sc->sc_last_status = connector_status_unknown;
897
898	aprint_naive("\n");
899	aprint_normal(": NXP TDA19988 HDMI transmitter\n");
900
901	iic_acquire_bus(sc->sc_i2c, 0);
902	tda19988_start(sc);
903	iic_release_bus(sc->sc_i2c, 0);
904
905	sc->sc_ports.dp_ep_activate = tda19988_ep_activate;
906	sc->sc_ports.dp_ep_get_data = tda19988_ep_get_data;
907	fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
908}
909
910CFATTACH_DECL_NEW(tdahdmi, sizeof(struct tda19988_softc),
911    tda19988_match, tda19988_attach, NULL, NULL);
912