xref: /rk3399_rockchip-uboot/drivers/video/drm/rk628/rk628_gvi.c (revision ab3bc87339b1566ceabcfb54995e11928492c356)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 #include <linux/iopoll.h>
11 
12 #include "rk628.h"
13 #include "rk628_cru.h"
14 #include "rk628_combtxphy.h"
15 #include "rk628_gvi.h"
16 #include "panel.h"
17 
18 #define GVI_RETRY_TIMEOUT	10
19 
rk628_gvi_parse(struct rk628 * rk628,ofnode gvi_np)20 int rk628_gvi_parse(struct rk628 *rk628, ofnode gvi_np)
21 {
22 	const char *string;
23 	u32 val;
24 	int ret;
25 
26 	if (!ofnode_valid(gvi_np))
27 		return -EINVAL;
28 
29 	if (!ofnode_read_u32(gvi_np, "gvi,lanes", &val))
30 		rk628->gvi.lanes = val;
31 
32 	if (ofnode_read_bool(gvi_np, "rockchip,division-mode"))
33 		rk628->gvi.division_mode = true;
34 	else
35 		rk628->gvi.division_mode = false;
36 
37 	if (ofnode_read_bool(gvi_np, "rockchip,gvi-frm-rst"))
38 		rk628->gvi.frm_rst = true;
39 	else
40 		rk628->gvi.frm_rst = false;
41 
42 	string = ofnode_read_string(gvi_np, "bus-format");
43 	if (string) {
44 		if (!strcmp(string, "rgb666"))
45 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB666_1X18;
46 		else if (!strcmp(string, "rgb101010"))
47 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB101010_1X30;
48 		else if (!strcmp(string, "yuyv8"))
49 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV8_1X16;
50 		else if (!strcmp(string, "yuyv10"))
51 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV10_1X20;
52 		else
53 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB888_1X24;
54 	}
55 
56 	ret = rk628_panel_info_get(rk628, gvi_np);
57 	if (ret)
58 		return ret;
59 
60 	return 0;
61 }
62 
rk628_gvi_get_info(struct rk628_gvi * gvi)63 static void rk628_gvi_get_info(struct rk628_gvi *gvi)
64 {
65 	switch (gvi->bus_format) {
66 	case GVI_MEDIA_BUS_FMT_RGB666_1X18:
67 		gvi->byte_mode = 3;
68 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_18BIT;
69 		break;
70 	case GVI_MEDIA_BUS_FMT_RGB888_1X24:
71 		gvi->byte_mode = 4;
72 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT;
73 		break;
74 	case GVI_MEDIA_BUS_FMT_RGB101010_1X30:
75 		gvi->byte_mode = 4;
76 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_30BIT;
77 		break;
78 	case GVI_MEDIA_BUS_FMT_YUYV8_1X16:
79 		gvi->byte_mode = 3;
80 		gvi->color_depth = COLOR_DEPTH_YUV422_16BIT;
81 		break;
82 	case GVI_MEDIA_BUS_FMT_YUYV10_1X20:
83 		gvi->byte_mode = 3;
84 		gvi->color_depth = COLOR_DEPTH_YUV422_20BIT;
85 		break;
86 	default:
87 		gvi->byte_mode = 3;
88 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT;
89 		pr_err("unsupported bus_format: 0x%x\n", gvi->bus_format);
90 		break;
91 	}
92 }
93 
rk628_gvi_get_lane_rate(struct rk628 * rk628)94 static unsigned int rk628_gvi_get_lane_rate(struct rk628 *rk628)
95 {
96 	struct rk628_gvi *gvi = &rk628->gvi;
97 	u32 lane_bit_rate, min_lane_rate = 500000, max_lane_rate = 4000000;
98 	u64 total_bw;
99 	struct drm_display_mode *src = &rk628->src_mode;
100 	const struct drm_display_mode *dst = &rk628->dst_mode;
101 	u64 dst_rate, src_rate;
102 
103 	src_rate = src->clock * 1000;
104 	dst_rate = src_rate * dst->vtotal * dst->htotal;
105 	do_div(dst_rate, (src->vtotal * src->htotal));
106 	do_div(dst_rate, 1000);
107 
108 	/**
109 	 * [ENCODER TOTAL BIT-RATE](bps) = [byte mode](byte) x 10 / [pixel clock](HZ)
110 	 *
111 	 * lane_bit_rate = [total bit-rate](bps) / [lane number]
112 	 *
113 	 * 500Mbps <= lane_bit_rate <= 4Gbps
114 	 */
115 	total_bw = (u64)gvi->byte_mode * 10 * dst_rate;/* Kbps */
116 	do_div(total_bw, gvi->lanes);
117 	lane_bit_rate = total_bw;
118 
119 	if (lane_bit_rate < min_lane_rate)
120 		lane_bit_rate = min_lane_rate;
121 	if (lane_bit_rate > max_lane_rate)
122 		lane_bit_rate = max_lane_rate;
123 
124 	return lane_bit_rate;
125 }
126 
rk628_gvi_pre_enable(struct rk628 * rk628,struct rk628_gvi * gvi)127 static void rk628_gvi_pre_enable(struct rk628 *rk628, struct rk628_gvi *gvi)
128 {
129 	/* gvi reset */
130 	rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST,
131 			      SYS_RST_SOFT_RST);
132 	udelay(10);
133 	rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST, 0);
134 	udelay(10);
135 
136 	rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_8_PIXEL_ALIGN(1));
137 
138 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_LANE_NUM_MASK,
139 			      SYS_CTRL0_LANE_NUM(gvi->lanes - 1));
140 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_BYTE_MODE_MASK,
141 			      SYS_CTRL0_BYTE_MODE(gvi->byte_mode ==
142 			      3 ? 0 : (gvi->byte_mode == 4 ? 1 : 2)));
143 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_SECTION_NUM_MASK,
144 			      SYS_CTRL0_SECTION_NUM(gvi->division_mode));
145 	rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_SPLIT_EN,
146 			      gvi->division_mode ? SW_SPLIT_EN : 0);
147 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_DUAL_PIXEL_EN,
148 			      gvi->division_mode ? SYS_CTRL1_DUAL_PIXEL_EN : 0);
149 
150 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_FRM_RST_EN,
151 			      gvi->frm_rst ? SYS_CTRL0_FRM_RST_EN : 0);
152 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_LANE_ALIGN_EN, 0);
153 
154 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_COLOR_DEPTH_MASK,
155 			      SYS_CTRL1_COLOR_DEPTH(gvi->color_depth));
156 }
157 
rk628_gvi_enable_color_bar(struct rk628 * rk628,struct rk628_gvi * gvi)158 static void rk628_gvi_enable_color_bar(struct rk628 *rk628,
159 				       struct rk628_gvi *gvi)
160 {
161 	const struct drm_display_mode *mode = &rk628->dst_mode;
162 	u16 vm_hactive, vm_hback_porch, vm_hsync_len;
163 	u16 vm_vactive, vm_vback_porch, vm_vsync_len;
164 	u16 hsync_len, hact_st, hact_end, htotal;
165 	u16 vsync_len, vact_st, vact_end, vtotal;
166 
167 	vm_hactive = mode->hdisplay;
168 	vm_hsync_len = mode->hsync_end - mode->hsync_start;
169 	vm_hback_porch = mode->htotal - mode->hsync_end;
170 
171 	vm_vactive = mode->vdisplay;
172 	vm_vsync_len = mode->vsync_end - mode->vsync_start;
173 	vm_vback_porch = mode->vtotal - mode->vsync_end;
174 
175 	if (gvi->division_mode) {
176 		hsync_len = vm_hsync_len / 2;
177 		hact_st = (vm_hsync_len + vm_hback_porch) / 2;
178 		hact_end = (vm_hsync_len + vm_hback_porch + vm_hactive) / 2;
179 		htotal = mode->htotal / 2;
180 	} else {
181 		hsync_len = vm_hsync_len;
182 		hact_st = vm_hsync_len + vm_hback_porch;
183 		hact_end = vm_hsync_len + vm_hback_porch + vm_hactive;
184 		htotal = mode->htotal;
185 	}
186 	vsync_len = vm_vsync_len;
187 	vact_st = vsync_len + vm_vback_porch;
188 	vact_end = vact_st + vm_vactive;
189 	vtotal = mode->vtotal;
190 
191 	rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING0,
192 			hact_st << 16 | hsync_len);
193 	rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING1,
194 			(htotal - 1) << 16 | hact_end);
195 	rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING0,
196 			vact_st << 16 | vsync_len);
197 	rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING1,
198 			(vtotal - 1) << 16 | vact_end);
199 	rk628_i2c_update_bits(rk628, GVI_COLOR_BAR_CTRL, COLOR_BAR_EN, 0);
200 }
201 
rk628_gvi_post_enable(struct rk628 * rk628,struct rk628_gvi * gvi)202 static void rk628_gvi_post_enable(struct rk628 *rk628, struct rk628_gvi *gvi)
203 {
204 	u32 val;
205 
206 	val = SYS_CTRL0_GVI_EN | SYS_CTRL0_AUTO_GATING;
207 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, val, 3);
208 }
209 
rk628_gvi_enable(struct rk628 * rk628)210 void rk628_gvi_enable(struct rk628 *rk628)
211 {
212 	struct rk628_gvi *gvi = &rk628->gvi;
213 	unsigned int rate;
214 	u32 mask = SW_OUTPUT_MODE_MASK;
215 	u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_GVI);
216 	int i = 0;
217 
218 	rk628_gvi_get_info(gvi);
219 	rate = rk628_gvi_get_lane_rate(rk628);
220 
221 	/* set gvi_hpd and gvi_lock mux */
222 	rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x06000600);
223 
224 	if (rk628->version == RK628F_VERSION) {
225 		mask = SW_OUTPUT_COMBTX_MODE_MASK;
226 		val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_GVI);
227 	}
228 
229 	rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, mask, val);
230 	rk628_combtxphy_set_bus_width(rk628, rate);
231 	rk628_combtxphy_set_gvi_division_mode(rk628, gvi->division_mode);
232 	rk628_combtxphy_set_mode(rk628, RK628_PHY_MODE_VIDEO_GVI);
233 	rate = rk628_combtxphy_get_bus_width(rk628);
234 	rk628_combtxphy_power_on(rk628);
235 	rk628_gvi_pre_enable(rk628, gvi);
236 	rk628_panel_prepare(rk628);
237 	rk628_gvi_enable_color_bar(rk628, gvi);
238 	rk628_gvi_post_enable(rk628, gvi);
239 
240 	for (i = 0; i < 100; i++) {
241 		rk628_i2c_read(rk628, GVI_STATUS, &val);
242 		if ((val & GVI_LOCKED_MASK) == GVI_LOCKED_STATUS)
243 			break;
244 		udelay(1000);
245 	}
246 
247 	if (i == 100 && gvi->retry_times < GVI_RETRY_TIMEOUT) {
248 		dev_info(rk628->dev, "GVI Lock failed: 0x%x, try again: %d\n", val, gvi->retry_times);
249 		gvi->retry_times++;
250 		rk628_gvi_disable(rk628);
251 		udelay(50000);
252 		rk628_gvi_enable(rk628);
253 	}
254 
255 	if (gvi->retry_times >= GVI_RETRY_TIMEOUT && i == 100) {
256 		dev_info(rk628->dev, "GVI Lock failed, please check hardware!\n");
257 		return;
258 	}
259 	rk628_panel_enable(rk628);
260 
261 	if (i != 100)
262 		gvi->retry_times = 0;
263 
264 	printf("rk628 GVI-Link bandwidth: %d x %d Mbps, Byte mode: %d, Color Depty: %d, %s division mode\n",
265 	       rate, gvi->lanes, gvi->byte_mode, gvi->color_depth,
266 	       gvi->division_mode ? "two" : "one");
267 }
268 
rk628_gvi_disable(struct rk628 * rk628)269 void rk628_gvi_disable(struct rk628 *rk628)
270 {
271 	rk628_panel_disable(rk628);
272 	rk628_panel_unprepare(rk628);
273 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_GVI_EN, 0);
274 	rk628_combtxphy_power_off(rk628);
275 }
276 
277