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