xref: /OK3568_Linux_fs/kernel/drivers/phy/rockchip/phy-rockchip-naneng-edp.c (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: Wyon Bi <bivvy.bi@rock-chips.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/bitfield.h>
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/io.h>
12*4882a593Smuzhiyun #include <linux/iopoll.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/init.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/of_device.h>
17*4882a593Smuzhiyun #include <linux/platform_device.h>
18*4882a593Smuzhiyun #include <linux/regmap.h>
19*4882a593Smuzhiyun #include <linux/mfd/syscon.h>
20*4882a593Smuzhiyun #include <linux/phy/phy.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define EDP_PHY_GRF_CON0		0x0000
23*4882a593Smuzhiyun #define EDP_PHY_TX_IDLE			GENMASK(11, 8)
24*4882a593Smuzhiyun #define EDP_PHY_TX_PD			GENMASK(7, 4)
25*4882a593Smuzhiyun #define EDP_PHY_IDDQ_EN			BIT(1)
26*4882a593Smuzhiyun #define EDP_PHY_PD_PLL			BIT(0)
27*4882a593Smuzhiyun #define EDP_PHY_GRF_CON1		0x0004
28*4882a593Smuzhiyun #define EDP_PHY_PLL_DIV			GENMASK(14, 0)
29*4882a593Smuzhiyun #define EDP_PHY_GRF_CON2		0x0008
30*4882a593Smuzhiyun #define EDP_PHY_TX_RTERM		GENMASK(10, 8)
31*4882a593Smuzhiyun #define EDP_PHY_RATE			GENMASK(5, 4)
32*4882a593Smuzhiyun #define EDP_PHY_REF_DIV			GENMASK(3, 0)
33*4882a593Smuzhiyun #define EDP_PHY_GRF_CON3		0x000c
34*4882a593Smuzhiyun #define EDP_PHY_TX3_EMP			GENMASK(15, 12)
35*4882a593Smuzhiyun #define EDP_PHY_TX2_EMP			GENMASK(11, 8)
36*4882a593Smuzhiyun #define EDP_PHY_TX1_EMP			GENMASK(7, 4)
37*4882a593Smuzhiyun #define EDP_PHY_TX0_EMP			GENMASK(3, 0)
38*4882a593Smuzhiyun #define EDP_PHY_GRF_CON4		0x0010
39*4882a593Smuzhiyun #define EDP_PHY_TX3_AMP			GENMASK(14, 12)
40*4882a593Smuzhiyun #define EDP_PHY_TX2_AMP			GENMASK(10, 8)
41*4882a593Smuzhiyun #define EDP_PHY_TX1_AMP			GENMASK(6, 4)
42*4882a593Smuzhiyun #define EDP_PHY_TX0_AMP			GENMASK(2, 0)
43*4882a593Smuzhiyun #define EDP_PHY_GRF_CON5		0x0014
44*4882a593Smuzhiyun #define EDP_PHY_TX_MODE			GENMASK(9, 8)
45*4882a593Smuzhiyun #define EDP_PHY_TX3_AMP_SCALE		GENMASK(7, 6)
46*4882a593Smuzhiyun #define EDP_PHY_TX2_AMP_SCALE		GENMASK(5, 4)
47*4882a593Smuzhiyun #define EDP_PHY_TX1_AMP_SCALE		GENMASK(3, 2)
48*4882a593Smuzhiyun #define EDP_PHY_TX0_AMP_SCALE		GENMASK(1, 0)
49*4882a593Smuzhiyun #define EDP_PHY_GRF_CON6		0x0018
50*4882a593Smuzhiyun #define EDP_PHY_SSC_DEPTH		GENMASK(15, 12)
51*4882a593Smuzhiyun #define EDP_PHY_SSC_EN			BIT(11)
52*4882a593Smuzhiyun #define EDP_PHY_SSC_CNT			GENMASK(9, 0)
53*4882a593Smuzhiyun #define EDP_PHY_GRF_CON7		0x001c
54*4882a593Smuzhiyun #define EDP_PHY_GRF_CON8		0x0020
55*4882a593Smuzhiyun #define EDP_PHY_PLL_CTL_H		GENMASK(15, 0)
56*4882a593Smuzhiyun #define EDP_PHY_GRF_CON9		0x0024
57*4882a593Smuzhiyun #define EDP_PHY_TX_CTL			GENMASK(15, 0)
58*4882a593Smuzhiyun #define EDP_PHY_GRF_CON10		0x0028
59*4882a593Smuzhiyun #define EDP_PHY_AUX_RCV_PD_SEL		BIT(5)
60*4882a593Smuzhiyun #define EDP_PHY_AUX_DRV_PD_SEL		BIT(4)
61*4882a593Smuzhiyun #define EDP_PHY_AUX_IDLE		BIT(2)
62*4882a593Smuzhiyun #define EDP_PHY_AUX_RCV_PD		BIT(1)
63*4882a593Smuzhiyun #define EDP_PHY_AUX_DRV_PD		BIT(0)
64*4882a593Smuzhiyun #define EDP_PHY_GRF_CON11		0x002c
65*4882a593Smuzhiyun #define EDP_PHY_AUX_RCV_VCM		GENMASK(14, 12)
66*4882a593Smuzhiyun #define EDP_PHY_AUX_MODE		GENMASK(11, 10)
67*4882a593Smuzhiyun #define EDP_PHY_AUX_AMP_SCALE		GENMASK(9, 8)
68*4882a593Smuzhiyun #define EDP_PHY_AUX_AMP			GENMASK(6, 4)
69*4882a593Smuzhiyun #define EDP_PHY_AUX_RTERM		GENMASK(2, 0)
70*4882a593Smuzhiyun #define EDP_PHY_GRF_STATUS0		0x0030
71*4882a593Smuzhiyun #define PLL_RDY				BIT(0)
72*4882a593Smuzhiyun #define EDP_PHY_GRF_STATUS1		0x0034
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun struct rockchip_edp_phy {
75*4882a593Smuzhiyun 	struct regmap *grf;
76*4882a593Smuzhiyun 	struct device *dev;
77*4882a593Smuzhiyun 	struct clk *refclk;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
rockchip_grf_write(struct regmap * grf,unsigned int reg,unsigned int mask,unsigned int val)80*4882a593Smuzhiyun static inline int rockchip_grf_write(struct regmap *grf, unsigned int reg,
81*4882a593Smuzhiyun 				     unsigned int mask, unsigned int val)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	return regmap_write(grf, reg, (mask << 16) | (val & mask));
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun static struct {
87*4882a593Smuzhiyun 	int amp;
88*4882a593Smuzhiyun 	int amp_scale;
89*4882a593Smuzhiyun 	int emp;
90*4882a593Smuzhiyun } vp[4][4] = {
91*4882a593Smuzhiyun 	{ {0x1, 0x1, 0x0}, {0x2, 0x1, 0x4}, {0x3, 0x1, 0x8}, {0x4, 0x1, 0xd} },
92*4882a593Smuzhiyun 	{ {0x3, 0x1, 0x0}, {0x5, 0x1, 0x7}, {0x6, 0x1, 0x6}, { -1,  -1,  -1} },
93*4882a593Smuzhiyun 	{ {0x5, 0x1, 0x0}, {0x7, 0x1, 0x4}, { -1,  -1,  -1}, { -1,  -1,  -1} },
94*4882a593Smuzhiyun 	{ {0x7, 0x1, 0x0}, { -1,  -1,  -1}, { -1,  -1,  -1}, { -1,  -1,  -1} },
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
rockchip_edp_phy_set_voltage(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp,u8 lane)97*4882a593Smuzhiyun static void rockchip_edp_phy_set_voltage(struct rockchip_edp_phy *edpphy,
98*4882a593Smuzhiyun 					 struct phy_configure_opts_dp *dp,
99*4882a593Smuzhiyun 					 u8 lane)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	u32 amp, amp_scale, emp;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	amp = vp[dp->voltage[lane]][dp->pre[lane]].amp;
104*4882a593Smuzhiyun 	amp_scale = vp[dp->voltage[lane]][dp->pre[lane]].amp_scale;
105*4882a593Smuzhiyun 	emp = vp[dp->voltage[lane]][dp->pre[lane]].emp;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	switch (lane) {
108*4882a593Smuzhiyun 	case 0:
109*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
110*4882a593Smuzhiyun 				   EDP_PHY_TX0_EMP,
111*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX0_EMP, emp));
112*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
113*4882a593Smuzhiyun 				   EDP_PHY_TX0_AMP,
114*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX0_AMP, amp));
115*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
116*4882a593Smuzhiyun 				   EDP_PHY_TX0_AMP_SCALE,
117*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX0_AMP_SCALE, amp_scale));
118*4882a593Smuzhiyun 		break;
119*4882a593Smuzhiyun 	case 1:
120*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
121*4882a593Smuzhiyun 				   EDP_PHY_TX1_EMP,
122*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX1_EMP, emp));
123*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
124*4882a593Smuzhiyun 				   EDP_PHY_TX1_AMP,
125*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX1_AMP, amp));
126*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
127*4882a593Smuzhiyun 				   EDP_PHY_TX1_AMP_SCALE,
128*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX1_AMP_SCALE, amp_scale));
129*4882a593Smuzhiyun 		break;
130*4882a593Smuzhiyun 	case 2:
131*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
132*4882a593Smuzhiyun 				   EDP_PHY_TX2_EMP,
133*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX2_EMP, emp));
134*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
135*4882a593Smuzhiyun 				   EDP_PHY_TX2_AMP,
136*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX2_AMP, amp));
137*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
138*4882a593Smuzhiyun 				   EDP_PHY_TX2_AMP_SCALE,
139*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX2_AMP_SCALE, amp_scale));
140*4882a593Smuzhiyun 		break;
141*4882a593Smuzhiyun 	case 3:
142*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
143*4882a593Smuzhiyun 				   EDP_PHY_TX3_EMP,
144*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX3_EMP, emp));
145*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
146*4882a593Smuzhiyun 				   EDP_PHY_TX3_AMP,
147*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX3_AMP, amp));
148*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
149*4882a593Smuzhiyun 				   EDP_PHY_TX3_AMP_SCALE,
150*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX3_AMP_SCALE, amp_scale));
151*4882a593Smuzhiyun 		break;
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun 
rockchip_edp_phy_set_voltages(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)155*4882a593Smuzhiyun static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy,
156*4882a593Smuzhiyun 					 struct phy_configure_opts_dp *dp)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	u8 lane;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	for (lane = 0; lane < dp->lanes; lane++)
161*4882a593Smuzhiyun 		rockchip_edp_phy_set_voltage(edpphy, dp, lane);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
rockchip_edp_phy_set_rate(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)166*4882a593Smuzhiyun static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy,
167*4882a593Smuzhiyun 				     struct phy_configure_opts_dp *dp)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	u32 value;
170*4882a593Smuzhiyun 	int ret;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
173*4882a593Smuzhiyun 			   EDP_PHY_TX_IDLE | EDP_PHY_TX_PD,
174*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
175*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_PD, 0xf));
176*4882a593Smuzhiyun 	usleep_range(100, 101);
177*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
178*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_MODE, 0x3));
179*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
180*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	switch (dp->link_rate) {
183*4882a593Smuzhiyun 	case 1620:
184*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON1,
185*4882a593Smuzhiyun 				   EDP_PHY_PLL_DIV,
186*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_PLL_DIV, 0x4380));
187*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON2,
188*4882a593Smuzhiyun 				   EDP_PHY_TX_RTERM | EDP_PHY_RATE | EDP_PHY_REF_DIV,
189*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX_RTERM, 0x1) |
190*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_RATE, 0x1) |
191*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_REF_DIV, 0x0));
192*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON8,
193*4882a593Smuzhiyun 				   EDP_PHY_PLL_CTL_H,
194*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_PLL_CTL_H, 0x0800));
195*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON9,
196*4882a593Smuzhiyun 				   EDP_PHY_TX_CTL,
197*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX_CTL, 0x0000));
198*4882a593Smuzhiyun 		break;
199*4882a593Smuzhiyun 	case 2700:
200*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON1,
201*4882a593Smuzhiyun 				   EDP_PHY_PLL_DIV,
202*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_PLL_DIV, 0x3840));
203*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON2,
204*4882a593Smuzhiyun 				   EDP_PHY_TX_RTERM | EDP_PHY_RATE | EDP_PHY_REF_DIV,
205*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX_RTERM, 0x1) |
206*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_RATE, 0x0) |
207*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_REF_DIV, 0x0));
208*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON8,
209*4882a593Smuzhiyun 				   EDP_PHY_PLL_CTL_H,
210*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_PLL_CTL_H, 0x0800));
211*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON9,
212*4882a593Smuzhiyun 				   EDP_PHY_TX_CTL,
213*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_TX_CTL, 0x0000));
214*4882a593Smuzhiyun 		break;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	if (dp->ssc)
218*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON6,
219*4882a593Smuzhiyun 				   EDP_PHY_SSC_DEPTH | EDP_PHY_SSC_EN | EDP_PHY_SSC_CNT,
220*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_SSC_DEPTH, 0x9) |
221*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_SSC_EN, 0x1) |
222*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_SSC_CNT, 0x17d));
223*4882a593Smuzhiyun 	else
224*4882a593Smuzhiyun 		rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON6,
225*4882a593Smuzhiyun 				   EDP_PHY_SSC_EN,
226*4882a593Smuzhiyun 				   FIELD_PREP(EDP_PHY_SSC_EN, 0x0));
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
229*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_PD_PLL, 0));
230*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_TX_PD,
231*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_PD, ~GENMASK(dp->lanes - 1, 0)));
232*4882a593Smuzhiyun 	ret = regmap_read_poll_timeout(edpphy->grf, EDP_PHY_GRF_STATUS0,
233*4882a593Smuzhiyun 				       value, value & PLL_RDY, 100, 1000);
234*4882a593Smuzhiyun 	if (ret) {
235*4882a593Smuzhiyun 		dev_err(edpphy->dev, "pll is not ready: %d\n", ret);
236*4882a593Smuzhiyun 		return ret;
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
240*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_MODE, 0x0));
241*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_TX_IDLE,
242*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_IDLE, ~GENMASK(dp->lanes - 1, 0)));
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	return 0;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun 
rockchip_edp_phy_verify_config(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)247*4882a593Smuzhiyun static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy,
248*4882a593Smuzhiyun 					  struct phy_configure_opts_dp *dp)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	int i;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	/* If changing link rate was required, verify it's supported. */
253*4882a593Smuzhiyun 	if (dp->set_rate) {
254*4882a593Smuzhiyun 		switch (dp->link_rate) {
255*4882a593Smuzhiyun 		case 1620:
256*4882a593Smuzhiyun 		case 2700:
257*4882a593Smuzhiyun 			/* valid bit rate */
258*4882a593Smuzhiyun 			break;
259*4882a593Smuzhiyun 		default:
260*4882a593Smuzhiyun 			return -EINVAL;
261*4882a593Smuzhiyun 		}
262*4882a593Smuzhiyun 	}
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	/* Verify lane count. */
265*4882a593Smuzhiyun 	switch (dp->lanes) {
266*4882a593Smuzhiyun 	case 1:
267*4882a593Smuzhiyun 	case 2:
268*4882a593Smuzhiyun 	case 4:
269*4882a593Smuzhiyun 		/* valid lane count. */
270*4882a593Smuzhiyun 		break;
271*4882a593Smuzhiyun 	default:
272*4882a593Smuzhiyun 		return -EINVAL;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	/*
276*4882a593Smuzhiyun 	 * If changing voltages is required, check swing and pre-emphasis
277*4882a593Smuzhiyun 	 * levels, per-lane.
278*4882a593Smuzhiyun 	 */
279*4882a593Smuzhiyun 	if (dp->set_voltages) {
280*4882a593Smuzhiyun 		/* Lane count verified previously. */
281*4882a593Smuzhiyun 		for (i = 0; i < dp->lanes; i++) {
282*4882a593Smuzhiyun 			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
283*4882a593Smuzhiyun 				return -EINVAL;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 			/*
286*4882a593Smuzhiyun 			 * Sum of voltage swing and pre-emphasis levels cannot
287*4882a593Smuzhiyun 			 * exceed 3.
288*4882a593Smuzhiyun 			 */
289*4882a593Smuzhiyun 			if (dp->voltage[i] + dp->pre[i] > 3)
290*4882a593Smuzhiyun 				return -EINVAL;
291*4882a593Smuzhiyun 		}
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
rockchip_edp_phy_configure(struct phy * phy,union phy_configure_opts * opts)297*4882a593Smuzhiyun static int rockchip_edp_phy_configure(struct phy *phy,
298*4882a593Smuzhiyun 				      union phy_configure_opts *opts)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
301*4882a593Smuzhiyun 	int ret;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp);
304*4882a593Smuzhiyun 	if (ret) {
305*4882a593Smuzhiyun 		dev_err(edpphy->dev, "invalid params for phy configure\n");
306*4882a593Smuzhiyun 		return ret;
307*4882a593Smuzhiyun 	}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	if (opts->dp.set_rate) {
310*4882a593Smuzhiyun 		ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp);
311*4882a593Smuzhiyun 		if (ret) {
312*4882a593Smuzhiyun 			dev_err(edpphy->dev,
313*4882a593Smuzhiyun 				"rockchip_edp_phy_set_rate failed\n");
314*4882a593Smuzhiyun 			return ret;
315*4882a593Smuzhiyun 		}
316*4882a593Smuzhiyun 	}
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	if (opts->dp.set_voltages) {
319*4882a593Smuzhiyun 		ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp);
320*4882a593Smuzhiyun 		if (ret) {
321*4882a593Smuzhiyun 			dev_err(edpphy->dev,
322*4882a593Smuzhiyun 				"rockchip_edp_phy_set_voltages failed\n");
323*4882a593Smuzhiyun 			return ret;
324*4882a593Smuzhiyun 		}
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	return 0;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
rockchip_edp_phy_enabled(struct rockchip_edp_phy * edpphy)330*4882a593Smuzhiyun static bool rockchip_edp_phy_enabled(struct rockchip_edp_phy *edpphy)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	u32 val;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	regmap_read(edpphy->grf, EDP_PHY_GRF_STATUS0, &val);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	return FIELD_GET(PLL_RDY, val);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun 
rockchip_edp_phy_power_on(struct phy * phy)339*4882a593Smuzhiyun static int rockchip_edp_phy_power_on(struct phy *phy)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	clk_prepare_enable(edpphy->refclk);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (rockchip_edp_phy_enabled(edpphy))
346*4882a593Smuzhiyun 		return 0;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
349*4882a593Smuzhiyun 			   EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD | EDP_PHY_AUX_IDLE,
350*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x1) |
351*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x1) |
352*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_IDLE, 0x1));
353*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
354*4882a593Smuzhiyun 			   EDP_PHY_TX_IDLE | EDP_PHY_TX_PD | EDP_PHY_PD_PLL,
355*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
356*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_PD, 0xf) |
357*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
358*4882a593Smuzhiyun 	usleep_range(100, 101);
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON11,
361*4882a593Smuzhiyun 			   EDP_PHY_AUX_RCV_VCM | EDP_PHY_AUX_MODE |
362*4882a593Smuzhiyun 			   EDP_PHY_AUX_AMP_SCALE | EDP_PHY_AUX_AMP |
363*4882a593Smuzhiyun 			   EDP_PHY_AUX_RTERM,
364*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_RCV_VCM, 0x4) |
365*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_MODE, 0x1) |
366*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_AMP_SCALE, 0x1) |
367*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_AMP, 0x3) |
368*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_RTERM, 0x1));
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
371*4882a593Smuzhiyun 			   EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD,
372*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x0) |
373*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x0));
374*4882a593Smuzhiyun 	usleep_range(100, 101);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
377*4882a593Smuzhiyun 			   EDP_PHY_AUX_IDLE,
378*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_IDLE, 0x0));
379*4882a593Smuzhiyun 	usleep_range(10000, 11000);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	return 0;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
rockchip_edp_phy_power_off(struct phy * phy)384*4882a593Smuzhiyun static int rockchip_edp_phy_power_off(struct phy *phy)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
389*4882a593Smuzhiyun 			   EDP_PHY_TX_IDLE | EDP_PHY_TX_PD,
390*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
391*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_PD, 0xf));
392*4882a593Smuzhiyun 	usleep_range(100, 101);
393*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
394*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_TX_MODE, 0x3));
395*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
396*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
397*4882a593Smuzhiyun 	rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
398*4882a593Smuzhiyun 			   EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD | EDP_PHY_AUX_IDLE,
399*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x1) |
400*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x1) |
401*4882a593Smuzhiyun 			   FIELD_PREP(EDP_PHY_AUX_IDLE, 0x1));
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	clk_disable_unprepare(edpphy->refclk);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	return 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun static const struct phy_ops rockchip_edp_phy_ops = {
409*4882a593Smuzhiyun 	.power_on = rockchip_edp_phy_power_on,
410*4882a593Smuzhiyun 	.power_off = rockchip_edp_phy_power_off,
411*4882a593Smuzhiyun 	.configure = rockchip_edp_phy_configure,
412*4882a593Smuzhiyun 	.owner = THIS_MODULE,
413*4882a593Smuzhiyun };
414*4882a593Smuzhiyun 
rockchip_edp_phy_probe(struct platform_device * pdev)415*4882a593Smuzhiyun static int rockchip_edp_phy_probe(struct platform_device *pdev)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
418*4882a593Smuzhiyun 	struct rockchip_edp_phy *edpphy;
419*4882a593Smuzhiyun 	struct phy *phy;
420*4882a593Smuzhiyun 	struct phy_provider *phy_provider;
421*4882a593Smuzhiyun 	int ret;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	edpphy = devm_kzalloc(dev, sizeof(*edpphy), GFP_KERNEL);
424*4882a593Smuzhiyun 	if (!edpphy)
425*4882a593Smuzhiyun 		return -ENOMEM;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	edpphy->dev = dev;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	edpphy->grf = syscon_node_to_regmap(dev->parent->of_node);
430*4882a593Smuzhiyun 	if (IS_ERR(edpphy->grf)) {
431*4882a593Smuzhiyun 		ret = PTR_ERR(edpphy->grf);
432*4882a593Smuzhiyun 		dev_err(dev, "failed to get grf: %d\n", ret);
433*4882a593Smuzhiyun 		return ret;
434*4882a593Smuzhiyun 	}
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	edpphy->refclk = devm_clk_get(dev, "refclk");
437*4882a593Smuzhiyun 	if (IS_ERR(edpphy->refclk)) {
438*4882a593Smuzhiyun 		ret = PTR_ERR(edpphy->refclk);
439*4882a593Smuzhiyun 		dev_err(dev, "failed to get refclk: %d\n", ret);
440*4882a593Smuzhiyun 		return ret;
441*4882a593Smuzhiyun 	}
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	phy = devm_phy_create(dev, NULL, &rockchip_edp_phy_ops);
444*4882a593Smuzhiyun 	if (IS_ERR(phy)) {
445*4882a593Smuzhiyun 		ret = PTR_ERR(phy);
446*4882a593Smuzhiyun 		dev_err(dev, "failed to create PHY: %d\n", ret);
447*4882a593Smuzhiyun 		return ret;
448*4882a593Smuzhiyun 	}
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	phy_set_drvdata(phy, edpphy);
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
453*4882a593Smuzhiyun 	if (IS_ERR(phy_provider)) {
454*4882a593Smuzhiyun 		dev_err(dev, "failed to register phy provider\n");
455*4882a593Smuzhiyun 		return PTR_ERR(phy_provider);
456*4882a593Smuzhiyun 	}
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	return 0;
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun static const struct of_device_id rockchip_edp_phy_of_match[] = {
462*4882a593Smuzhiyun 	{ .compatible = "rockchip,rk3568-edp-phy", },
463*4882a593Smuzhiyun 	{}
464*4882a593Smuzhiyun };
465*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rockchip_edp_phy_of_match);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun static struct platform_driver rockchip_edp_phy_driver = {
468*4882a593Smuzhiyun 	.driver = {
469*4882a593Smuzhiyun 		.name = "rockchip-edpphy-naneng",
470*4882a593Smuzhiyun 		.of_match_table	= of_match_ptr(rockchip_edp_phy_of_match),
471*4882a593Smuzhiyun 	},
472*4882a593Smuzhiyun 	.probe = rockchip_edp_phy_probe,
473*4882a593Smuzhiyun };
474*4882a593Smuzhiyun module_platform_driver(rockchip_edp_phy_driver);
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
477*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip Naneng eDP Transmitter PHY driver");
478*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
479