xref: /OK3568_Linux_fs/kernel/drivers/misc/rk628/rk628_csi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Shunqing Chen <csq@rock-chisp.com>
6  */
7 
8 #include "rk628.h"
9 #include "rk628_combtxphy.h"
10 #include "rk628_config.h"
11 #include "rk628_csi.h"
12 
13 #define CSITX_ERR_RETRY_TIMES		3
14 
15 #define MIPI_DATARATE_MBPS_LOW		750
16 #define MIPI_DATARATE_MBPS_HIGH		1250
17 
18 #define USE_4_LANES			4
19 #define YUV422_8BIT			0x1e
20 /* Test Code: 0x44 (HS RX Control of Lane 0) */
21 #define HSFREQRANGE(x)			UPDATE(x, 6, 1)
22 
23 struct rk628_csi {
24 	struct rk628_display_mode mode;
25 	bool txphy_pwron;
26 	u64 lane_mbps;
27 };
28 
testif_testclk_assert(struct rk628 * rk628)29 static inline void testif_testclk_assert(struct rk628 *rk628)
30 {
31 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
32 			   PHY_TESTCLK, PHY_TESTCLK);
33 	udelay(1);
34 }
35 
testif_testclk_deassert(struct rk628 * rk628)36 static inline void testif_testclk_deassert(struct rk628 *rk628)
37 {
38 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
39 			   PHY_TESTCLK, 0);
40 	udelay(1);
41 }
42 
testif_testclr_assert(struct rk628 * rk628)43 static inline void testif_testclr_assert(struct rk628 *rk628)
44 {
45 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
46 			   PHY_TESTCLR, PHY_TESTCLR);
47 	udelay(1);
48 }
49 
testif_testclr_deassert(struct rk628 * rk628)50 static inline void testif_testclr_deassert(struct rk628 *rk628)
51 {
52 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
53 			   PHY_TESTCLR, 0);
54 	udelay(1);
55 }
56 
testif_testen_assert(struct rk628 * rk628)57 static inline void testif_testen_assert(struct rk628 *rk628)
58 {
59 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
60 			   PHY_TESTEN, PHY_TESTEN);
61 	udelay(1);
62 }
63 
testif_testen_deassert(struct rk628 * rk628)64 static inline void testif_testen_deassert(struct rk628 *rk628)
65 {
66 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
67 			   PHY_TESTEN, 0);
68 	udelay(1);
69 }
70 
testif_set_data(struct rk628 * rk628,u8 data)71 static inline void testif_set_data(struct rk628 *rk628, u8 data)
72 {
73 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
74 			   PHY_TESTDIN_MASK, PHY_TESTDIN(data));
75 	udelay(1);
76 }
77 
testif_get_data(struct rk628 * rk628)78 static inline u8 testif_get_data(struct rk628 *rk628)
79 {
80 	u32 data = 0;
81 
82 	rk628_i2c_read(rk628, GRF_DPHY0_STATUS, &data);
83 
84 	return data >> PHY_TESTDOUT_SHIFT;
85 }
86 
testif_test_code_write(struct rk628 * rk628,u8 test_code)87 static void testif_test_code_write(struct rk628 *rk628, u8 test_code)
88 {
89 	testif_testclk_assert(rk628);
90 	testif_set_data(rk628, test_code);
91 	testif_testen_assert(rk628);
92 	testif_testclk_deassert(rk628);
93 	testif_testen_deassert(rk628);
94 }
95 
testif_test_data_write(struct rk628 * rk628,u8 test_data)96 static void testif_test_data_write(struct rk628 *rk628, u8 test_data)
97 {
98 	testif_testclk_deassert(rk628);
99 	testif_set_data(rk628, test_data);
100 	testif_testclk_assert(rk628);
101 }
102 
testif_write(struct rk628 * rk628,u8 test_code,u8 test_data)103 static u8 testif_write(struct rk628 *rk628, u8 test_code, u8 test_data)
104 {
105 	u8 monitor_data;
106 
107 	testif_test_code_write(rk628, test_code);
108 	testif_test_data_write(rk628, test_data);
109 	monitor_data = testif_get_data(rk628);
110 
111 	dev_info(rk628->dev, "test_code=0x%02x, ", test_code);
112 	dev_info(rk628->dev, "test_data=0x%02x, ", test_data);
113 	dev_info(rk628->dev, "monitor_data=0x%02x\n", monitor_data);
114 
115 	return monitor_data;
116 }
rk628_csi_get_detected_timings(struct rk628 * rk628)117 static void rk628_csi_get_detected_timings(struct rk628 *rk628)
118 {
119 	struct rk628_display_mode *src, *dst;
120 	struct rk628_csi *csi = rk628->csi;
121 
122 	if (!csi)
123 		return;
124 
125 	src = rk628_display_get_src_mode(rk628);
126 	dst = rk628_display_get_dst_mode(rk628);
127 
128 	rk628_set_output_bus_format(rk628, BUS_FMT_YUV422);
129 	rk628_mode_copy(dst, src);
130 	rk628_mode_copy(&csi->mode, dst);
131 }
132 
133 
testif_read(struct rk628 * rk628,u8 test_code)134 static inline u8 testif_read(struct rk628 *rk628, u8 test_code)
135 {
136 	u8 test_data;
137 
138 	testif_test_code_write(rk628, test_code);
139 	test_data = testif_get_data(rk628);
140 	testif_test_data_write(rk628, test_data);
141 
142 	return test_data;
143 }
144 
mipi_dphy_enableclk_assert(struct rk628 * rk628)145 static inline void mipi_dphy_enableclk_assert(struct rk628 *rk628)
146 {
147 	rk628_i2c_update_bits(rk628, CSITX_DPHY_CTRL, DPHY_ENABLECLK,
148 			DPHY_ENABLECLK);
149 	udelay(1);
150 }
151 
mipi_dphy_enableclk_deassert(struct rk628 * rk628)152 static inline void mipi_dphy_enableclk_deassert(struct rk628 *rk628)
153 {
154 	rk628_i2c_update_bits(rk628,  CSITX_DPHY_CTRL, DPHY_ENABLECLK, 0);
155 	udelay(1);
156 }
157 
mipi_dphy_shutdownz_assert(struct rk628 * rk628)158 static inline void mipi_dphy_shutdownz_assert(struct rk628 *rk628)
159 {
160 	rk628_i2c_update_bits(rk628,  GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, 0);
161 	udelay(1);
162 }
163 
mipi_dphy_shutdownz_deassert(struct rk628 * rk628)164 static inline void mipi_dphy_shutdownz_deassert(struct rk628 *rk628)
165 {
166 	rk628_i2c_update_bits(rk628,  GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ,
167 			CSI_PHYSHUTDOWNZ);
168 	udelay(1);
169 }
170 
mipi_dphy_rstz_assert(struct rk628 * rk628)171 static inline void mipi_dphy_rstz_assert(struct rk628 *rk628)
172 {
173 	rk628_i2c_update_bits(rk628,  GRF_MIPI_TX0_CON, CSI_PHYRSTZ, 0);
174 	udelay(1);
175 }
176 
mipi_dphy_rstz_deassert(struct rk628 * rk628)177 static inline void mipi_dphy_rstz_deassert(struct rk628 *rk628)
178 {
179 	rk628_i2c_update_bits(rk628,  GRF_MIPI_TX0_CON, CSI_PHYRSTZ,
180 			CSI_PHYRSTZ);
181 	udelay(1);
182 }
183 
mipi_dphy_init_hsfreqrange(struct rk628 * rk628)184 static void mipi_dphy_init_hsfreqrange(struct rk628 *rk628)
185 {
186 	const struct {
187 		unsigned long max_lane_mbps;
188 		u8 hsfreqrange;
189 	} hsfreqrange_table[] = {
190 		{  90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
191 		{ 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
192 		{ 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
193 		{ 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
194 		{ 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
195 		{ 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
196 		{ 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
197 		{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
198 		{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
199 		{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
200 	};
201 	u8 hsfreqrange;
202 	unsigned int index;
203 	struct rk628_csi *csi = rk628->csi;
204 
205 	if (!csi)
206 		return;
207 
208 	for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++)
209 		if (csi->lane_mbps <= hsfreqrange_table[index].max_lane_mbps)
210 			break;
211 
212 	if (index == ARRAY_SIZE(hsfreqrange_table))
213 		--index;
214 
215 	hsfreqrange = hsfreqrange_table[index].hsfreqrange;
216 	testif_write(rk628, 0x44, HSFREQRANGE(hsfreqrange));
217 }
218 
mipi_dphy_reset(struct rk628 * rk628)219 static int mipi_dphy_reset(struct rk628 *rk628)
220 {
221 	u32 val;
222 	int ret;
223 
224 	mipi_dphy_enableclk_deassert(rk628);
225 	mipi_dphy_shutdownz_assert(rk628);
226 	mipi_dphy_rstz_assert(rk628);
227 	testif_testclr_assert(rk628);
228 
229 	/* Set all REQUEST inputs to zero */
230 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
231 		     FORCETXSTOPMODE_MASK | FORCERXMODE_MASK,
232 		     FORCETXSTOPMODE(0) | FORCERXMODE(0));
233 	udelay(1);
234 	testif_testclr_deassert(rk628);
235 	mipi_dphy_enableclk_assert(rk628);
236 	mipi_dphy_shutdownz_deassert(rk628);
237 	mipi_dphy_rstz_deassert(rk628);
238 	usleep_range(1500, 2000);
239 
240 	ret = rk628_i2c_read(rk628, CSITX_CSITX_STATUS1, &val);
241 	if (ret < 0) {
242 		dev_info(rk628->dev, "lane module is not in stop state\n");
243 		return ret;
244 	}
245 
246 	return 0;
247 }
248 
mipi_dphy_power_on(struct rk628 * rk628)249 static int mipi_dphy_power_on(struct rk628 *rk628)
250 {
251 	unsigned int val;
252 	u32 bus_width, mask;
253 	struct rk628_csi *csi = rk628->csi;
254 
255 	if (!csi)
256 		return -1;
257 
258 	if ((csi->mode.hdisplay == 3840) &&
259 	    (csi->mode.vdisplay == 2160)) {
260 		csi->lane_mbps = MIPI_DATARATE_MBPS_HIGH;
261 	} else {
262 		csi->lane_mbps = MIPI_DATARATE_MBPS_LOW;
263 	}
264 
265 	bus_width =  csi->lane_mbps << 8;
266 	bus_width |= COMBTXPHY_MODULEA_EN;
267 	dev_info(rk628->dev, "%s mipi bitrate:%llu mbps\n", __func__, csi->lane_mbps);
268 	rk628_combtxphy_set_bus_width(rk628, bus_width);
269 	rk628_combtxphy_set_mode(rk628, PHY_MODE_VIDEO_MIPI);
270 
271 	mipi_dphy_init_hsfreqrange(rk628);
272 	usleep_range(1500, 2000);
273 	rk628_combtxphy_power_on(rk628);
274 
275 	usleep_range(1500, 2000);
276 	mask = DPHY_PLL_LOCK;
277 	rk628_i2c_read(rk628, CSITX_CSITX_STATUS1, &val);
278 	if ((val & mask) != mask) {
279 		dev_info(rk628->dev, "PHY is not locked\n");
280 		return -1;
281 	}
282 
283 	udelay(10);
284 
285 	return 0;
286 }
287 
mipi_dphy_power_off(struct rk628 * rk628)288 static void mipi_dphy_power_off(struct rk628 *rk628)
289 {
290 	rk628_combtxphy_power_off(rk628);
291 }
292 
rk62_csi_reset(struct rk628 * rk628)293 static void rk62_csi_reset(struct rk628 *rk628)
294 {
295 	rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x1);
296 	usleep_range(1000, 1100);
297 	rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x0);
298 }
299 
rk628_csi_set_csi(struct rk628 * rk628)300 static void rk628_csi_set_csi(struct rk628 *rk628)
301 {
302 	u8 lanes = USE_4_LANES;
303 	u8 lane_num;
304 	u8 dphy_lane_en;
305 	u32 wc_usrdef;
306 	struct rk628_csi *csi;
307 
308 	if (!rk628->csi) {
309 		csi = devm_kzalloc(rk628->dev, sizeof(*csi), GFP_KERNEL);
310 		if (!csi)
311 			return;
312 		rk628->csi = csi;
313 	} else {
314 		csi = rk628->csi;
315 	}
316 	lane_num = lanes - 1;
317 	dphy_lane_en = (1 << (lanes + 1)) - 1;
318 	wc_usrdef = csi->mode.hdisplay * 2;
319 
320 	rk62_csi_reset(rk628);
321 
322 	if (csi->txphy_pwron) {
323 		dev_info(rk628->dev, "%s: txphy already power on, power off\n",
324 			__func__);
325 		mipi_dphy_power_off(rk628);
326 		csi->txphy_pwron = false;
327 	}
328 
329 	mipi_dphy_power_on(rk628);
330 	csi->txphy_pwron = true;
331 	dev_info(rk628->dev, "%s: txphy power on!\n", __func__);
332 	usleep_range(1000, 1500);
333 
334 	rk628_i2c_update_bits(rk628, CSITX_CSITX_EN,
335 			VOP_UV_SWAP_MASK |
336 			VOP_YUV422_EN_MASK |
337 			VOP_P2_EN_MASK |
338 			LANE_NUM_MASK |
339 			DPHY_EN_MASK |
340 			CSITX_EN_MASK,
341 			VOP_UV_SWAP(1) |
342 			VOP_YUV422_EN(1) |
343 			VOP_P2_EN(1) |
344 			LANE_NUM(lane_num) |
345 			DPHY_EN(0) |
346 			CSITX_EN(0));
347 	rk628_i2c_update_bits(rk628, CSITX_SYS_CTRL1,
348 			BYPASS_SELECT_MASK,
349 			BYPASS_SELECT(1));
350 	rk628_i2c_write(rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
351 	rk628_i2c_write(rk628, CSITX_SYS_CTRL2, VOP_WHOLE_FRM_EN | VSYNC_ENABLE);
352 	rk628_i2c_update_bits(rk628, CSITX_SYS_CTRL3_IMD,
353 			CONT_MODE_CLK_CLR_MASK |
354 			CONT_MODE_CLK_SET_MASK |
355 			NON_CONTINOUS_MODE_MASK,
356 			CONT_MODE_CLK_CLR(0) |
357 			CONT_MODE_CLK_SET(0) |
358 			NON_CONTINOUS_MODE(1));
359 
360 	rk628_i2c_write(rk628, CSITX_VOP_PATH_CTRL,
361 			VOP_WC_USERDEFINE(wc_usrdef) |
362 			VOP_DT_USERDEFINE(YUV422_8BIT) |
363 			VOP_PIXEL_FORMAT(0) |
364 			VOP_WC_USERDEFINE_EN(1) |
365 			VOP_DT_USERDEFINE_EN(1) |
366 			VOP_PATH_EN(1));
367 	rk628_i2c_update_bits(rk628, CSITX_DPHY_CTRL,
368 				CSI_DPHY_EN_MASK,
369 				CSI_DPHY_EN(dphy_lane_en));
370 	rk628_i2c_write(rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
371 	dev_info(rk628->dev, "%s csi cofig done\n", __func__);
372 }
373 
enable_csitx(struct rk628 * rk628)374 static void enable_csitx(struct rk628 *rk628)
375 {
376 	u32 i, ret, val;
377 
378 	for (i = 0; i < CSITX_ERR_RETRY_TIMES; i++) {
379 		rk628_csi_set_csi(rk628);
380 		rk628_i2c_update_bits(rk628, CSITX_CSITX_EN,
381 					DPHY_EN_MASK |
382 					CSITX_EN_MASK,
383 					DPHY_EN(1) |
384 					CSITX_EN(1));
385 		rk628_i2c_write(rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
386 		msleep(40);
387 		rk628_i2c_write(rk628, CSITX_ERR_INTR_CLR_IMD, 0xffffffff);
388 		rk628_i2c_update_bits(rk628, CSITX_SYS_CTRL1,
389 				BYPASS_SELECT_MASK, BYPASS_SELECT(0));
390 		rk628_i2c_write(rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
391 		msleep(40);
392 		ret = rk628_i2c_read(rk628, CSITX_ERR_INTR_RAW_STATUS_IMD, &val);
393 		if (!ret && !val)
394 			break;
395 
396 		dev_info(rk628->dev, "%s csitx err, retry:%d, err status:%#x, ret:%d\n",
397 			 __func__, i, val, ret);
398 	}
399 
400 }
401 
enable_stream(struct rk628 * rk628,bool en)402 static void enable_stream(struct rk628 *rk628, bool en)
403 {
404 	dev_info(rk628->dev, "%s: %sable\n", __func__, en ? "en" : "dis");
405 	if (en) {
406 		enable_csitx(rk628);
407 	} else {
408 		rk628_i2c_update_bits(rk628, CSITX_CSITX_EN,
409 					DPHY_EN_MASK |
410 					CSITX_EN_MASK,
411 					DPHY_EN(0) |
412 					CSITX_EN(0));
413 		rk628_i2c_write(rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
414 	}
415 }
416 
rk628_csi_init(struct rk628 * rk628)417 void rk628_csi_init(struct rk628 *rk628)
418 {
419 	rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
420 			      SW_OUTPUT_MODE_MASK, SW_OUTPUT_MODE(OUTPUT_MODE_CSI));
421 	rk628_csi_get_detected_timings(rk628);
422 	mipi_dphy_reset(rk628);
423 }
424 
rk628_csi_enable(struct rk628 * rk628)425 void rk628_csi_enable(struct rk628 *rk628)
426 {
427 	rk628_csi_get_detected_timings(rk628);
428 	return enable_stream(rk628, true);
429 }
430 
rk628_csi_disable(struct rk628 * rk628)431 void rk628_csi_disable(struct rk628 *rk628)
432 {
433 	return enable_stream(rk628, false);
434 }
435