xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/rk628/rk628_mipi_dphy.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author: Shunqing Chen <csq@rock-chips.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef _RK628_MIPI_DPHY_H
9*4882a593Smuzhiyun #define _RK628_MIPI_DPHY_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/i2c.h>
13*4882a593Smuzhiyun #include <linux/regmap.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include "rk628_csi.h"
16*4882a593Smuzhiyun #include "rk628_dsi.h"
17*4882a593Smuzhiyun #include "rk628.h"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Test Code: 0x44 (HS RX Control of Lane 0) */
20*4882a593Smuzhiyun #define HSFREQRANGE(x)			UPDATE(x, 6, 1)
21*4882a593Smuzhiyun 
testif_testclk_assert(struct rk628 * rk628)22*4882a593Smuzhiyun static inline void testif_testclk_assert(struct rk628 *rk628)
23*4882a593Smuzhiyun {
24*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
25*4882a593Smuzhiyun 			   PHY_TESTCLK, PHY_TESTCLK);
26*4882a593Smuzhiyun 	udelay(1);
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun 
testif_testclk_deassert(struct rk628 * rk628)29*4882a593Smuzhiyun static inline void testif_testclk_deassert(struct rk628 *rk628)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
32*4882a593Smuzhiyun 			   PHY_TESTCLK, 0);
33*4882a593Smuzhiyun 	udelay(1);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
testif_testclr_assert(struct rk628 * rk628)36*4882a593Smuzhiyun static inline void testif_testclr_assert(struct rk628 *rk628)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
39*4882a593Smuzhiyun 			   PHY_TESTCLR, PHY_TESTCLR);
40*4882a593Smuzhiyun 	udelay(1);
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun 
testif_testclr_deassert(struct rk628 * rk628)43*4882a593Smuzhiyun static inline void testif_testclr_deassert(struct rk628 *rk628)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
46*4882a593Smuzhiyun 			   PHY_TESTCLR, 0);
47*4882a593Smuzhiyun 	udelay(1);
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
testif_testen_assert(struct rk628 * rk628)50*4882a593Smuzhiyun static inline void testif_testen_assert(struct rk628 *rk628)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
53*4882a593Smuzhiyun 			   PHY_TESTEN, PHY_TESTEN);
54*4882a593Smuzhiyun 	udelay(1);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
testif_testen_deassert(struct rk628 * rk628)57*4882a593Smuzhiyun static inline void testif_testen_deassert(struct rk628 *rk628)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
60*4882a593Smuzhiyun 			   PHY_TESTEN, 0);
61*4882a593Smuzhiyun 	udelay(1);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
testif_set_data(struct rk628 * rk628,u8 data)64*4882a593Smuzhiyun static inline void testif_set_data(struct rk628 *rk628, u8 data)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
67*4882a593Smuzhiyun 			   PHY_TESTDIN_MASK, PHY_TESTDIN(data));
68*4882a593Smuzhiyun 	udelay(1);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
testif_get_data(struct rk628 * rk628)71*4882a593Smuzhiyun static inline u8 testif_get_data(struct rk628 *rk628)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	u32 data = 0;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	rk628_i2c_read(rk628, GRF_DPHY0_STATUS, &data);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	return data >> PHY_TESTDOUT_SHIFT;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
testif_test_code_write(struct rk628 * rk628,u8 test_code)80*4882a593Smuzhiyun static void testif_test_code_write(struct rk628 *rk628, u8 test_code)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	testif_testclk_assert(rk628);
83*4882a593Smuzhiyun 	testif_set_data(rk628, test_code);
84*4882a593Smuzhiyun 	testif_testen_assert(rk628);
85*4882a593Smuzhiyun 	testif_testclk_deassert(rk628);
86*4882a593Smuzhiyun 	testif_testen_deassert(rk628);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
testif_test_data_write(struct rk628 * rk628,u8 test_data)89*4882a593Smuzhiyun static void testif_test_data_write(struct rk628 *rk628, u8 test_data)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	testif_testclk_deassert(rk628);
92*4882a593Smuzhiyun 	testif_set_data(rk628, test_data);
93*4882a593Smuzhiyun 	testif_testclk_assert(rk628);
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
testif_write(struct rk628 * rk628,u8 test_code,u8 test_data)96*4882a593Smuzhiyun static u8 testif_write(struct rk628 *rk628, u8 test_code, u8 test_data)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	u8 monitor_data;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	testif_test_code_write(rk628, test_code);
101*4882a593Smuzhiyun 	testif_test_data_write(rk628, test_data);
102*4882a593Smuzhiyun 	monitor_data = testif_get_data(rk628);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	dev_dbg(rk628->dev, "test_code=0x%02x, ", test_code);
105*4882a593Smuzhiyun 	dev_dbg(rk628->dev, "test_data=0x%02x, ", test_data);
106*4882a593Smuzhiyun 	dev_dbg(rk628->dev, "monitor_data=0x%02x\n", monitor_data);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	return monitor_data;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
testif_read(struct rk628 * rk628,u8 test_code)111*4882a593Smuzhiyun static inline u8 testif_read(struct rk628 *rk628, u8 test_code)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	u8 test_data;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	testif_test_code_write(rk628, test_code);
116*4882a593Smuzhiyun 	test_data = testif_get_data(rk628);
117*4882a593Smuzhiyun 	testif_test_data_write(rk628, test_data);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	return test_data;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
mipi_dphy_enableclk_assert(struct rk628 * rk628)122*4882a593Smuzhiyun static inline void mipi_dphy_enableclk_assert(struct rk628 *rk628)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, CSITX_DPHY_CTRL, DPHY_ENABLECLK,
125*4882a593Smuzhiyun 			DPHY_ENABLECLK);
126*4882a593Smuzhiyun 	udelay(1);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
mipi_dphy_enableclk_deassert(struct rk628 * rk628)129*4882a593Smuzhiyun static inline void mipi_dphy_enableclk_deassert(struct rk628 *rk628)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, CSITX_DPHY_CTRL, DPHY_ENABLECLK, 0);
132*4882a593Smuzhiyun 	udelay(1);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
mipi_dphy_shutdownz_assert(struct rk628 * rk628)135*4882a593Smuzhiyun static inline void mipi_dphy_shutdownz_assert(struct rk628 *rk628)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, 0);
138*4882a593Smuzhiyun 	udelay(1);
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
mipi_dphy_shutdownz_deassert(struct rk628 * rk628)141*4882a593Smuzhiyun static inline void mipi_dphy_shutdownz_deassert(struct rk628 *rk628)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ,
144*4882a593Smuzhiyun 			CSI_PHYSHUTDOWNZ);
145*4882a593Smuzhiyun 	udelay(1);
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
mipi_dphy_rstz_assert(struct rk628 * rk628)148*4882a593Smuzhiyun static inline void mipi_dphy_rstz_assert(struct rk628 *rk628)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ, 0);
151*4882a593Smuzhiyun 	udelay(1);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
mipi_dphy_rstz_deassert(struct rk628 * rk628)154*4882a593Smuzhiyun static inline void mipi_dphy_rstz_deassert(struct rk628 *rk628)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ,
157*4882a593Smuzhiyun 			CSI_PHYRSTZ);
158*4882a593Smuzhiyun 	udelay(1);
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
mipi_dphy_init_hsfreqrange(struct rk628 * rk628,int lane_mbps)161*4882a593Smuzhiyun static inline void mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	const struct {
164*4882a593Smuzhiyun 		unsigned long max_lane_mbps;
165*4882a593Smuzhiyun 		u8 hsfreqrange;
166*4882a593Smuzhiyun 	} hsfreqrange_table[] = {
167*4882a593Smuzhiyun 		{  90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
168*4882a593Smuzhiyun 		{ 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
169*4882a593Smuzhiyun 		{ 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
170*4882a593Smuzhiyun 		{ 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
171*4882a593Smuzhiyun 		{ 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
172*4882a593Smuzhiyun 		{ 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
173*4882a593Smuzhiyun 		{ 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
174*4882a593Smuzhiyun 		{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
175*4882a593Smuzhiyun 		{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
176*4882a593Smuzhiyun 		{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
177*4882a593Smuzhiyun 	};
178*4882a593Smuzhiyun 	u8 hsfreqrange;
179*4882a593Smuzhiyun 	unsigned int index;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++)
182*4882a593Smuzhiyun 		if (lane_mbps <= hsfreqrange_table[index].max_lane_mbps)
183*4882a593Smuzhiyun 			break;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (index == ARRAY_SIZE(hsfreqrange_table))
186*4882a593Smuzhiyun 		--index;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	hsfreqrange = hsfreqrange_table[index].hsfreqrange;
189*4882a593Smuzhiyun 	testif_write(rk628, 0x44, HSFREQRANGE(hsfreqrange));
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
mipi_dphy_reset(struct rk628 * rk628)192*4882a593Smuzhiyun static inline int mipi_dphy_reset(struct rk628 *rk628)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	u32 val, mask;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	mipi_dphy_enableclk_deassert(rk628);
197*4882a593Smuzhiyun 	mipi_dphy_shutdownz_assert(rk628);
198*4882a593Smuzhiyun 	mipi_dphy_rstz_assert(rk628);
199*4882a593Smuzhiyun 	testif_testclr_assert(rk628);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	/* Set all REQUEST inputs to zero */
202*4882a593Smuzhiyun 	rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON,
203*4882a593Smuzhiyun 		     FORCETXSTOPMODE_MASK | FORCERXMODE_MASK,
204*4882a593Smuzhiyun 		     FORCETXSTOPMODE(0) | FORCERXMODE(0));
205*4882a593Smuzhiyun 	udelay(1);
206*4882a593Smuzhiyun 	testif_testclr_deassert(rk628);
207*4882a593Smuzhiyun 	mipi_dphy_enableclk_assert(rk628);
208*4882a593Smuzhiyun 	mipi_dphy_shutdownz_deassert(rk628);
209*4882a593Smuzhiyun 	mipi_dphy_rstz_deassert(rk628);
210*4882a593Smuzhiyun 	usleep_range(1500, 2000);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	mask = STOPSTATE_CLK | STOPSTATE_LANE0;
213*4882a593Smuzhiyun 	rk628_i2c_read(rk628, CSITX_CSITX_STATUS1, &val);
214*4882a593Smuzhiyun 	if ((val & mask) != mask) {
215*4882a593Smuzhiyun 		dev_err(rk628->dev, "lane module is not in stop state\n");
216*4882a593Smuzhiyun 		return -1;
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	return 0;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #endif
223