xref: /OK3568_Linux_fs/kernel/drivers/misc/rk628/rk628_gvi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Guochun Huang <hero.huang@rock-chips.com>
6  */
7 
8 #include "linux/printk.h"
9 #include "rk628.h"
10 #include "rk628_config.h"
11 #include "rk628_combtxphy.h"
12 #include "rk628_gvi.h"
13 #include "panel.h"
14 
rk628_gvi_parse(struct rk628 * rk628,struct device_node * gvi_np)15 int rk628_gvi_parse(struct rk628 *rk628, struct device_node *gvi_np)
16 {
17 	const char *string;
18 	u32 val;
19 	int ret;
20 
21 	if (!of_device_is_available(gvi_np))
22 		return -EINVAL;
23 
24 	rk628->output_mode = OUTPUT_MODE_GVI;
25 
26 	if (!of_property_read_u32(gvi_np, "gvi,lanes", &val))
27 		rk628->gvi.lanes = val;
28 
29 	if (of_property_read_bool(gvi_np, "rockchip,division-mode"))
30 		rk628->gvi.division_mode = true;
31 	else
32 		rk628->gvi.division_mode = false;
33 
34 	if (of_property_read_bool(gvi_np, "rockchip,gvi-frm-rst"))
35 		rk628->gvi.frm_rst = true;
36 	else
37 		rk628->gvi.frm_rst = false;
38 
39 	if (!of_property_read_string(gvi_np, "bus-format", &string)) {
40 		if (!strcmp(string, "rgb666"))
41 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB666_1X18;
42 		else if (!strcmp(string, "rgb101010"))
43 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB101010_1X30;
44 		else if (!strcmp(string, "yuyv8"))
45 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV8_1X16;
46 		else if (!strcmp(string, "yuyv10"))
47 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV10_1X20;
48 		else
49 			rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB888_1X24;
50 	}
51 
52 	ret = rk628_panel_info_get(rk628, gvi_np);
53 	if (ret)
54 		return ret;
55 
56 	return 0;
57 }
58 
rk628_gvi_get_info(struct rk628_gvi * gvi)59 static void rk628_gvi_get_info(struct rk628_gvi *gvi)
60 {
61 	switch (gvi->bus_format) {
62 	case GVI_MEDIA_BUS_FMT_RGB666_1X18:
63 		gvi->byte_mode = 3;
64 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_18BIT;
65 		break;
66 	case GVI_MEDIA_BUS_FMT_RGB888_1X24:
67 		gvi->byte_mode = 4;
68 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT;
69 		break;
70 	case GVI_MEDIA_BUS_FMT_RGB101010_1X30:
71 		gvi->byte_mode = 4;
72 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_30BIT;
73 		break;
74 	case GVI_MEDIA_BUS_FMT_YUYV8_1X16:
75 		gvi->byte_mode = 3;
76 		gvi->color_depth = COLOR_DEPTH_YUV422_16BIT;
77 		break;
78 	case GVI_MEDIA_BUS_FMT_YUYV10_1X20:
79 		gvi->byte_mode = 3;
80 		gvi->color_depth = COLOR_DEPTH_YUV422_20BIT;
81 		break;
82 	default:
83 		gvi->byte_mode = 3;
84 		gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT;
85 		pr_err("unsupported bus_format: 0x%x\n", gvi->bus_format);
86 		break;
87 	}
88 }
89 
rk628_gvi_get_lane_rate(struct rk628 * rk628)90 static unsigned int rk628_gvi_get_lane_rate(struct rk628 *rk628)
91 {
92 	const struct rk628_display_mode *mode = &rk628->dst_mode;
93 	struct rk628_gvi *gvi = &rk628->gvi;
94 	u32 lane_bit_rate, min_lane_rate = 500000, max_lane_rate = 4000000;
95 	u64 total_bw;
96 
97 	/**
98 	 * [ENCODER TOTAL BIT-RATE](bps) = [byte mode](byte) x 10 / [pixel clock](HZ)
99 	 *
100 	 * lane_bit_rate = [total bit-rate](bps) / [lane number]
101 	 *
102 	 * 500Mbps <= lane_bit_rate <= 4Gbps
103 	 */
104 	total_bw = (u64)gvi->byte_mode * 10 * mode->clock;/* Kbps */
105 	do_div(total_bw, gvi->lanes);
106 	lane_bit_rate = total_bw;
107 
108 	if (lane_bit_rate < min_lane_rate)
109 		lane_bit_rate = min_lane_rate;
110 	if (lane_bit_rate > max_lane_rate)
111 		lane_bit_rate = max_lane_rate;
112 
113 	return lane_bit_rate;
114 }
115 
rk628_gvi_pre_enable(struct rk628 * rk628,struct rk628_gvi * gvi)116 static void rk628_gvi_pre_enable(struct rk628 *rk628, struct rk628_gvi *gvi)
117 {
118 	/* gvi reset */
119 	rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST,
120 			      SYS_RST_SOFT_RST);
121 	udelay(10);
122 	rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST, 0);
123 	udelay(10);
124 
125 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_LANE_NUM_MASK,
126 			      SYS_CTRL0_LANE_NUM(gvi->lanes - 1));
127 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_BYTE_MODE_MASK,
128 			      SYS_CTRL0_BYTE_MODE(gvi->byte_mode ==
129 			      3 ? 0 : (gvi->byte_mode == 4 ? 1 : 2)));
130 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_SECTION_NUM_MASK,
131 			      SYS_CTRL0_SECTION_NUM(gvi->division_mode));
132 	rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_SPLIT_EN,
133 			      gvi->division_mode ? SW_SPLIT_EN : 0);
134 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_DUAL_PIXEL_EN,
135 			      gvi->division_mode ? SYS_CTRL1_DUAL_PIXEL_EN : 0);
136 
137 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_FRM_RST_EN,
138 			      gvi->frm_rst ? SYS_CTRL0_FRM_RST_EN : 0);
139 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_LANE_ALIGN_EN, 0);
140 }
141 
rk628_gvi_enable_color_bar(struct rk628 * rk628,struct rk628_gvi * gvi)142 static void rk628_gvi_enable_color_bar(struct rk628 *rk628,
143 				       struct rk628_gvi *gvi)
144 {
145 	const struct rk628_display_mode *mode = &rk628->dst_mode;
146 	u16 vm_hactive, vm_hback_porch, vm_hsync_len;
147 	u16 vm_vactive, vm_vback_porch, vm_vsync_len;
148 	u16 hsync_len, hact_st, hact_end, htotal;
149 	u16 vsync_len, vact_st, vact_end, vtotal;
150 
151 	vm_hactive = mode->hdisplay;
152 	vm_hsync_len = mode->hsync_end - mode->hsync_start;
153 	vm_hback_porch = mode->htotal - mode->hsync_end;
154 
155 	vm_vactive = mode->vdisplay;
156 	vm_vsync_len = mode->vsync_end - mode->vsync_start;
157 	vm_vback_porch = mode->vtotal - mode->vsync_end;
158 
159 	if (gvi->division_mode) {
160 		hsync_len = vm_hsync_len / 2;
161 		hact_st = (vm_hsync_len + vm_hback_porch) / 2;
162 		hact_end = (vm_hsync_len + vm_hback_porch + vm_hactive) / 2;
163 		htotal = mode->htotal / 2;
164 	} else {
165 		hsync_len = vm_hsync_len;
166 		hact_st = vm_hsync_len + vm_hback_porch;
167 		hact_end = vm_hsync_len + vm_hback_porch + vm_hactive;
168 		htotal = mode->htotal;
169 	}
170 	vsync_len = vm_vsync_len;
171 	vact_st = vsync_len + vm_vback_porch;
172 	vact_end = vact_st + vm_vactive;
173 	vtotal = mode->vtotal;
174 
175 	rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING0,
176 			hact_st << 16 | hsync_len);
177 	rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING1,
178 			(htotal - 1) << 16 | hact_end);
179 	rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING0,
180 			vact_st << 16 | vsync_len);
181 	rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING1,
182 			(vtotal - 1) << 16 | vact_end);
183 	rk628_i2c_update_bits(rk628, GVI_COLOR_BAR_CTRL, COLOR_BAR_EN, 0);
184 }
185 
186 
rk628_gvi_post_enable(struct rk628 * rk628,struct rk628_gvi * gvi)187 static void rk628_gvi_post_enable(struct rk628 *rk628, struct rk628_gvi *gvi)
188 {
189 	u32 val;
190 
191 	val = SYS_CTRL0_GVI_EN | SYS_CTRL0_AUTO_GATING;
192 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, val, 3);
193 }
194 
rk628_gvi_enable(struct rk628 * rk628)195 void rk628_gvi_enable(struct rk628 *rk628)
196 {
197 	struct rk628_gvi *gvi = &rk628->gvi;
198 	unsigned int rate;
199 
200 	rk628_gvi_get_info(gvi);
201 	rate = rk628_gvi_get_lane_rate(rk628);
202 
203 	/* set gvi_hpd and gvi_lock mux */
204 	rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x06000600);
205 	rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_OUTPUT_MODE_MASK,
206 			      SW_OUTPUT_MODE(OUTPUT_MODE_GVI));
207 	rk628_combtxphy_set_bus_width(rk628, rate);
208 	rk628_combtxphy_set_gvi_division_mode(rk628, gvi->division_mode);
209 	rk628_combtxphy_set_mode(rk628, PHY_MODE_VIDEO_GVI);
210 	rate = rk628_combtxphy_get_bus_width(rk628);
211 	rk628_combtxphy_power_on(rk628);
212 	rk628_gvi_pre_enable(rk628, gvi);
213 	rk628_panel_prepare(rk628);
214 	rk628_gvi_enable_color_bar(rk628, gvi);
215 	rk628_gvi_post_enable(rk628, gvi);
216 	rk628_panel_enable(rk628);
217 	dev_info(rk628->dev,
218 		 "GVI-Link bandwidth: %d x %d Mbps, Byte mode: %d, Color Depty: %d, %s division mode\n",
219 		 rate, gvi->lanes, gvi->byte_mode, gvi->color_depth,
220 		 gvi->division_mode ? "two" : "one");
221 }
222 
rk628_gvi_disable(struct rk628 * rk628)223 void rk628_gvi_disable(struct rk628 *rk628)
224 {
225 	rk628_panel_disable(rk628);
226 	rk628_panel_unprepare(rk628);
227 	rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_GVI_EN, 0);
228 	rk628_combtxphy_power_off(rk628);
229 }
230 
231