xref: /linux/drivers/gpu/drm/sprd/megacores_pll.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1*1c66496bSKevin Tang // SPDX-License-Identifier: GPL-2.0
2*1c66496bSKevin Tang /*
3*1c66496bSKevin Tang  * Copyright (C) 2020 Unisoc Inc.
4*1c66496bSKevin Tang  */
5*1c66496bSKevin Tang 
6*1c66496bSKevin Tang #include <asm/div64.h>
7*1c66496bSKevin Tang #include <linux/delay.h>
8*1c66496bSKevin Tang #include <linux/init.h>
9*1c66496bSKevin Tang #include <linux/kernel.h>
10*1c66496bSKevin Tang #include <linux/regmap.h>
11*1c66496bSKevin Tang #include <linux/string.h>
12*1c66496bSKevin Tang 
13*1c66496bSKevin Tang #include "sprd_dsi.h"
14*1c66496bSKevin Tang 
15*1c66496bSKevin Tang #define L						0
16*1c66496bSKevin Tang #define H						1
17*1c66496bSKevin Tang #define CLK						0
18*1c66496bSKevin Tang #define DATA					1
19*1c66496bSKevin Tang #define INFINITY				0xffffffff
20*1c66496bSKevin Tang #define MIN_OUTPUT_FREQ			(100)
21*1c66496bSKevin Tang 
22*1c66496bSKevin Tang #define AVERAGE(a, b) (min(a, b) + abs((b) - (a)) / 2)
23*1c66496bSKevin Tang 
24*1c66496bSKevin Tang /* sharkle */
25*1c66496bSKevin Tang #define VCO_BAND_LOW	750
26*1c66496bSKevin Tang #define VCO_BAND_MID	1100
27*1c66496bSKevin Tang #define VCO_BAND_HIGH	1500
28*1c66496bSKevin Tang #define PHY_REF_CLK	26000
29*1c66496bSKevin Tang 
dphy_calc_pll_param(struct dphy_pll * pll)30*1c66496bSKevin Tang static int dphy_calc_pll_param(struct dphy_pll *pll)
31*1c66496bSKevin Tang {
32*1c66496bSKevin Tang 	const u32 khz = 1000;
33*1c66496bSKevin Tang 	const u32 mhz = 1000000;
34*1c66496bSKevin Tang 	const unsigned long long factor = 100;
35*1c66496bSKevin Tang 	unsigned long long tmp;
36*1c66496bSKevin Tang 	int i;
37*1c66496bSKevin Tang 
38*1c66496bSKevin Tang 	pll->potential_fvco = pll->freq / khz;
39*1c66496bSKevin Tang 	pll->ref_clk = PHY_REF_CLK / khz;
40*1c66496bSKevin Tang 
41*1c66496bSKevin Tang 	for (i = 0; i < 4; ++i) {
42*1c66496bSKevin Tang 		if (pll->potential_fvco >= VCO_BAND_LOW &&
43*1c66496bSKevin Tang 		    pll->potential_fvco <= VCO_BAND_HIGH) {
44*1c66496bSKevin Tang 			pll->fvco = pll->potential_fvco;
45*1c66496bSKevin Tang 			pll->out_sel = BIT(i);
46*1c66496bSKevin Tang 			break;
47*1c66496bSKevin Tang 		}
48*1c66496bSKevin Tang 		pll->potential_fvco <<= 1;
49*1c66496bSKevin Tang 	}
50*1c66496bSKevin Tang 	if (pll->fvco == 0)
51*1c66496bSKevin Tang 		return -EINVAL;
52*1c66496bSKevin Tang 
53*1c66496bSKevin Tang 	if (pll->fvco >= VCO_BAND_LOW && pll->fvco <= VCO_BAND_MID) {
54*1c66496bSKevin Tang 		/* vco band control */
55*1c66496bSKevin Tang 		pll->vco_band = 0x0;
56*1c66496bSKevin Tang 		/* low pass filter control */
57*1c66496bSKevin Tang 		pll->lpf_sel = 1;
58*1c66496bSKevin Tang 	} else if (pll->fvco > VCO_BAND_MID && pll->fvco <= VCO_BAND_HIGH) {
59*1c66496bSKevin Tang 		pll->vco_band = 0x1;
60*1c66496bSKevin Tang 		pll->lpf_sel = 0;
61*1c66496bSKevin Tang 	} else {
62*1c66496bSKevin Tang 		return -EINVAL;
63*1c66496bSKevin Tang 	}
64*1c66496bSKevin Tang 
65*1c66496bSKevin Tang 	pll->nint = pll->fvco / pll->ref_clk;
66*1c66496bSKevin Tang 	tmp = pll->fvco * factor * mhz;
67*1c66496bSKevin Tang 	do_div(tmp, pll->ref_clk);
68*1c66496bSKevin Tang 	tmp = tmp - pll->nint * factor * mhz;
69*1c66496bSKevin Tang 	tmp *= BIT(20);
70*1c66496bSKevin Tang 	do_div(tmp, 100000000);
71*1c66496bSKevin Tang 	pll->kint = (u32)tmp;
72*1c66496bSKevin Tang 	pll->refin = 3; /* pre-divider bypass */
73*1c66496bSKevin Tang 	pll->sdm_en = true; /* use fraction N PLL */
74*1c66496bSKevin Tang 	pll->fdk_s = 0x1; /* fraction */
75*1c66496bSKevin Tang 	pll->cp_s = 0x0;
76*1c66496bSKevin Tang 	pll->det_delay = 0x1;
77*1c66496bSKevin Tang 
78*1c66496bSKevin Tang 	return 0;
79*1c66496bSKevin Tang }
80*1c66496bSKevin Tang 
dphy_set_pll_reg(struct dphy_pll * pll,struct regmap * regmap)81*1c66496bSKevin Tang static void dphy_set_pll_reg(struct dphy_pll *pll, struct regmap *regmap)
82*1c66496bSKevin Tang {
83*1c66496bSKevin Tang 	u8 reg_val[9] = {0};
84*1c66496bSKevin Tang 	int i;
85*1c66496bSKevin Tang 
86*1c66496bSKevin Tang 	u8 reg_addr[] = {
87*1c66496bSKevin Tang 		0x03, 0x04, 0x06, 0x08, 0x09,
88*1c66496bSKevin Tang 		0x0a, 0x0b, 0x0e, 0x0f
89*1c66496bSKevin Tang 	};
90*1c66496bSKevin Tang 
91*1c66496bSKevin Tang 	reg_val[0] = 1 | (1 << 1) |  (pll->lpf_sel << 2);
92*1c66496bSKevin Tang 	reg_val[1] = pll->div | (1 << 3) | (pll->cp_s << 5) | (pll->fdk_s << 7);
93*1c66496bSKevin Tang 	reg_val[2] = pll->nint;
94*1c66496bSKevin Tang 	reg_val[3] = pll->vco_band | (pll->sdm_en << 1) | (pll->refin << 2);
95*1c66496bSKevin Tang 	reg_val[4] = pll->kint >> 12;
96*1c66496bSKevin Tang 	reg_val[5] = pll->kint >> 4;
97*1c66496bSKevin Tang 	reg_val[6] = pll->out_sel | ((pll->kint << 4) & 0xf);
98*1c66496bSKevin Tang 	reg_val[7] = 1 << 4;
99*1c66496bSKevin Tang 	reg_val[8] = pll->det_delay;
100*1c66496bSKevin Tang 
101*1c66496bSKevin Tang 	for (i = 0; i < sizeof(reg_addr); ++i) {
102*1c66496bSKevin Tang 		regmap_write(regmap, reg_addr[i], reg_val[i]);
103*1c66496bSKevin Tang 		DRM_DEBUG("%02x: %02x\n", reg_addr[i], reg_val[i]);
104*1c66496bSKevin Tang 	}
105*1c66496bSKevin Tang }
106*1c66496bSKevin Tang 
dphy_pll_config(struct dsi_context * ctx)107*1c66496bSKevin Tang int dphy_pll_config(struct dsi_context *ctx)
108*1c66496bSKevin Tang {
109*1c66496bSKevin Tang 	struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);
110*1c66496bSKevin Tang 	struct regmap *regmap = ctx->regmap;
111*1c66496bSKevin Tang 	struct dphy_pll *pll = &ctx->pll;
112*1c66496bSKevin Tang 	int ret;
113*1c66496bSKevin Tang 
114*1c66496bSKevin Tang 	pll->freq = dsi->slave->hs_rate;
115*1c66496bSKevin Tang 
116*1c66496bSKevin Tang 	/* FREQ = 26M * (NINT + KINT / 2^20) / out_sel */
117*1c66496bSKevin Tang 	ret = dphy_calc_pll_param(pll);
118*1c66496bSKevin Tang 	if (ret) {
119*1c66496bSKevin Tang 		drm_err(dsi->drm, "failed to calculate dphy pll parameters\n");
120*1c66496bSKevin Tang 		return ret;
121*1c66496bSKevin Tang 	}
122*1c66496bSKevin Tang 	dphy_set_pll_reg(pll, regmap);
123*1c66496bSKevin Tang 
124*1c66496bSKevin Tang 	return 0;
125*1c66496bSKevin Tang }
126*1c66496bSKevin Tang 
dphy_set_timing_reg(struct regmap * regmap,int type,u8 val[])127*1c66496bSKevin Tang static void dphy_set_timing_reg(struct regmap *regmap, int type, u8 val[])
128*1c66496bSKevin Tang {
129*1c66496bSKevin Tang 	switch (type) {
130*1c66496bSKevin Tang 	case REQUEST_TIME:
131*1c66496bSKevin Tang 		regmap_write(regmap, 0x31, val[CLK]);
132*1c66496bSKevin Tang 		regmap_write(regmap, 0x41, val[DATA]);
133*1c66496bSKevin Tang 		regmap_write(regmap, 0x51, val[DATA]);
134*1c66496bSKevin Tang 		regmap_write(regmap, 0x61, val[DATA]);
135*1c66496bSKevin Tang 		regmap_write(regmap, 0x71, val[DATA]);
136*1c66496bSKevin Tang 
137*1c66496bSKevin Tang 		regmap_write(regmap, 0x90, val[CLK]);
138*1c66496bSKevin Tang 		regmap_write(regmap, 0xa0, val[DATA]);
139*1c66496bSKevin Tang 		regmap_write(regmap, 0xb0, val[DATA]);
140*1c66496bSKevin Tang 		regmap_write(regmap, 0xc0, val[DATA]);
141*1c66496bSKevin Tang 		regmap_write(regmap, 0xd0, val[DATA]);
142*1c66496bSKevin Tang 		break;
143*1c66496bSKevin Tang 	case PREPARE_TIME:
144*1c66496bSKevin Tang 		regmap_write(regmap, 0x32, val[CLK]);
145*1c66496bSKevin Tang 		regmap_write(regmap, 0x42, val[DATA]);
146*1c66496bSKevin Tang 		regmap_write(regmap, 0x52, val[DATA]);
147*1c66496bSKevin Tang 		regmap_write(regmap, 0x62, val[DATA]);
148*1c66496bSKevin Tang 		regmap_write(regmap, 0x72, val[DATA]);
149*1c66496bSKevin Tang 
150*1c66496bSKevin Tang 		regmap_write(regmap, 0x91, val[CLK]);
151*1c66496bSKevin Tang 		regmap_write(regmap, 0xa1, val[DATA]);
152*1c66496bSKevin Tang 		regmap_write(regmap, 0xb1, val[DATA]);
153*1c66496bSKevin Tang 		regmap_write(regmap, 0xc1, val[DATA]);
154*1c66496bSKevin Tang 		regmap_write(regmap, 0xd1, val[DATA]);
155*1c66496bSKevin Tang 		break;
156*1c66496bSKevin Tang 	case ZERO_TIME:
157*1c66496bSKevin Tang 		regmap_write(regmap, 0x33, val[CLK]);
158*1c66496bSKevin Tang 		regmap_write(regmap, 0x43, val[DATA]);
159*1c66496bSKevin Tang 		regmap_write(regmap, 0x53, val[DATA]);
160*1c66496bSKevin Tang 		regmap_write(regmap, 0x63, val[DATA]);
161*1c66496bSKevin Tang 		regmap_write(regmap, 0x73, val[DATA]);
162*1c66496bSKevin Tang 
163*1c66496bSKevin Tang 		regmap_write(regmap, 0x92, val[CLK]);
164*1c66496bSKevin Tang 		regmap_write(regmap, 0xa2, val[DATA]);
165*1c66496bSKevin Tang 		regmap_write(regmap, 0xb2, val[DATA]);
166*1c66496bSKevin Tang 		regmap_write(regmap, 0xc2, val[DATA]);
167*1c66496bSKevin Tang 		regmap_write(regmap, 0xd2, val[DATA]);
168*1c66496bSKevin Tang 		break;
169*1c66496bSKevin Tang 	case TRAIL_TIME:
170*1c66496bSKevin Tang 		regmap_write(regmap, 0x34, val[CLK]);
171*1c66496bSKevin Tang 		regmap_write(regmap, 0x44, val[DATA]);
172*1c66496bSKevin Tang 		regmap_write(regmap, 0x54, val[DATA]);
173*1c66496bSKevin Tang 		regmap_write(regmap, 0x64, val[DATA]);
174*1c66496bSKevin Tang 		regmap_write(regmap, 0x74, val[DATA]);
175*1c66496bSKevin Tang 
176*1c66496bSKevin Tang 		regmap_write(regmap, 0x93, val[CLK]);
177*1c66496bSKevin Tang 		regmap_write(regmap, 0xa3, val[DATA]);
178*1c66496bSKevin Tang 		regmap_write(regmap, 0xb3, val[DATA]);
179*1c66496bSKevin Tang 		regmap_write(regmap, 0xc3, val[DATA]);
180*1c66496bSKevin Tang 		regmap_write(regmap, 0xd3, val[DATA]);
181*1c66496bSKevin Tang 		break;
182*1c66496bSKevin Tang 	case EXIT_TIME:
183*1c66496bSKevin Tang 		regmap_write(regmap, 0x36, val[CLK]);
184*1c66496bSKevin Tang 		regmap_write(regmap, 0x46, val[DATA]);
185*1c66496bSKevin Tang 		regmap_write(regmap, 0x56, val[DATA]);
186*1c66496bSKevin Tang 		regmap_write(regmap, 0x66, val[DATA]);
187*1c66496bSKevin Tang 		regmap_write(regmap, 0x76, val[DATA]);
188*1c66496bSKevin Tang 
189*1c66496bSKevin Tang 		regmap_write(regmap, 0x95, val[CLK]);
190*1c66496bSKevin Tang 		regmap_write(regmap, 0xA5, val[DATA]);
191*1c66496bSKevin Tang 		regmap_write(regmap, 0xB5, val[DATA]);
192*1c66496bSKevin Tang 		regmap_write(regmap, 0xc5, val[DATA]);
193*1c66496bSKevin Tang 		regmap_write(regmap, 0xd5, val[DATA]);
194*1c66496bSKevin Tang 		break;
195*1c66496bSKevin Tang 	case CLKPOST_TIME:
196*1c66496bSKevin Tang 		regmap_write(regmap, 0x35, val[CLK]);
197*1c66496bSKevin Tang 		regmap_write(regmap, 0x94, val[CLK]);
198*1c66496bSKevin Tang 		break;
199*1c66496bSKevin Tang 
200*1c66496bSKevin Tang 	/* the following just use default value */
201*1c66496bSKevin Tang 	case SETTLE_TIME:
202*1c66496bSKevin Tang 		fallthrough;
203*1c66496bSKevin Tang 	case TA_GET:
204*1c66496bSKevin Tang 		fallthrough;
205*1c66496bSKevin Tang 	case TA_GO:
206*1c66496bSKevin Tang 		fallthrough;
207*1c66496bSKevin Tang 	case TA_SURE:
208*1c66496bSKevin Tang 		fallthrough;
209*1c66496bSKevin Tang 	default:
210*1c66496bSKevin Tang 		break;
211*1c66496bSKevin Tang 	}
212*1c66496bSKevin Tang }
213*1c66496bSKevin Tang 
dphy_timing_config(struct dsi_context * ctx)214*1c66496bSKevin Tang void dphy_timing_config(struct dsi_context *ctx)
215*1c66496bSKevin Tang {
216*1c66496bSKevin Tang 	struct regmap *regmap = ctx->regmap;
217*1c66496bSKevin Tang 	struct dphy_pll *pll = &ctx->pll;
218*1c66496bSKevin Tang 	const u32 factor = 2;
219*1c66496bSKevin Tang 	const u32 scale = 100;
220*1c66496bSKevin Tang 	u32 t_ui, t_byteck, t_half_byteck;
221*1c66496bSKevin Tang 	u32 range[2], constant;
222*1c66496bSKevin Tang 	u8 val[2];
223*1c66496bSKevin Tang 	u32 tmp = 0;
224*1c66496bSKevin Tang 
225*1c66496bSKevin Tang 	/* t_ui: 1 ui, byteck: 8 ui, half byteck: 4 ui */
226*1c66496bSKevin Tang 	t_ui = 1000 * scale / (pll->freq / 1000);
227*1c66496bSKevin Tang 	t_byteck = t_ui << 3;
228*1c66496bSKevin Tang 	t_half_byteck = t_ui << 2;
229*1c66496bSKevin Tang 	constant = t_ui << 1;
230*1c66496bSKevin Tang 
231*1c66496bSKevin Tang 	/* REQUEST_TIME: HS T-LPX: LP-01
232*1c66496bSKevin Tang 	 * For T-LPX, mipi spec defined min value is 50ns,
233*1c66496bSKevin Tang 	 * but maybe it shouldn't be too small, because BTA,
234*1c66496bSKevin Tang 	 * LP-10, LP-00, LP-01, all of this is related to T-LPX.
235*1c66496bSKevin Tang 	 */
236*1c66496bSKevin Tang 	range[L] = 50 * scale;
237*1c66496bSKevin Tang 	range[H] = INFINITY;
238*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(range[L] * (factor << 1), t_byteck) - 2;
239*1c66496bSKevin Tang 	val[DATA] = val[CLK];
240*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, REQUEST_TIME, val);
241*1c66496bSKevin Tang 
242*1c66496bSKevin Tang 	/* PREPARE_TIME: HS sequence: LP-00 */
243*1c66496bSKevin Tang 	range[L] = 38 * scale;
244*1c66496bSKevin Tang 	range[H] = 95 * scale;
245*1c66496bSKevin Tang 	tmp = AVERAGE(range[L], range[H]);
246*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(AVERAGE(range[L], range[H]), t_half_byteck) - 1;
247*1c66496bSKevin Tang 	range[L] = 40 * scale + 4 * t_ui;
248*1c66496bSKevin Tang 	range[H] = 85 * scale + 6 * t_ui;
249*1c66496bSKevin Tang 	tmp |= AVERAGE(range[L], range[H]) << 16;
250*1c66496bSKevin Tang 	val[DATA] = DIV_ROUND_UP(AVERAGE(range[L], range[H]), t_half_byteck) - 1;
251*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, PREPARE_TIME, val);
252*1c66496bSKevin Tang 
253*1c66496bSKevin Tang 	/* ZERO_TIME: HS-ZERO */
254*1c66496bSKevin Tang 	range[L] = 300 * scale;
255*1c66496bSKevin Tang 	range[H] = INFINITY;
256*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(range[L] * factor + (tmp & 0xffff)
257*1c66496bSKevin Tang 			- 525 * t_byteck / 100, t_byteck) - 2;
258*1c66496bSKevin Tang 	range[L] = 145 * scale + 10 * t_ui;
259*1c66496bSKevin Tang 	val[DATA] = DIV_ROUND_UP(range[L] * factor
260*1c66496bSKevin Tang 			+ ((tmp >> 16) & 0xffff) - 525 * t_byteck / 100,
261*1c66496bSKevin Tang 			t_byteck) - 2;
262*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, ZERO_TIME, val);
263*1c66496bSKevin Tang 
264*1c66496bSKevin Tang 	/* TRAIL_TIME: HS-TRAIL */
265*1c66496bSKevin Tang 	range[L] = 60 * scale;
266*1c66496bSKevin Tang 	range[H] = INFINITY;
267*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(range[L] * factor - constant, t_half_byteck);
268*1c66496bSKevin Tang 	range[L] = max(8 * t_ui, 60 * scale + 4 * t_ui);
269*1c66496bSKevin Tang 	val[DATA] = DIV_ROUND_UP(range[L] * 3 / 2 - constant, t_half_byteck) - 2;
270*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, TRAIL_TIME, val);
271*1c66496bSKevin Tang 
272*1c66496bSKevin Tang 	/* EXIT_TIME: */
273*1c66496bSKevin Tang 	range[L] = 100 * scale;
274*1c66496bSKevin Tang 	range[H] = INFINITY;
275*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(range[L] * factor, t_byteck) - 2;
276*1c66496bSKevin Tang 	val[DATA] = val[CLK];
277*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, EXIT_TIME, val);
278*1c66496bSKevin Tang 
279*1c66496bSKevin Tang 	/* CLKPOST_TIME: */
280*1c66496bSKevin Tang 	range[L] = 60 * scale + 52 * t_ui;
281*1c66496bSKevin Tang 	range[H] = INFINITY;
282*1c66496bSKevin Tang 	val[CLK] = DIV_ROUND_UP(range[L] * factor, t_byteck) - 2;
283*1c66496bSKevin Tang 	val[DATA] = val[CLK];
284*1c66496bSKevin Tang 	dphy_set_timing_reg(regmap, CLKPOST_TIME, val);
285*1c66496bSKevin Tang 
286*1c66496bSKevin Tang 	/* SETTLE_TIME:
287*1c66496bSKevin Tang 	 * This time is used for receiver. So for transmitter,
288*1c66496bSKevin Tang 	 * it can be ignored.
289*1c66496bSKevin Tang 	 */
290*1c66496bSKevin Tang 
291*1c66496bSKevin Tang 	/* TA_GO:
292*1c66496bSKevin Tang 	 * transmitter drives bridge state(LP-00) before releasing control,
293*1c66496bSKevin Tang 	 * reg 0x1f default value: 0x04, which is good.
294*1c66496bSKevin Tang 	 */
295*1c66496bSKevin Tang 
296*1c66496bSKevin Tang 	/* TA_SURE:
297*1c66496bSKevin Tang 	 * After LP-10 state and before bridge state(LP-00),
298*1c66496bSKevin Tang 	 * reg 0x20 default value: 0x01, which is good.
299*1c66496bSKevin Tang 	 */
300*1c66496bSKevin Tang 
301*1c66496bSKevin Tang 	/* TA_GET:
302*1c66496bSKevin Tang 	 * receiver drives Bridge state(LP-00) before releasing control
303*1c66496bSKevin Tang 	 * reg 0x21 default value: 0x03, which is good.
304*1c66496bSKevin Tang 	 */
305*1c66496bSKevin Tang }
306