xref: /rk3399_rockchip-uboot/drivers/video/drm/rk1000_tve.c (revision 9c9eff4383781163466df78b3624da411821f83d)
1*9c9eff43SAlgea Cao // SPDX-License-Identifier: GPL-2.0
2*9c9eff43SAlgea Cao /*
3*9c9eff43SAlgea Cao  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4*9c9eff43SAlgea Cao  */
5*9c9eff43SAlgea Cao 
6*9c9eff43SAlgea Cao #include <common.h>
7*9c9eff43SAlgea Cao #include <boot_rkimg.h>
8*9c9eff43SAlgea Cao #include <dm.h>
9*9c9eff43SAlgea Cao #include <errno.h>
10*9c9eff43SAlgea Cao #include <i2c.h>
11*9c9eff43SAlgea Cao #include <video_bridge.h>
12*9c9eff43SAlgea Cao #include <asm/io.h>
13*9c9eff43SAlgea Cao #include <dm/device.h>
14*9c9eff43SAlgea Cao #include <dm/device-internal.h>
15*9c9eff43SAlgea Cao #include <linux/media-bus-format.h>
16*9c9eff43SAlgea Cao 
17*9c9eff43SAlgea Cao #include "rockchip_bridge.h"
18*9c9eff43SAlgea Cao #include "rockchip_display.h"
19*9c9eff43SAlgea Cao #include "rockchip_panel.h"
20*9c9eff43SAlgea Cao 
21*9c9eff43SAlgea Cao #include "rk1000.h"
22*9c9eff43SAlgea Cao 
23*9c9eff43SAlgea Cao #define TVE_POWCR	0x03
24*9c9eff43SAlgea Cao #define TVE_OFF		0X07
25*9c9eff43SAlgea Cao #define TVE_ON		0x03
26*9c9eff43SAlgea Cao 
27*9c9eff43SAlgea Cao struct rk1000_tve {
28*9c9eff43SAlgea Cao 	struct udevice *dev;
29*9c9eff43SAlgea Cao 	struct rk1000_ctl rk1000_ctl;
30*9c9eff43SAlgea Cao };
31*9c9eff43SAlgea Cao 
32*9c9eff43SAlgea Cao enum {
33*9c9eff43SAlgea Cao 	CVBS_NTSC = 0,
34*9c9eff43SAlgea Cao 	CVBS_PAL,
35*9c9eff43SAlgea Cao };
36*9c9eff43SAlgea Cao 
rk1000_tve_i2c_write(struct rk1000_tve * rk1000_tve,u8 reg,u8 val)37*9c9eff43SAlgea Cao int rk1000_tve_i2c_write(struct rk1000_tve *rk1000_tve, u8 reg, u8 val)
38*9c9eff43SAlgea Cao {
39*9c9eff43SAlgea Cao 	struct dm_i2c_chip *chip = dev_get_parent_platdata(rk1000_tve->dev);
40*9c9eff43SAlgea Cao 	struct i2c_msg msg;
41*9c9eff43SAlgea Cao 	u8 buf[2];
42*9c9eff43SAlgea Cao 	int ret;
43*9c9eff43SAlgea Cao 
44*9c9eff43SAlgea Cao 	buf[0] = reg;
45*9c9eff43SAlgea Cao 	buf[1] = val;
46*9c9eff43SAlgea Cao 	msg.addr = chip->chip_addr;
47*9c9eff43SAlgea Cao 	msg.flags = 0;
48*9c9eff43SAlgea Cao 	msg.len = 2;
49*9c9eff43SAlgea Cao 	msg.buf = buf;
50*9c9eff43SAlgea Cao 
51*9c9eff43SAlgea Cao 	ret = dm_i2c_xfer(rk1000_tve->dev, &msg, 1);
52*9c9eff43SAlgea Cao 	if (ret) {
53*9c9eff43SAlgea Cao 		dev_err(rk1000_tve->dev,
54*9c9eff43SAlgea Cao 			"rk1000 tve i2c write failed: %d\n", ret);
55*9c9eff43SAlgea Cao 		return ret;
56*9c9eff43SAlgea Cao 	}
57*9c9eff43SAlgea Cao 
58*9c9eff43SAlgea Cao 	return 0;
59*9c9eff43SAlgea Cao }
60*9c9eff43SAlgea Cao 
rk1000_tve_i2c_read(struct rk1000_tve * rk1000_tve,u8 reg,u8 * val)61*9c9eff43SAlgea Cao int rk1000_tve_i2c_read(struct rk1000_tve *rk1000_tve, u8 reg, u8 *val)
62*9c9eff43SAlgea Cao {
63*9c9eff43SAlgea Cao 	struct dm_i2c_chip *chip = dev_get_parent_platdata(rk1000_tve->dev);
64*9c9eff43SAlgea Cao 	u8 data;
65*9c9eff43SAlgea Cao 	struct i2c_msg msg[] = {
66*9c9eff43SAlgea Cao 		{
67*9c9eff43SAlgea Cao 			.addr = chip->chip_addr,
68*9c9eff43SAlgea Cao 			.flags = 0,
69*9c9eff43SAlgea Cao 			.buf = (u8 *)&reg,
70*9c9eff43SAlgea Cao 			.len = 1,
71*9c9eff43SAlgea Cao 		}, {
72*9c9eff43SAlgea Cao 			.addr = chip->chip_addr,
73*9c9eff43SAlgea Cao 			.flags = I2C_M_RD,
74*9c9eff43SAlgea Cao 			.buf = (u8 *)&data,
75*9c9eff43SAlgea Cao 			.len = 1,
76*9c9eff43SAlgea Cao 		}
77*9c9eff43SAlgea Cao 	};
78*9c9eff43SAlgea Cao 	int ret;
79*9c9eff43SAlgea Cao 
80*9c9eff43SAlgea Cao 	ret = dm_i2c_xfer(rk1000_tve->dev, msg, 2);
81*9c9eff43SAlgea Cao 	if (ret) {
82*9c9eff43SAlgea Cao 		dev_err(rk1000_tve->dev,
83*9c9eff43SAlgea Cao 			"rk1000 tve i2c read failed: %d\n", ret);
84*9c9eff43SAlgea Cao 		return ret;
85*9c9eff43SAlgea Cao 	}
86*9c9eff43SAlgea Cao 
87*9c9eff43SAlgea Cao 	*val = data;
88*9c9eff43SAlgea Cao 
89*9c9eff43SAlgea Cao 	return 0;
90*9c9eff43SAlgea Cao }
91*9c9eff43SAlgea Cao 
rk1000_tv_write_block(struct rk1000_tve * rk1000_tve,u8 reg,const u8 * buf,u8 len)92*9c9eff43SAlgea Cao static int rk1000_tv_write_block(struct rk1000_tve *rk1000_tve,
93*9c9eff43SAlgea Cao 				 u8 reg, const u8 *buf, u8 len)
94*9c9eff43SAlgea Cao {
95*9c9eff43SAlgea Cao 	int i, ret;
96*9c9eff43SAlgea Cao 
97*9c9eff43SAlgea Cao 	for (i = 0; i < len; i++) {
98*9c9eff43SAlgea Cao 		ret = rk1000_tve_i2c_write(rk1000_tve, reg + i, buf[i]);
99*9c9eff43SAlgea Cao 		if (ret)
100*9c9eff43SAlgea Cao 			break;
101*9c9eff43SAlgea Cao 	}
102*9c9eff43SAlgea Cao 
103*9c9eff43SAlgea Cao 	return ret;
104*9c9eff43SAlgea Cao }
105*9c9eff43SAlgea Cao 
rk1000_tve_probe(struct udevice * dev)106*9c9eff43SAlgea Cao static int rk1000_tve_probe(struct udevice *dev)
107*9c9eff43SAlgea Cao {
108*9c9eff43SAlgea Cao 	struct rk1000_tve *rk1000_tve = dev_get_priv(dev);
109*9c9eff43SAlgea Cao 	struct rockchip_bridge *bridge =
110*9c9eff43SAlgea Cao 		(struct rockchip_bridge *)dev_get_driver_data(dev);
111*9c9eff43SAlgea Cao 	int ret;
112*9c9eff43SAlgea Cao 
113*9c9eff43SAlgea Cao 	rk1000_tve->dev = dev;
114*9c9eff43SAlgea Cao 
115*9c9eff43SAlgea Cao 	ret = uclass_get_device_by_name(UCLASS_I2C_GENERIC,
116*9c9eff43SAlgea Cao 					"rk1000-ctl@40",
117*9c9eff43SAlgea Cao 					&rk1000_tve->rk1000_ctl.dev);
118*9c9eff43SAlgea Cao 	if (ret)
119*9c9eff43SAlgea Cao 		return ret;
120*9c9eff43SAlgea Cao 
121*9c9eff43SAlgea Cao 	bridge->dev = dev;
122*9c9eff43SAlgea Cao 
123*9c9eff43SAlgea Cao 	return 0;
124*9c9eff43SAlgea Cao }
125*9c9eff43SAlgea Cao 
rk1000_tve_bridge_enable(struct rockchip_bridge * bridge)126*9c9eff43SAlgea Cao static void rk1000_tve_bridge_enable(struct rockchip_bridge *bridge)
127*9c9eff43SAlgea Cao {
128*9c9eff43SAlgea Cao 	u8 tv_encoder_regs_pal[] = {0x06, 0x00, 0x00, 0x03, 0x00, 0x00};
129*9c9eff43SAlgea Cao 	u8 tv_encoder_control_regs_pal[] = {0x41, 0x01};
130*9c9eff43SAlgea Cao 	u8 tv_encoder_regs_ntsc[] = {0x00, 0x00, 0x00, 0x03, 0x00, 0x00};
131*9c9eff43SAlgea Cao 	u8 tv_encoder_control_regs_ntsc[] = {0x43, 0x01};
132*9c9eff43SAlgea Cao 	char data[4] = {0x88, 0x00, 0x22, 0x00};
133*9c9eff43SAlgea Cao 	struct rk1000_tve *rk1000_tve = dev_get_priv(bridge->dev);
134*9c9eff43SAlgea Cao 	struct connector_state *conn_state = &bridge->state->conn_state;
135*9c9eff43SAlgea Cao 	struct drm_display_mode *mode = &conn_state->mode;
136*9c9eff43SAlgea Cao 	struct rk1000_ctl *rk1000_ctl = &rk1000_tve->rk1000_ctl;
137*9c9eff43SAlgea Cao 
138*9c9eff43SAlgea Cao 	rk1000_ctl_write_block(rk1000_ctl, 0, (u8 *)data, 4);
139*9c9eff43SAlgea Cao 
140*9c9eff43SAlgea Cao 	/* rk1000 power down output dac */
141*9c9eff43SAlgea Cao 	data[0] = 0x07;
142*9c9eff43SAlgea Cao 	rk1000_tv_write_block(rk1000_tve, 0x03, (u8 *)data, 1);
143*9c9eff43SAlgea Cao 
144*9c9eff43SAlgea Cao 	if (mode->vdisplay == 576) {
145*9c9eff43SAlgea Cao 		rk1000_tv_write_block(rk1000_tve, 0, tv_encoder_regs_pal,
146*9c9eff43SAlgea Cao 				      sizeof(tv_encoder_regs_pal));
147*9c9eff43SAlgea Cao 		rk1000_ctl_write_block(rk1000_ctl, 3,
148*9c9eff43SAlgea Cao 				       tv_encoder_control_regs_pal,
149*9c9eff43SAlgea Cao 				       sizeof(tv_encoder_control_regs_pal));
150*9c9eff43SAlgea Cao 	} else {
151*9c9eff43SAlgea Cao 		rk1000_tv_write_block(rk1000_tve, 0, tv_encoder_regs_ntsc,
152*9c9eff43SAlgea Cao 				      sizeof(tv_encoder_regs_ntsc));
153*9c9eff43SAlgea Cao 		rk1000_ctl_write_block(rk1000_ctl, 3,
154*9c9eff43SAlgea Cao 				       tv_encoder_control_regs_ntsc,
155*9c9eff43SAlgea Cao 				       sizeof(tv_encoder_control_regs_ntsc));
156*9c9eff43SAlgea Cao 	}
157*9c9eff43SAlgea Cao }
158*9c9eff43SAlgea Cao 
rk1000_tve_bridge_disable(struct rockchip_bridge * bridge)159*9c9eff43SAlgea Cao static void rk1000_tve_bridge_disable(struct rockchip_bridge *bridge)
160*9c9eff43SAlgea Cao {
161*9c9eff43SAlgea Cao 	struct rk1000_tve *rk1000_tve = dev_get_priv(bridge->dev);
162*9c9eff43SAlgea Cao 	char data[1] = {0x07};
163*9c9eff43SAlgea Cao 
164*9c9eff43SAlgea Cao 	/* rk1000 power down output dac */
165*9c9eff43SAlgea Cao 	rk1000_tv_write_block(rk1000_tve, 0x03, (u8 *)data, 1);
166*9c9eff43SAlgea Cao }
167*9c9eff43SAlgea Cao 
drm_rk1000_select_output(struct overscan * overscan,struct drm_display_mode * mode)168*9c9eff43SAlgea Cao static void drm_rk1000_select_output(struct overscan *overscan,
169*9c9eff43SAlgea Cao 				     struct drm_display_mode *mode)
170*9c9eff43SAlgea Cao {
171*9c9eff43SAlgea Cao 	char baseparameter_buf[8 * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN);
172*9c9eff43SAlgea Cao 	struct base_screen_info *screen_info = NULL;
173*9c9eff43SAlgea Cao 	struct base_disp_info base_parameter;
174*9c9eff43SAlgea Cao 	struct blk_desc *dev_desc;
175*9c9eff43SAlgea Cao 	const struct base_overscan *scan;
176*9c9eff43SAlgea Cao 	disk_partition_t part_info;
177*9c9eff43SAlgea Cao 	int ret, i, screen_size;
178*9c9eff43SAlgea Cao 	int max_scan = 100;
179*9c9eff43SAlgea Cao 	int min_scan = 51;
180*9c9eff43SAlgea Cao 
181*9c9eff43SAlgea Cao 	overscan->left_margin = max_scan;
182*9c9eff43SAlgea Cao 	overscan->right_margin = max_scan;
183*9c9eff43SAlgea Cao 	overscan->top_margin = max_scan;
184*9c9eff43SAlgea Cao 	overscan->bottom_margin = max_scan;
185*9c9eff43SAlgea Cao 
186*9c9eff43SAlgea Cao 	mode->hdisplay = 720;
187*9c9eff43SAlgea Cao 	mode->hsync_start = 732;
188*9c9eff43SAlgea Cao 	mode->hsync_end = 738;
189*9c9eff43SAlgea Cao 	mode->htotal = 864;
190*9c9eff43SAlgea Cao 	mode->vdisplay = 576;
191*9c9eff43SAlgea Cao 	mode->vsync_start = 582;
192*9c9eff43SAlgea Cao 	mode->vsync_end = 588;
193*9c9eff43SAlgea Cao 	mode->vtotal = 625;
194*9c9eff43SAlgea Cao 	mode->clock = 27000;
195*9c9eff43SAlgea Cao 	mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
196*9c9eff43SAlgea Cao 
197*9c9eff43SAlgea Cao 	dev_desc = rockchip_get_bootdev();
198*9c9eff43SAlgea Cao 	if (!dev_desc) {
199*9c9eff43SAlgea Cao 		printf("%s: Could not find device\n", __func__);
200*9c9eff43SAlgea Cao 		return;
201*9c9eff43SAlgea Cao 	}
202*9c9eff43SAlgea Cao 
203*9c9eff43SAlgea Cao 	if (part_get_info_by_name(dev_desc, "baseparameter", &part_info) < 0) {
204*9c9eff43SAlgea Cao 		printf("Could not find baseparameter partition\n");
205*9c9eff43SAlgea Cao 		return;
206*9c9eff43SAlgea Cao 	}
207*9c9eff43SAlgea Cao 
208*9c9eff43SAlgea Cao 	ret = blk_dread(dev_desc, part_info.start, 1,
209*9c9eff43SAlgea Cao 			(void *)baseparameter_buf);
210*9c9eff43SAlgea Cao 	if (ret < 0) {
211*9c9eff43SAlgea Cao 		printf("read baseparameter failed\n");
212*9c9eff43SAlgea Cao 		return;
213*9c9eff43SAlgea Cao 	}
214*9c9eff43SAlgea Cao 
215*9c9eff43SAlgea Cao 	memcpy(&base_parameter, baseparameter_buf, sizeof(base_parameter));
216*9c9eff43SAlgea Cao 	scan = &base_parameter.scan;
217*9c9eff43SAlgea Cao 
218*9c9eff43SAlgea Cao 	screen_size = sizeof(base_parameter.screen_list) /
219*9c9eff43SAlgea Cao 		sizeof(base_parameter.screen_list[0]);
220*9c9eff43SAlgea Cao 
221*9c9eff43SAlgea Cao 	for (i = 0; i < screen_size; i++) {
222*9c9eff43SAlgea Cao 		if (base_parameter.screen_list[i].type ==
223*9c9eff43SAlgea Cao 		    DRM_MODE_CONNECTOR_TV) {
224*9c9eff43SAlgea Cao 			screen_info = &base_parameter.screen_list[i];
225*9c9eff43SAlgea Cao 			break;
226*9c9eff43SAlgea Cao 		}
227*9c9eff43SAlgea Cao 	}
228*9c9eff43SAlgea Cao 
229*9c9eff43SAlgea Cao 	if (scan->leftscale < min_scan && scan->leftscale > 0)
230*9c9eff43SAlgea Cao 		overscan->left_margin = min_scan;
231*9c9eff43SAlgea Cao 	else if (scan->leftscale < max_scan)
232*9c9eff43SAlgea Cao 		overscan->left_margin = scan->leftscale;
233*9c9eff43SAlgea Cao 
234*9c9eff43SAlgea Cao 	if (scan->rightscale < min_scan && scan->rightscale > 0)
235*9c9eff43SAlgea Cao 		overscan->right_margin = min_scan;
236*9c9eff43SAlgea Cao 	else if (scan->rightscale < max_scan)
237*9c9eff43SAlgea Cao 		overscan->right_margin = scan->rightscale;
238*9c9eff43SAlgea Cao 
239*9c9eff43SAlgea Cao 	if (scan->topscale < min_scan && scan->topscale > 0)
240*9c9eff43SAlgea Cao 		overscan->top_margin = min_scan;
241*9c9eff43SAlgea Cao 	else if (scan->topscale < max_scan)
242*9c9eff43SAlgea Cao 		overscan->top_margin = scan->topscale;
243*9c9eff43SAlgea Cao 
244*9c9eff43SAlgea Cao 	if (scan->bottomscale < min_scan && scan->bottomscale > 0)
245*9c9eff43SAlgea Cao 		overscan->bottom_margin = min_scan;
246*9c9eff43SAlgea Cao 	else if (scan->bottomscale < max_scan)
247*9c9eff43SAlgea Cao 		overscan->bottom_margin = scan->bottomscale;
248*9c9eff43SAlgea Cao 
249*9c9eff43SAlgea Cao 	if (screen_info &&
250*9c9eff43SAlgea Cao 	    (screen_info->mode.hdisplay == 720 &&
251*9c9eff43SAlgea Cao 	     screen_info->mode.hsync_end == 742 &&
252*9c9eff43SAlgea Cao 	     screen_info->mode.vdisplay == 480)) {
253*9c9eff43SAlgea Cao 		mode->hdisplay = 720;
254*9c9eff43SAlgea Cao 		mode->hsync_start = 736;
255*9c9eff43SAlgea Cao 		mode->hsync_end = 742;
256*9c9eff43SAlgea Cao 		mode->htotal = 858;
257*9c9eff43SAlgea Cao 		mode->vdisplay = 480;
258*9c9eff43SAlgea Cao 		mode->vsync_start = 494;
259*9c9eff43SAlgea Cao 		mode->vsync_end = 500;
260*9c9eff43SAlgea Cao 		mode->vtotal = 525;
261*9c9eff43SAlgea Cao 		mode->clock = 27000;
262*9c9eff43SAlgea Cao 	} else {
263*9c9eff43SAlgea Cao 		mode->hdisplay = 720;
264*9c9eff43SAlgea Cao 		mode->hsync_start = 732;
265*9c9eff43SAlgea Cao 		mode->hsync_end = 738;
266*9c9eff43SAlgea Cao 		mode->htotal = 864;
267*9c9eff43SAlgea Cao 		mode->vdisplay = 576;
268*9c9eff43SAlgea Cao 		mode->vsync_start = 582;
269*9c9eff43SAlgea Cao 		mode->vsync_end = 588;
270*9c9eff43SAlgea Cao 		mode->vtotal = 625;
271*9c9eff43SAlgea Cao 		mode->clock = 27000;
272*9c9eff43SAlgea Cao 	}
273*9c9eff43SAlgea Cao }
274*9c9eff43SAlgea Cao 
rk1000_tve_get_timing(struct udevice * dev)275*9c9eff43SAlgea Cao static int rk1000_tve_get_timing(struct udevice *dev)
276*9c9eff43SAlgea Cao {
277*9c9eff43SAlgea Cao 	struct rockchip_bridge *bridge =
278*9c9eff43SAlgea Cao 		(struct rockchip_bridge *)dev_get_driver_data(dev);
279*9c9eff43SAlgea Cao 	struct connector_state *conn_state = &bridge->state->conn_state;
280*9c9eff43SAlgea Cao 	struct drm_display_mode *mode = &conn_state->mode;
281*9c9eff43SAlgea Cao 	struct overscan *overscan = &conn_state->overscan;
282*9c9eff43SAlgea Cao 
283*9c9eff43SAlgea Cao 	drm_rk1000_select_output(overscan, mode);
284*9c9eff43SAlgea Cao 
285*9c9eff43SAlgea Cao 	return 0;
286*9c9eff43SAlgea Cao }
287*9c9eff43SAlgea Cao 
288*9c9eff43SAlgea Cao static const struct rockchip_bridge_funcs rk1000_tve_bridge_funcs = {
289*9c9eff43SAlgea Cao 	.enable = rk1000_tve_bridge_enable,
290*9c9eff43SAlgea Cao 	.disable = rk1000_tve_bridge_disable,
291*9c9eff43SAlgea Cao };
292*9c9eff43SAlgea Cao 
293*9c9eff43SAlgea Cao static struct rockchip_bridge rk1000_tve_driver_data = {
294*9c9eff43SAlgea Cao 	.funcs = &rk1000_tve_bridge_funcs,
295*9c9eff43SAlgea Cao };
296*9c9eff43SAlgea Cao 
297*9c9eff43SAlgea Cao struct video_bridge_ops rk1000_tve_ops = {
298*9c9eff43SAlgea Cao 	.get_timing = rk1000_tve_get_timing,
299*9c9eff43SAlgea Cao };
300*9c9eff43SAlgea Cao 
301*9c9eff43SAlgea Cao static const struct udevice_id rk1000_tve_ids[] = {
302*9c9eff43SAlgea Cao 	{
303*9c9eff43SAlgea Cao 		.compatible = "rockchip,rk1000-tve",
304*9c9eff43SAlgea Cao 		.data = (ulong)&rk1000_tve_driver_data,
305*9c9eff43SAlgea Cao 	},
306*9c9eff43SAlgea Cao 	{ }
307*9c9eff43SAlgea Cao };
308*9c9eff43SAlgea Cao 
309*9c9eff43SAlgea Cao U_BOOT_DRIVER(rk1000_tve) = {
310*9c9eff43SAlgea Cao 	.name = "rk1000_tve",
311*9c9eff43SAlgea Cao 	.id = UCLASS_VIDEO_BRIDGE,
312*9c9eff43SAlgea Cao 	.of_match = rk1000_tve_ids,
313*9c9eff43SAlgea Cao 	.ops = &rk1000_tve_ops,
314*9c9eff43SAlgea Cao 	.probe = rk1000_tve_probe,
315*9c9eff43SAlgea Cao 	.priv_auto_alloc_size = sizeof(struct rk1000_tve),
316*9c9eff43SAlgea Cao };
317