xref: /linux/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c (revision 21eeefe76919c904dd50d543bd6d3eee05d97e15)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2025 Rockchip Electronics Co.Ltd
4  * Author:
5  *      Guochun Huang <hero.huang@rock-chips.com>
6  */
7 
8 #include <dt-bindings/phy/phy.h>
9 #include <linux/bitfield.h>
10 #include <linux/clk.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/mod_devicetable.h>
16 #include <linux/of.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/reset.h>
22 
23 #define FIELD_PREP_HIWORD(_mask, _val)		\
24 	(					\
25 		FIELD_PREP((_mask), (_val)) |	\
26 		((_mask) << 16)			\
27 	)
28 
29 #define BIAS_CON0		0x0000
30 #define I_RES_CNTL_MASK		GENMASK(6, 4)
31 #define I_RES_CNTL(x)		FIELD_PREP(I_RES_CNTL_MASK, x)
32 #define I_RES_059_2UA		I_RES_CNTL(0)
33 #define I_RES_100_2UA		I_RES_CNTL(1)
34 #define I_RES_094_2UA		I_RES_CNTL(2)
35 #define I_RES_113_8UA		I_RES_CNTL(3)
36 #define I_RES_089_7UA		I_RES_CNTL(4)
37 #define I_RES_111_8UA		I_RES_CNTL(5)
38 #define I_RES_108_2UA		I_RES_CNTL(6)
39 #define I_RES_120_8UA		I_RES_CNTL(7)
40 #define I_DEV_SEL_MASK		GENMASK(1, 0)
41 #define I_DEV_SEL(x)		FIELD_PREP(I_DEV_SEL_MASK, x)
42 #define I_DEV_DIV_6		I_DEV_SEL(0)
43 #define I_DEV_DIV_12		I_DEV_SEL(1)
44 #define I_DEV_DIV_20		I_DEV_SEL(2)
45 #define I_DEV_DIV_40		I_DEV_SEL(3)
46 
47 #define BIAS_CON1		0x0004
48 #define I_VBG_SEL_MASK		GENMASK(9, 8)
49 #define I_VBG_SEL(x)		FIELD_PREP(I_VBG_SEL_MASK, x)
50 #define I_VBG_SEL_780MV		I_VBG_SEL(0)
51 #define I_VBG_SEL_820MV		I_VBG_SEL(1)
52 #define I_VBG_SEL_860MV		I_VBG_SEL(2)
53 #define I_VBG_SEL_900MV		I_VBG_SEL(3)
54 #define I_BGR_VREF_SEL_MASK	GENMASK(5, 4)
55 #define I_BGR_VREF_SEL(x)	FIELD_PREP(I_BGR_VREF_SEL_MASK, x)
56 #define I_BGR_VREF_810MV	I_BGR_VREF_SEL(0)
57 #define I_BGR_VREF_820MV	I_BGR_VREF_SEL(1)
58 #define I_BGR_VREF_830MV	I_BGR_VREF_SEL(2)
59 #define I_BGR_VREF_840MV	I_BGR_VREF_SEL(3)
60 #define I_LADDER_SEL_MASK	GENMASK(2, 0)
61 #define I_LADDER_SEL(x)		FIELD_PREP(I_LADDER_SEL_MASK, x)
62 #define I_LADDER_1_00V		I_LADDER_SEL(0)
63 #define I_LADDER_0_96V		I_LADDER_SEL(1)
64 #define I_LADDER_0_92V		I_LADDER_SEL(2)
65 #define I_LADDER_0_88V		I_LADDER_SEL(3)
66 #define I_LADDER_0_84V		I_LADDER_SEL(4)
67 #define I_LADDER_0_80V		I_LADDER_SEL(5)
68 #define I_LADDER_0_76V		I_LADDER_SEL(6)
69 #define I_LADDER_0_72V		I_LADDER_SEL(7)
70 
71 /*
72  * Voltage corrections around reference voltages
73  * The selection between the 400-based or 200-based values for REG_400M
74  * is done by the hw depending on I_MUX below being 400MV or 200MV.
75  */
76 #define BIAS_CON2		0x0008
77 #define REG_325M_MASK		GENMASK(14, 12)
78 #define REG_325M(x)		FIELD_PREP(REG_325M_MASK, x)
79 #define REG_325M_295MV		REG_325M(0)
80 #define REG_325M_305MV		REG_325M(1)
81 #define REG_325M_315MV		REG_325M(2)
82 #define REG_325M_325MV		REG_325M(3)
83 #define REG_325M_335MV		REG_325M(4)
84 #define REG_325M_345MV		REG_325M(5)
85 #define REG_325M_355MV		REG_325M(6)
86 #define REG_325M_365MV		REG_325M(7)
87 #define REG_LP_400M_MASK	GENMASK(10, 8)
88 #define REG_LP_400M(x)		FIELD_PREP(REG_LP_400M_MASK, x)
89 #define REG_LP_400M_380MV	REG_LP_400M(0)
90 #define REG_LP_400M_390MV	REG_LP_400M(1)
91 #define REG_LP_400M_400MV	REG_LP_400M(2)
92 #define REG_LP_400M_410MV	REG_LP_400M(3)
93 #define REG_LP_400M_420MV	REG_LP_400M(4)
94 #define REG_LP_400M_430MV	REG_LP_400M(5)
95 #define REG_LP_400M_440MV	REG_LP_400M(6)
96 #define REG_LP_400M_450MV	REG_LP_400M(7)
97 #define REG_400M_MASK		GENMASK(6, 4)
98 #define REG_400M(x)		FIELD_PREP(REG_400M_MASK, x)
99 #define REG_400M_380MV		REG_400M(0)
100 #define REG_400M_390MV		REG_400M(1)
101 #define REG_400M_400MV		REG_400M(2)
102 #define REG_400M_410MV		REG_400M(3)
103 #define REG_400M_420MV		REG_400M(4)
104 #define REG_400M_430MV		REG_400M(5)
105 #define REG_400M_440MV		REG_400M(6)
106 #define REG_400M_450MV		REG_400M(7)
107 #define REG_400M_230MV		REG_400M(0)
108 #define REG_400M_220MV		REG_400M(1)
109 #define REG_400M_210MV		REG_400M(2)
110 #define REG_400M_200MV		REG_400M(3)
111 #define REG_400M_190MV		REG_400M(4)
112 #define REG_400M_180MV		REG_400M(5)
113 #define REG_400M_170MV		REG_400M(6)
114 #define REG_400M_160MV		REG_400M(7)
115 #define REG_645M_MASK		GENMASK(2, 0)
116 #define REG_645M(x)		FIELD_PREP(REG_645M_MASK, x)
117 #define REG_645M_605MV		REG_645M(0)
118 #define REG_645M_625MV		REG_645M(1)
119 #define REG_645M_635MV		REG_645M(2)
120 #define REG_645M_645MV		REG_645M(3)
121 #define REG_645M_655MV		REG_645M(4)
122 #define REG_645M_665MV		REG_645M(5)
123 #define REG_645M_685MV		REG_645M(6)
124 #define REG_645M_725MV		REG_645M(7)
125 
126 #define BIAS_CON4		0x0010
127 #define I_MUX_SEL_MASK		GENMASK(6, 5)
128 #define I_MUX_SEL(x)		FIELD_PREP(I_MUX_SEL_MASK, x)
129 #define I_MUX_400MV		I_MUX_SEL(0)
130 #define I_MUX_200MV		I_MUX_SEL(1)
131 #define I_MUX_530MV		I_MUX_SEL(2)
132 
133 #define PLL_CON0		0x0100
134 #define PLL_EN			BIT(12)
135 #define S_MASK			GENMASK(10, 8)
136 #define S(x)			FIELD_PREP(S_MASK, x)
137 #define P_MASK			GENMASK(5, 0)
138 #define P(x)			FIELD_PREP(P_MASK, x)
139 #define PLL_CON1		0x0104
140 #define PLL_CON2		0x0108
141 #define M_MASK			GENMASK(9, 0)
142 #define M(x)			FIELD_PREP(M_MASK, x)
143 #define PLL_CON3		0x010c
144 #define MRR_MASK		GENMASK(13, 8)
145 #define MRR(x)			FIELD_PREP(MRR_MASK, x)
146 #define MFR_MASK		GENMASK(7, 0)
147 #define MFR(x)			FIELD_PREP(MFR_MASK, x)
148 #define PLL_CON4		0x0110
149 #define SSCG_EN			BIT(11)
150 #define PLL_CON5		0x0114
151 #define RESET_N_SEL		BIT(10)
152 #define PLL_ENABLE_SEL		BIT(8)
153 #define PLL_CON6		0x0118
154 #define PLL_CON7		0x011c
155 #define PLL_LOCK_CNT(x)		FIELD_PREP(GENMASK(15, 0), x)
156 #define PLL_CON8		0x0120
157 #define PLL_STB_CNT(x)		FIELD_PREP(GENMASK(15, 0), x)
158 #define PLL_STAT0		0x0140
159 #define PLL_LOCK		BIT(0)
160 
161 #define DPHY_MC_GNR_CON0	0x0300
162 #define PHY_READY		BIT(1)
163 #define PHY_ENABLE		BIT(0)
164 #define DPHY_MC_GNR_CON1	0x0304
165 #define T_PHY_READY(x)		FIELD_PREP(GENMASK(15, 0), x)
166 #define DPHY_MC_ANA_CON0	0x0308
167 #define EDGE_CON(x)		FIELD_PREP(GENMASK(14, 12), x)
168 #define EDGE_CON_DIR(x)		FIELD_PREP(BIT(9), x)
169 #define EDGE_CON_EN		BIT(8)
170 #define RES_UP(x)		FIELD_PREP(GENMASK(7, 4), x)
171 #define RES_DN(x)		FIELD_PREP(GENMASK(3, 0), x)
172 #define DPHY_MC_ANA_CON1	0x030c
173 #define DPHY_MC_ANA_CON2	0x0310
174 #define HS_VREG_AMP_ICON(x)	FIELD_PREP(GENMASK(1, 0), x)
175 #define DPHY_MC_TIME_CON0	0x0330
176 #define HSTX_CLK_SEL		BIT(12)
177 #define T_LPX(x)		FIELD_PREP(GENMASK(11, 4), x)
178 #define DPHY_MC_TIME_CON1	0x0334
179 #define T_CLK_ZERO(x)		FIELD_PREP(GENMASK(15, 8), x)
180 #define T_CLK_PREPARE(x)	FIELD_PREP(GENMASK(7, 0), x)
181 #define DPHY_MC_TIME_CON2	0x0338
182 #define T_HS_EXIT(x)		FIELD_PREP(GENMASK(15, 8), x)
183 #define T_CLK_TRAIL(x)		FIELD_PREP(GENMASK(7, 0), x)
184 #define DPHY_MC_TIME_CON3	0x033c
185 #define T_CLK_POST(x)		FIELD_PREP(GENMASK(7, 0), x)
186 #define DPHY_MC_TIME_CON4	0x0340
187 #define T_ULPS_EXIT(x)		FIELD_PREP(GENMASK(9, 0), x)
188 #define DPHY_MC_DESKEW_CON0	0x0350
189 #define SKEW_CAL_RUN_TIME(x)	FIELD_PREP(GENMASK(15, 12), x)
190 
191 #define SKEW_CAL_INIT_RUN_TIME(x)	FIELD_PREP(GENMASK(11, 8), x)
192 #define SKEW_CAL_INIT_WAIT_TIME(x)	FIELD_PREP(GENMASK(7, 4), x)
193 #define SKEW_CAL_EN			BIT(0)
194 
195 #define COMBO_MD0_GNR_CON0	0x0400
196 #define COMBO_MD0_GNR_CON1	0x0404
197 #define COMBO_MD0_ANA_CON0	0x0408
198 #define COMBO_MD0_ANA_CON1	0x040c
199 #define COMBO_MD0_ANA_CON2	0x0410
200 
201 #define COMBO_MD0_TIME_CON0	0x0430
202 #define COMBO_MD0_TIME_CON1	0x0434
203 #define COMBO_MD0_TIME_CON2	0x0438
204 #define COMBO_MD0_TIME_CON3	0x043c
205 #define COMBO_MD0_TIME_CON4	0x0440
206 #define COMBO_MD0_DATA_CON0	0x0444
207 
208 #define COMBO_MD1_GNR_CON0	0x0500
209 #define COMBO_MD1_GNR_CON1	0x0504
210 #define COMBO_MD1_ANA_CON0	0x0508
211 #define COMBO_MD1_ANA_CON1	0x050c
212 #define COMBO_MD1_ANA_CON2	0x0510
213 #define COMBO_MD1_TIME_CON0	0x0530
214 #define COMBO_MD1_TIME_CON1	0x0534
215 #define COMBO_MD1_TIME_CON2	0x0538
216 #define COMBO_MD1_TIME_CON3	0x053c
217 #define COMBO_MD1_TIME_CON4	0x0540
218 #define COMBO_MD1_DATA_CON0	0x0544
219 
220 #define COMBO_MD2_GNR_CON0	0x0600
221 #define COMBO_MD2_GNR_CON1	0x0604
222 #define COMBO_MD2_ANA_CON0	0X0608
223 #define COMBO_MD2_ANA_CON1	0X060c
224 #define COMBO_MD2_ANA_CON2	0X0610
225 #define COMBO_MD2_TIME_CON0	0x0630
226 #define COMBO_MD2_TIME_CON1	0x0634
227 #define COMBO_MD2_TIME_CON2	0x0638
228 #define COMBO_MD2_TIME_CON3	0x063c
229 #define COMBO_MD2_TIME_CON4	0x0640
230 #define COMBO_MD2_DATA_CON0	0x0644
231 
232 #define DPHY_MD3_GNR_CON0	0x0700
233 #define DPHY_MD3_GNR_CON1	0x0704
234 #define DPHY_MD3_ANA_CON0	0X0708
235 #define DPHY_MD3_ANA_CON1	0X070c
236 #define DPHY_MD3_ANA_CON2	0X0710
237 #define DPHY_MD3_TIME_CON0	0x0730
238 #define DPHY_MD3_TIME_CON1	0x0734
239 #define DPHY_MD3_TIME_CON2	0x0738
240 #define DPHY_MD3_TIME_CON3	0x073c
241 #define DPHY_MD3_TIME_CON4	0x0740
242 #define DPHY_MD3_DATA_CON0	0x0744
243 
244 #define T_LP_EXIT_SKEW(x)	FIELD_PREP(GENMASK(3, 2), x)
245 #define T_LP_ENTRY_SKEW(x)	FIELD_PREP(GENMASK(1, 0), x)
246 #define T_HS_ZERO(x)		FIELD_PREP(GENMASK(15, 8), x)
247 #define T_HS_PREPARE(x)		FIELD_PREP(GENMASK(7, 0), x)
248 #define T_HS_EXIT(x)		FIELD_PREP(GENMASK(15, 8), x)
249 #define T_HS_TRAIL(x)		FIELD_PREP(GENMASK(7, 0), x)
250 #define T_TA_GET(x)		FIELD_PREP(GENMASK(7, 4), x)
251 #define T_TA_GO(x)		FIELD_PREP(GENMASK(3, 0), x)
252 
253 /* MIPI_CDPHY_GRF registers */
254 #define MIPI_DCPHY_GRF_CON0		0x0000
255 #define S_CPHY_MODE			FIELD_PREP_HIWORD(BIT(3), 1)
256 #define M_CPHY_MODE			FIELD_PREP_HIWORD(BIT(0), 1)
257 
258 enum hs_drv_res_ohm {
259 	STRENGTH_30_OHM = 0x8,
260 	STRENGTH_31_2_OHM,
261 	STRENGTH_32_5_OHM,
262 	STRENGTH_34_OHM,
263 	STRENGTH_35_5_OHM,
264 	STRENGTH_37_OHM,
265 	STRENGTH_39_OHM,
266 	STRENGTH_41_OHM,
267 	STRENGTH_43_OHM = 0x0,
268 	STRENGTH_46_OHM,
269 	STRENGTH_49_OHM,
270 	STRENGTH_52_OHM,
271 	STRENGTH_56_OHM,
272 	STRENGTH_60_OHM,
273 	STRENGTH_66_OHM,
274 	STRENGTH_73_OHM,
275 };
276 
277 struct hs_drv_res_cfg {
278 	enum hs_drv_res_ohm clk_hs_drv_up_ohm;
279 	enum hs_drv_res_ohm clk_hs_drv_down_ohm;
280 	enum hs_drv_res_ohm data_hs_drv_up_ohm;
281 	enum hs_drv_res_ohm data_hs_drv_down_ohm;
282 };
283 
284 struct samsung_mipi_dcphy_plat_data {
285 	const struct hs_drv_res_cfg *dphy_hs_drv_res_cfg;
286 	u32 dphy_tx_max_lane_kbps;
287 };
288 
289 struct samsung_mipi_dcphy {
290 	struct device *dev;
291 	struct clk *ref_clk;
292 	struct clk *pclk;
293 	struct regmap *regmap;
294 	struct regmap *grf_regmap;
295 	struct reset_control *m_phy_rst;
296 	struct reset_control *s_phy_rst;
297 	struct reset_control *apb_rst;
298 	struct reset_control *grf_apb_rst;
299 	unsigned int lanes;
300 	struct phy *phy;
301 	u8 type;
302 
303 	const struct samsung_mipi_dcphy_plat_data *pdata;
304 	struct {
305 		unsigned long long rate;
306 		u8 prediv;
307 		u16 fbdiv;
308 		long dsm;
309 		u8 scaler;
310 
311 		bool ssc_en;
312 		u8 mfr;
313 		u8 mrr;
314 	} pll;
315 };
316 
317 struct samsung_mipi_dphy_timing {
318 	unsigned int max_lane_mbps;
319 	u8 clk_prepare;
320 	u8 clk_zero;
321 	u8 clk_post;
322 	u8 clk_trail_eot;
323 	u8 hs_prepare;
324 	u8 hs_zero;
325 	u8 hs_trail_eot;
326 	u8 lpx;
327 	u8 hs_exit;
328 	u8 hs_settle;
329 };
330 
331 /*
332  * Timing values taken from rk3588 vendor kernel.
333  * Not documented in hw documentation.
334  */
335 static const
336 struct samsung_mipi_dphy_timing samsung_mipi_dphy_timing_table[] = {
337 	{6500, 32, 117, 31, 28, 30, 56, 27, 24, 44, 37},
338 	{6490, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
339 	{6480, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
340 	{6470, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
341 	{6460, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
342 	{6450, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
343 	{6440, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
344 	{6430, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
345 	{6420, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
346 	{6410, 31, 116, 31, 27, 30, 55, 27, 24, 44, 37},
347 	{6400, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
348 	{6390, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
349 	{6380, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
350 	{6370, 31, 115, 30, 27, 30, 55, 26, 23, 43, 36},
351 	{6360, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
352 	{6350, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
353 	{6340, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
354 	{6330, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
355 	{6320, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
356 	{6310, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
357 	{6300, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
358 	{6290, 31, 113, 30, 27, 29, 54, 26, 23, 43, 36},
359 	{6280, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
360 	{6270, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
361 	{6260, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
362 	{6250, 31, 112, 30, 27, 29, 54, 26, 23, 42, 36},
363 	{6240, 30, 113, 30, 27, 29, 54, 26, 23, 42, 36},
364 	{6230, 30, 112, 30, 27, 29, 54, 26, 23, 42, 35},
365 	{6220, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
366 	{6210, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
367 	{6200, 30, 112, 29, 27, 29, 53, 26, 23, 42, 35},
368 	{6190, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
369 	{6180, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
370 	{6170, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
371 	{6160, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
372 	{6150, 30, 110, 29, 26, 29, 53, 26, 23, 42, 35},
373 	{6140, 30, 110, 29, 26, 29, 52, 26, 23, 42, 35},
374 	{6130, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
375 	{6120, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
376 	{6110, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
377 	{6100, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
378 	{6090, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
379 	{6080, 30, 109, 29, 26, 28, 53, 25, 22, 41, 35},
380 	{6070, 30, 109, 29, 26, 28, 52, 25, 22, 41, 34},
381 	{6060, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
382 	{6050, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
383 	{6040, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
384 	{6030, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
385 	{6020, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
386 	{6010, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
387 	{6000, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
388 	{5990, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
389 	{5980, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
390 	{5970, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
391 	{5960, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
392 	{5950, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
393 	{5940, 29, 107, 28, 25, 28, 51, 25, 22, 40, 34},
394 	{5930, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
395 	{5920, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
396 	{5910, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
397 	{5900, 29, 106, 28, 25, 28, 50, 24, 22, 40, 33},
398 	{5890, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
399 	{5880, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
400 	{5870, 29, 105, 28, 25, 27, 51, 24, 22, 40, 33},
401 	{5860, 29, 105, 28, 25, 27, 51, 24, 21, 40, 33},
402 	{5850, 29, 104, 28, 25, 27, 50, 24, 21, 40, 33},
403 	{5840, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
404 	{5830, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
405 	{5820, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
406 	{5810, 28, 104, 28, 25, 27, 50, 24, 21, 39, 33},
407 	{5800, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
408 	{5790, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
409 	{5780, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
410 	{5770, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
411 	{5760, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
412 	{5750, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
413 	{5740, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
414 	{5730, 28, 103, 27, 25, 27, 49, 24, 21, 39, 32},
415 	{5720, 28, 102, 27, 25, 27, 49, 24, 21, 39, 32},
416 	{5710, 28, 102, 27, 25, 27, 48, 24, 21, 39, 32},
417 	{5700, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
418 	{5690, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
419 	{5680, 28, 101, 27, 24, 27, 48, 24, 21, 39, 32},
420 	{5670, 28, 101, 27, 24, 27, 48, 23, 21, 38, 32},
421 	{5660, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
422 	{5650, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
423 	{5640, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
424 	{5630, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
425 	{5620, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
426 	{5610, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
427 	{5600, 27, 101, 26, 24, 26, 48, 23, 20, 38, 32},
428 	{5590, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
429 	{5580, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
430 	{5570, 27, 100, 26, 24, 26, 48, 23, 20, 38, 31},
431 	{5560, 27, 100, 26, 24, 26, 47, 23, 20, 38, 31},
432 	{5550, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
433 	{5540, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
434 	{5530, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
435 	{5520, 27,  99, 26, 24, 26, 47, 23, 20, 37, 31},
436 	{5510, 27,  98, 26, 24, 26, 47, 23, 20, 37, 31},
437 	{5500, 27,  98, 26, 24, 26, 47, 23, 20, 37, 31},
438 	{5490, 27,  98, 26, 24, 26, 46, 23, 20, 37, 31},
439 	{5480, 27,  98, 26, 24, 26, 46, 23, 20, 37, 31},
440 	{5470, 27,  97, 26, 23, 26, 46, 23, 20, 37, 31},
441 	{5460, 27,  97, 26, 23, 26, 46, 23, 20, 37, 31},
442 	{5450, 27,  97, 26, 23, 25, 47, 23, 20, 37, 31},
443 	{5440, 26,  98, 26, 23, 25, 47, 23, 20, 37, 31},
444 	{5430, 26,  98, 26, 23, 25, 47, 22, 20, 37, 31},
445 	{5420, 26,  97, 26, 23, 25, 46, 22, 20, 37, 31},
446 	{5410, 26,  97, 26, 23, 25, 46, 22, 20, 37, 31},
447 	{5400, 26,  97, 25, 23, 25, 46, 22, 20, 37, 30},
448 	{5390, 26,  97, 25, 23, 25, 46, 22, 20, 37, 30},
449 	{5380, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
450 	{5370, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
451 	{5360, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
452 	{5350, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
453 	{5340, 26,  95, 25, 23, 25, 45, 22, 20, 36, 30},
454 	{5330, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
455 	{5320, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
456 	{5310, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
457 	{5300, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
458 	{5290, 26,  94, 25, 23, 25, 45, 22, 19, 36, 30},
459 	{5280, 26,  94, 25, 23, 25, 45, 22, 19, 36, 30},
460 	{5270, 26,  94, 25, 23, 25, 44, 22, 19, 36, 30},
461 	{5260, 26,  94, 25, 23, 25, 44, 22, 19, 36, 30},
462 	{5250, 25,  94, 25, 23, 24, 45, 22, 19, 36, 30},
463 	{5240, 25,  94, 25, 23, 24, 45, 22, 19, 36, 29},
464 	{5230, 25,  94, 25, 22, 24, 45, 22, 19, 35, 29},
465 	{5220, 25,  94, 25, 22, 24, 45, 22, 19, 35, 29},
466 	{5210, 25,  93, 25, 22, 24, 45, 22, 19, 35, 29},
467 	{5200, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
468 	{5190, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
469 	{5180, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
470 	{5170, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
471 	{5160, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
472 	{5150, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
473 	{5140, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
474 	{5130, 25,  92, 24, 22, 24, 43, 21, 19, 35, 29},
475 	{5120, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
476 	{5110, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
477 	{5100, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
478 	{5090, 25,  91, 24, 22, 24, 43, 21, 19, 34, 29},
479 	{5080, 25,  90, 24, 22, 24, 43, 21, 19, 34, 29},
480 	{5070, 25,  90, 24, 22, 24, 43, 21, 19, 34, 28},
481 	{5060, 25,  90, 24, 22, 24, 43, 21, 18, 34, 28},
482 	{5050, 24,  91, 24, 22, 24, 42, 21, 18, 34, 28},
483 	{5040, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
484 	{5030, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
485 	{5020, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
486 	{5010, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
487 	{5000, 24,  89, 23, 21, 23, 43, 21, 18, 34, 28},
488 	{4990, 24,  89, 23, 21, 23, 43, 21, 18, 34, 28},
489 	{4980, 24,  89, 23, 21, 23, 42, 21, 18, 34, 28},
490 	{4970, 24,  89, 23, 21, 23, 42, 21, 18, 34, 28},
491 	{4960, 24,  89, 23, 21, 23, 42, 20, 18, 34, 28},
492 	{4950, 24,  88, 23, 21, 23, 42, 20, 18, 34, 28},
493 	{4940, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
494 	{4930, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
495 	{4920, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
496 	{4910, 24,  87, 23, 21, 23, 41, 20, 18, 33, 28},
497 	{4900, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
498 	{4890, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
499 	{4880, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
500 	{4870, 24,  86, 23, 21, 23, 41, 20, 18, 33, 27},
501 	{4860, 24,  86, 23, 21, 23, 41, 20, 18, 33, 27},
502 	{4850, 23,  87, 23, 21, 23, 41, 20, 18, 33, 27},
503 	{4840, 23,  87, 23, 21, 23, 40, 20, 18, 33, 27},
504 	{4830, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
505 	{4820, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
506 	{4810, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
507 	{4800, 23,  86, 22, 21, 22, 41, 20, 17, 32, 27},
508 	{4790, 23,  86, 22, 21, 22, 41, 20, 17, 32, 27},
509 	{4780, 23,  85, 22, 21, 22, 41, 20, 17, 32, 27},
510 	{4770, 23,  85, 22, 21, 22, 41, 20, 17, 32, 27},
511 	{4760, 23,  85, 22, 20, 22, 40, 20, 17, 32, 27},
512 	{4750, 23,  85, 22, 20, 22, 40, 20, 17, 32, 27},
513 	{4740, 23,  84, 22, 20, 22, 40, 20, 17, 32, 26},
514 	{4730, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
515 	{4720, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
516 	{4710, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
517 	{4700, 23,  83, 22, 20, 22, 40, 19, 17, 32, 26},
518 	{4690, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
519 	{4680, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
520 	{4670, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
521 	{4660, 23,  82, 22, 20, 22, 39, 19, 17, 32, 26},
522 	{4650, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
523 	{4640, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
524 	{4630, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
525 	{4620, 22,  83, 22, 20, 21, 39, 19, 17, 31, 26},
526 	{4610, 22,  82, 22, 20, 21, 39, 19, 17, 31, 26},
527 	{4600, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
528 	{4590, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
529 	{4580, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
530 	{4570, 22,  81, 21, 20, 21, 39, 19, 17, 31, 25},
531 	{4560, 22,  81, 21, 20, 21, 39, 19, 17, 31, 25},
532 	{4550, 22,  81, 21, 20, 21, 38, 19, 17, 31, 25},
533 	{4540, 22,  81, 21, 20, 21, 38, 19, 17, 31, 25},
534 	{4530, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
535 	{4520, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
536 	{4510, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
537 	{4500, 22,  80, 21, 19, 21, 38, 19, 16, 30, 25},
538 	{4490, 22,  80, 21, 19, 21, 38, 18, 16, 30, 25},
539 	{4480, 22,  79, 21, 19, 21, 38, 18, 16, 30, 25},
540 	{4470, 22,  79, 21, 19, 21, 37, 18, 16, 30, 25},
541 	{4460, 22,  79, 21, 19, 21, 37, 18, 16, 30, 25},
542 	{4450, 21,  80, 21, 19, 21, 37, 18, 16, 30, 25},
543 	{4440, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
544 	{4430, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
545 	{4420, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
546 	{4410, 21,  79, 21, 19, 20, 38, 18, 16, 30, 25},
547 	{4400, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
548 	{4390, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
549 	{4380, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
550 	{4370, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
551 	{4360, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
552 	{4350, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
553 	{4340, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
554 	{4330, 21,  77, 20, 19, 20, 36, 18, 16, 29, 24},
555 	{4320, 21,  77, 20, 19, 20, 36, 18, 16, 29, 24},
556 	{4310, 21,  76, 20, 19, 20, 36, 18, 16, 29, 24},
557 	{4300, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
558 	{4290, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
559 	{4280, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
560 	{4270, 21,  75, 20, 18, 20, 36, 18, 16, 29, 24},
561 	{4260, 21,  75, 20, 18, 20, 35, 17, 15, 29, 24},
562 	{4250, 20,  76, 20, 18, 20, 35, 17, 15, 29, 24},
563 	{4240, 20,  76, 20, 18, 20, 35, 17, 15, 29, 23},
564 	{4230, 20,  75, 20, 18, 20, 35, 17, 15, 29, 23},
565 	{4220, 20,  75, 20, 18, 20, 35, 17, 15, 29, 23},
566 	{4210, 20,  75, 20, 18, 20, 35, 17, 15, 28, 23},
567 	{4200, 20,  75, 19, 18, 19, 36, 17, 15, 28, 23},
568 	{4190, 20,  74, 19, 18, 19, 36, 17, 15, 28, 23},
569 	{4180, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
570 	{4170, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
571 	{4160, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
572 	{4150, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
573 	{4140, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
574 	{4130, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
575 	{4120, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
576 	{4110, 20,  73, 19, 18, 19, 34, 17, 15, 28, 23},
577 	{4100, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
578 	{4090, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
579 	{4080, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
580 	{4070, 20,  72, 19, 18, 19, 34, 17, 15, 27, 22},
581 	{4060, 19,  72, 19, 17, 19, 34, 17, 15, 27, 22},
582 	{4050, 19,  72, 19, 17, 19, 34, 17, 15, 27, 22},
583 	{4040, 19,  72, 19, 17, 19, 33, 17, 15, 27, 22},
584 	{4030, 19,  72, 19, 17, 19, 33, 17, 15, 27, 22},
585 	{4020, 19,  71, 19, 17, 19, 33, 16, 15, 27, 22},
586 	{4010, 19,  71, 19, 17, 19, 33, 16, 15, 27, 22},
587 	{4000, 19,  71, 18, 17, 19, 33, 16, 14, 27, 22},
588 	{3990, 19,  71, 18, 17, 18, 34, 16, 14, 27, 22},
589 	{3980, 19,  71, 18, 17, 18, 34, 16, 14, 27, 22},
590 	{3970, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
591 	{3960, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
592 	{3950, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
593 	{3940, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
594 	{3930, 19,  69, 18, 17, 18, 33, 16, 14, 27, 22},
595 	{3920, 19,  69, 18, 17, 18, 33, 16, 14, 26, 22},
596 	{3910, 19,  69, 18, 17, 18, 33, 16, 14, 26, 22},
597 	{3900, 19,  69, 18, 17, 18, 33, 16, 14, 26, 21},
598 	{3890, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
599 	{3880, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
600 	{3870, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
601 	{3860, 18,  69, 18, 17, 18, 32, 16, 14, 26, 21},
602 	{3850, 18,  68, 18, 17, 18, 32, 16, 14, 26, 21},
603 	{3840, 18,  68, 18, 17, 18, 32, 16, 14, 26, 21},
604 	{3830, 18,  68, 18, 16, 18, 32, 16, 14, 26, 21},
605 	{3820, 18,  68, 18, 16, 18, 31, 16, 14, 26, 21},
606 	{3810, 18,  68, 18, 16, 18, 31, 16, 14, 26, 21},
607 	{3800, 18,  67, 17, 16, 18, 31, 16, 14, 26, 21},
608 	{3790, 18,  67, 17, 16, 17, 32, 15, 14, 26, 21},
609 	{3780, 18,  67, 17, 16, 17, 32, 15, 14, 25, 21},
610 	{3770, 18,  67, 17, 16, 17, 32, 15, 14, 25, 21},
611 	{3760, 18,  66, 17, 16, 17, 32, 15, 14, 25, 21},
612 	{3750, 18,  66, 17, 16, 17, 31, 15, 14, 25, 21},
613 	{3740, 18,  66, 17, 16, 17, 31, 15, 14, 25, 20},
614 	{3730, 18,  66, 17, 16, 17, 31, 15, 13, 25, 20},
615 	{3720, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
616 	{3710, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
617 	{3700, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
618 	{3690, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
619 	{3680, 18,  64, 17, 16, 17, 31, 15, 13, 25, 20},
620 	{3670, 18,  64, 17, 16, 17, 30, 15, 13, 25, 20},
621 	{3660, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
622 	{3650, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
623 	{3640, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
624 	{3630, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
625 	{3620, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
626 	{3610, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
627 	{3600, 17,  64, 16, 16, 17, 29, 15, 13, 24, 20},
628 	{3590, 17,  63, 16, 15, 17, 29, 15, 13, 24, 20},
629 	{3580, 17,  63, 16, 15, 16, 30, 15, 13, 24, 20},
630 	{3570, 17,  63, 16, 15, 16, 30, 15, 13, 24, 19},
631 	{3560, 17,  63, 16, 15, 16, 30, 14, 13, 24, 19},
632 	{3550, 17,  62, 16, 15, 16, 30, 14, 13, 24, 19},
633 	{3540, 17,  62, 16, 15, 16, 30, 14, 13, 24, 19},
634 	{3530, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
635 	{3520, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
636 	{3510, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
637 	{3500, 17,  61, 16, 15, 16, 29, 14, 13, 24, 19},
638 	{3490, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
639 	{3480, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
640 	{3470, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
641 	{3460, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
642 	{3450, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
643 	{3440, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
644 	{3430, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
645 	{3420, 16,  60, 16, 15, 16, 28, 14, 12, 23, 19},
646 	{3410, 16,  60, 16, 15, 16, 28, 14, 12, 23, 18},
647 	{3400, 16,  60, 15, 15, 16, 28, 14, 12, 23, 18},
648 	{3390, 16,  60, 15, 15, 16, 28, 14, 12, 23, 18},
649 	{3380, 16,  59, 15, 15, 16, 27, 14, 12, 23, 18},
650 	{3370, 16,  59, 15, 15, 15, 28, 14, 12, 23, 18},
651 	{3360, 16,  59, 15, 14, 15, 28, 14, 12, 23, 18},
652 	{3350, 16,  59, 15, 14, 15, 28, 14, 12, 23, 18},
653 	{3340, 16,  59, 15, 14, 15, 28, 14, 12, 22, 18},
654 	{3330, 16,  58, 15, 14, 15, 28, 14, 12, 22, 18},
655 	{3320, 16,  58, 15, 14, 15, 28, 13, 12, 22, 18},
656 	{3310, 16,  58, 15, 14, 15, 27, 13, 12, 22, 18},
657 	{3300, 16,  58, 15, 14, 15, 27, 13, 12, 22, 18},
658 	{3290, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
659 	{3280, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
660 	{3270, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
661 	{3260, 15,  58, 15, 14, 15, 27, 13, 12, 22, 18},
662 	{3250, 15,  57, 15, 14, 15, 27, 13, 12, 22, 18},
663 	{3240, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
664 	{3230, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
665 	{3220, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
666 	{3210, 15,  56, 15, 14, 15, 26, 13, 12, 22, 17},
667 	{3200, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
668 	{3190, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
669 	{3180, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
670 	{3170, 15,  56, 14, 14, 15, 25, 13, 11, 21, 17},
671 	{3160, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
672 	{3150, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
673 	{3140, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
674 	{3130, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
675 	{3120, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
676 	{3110, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
677 	{3100, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
678 	{3090, 15,  54, 14, 13, 14, 25, 12, 11, 21, 17},
679 	{3080, 15,  53, 14, 13, 14, 25, 12, 11, 21, 17},
680 	{3070, 14,  54, 14, 13, 14, 25, 12, 11, 21, 16},
681 	{3060, 14,  54, 14, 13, 14, 25, 12, 11, 21, 16},
682 	{3050, 14,  54, 14, 13, 14, 25, 12, 11, 20, 16},
683 	{3040, 14,  53, 14, 13, 14, 25, 12, 11, 20, 16},
684 	{3030, 14,  53, 14, 13, 14, 25, 12, 11, 20, 16},
685 	{3020, 14,  53, 14, 13, 14, 24, 12, 11, 20, 16},
686 	{3010, 14,  53, 14, 13, 14, 24, 12, 11, 20, 16},
687 	{3000, 14,  53, 13, 13, 14, 24, 12, 11, 20, 16},
688 	{2990, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
689 	{2980, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
690 	{2970, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
691 	{2960, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
692 	{2950, 14,  51, 13, 13, 13, 24, 12, 11, 20, 16},
693 	{2940, 14,  51, 13, 13, 13, 24, 12, 11, 20, 16},
694 	{2930, 14,  51, 13, 13, 13, 24, 12, 10, 20, 16},
695 	{2920, 14,  51, 13, 13, 13, 24, 12, 10, 20, 16},
696 	{2910, 14,  50, 13, 13, 13, 24, 12, 10, 20, 15},
697 	{2900, 14,  50, 13, 13, 13, 24, 12, 10, 19, 15},
698 	{2890, 14,  50, 13, 12, 13, 24, 12, 10, 19, 15},
699 	{2880, 14,  50, 13, 12, 13, 23, 12, 10, 19, 15},
700 	{2870, 13,  50, 13, 12, 13, 23, 12, 10, 19, 15},
701 	{2860, 13,  50, 13, 12, 13, 23, 12, 10, 19, 15},
702 	{2850, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
703 	{2840, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
704 	{2830, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
705 	{2820, 13,  49, 13, 12, 13, 23, 11, 10, 19, 15},
706 	{2810, 13,  49, 13, 12, 13, 23, 11, 10, 19, 15},
707 	{2800, 13,  49, 12, 12, 13, 22, 11, 10, 19, 15},
708 	{2790, 13,  49, 12, 12, 13, 22, 11, 10, 19, 15},
709 	{2780, 13,  48, 12, 12, 13, 22, 11, 10, 19, 15},
710 	{2770, 13,  48, 12, 12, 13, 22, 11, 10, 19, 15},
711 	{2760, 13,  48, 12, 12, 13, 22, 11, 10, 18, 15},
712 	{2750, 13,  48, 12, 12, 13, 22, 11, 10, 18, 15},
713 	{2740, 13,  47, 12, 12, 12, 23, 11, 10, 18, 14},
714 	{2730, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
715 	{2720, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
716 	{2710, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
717 	{2700, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
718 	{2690, 13,  46, 12, 12, 12, 22, 11, 10, 18, 14},
719 	{2680, 13,  46, 12, 12, 12, 22, 11, 10, 18, 14},
720 	{2670, 12,  47, 12, 12, 12, 22, 11, 10, 18, 14},
721 	{2660, 12,  47, 12, 12, 12, 21, 11,  9, 18, 14},
722 	{2650, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
723 	{2640, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
724 	{2630, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
725 	{2620, 12,  46, 12, 11, 12, 21, 10,  9, 18, 14},
726 	{2610, 12,  45, 12, 11, 12, 21, 10,  9, 17, 14},
727 	{2600, 12,  45, 11, 11, 12, 21, 10,  9, 17, 14},
728 	{2590, 12,  45, 11, 11, 12, 20, 10,  9, 17, 14},
729 	{2580, 12,  45, 11, 11, 12, 20, 10,  9, 17, 14},
730 	{2570, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
731 	{2560, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
732 	{2550, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
733 	{2540, 12,  44, 11, 11, 11, 21, 10,  9, 17, 13},
734 	{2530, 12,  44, 11, 11, 11, 21, 10,  9, 17, 13},
735 	{2520, 12,  43, 11, 11, 11, 21, 10,  9, 17, 13},
736 	{2510, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
737 	{2500, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
738 	{2490, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
739 	{2480, 12,  42, 11, 11, 11, 20, 10,  9, 17, 13},
740 	{2470, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
741 	{2460, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
742 	{2450, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
743 	{2440, 11,  42, 11, 11, 11, 19, 10,  9, 16, 13},
744 	{2430, 11,  42, 11, 11, 11, 19, 10,  9, 16, 13},
745 	{2420, 11,  42, 11, 10, 11, 19, 10,  9, 16, 13},
746 	{2410, 11,  42, 11, 10, 11, 19, 10,  9, 16, 12},
747 	{2400, 11,  41, 10, 10, 11, 19, 10,  8, 16, 12},
748 	{2390, 11,  41, 10, 10, 11, 19, 10,  8, 16, 12},
749 	{2380, 11,  41, 10, 10, 11, 19,  9,  8, 16, 12},
750 	{2370, 11,  41, 10, 10, 11, 18,  9,  8, 16, 12},
751 	{2360, 11,  41, 10, 10, 11, 18,  9,  8, 16, 12},
752 	{2350, 11,  40, 10, 10, 11, 18,  9,  8, 16, 12},
753 	{2340, 11,  40, 10, 10, 11, 18,  9,  8, 16, 12},
754 	{2330, 11,  40, 10, 10, 10, 19,  9,  8, 16, 12},
755 	{2320, 11,  40, 10, 10, 10, 19,  9,  8, 15, 12},
756 	{2310, 11,  39, 10, 10, 10, 19,  9,  8, 15, 12},
757 	{2300, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
758 	{2290, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
759 	{2280, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
760 	{2270, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
761 	{2260, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
762 	{2250, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
763 	{2240, 10,  39, 10, 10, 10, 18,  9,  8, 15, 11},
764 	{2230, 10,  38, 10, 10, 10, 18,  9,  8, 15, 11},
765 	{2220, 10,  38, 10, 10, 10, 17,  9,  8, 15, 11},
766 	{2210, 10,  38, 10, 10, 10, 17,  9,  8, 15, 11},
767 	{2200, 10,  38,  9, 10, 10, 17,  9,  8, 15, 11},
768 	{2190, 10,  38,  9,  9, 10, 17,  9,  8, 15, 11},
769 	{2180, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
770 	{2170, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
771 	{2160, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
772 	{2150, 10,  37,  9,  9, 10, 16,  8,  8, 14, 11},
773 	{2140, 10,  36,  9,  9, 10, 16,  8,  8, 14, 11},
774 	{2130, 10,  36,  9,  9, 10, 16,  8,  7, 14, 11},
775 	{2120, 10,  36,  9,  9,  9, 17,  8,  7, 14, 11},
776 	{2110, 10,  36,  9,  9,  9, 17,  8,  7, 14, 11},
777 	{2100, 10,  35,  9,  9,  9, 17,  8,  7, 14, 11},
778 	{2090, 10,  35,  9,  9,  9, 17,  8,  7, 14, 11},
779 	{2080,  9,  36,  9,  9,  9, 16,  8,  7, 14, 11},
780 	{2070,  9,  36,  9,  9,  9, 16,  8,  7, 14, 10},
781 	{2060,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
782 	{2050,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
783 	{2040,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
784 	{2030,  9,  35,  9,  9,  9, 16,  8,  7, 13, 10},
785 	{2020,  9,  35,  9,  9,  9, 16,  8,  7, 13, 10},
786 	{2010,  9,  34,  9,  9,  9, 15,  8,  7, 13, 10},
787 	{2000,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
788 	{1990,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
789 	{1980,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
790 	{1970,  9,  33,  8,  9,  9, 15,  8,  7, 13, 10},
791 	{1960,  9,  33,  8,  9,  9, 15,  8,  7, 13, 10},
792 	{1950,  9,  33,  8,  8,  9, 15,  8,  7, 13, 10},
793 	{1940,  9,  33,  8,  8,  9, 15,  8,  7, 13, 10},
794 	{1930,  9,  32,  8,  8,  9, 14,  8,  7, 13, 10},
795 	{1920,  9,  32,  8,  8,  9, 14,  8,  7, 13, 10},
796 	{1910,  9,  32,  8,  8,  8, 15,  7,  7, 13,  9},
797 	{1900,  9,  32,  8,  8,  8, 15,  7,  7, 13,  9},
798 	{1890,  9,  31,  8,  8,  8, 15,  7,  7, 12,  9},
799 	{1880,  8,  32,  8,  8,  8, 15,  7,  7, 12,  9},
800 	{1870,  8,  32,  8,  8,  8, 15,  7,  7, 12,  9},
801 	{1860,  8,  32,  8,  8,  8, 14,  7,  6, 12,  9},
802 	{1850,  8,  32,  8,  8,  8, 14,  7,  6, 12,  9},
803 	{1840,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
804 	{1830,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
805 	{1820,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
806 	{1810,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
807 	{1800,  8,  30,  7,  8,  8, 14,  7,  6, 12,  9},
808 	{1790,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
809 	{1780,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
810 	{1770,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
811 	{1760,  8,  29,  7,  8,  8, 13,  7,  6, 12,  9},
812 	{1750,  8,  29,  7,  8,  8, 13,  7,  6, 12,  9},
813 	{1740,  8,  29,  7,  8,  8, 13,  7,  6, 11,  8},
814 	{1730,  8,  29,  7,  8,  8, 13,  7,  6, 11,  8},
815 	{1720,  8,  29,  7,  7,  8, 13,  7,  6, 11,  8},
816 	{1710,  8,  28,  7,  7,  8, 12,  7,  6, 11,  8},
817 	{1700,  8,  28,  7,  7,  7, 13,  7,  6, 11,  8},
818 	{1690,  8,  28,  7,  7,  7, 13,  7,  6, 11,  8},
819 	{1680,  7,  29,  7,  7,  7, 13,  6,  6, 11,  8},
820 	{1670,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
821 	{1660,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
822 	{1650,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
823 	{1640,  7,  28,  7,  7,  7, 12,  6,  6, 11,  8},
824 	{1630,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
825 	{1620,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
826 	{1610,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
827 	{1600,  7,  27,  6,  7,  7, 12,  6,  5, 10,  8},
828 	{1590,  7,  26,  6,  7,  7, 12,  6,  5, 10,  8},
829 	{1580,  7,  26,  6,  7,  7, 12,  6,  5, 10,  7},
830 	{1570,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
831 	{1560,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
832 	{1550,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
833 	{1540,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
834 	{1530,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
835 	{1520,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
836 	{1510,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
837 	{1500,  7,  24,  6,  7,  7, 10,  6,  5, 10,  7},
838 	{1490, 59,  25,  6, 77, 59, 10, 70, 44,  9, 73},
839 	{1480, 59,  24,  6, 76, 58, 10, 70, 44,  9, 73},
840 	{1470, 58,  24,  6, 76, 58, 10, 69, 44,  9, 72},
841 	{1460, 58,  24,  6, 76, 58, 10, 69, 43,  9, 72},
842 	{1450, 58,  24,  6, 75, 57, 10, 68, 43,  9, 71},
843 	{1440, 57,  24,  6, 75, 57, 10, 68, 43,  9, 71},
844 	{1430, 57,  23,  6, 75, 57, 10, 68, 43,  8, 70},
845 	{1420, 56,  23,  6, 74, 57,  9, 67, 43,  8, 70},
846 	{1410, 56,  23,  6, 74, 57,  9, 67, 43,  8, 69},
847 	{1400, 56,  23,  5, 74, 55,  9, 67, 41,  8, 69},
848 	{1390, 55,  23,  5, 73, 55,  9, 66, 41,  8, 68},
849 	{1380, 55,  23,  5, 73, 54,  9, 66, 41,  8, 68},
850 	{1370, 54,  22,  5, 72, 54,  9, 66, 41,  8, 67},
851 	{1360, 54,  22,  5, 72, 54,  9, 65, 40,  8, 67},
852 	{1350, 54,  22,  5, 72, 53,  9, 65, 40,  8, 66},
853 	{1340, 53,  22,  5, 71, 53,  9, 65, 40,  8, 66},
854 	{1330, 53,  22,  5, 71, 53,  9, 64, 39,  8, 65},
855 	{1320, 52,  22,  5, 71, 53,  8, 64, 40,  8, 65},
856 	{1310, 52,  21,  5, 70, 53,  8, 64, 40,  8, 64},
857 	{1300, 51,  21,  5, 70, 51,  8, 63, 38,  8, 64},
858 	{1290, 51,  21,  5, 70, 51,  8, 63, 38,  7, 64},
859 	{1280, 51,  21,  5, 69, 51,  8, 63, 38,  7, 63},
860 	{1270, 50,  21,  5, 69, 50,  8, 62, 38,  7, 63},
861 	{1260, 50,  20,  5, 69, 50,  8, 62, 37,  7, 62},
862 	{1250, 49,  20,  5, 68, 49,  8, 62, 37,  7, 62},
863 	{1240, 49,  20,  5, 68, 49,  8, 61, 37,  7, 61},
864 	{1230, 49,  20,  5, 68, 49,  8, 61, 36,  7, 61},
865 	{1220, 48,  20,  5, 67, 48,  8, 61, 36,  7, 60},
866 	{1210, 48,  19,  5, 67, 48,  7, 60, 36,  7, 60},
867 	{1200, 49,  19,  4, 67, 49,  7, 60, 36,  7, 59},
868 	{1190, 48,  19,  4, 66, 48,  7, 60, 36,  7, 59},
869 	{1180, 48,  19,  4, 66, 48,  7, 59, 36,  7, 58},
870 	{1170, 46,  19,  4, 66, 46,  7, 59, 35,  7, 58},
871 	{1160, 46,  18,  4, 65, 46,  7, 59, 34,  7, 57},
872 	{1150, 45,  18,  4, 65, 46,  7, 58, 34,  7, 57},
873 	{1140, 45,  18,  4, 65, 45,  7, 58, 34,  6, 56},
874 	{1130, 45,  18,  4, 64, 45,  7, 58, 33,  6, 56},
875 	{1120, 44,  18,  4, 64, 44,  7, 57, 33,  6, 55},
876 	{1110, 44,  18,  4, 64, 44,  7, 57, 33,  6, 55},
877 	{1100, 43,  17,  4, 63, 44,  6, 57, 32,  6, 54},
878 	{1090, 43,  17,  4, 63, 44,  6, 56, 33,  6, 54},
879 	{1080, 43,  17,  4, 63, 44,  6, 56, 33,  6, 53},
880 	{1070, 42,  17,  4, 62, 44,  6, 56, 33,  6, 53},
881 	{1060, 42,  17,  4, 62, 42,  6, 55, 31,  6, 52},
882 	{1050, 41,  17,  4, 62, 42,  6, 55, 31,  6, 52},
883 	{1040, 41,  16,  4, 61, 41,  6, 54, 31,  6, 52},
884 	{1030, 41,  16,  4, 61, 41,  6, 54, 30,  6, 51},
885 	{1020, 40,  16,  4, 61, 41,  6, 54, 30,  6, 51},
886 	{1010, 40,  16,  4, 60, 40,  6, 53, 30,  6, 50},
887 	{1000, 39,  16,  3, 60, 40,  6, 53, 29,  5, 50},
888 	{ 990, 39,  15,  3, 60, 39,  6, 53, 29,  5, 49},
889 	{ 980, 39,  15,  3, 59, 39,  5, 52, 29,  5, 49},
890 	{ 970, 38,  15,  3, 59, 39,  5, 52, 29,  5, 48},
891 	{ 960, 38,  15,  3, 59, 39,  5, 52, 29,  5, 48},
892 	{ 950, 37,  15,  3, 58, 39,  5, 51, 29,  5, 47},
893 	{ 940, 37,  14,  3, 58, 39,  5, 51, 29,  5, 47},
894 	{ 930, 37,  14,  3, 57, 37,  5, 51, 27,  5, 46},
895 	{ 920, 36,  14,  3, 57, 37,  5, 50, 27,  5, 46},
896 	{ 910, 36,  14,  3, 57, 36,  5, 50, 27,  5, 45},
897 	{ 900, 35,  14,  3, 56, 36,  5, 50, 26,  5, 45},
898 	{ 890, 35,  14,  3, 56, 36,  5, 49, 26,  5, 44},
899 	{ 880, 35,  13,  3, 56, 35,  5, 49, 26,  5, 44},
900 	{ 870, 34,  13,  3, 55, 35,  4, 49, 26,  5, 43},
901 	{ 860, 34,  13,  3, 55, 35,  4, 48, 25,  5, 43},
902 	{ 850, 33,  13,  3, 55, 35,  4, 48, 26,  4, 42},
903 	{ 840, 33,  13,  3, 54, 35,  4, 48, 26,  4, 42},
904 	{ 830, 33,  12,  3, 54, 33,  4, 47, 24,  4, 41},
905 	{ 820, 32,  12,  3, 54, 33,  4, 47, 24,  4, 41},
906 	{ 810, 32,  12,  3, 53, 33,  4, 47, 24,  4, 40},
907 	{ 800, 31,  12,  2, 53, 32,  4, 46, 23,  4, 40},
908 	{ 790, 31,  12,  2, 53, 32,  4, 46, 23,  4, 39},
909 	{ 780, 30,  12,  2, 52, 31,  4, 46, 23,  4, 39},
910 	{ 770, 30,  11,  2, 52, 31,  4, 45, 23,  4, 39},
911 	{ 760, 30,  11,  2, 52, 31,  3, 45, 22,  4, 38},
912 	{ 750, 29,  11,  2, 51, 30,  3, 45, 22,  4, 38},
913 	{ 740, 29,  11,  2, 51, 30,  3, 44, 22,  4, 37},
914 	{ 730, 28,  11,  2, 51, 31,  3, 44, 22,  4, 37},
915 	{ 720, 28,  10,  2, 50, 30,  3, 44, 22,  4, 36},
916 	{ 710, 28,  10,  2, 50, 30,  3, 43, 22,  4, 36},
917 	{ 700, 27,  10,  2, 50, 28,  3, 43, 20,  3, 35},
918 	{ 690, 27,  10,  2, 49, 28,  3, 43, 20,  3, 35},
919 	{ 680, 26,  10,  2, 49, 28,  3, 42, 20,  3, 34},
920 	{ 670, 26,  10,  2, 49, 27,  3, 42, 20,  3, 34},
921 	{ 660, 26,   9,  2, 48, 27,  3, 42, 19,  3, 33},
922 	{ 650, 25,   9,  2, 48, 26,  3, 41, 19,  3, 33},
923 	{ 640, 25,   9,  2, 48, 26,  2, 41, 19,  3, 32},
924 	{ 630, 24,   9,  2, 47, 26,  2, 40, 18,  3, 32},
925 	{ 620, 24,   9,  2, 47, 26,  2, 40, 19,  3, 31},
926 	{ 610, 24,   8,  2, 47, 26,  2, 40, 19,  3, 31},
927 	{ 600, 23,   8,  1, 46, 26,  2, 39, 18,  3, 30},
928 	{ 590, 23,   8,  1, 46, 24,  2, 39, 17,  3, 30},
929 	{ 580, 22,   8,  1, 46, 24,  2, 39, 17,  3, 29},
930 	{ 570, 22,   8,  1, 45, 23,  2, 38, 17,  3, 29},
931 	{ 560, 22,   7,  1, 45, 23,  2, 38, 16,  2, 28},
932 	{ 550, 21,   7,  1, 45, 23,  2, 38, 16,  2, 28},
933 	{ 540, 21,   7,  1, 44, 22,  2, 37, 16,  2, 27},
934 	{ 530, 20,   7,  1, 44, 22,  1, 37, 15,  2, 27},
935 	{ 520, 20,   7,  1, 43, 21,  1, 37, 15,  2, 27},
936 	{ 510, 20,   6,  1, 43, 21,  1, 36, 15,  2, 26},
937 	{ 500, 19,   6,  1, 43, 22,  1, 36, 15,  2, 26},
938 	{ 490, 19,   6,  1, 42, 21,  1, 36, 15,  2, 25},
939 	{ 480, 18,   6,  1, 42, 21,  1, 35, 15,  2, 25},
940 	{ 470, 18,   6,  1, 42, 21,  1, 35, 15,  2, 24},
941 	{ 460, 18,   6,  1, 41, 19,  1, 35, 13,  2, 24},
942 	{ 450, 17,   5,  1, 41, 19,  1, 34, 13,  2, 23},
943 	{ 440, 17,   5,  1, 41, 18,  1, 34, 13,  2, 23},
944 	{ 430, 16,   5,  1, 40, 18,  0, 34, 12,  2, 22},
945 	{ 420, 16,   5,  1, 40, 18,  0, 33, 12,  2, 22},
946 	{ 410, 16,   5,  1, 40, 17,  0, 33, 12,  1, 21},
947 	{ 400, 15,   5,  0, 39, 17,  0, 33, 11,  1, 21},
948 	{ 390, 15,   4,  0, 39, 17,  0, 32, 12,  1, 20},
949 	{ 380, 14,   4,  0, 39, 17,  0, 32, 12,  1, 20},
950 	{ 370, 14,   4,  0, 38, 17,  0, 32, 12,  1, 19},
951 	{ 360, 14,   4,  0, 38, 15,  0, 31, 10,  1, 19},
952 	{ 350, 13,   4,  0, 38, 15,  0, 31, 10,  1, 18},
953 	{ 340, 13,   3,  0, 37, 15,  0, 31, 10,  1, 18},
954 	{ 330, 12,   3,  0, 37, 14,  0, 30,  9,  1, 17},
955 	{ 320, 12,   3,  0, 37, 14,  0, 30,  9,  1, 17},
956 	{ 310, 12,   3,  0, 36, 13,  0, 30,  9,  1, 16},
957 	{ 300, 11,   3,  0, 36, 13,  0, 29,  8,  1, 16},
958 	{ 290, 11,   2,  0, 36, 13,  0, 29,  8,  1, 15},
959 	{ 280, 10,   2,  0, 35, 12,  0, 29,  8,  1, 15},
960 	{ 270, 10,   2,  0, 35, 12,  0, 28,  8,  0, 14},
961 	{ 260,  9,   2,  0, 35, 12,  0, 28,  8,  0, 14},
962 	{ 250,  9,   2,  0, 34, 12,  0, 28,  8,  0, 14},
963 	{ 240,  9,   2,  0, 34, 12,  0, 27,  8,  0, 13},
964 	{ 230,  8,   1,  0, 34, 10,  0, 27,  6,  0, 13},
965 	{ 220,  8,   1,  0, 33, 10,  0, 27,  6,  0, 12},
966 	{ 210,  7,   1,  0, 33, 10,  0, 26,  6,  0, 12},
967 	{ 200,  7,   1,  0, 33,  9,  0, 26,  5,  0, 11},
968 	{ 190,  7,   1,  0, 32,  9,  0, 25,  5,  0, 11},
969 	{ 180,  6,   1,  0, 32,  8,  0, 25,  5,  0, 10},
970 	{ 170,  6,   0,  0, 32,  8,  0, 25,  5,  0, 10},
971 	{ 160,  5,   0,  0, 31,  8,  0, 24,  4,  0,  9},
972 	{ 150,  5,   0,  0, 31,  8,  0, 24,  5,  0,  9},
973 	{ 140,  5,   0,  0, 31,  8,  0, 24,  5,  0,  8},
974 	{ 130,  4,   0,  0, 30,  6,  0, 23,  3,  0,  8},
975 	{ 120,  4,   0,  0, 30,  6,  0, 23,  3,  0,  7},
976 	{ 110,  3,   0,  0, 30,  6,  0, 23,  3,  0,  7},
977 	{ 100,  3,   0,  0, 29,  5,  0, 22,  2,  0,  6},
978 	{  90,  3,   0,  0, 29,  5,  0, 22,  2,  0,  6},
979 	{  80,  2,   0,  0, 28,  5,  0, 22,  2,  0,  5},
980 };
981 
samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy * samsung)982 static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung)
983 {
984 	regmap_write(samsung->regmap, BIAS_CON0, I_DEV_DIV_6 | I_RES_100_2UA);
985 	regmap_write(samsung->regmap, BIAS_CON1, I_VBG_SEL_820MV | I_BGR_VREF_820MV |
986 						 I_LADDER_1_00V);
987 	regmap_write(samsung->regmap, BIAS_CON2, REG_325M_325MV | REG_LP_400M_400MV |
988 						 REG_400M_400MV | REG_645M_645MV);
989 
990 	/* default output voltage select:
991 	 * dphy: 400mv
992 	 * cphy: 530mv
993 	 */
994 	regmap_update_bits(samsung->regmap, BIAS_CON4,
995 			   I_MUX_SEL_MASK, I_MUX_400MV);
996 }
997 
samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy * samsung)998 static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsung)
999 {
1000 	regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000));
1001 	regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0,
1002 			   PHY_ENABLE, PHY_ENABLE);
1003 
1004 	switch (samsung->lanes) {
1005 	case 4:
1006 		regmap_write(samsung->regmap, DPHY_MD3_GNR_CON1,
1007 			     T_PHY_READY(0x2000));
1008 		regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0,
1009 				   PHY_ENABLE, PHY_ENABLE);
1010 		fallthrough;
1011 	case 3:
1012 		regmap_write(samsung->regmap, COMBO_MD2_GNR_CON1,
1013 			     T_PHY_READY(0x2000));
1014 		regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0,
1015 				   PHY_ENABLE, PHY_ENABLE);
1016 		fallthrough;
1017 	case 2:
1018 		regmap_write(samsung->regmap, COMBO_MD1_GNR_CON1,
1019 			     T_PHY_READY(0x2000));
1020 		regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0,
1021 				   PHY_ENABLE, PHY_ENABLE);
1022 		fallthrough;
1023 	case 1:
1024 	default:
1025 		regmap_write(samsung->regmap, COMBO_MD0_GNR_CON1,
1026 			     T_PHY_READY(0x2000));
1027 		regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0,
1028 				   PHY_ENABLE, PHY_ENABLE);
1029 		break;
1030 	}
1031 }
1032 
samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy * samsung)1033 static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *samsung)
1034 {
1035 	switch (samsung->lanes) {
1036 	case 4:
1037 		regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0,
1038 				   PHY_ENABLE, 0);
1039 		fallthrough;
1040 	case 3:
1041 		regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0,
1042 				   PHY_ENABLE, 0);
1043 		fallthrough;
1044 	case 2:
1045 		regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0,
1046 				   PHY_ENABLE, 0);
1047 		fallthrough;
1048 	case 1:
1049 	default:
1050 		regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0,
1051 				   PHY_ENABLE, 0);
1052 		break;
1053 	}
1054 
1055 	regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, PHY_ENABLE, 0);
1056 }
1057 
samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy * samsung)1058 static void samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy *samsung)
1059 {
1060 	regmap_update_bits(samsung->regmap, PLL_CON0, S_MASK | P_MASK,
1061 			   S(samsung->pll.scaler) | P(samsung->pll.prediv));
1062 
1063 	if (samsung->pll.dsm < 0) {
1064 		u16 dsm_tmp;
1065 
1066 		/* Using opposite number subtraction to find complement */
1067 		dsm_tmp = abs(samsung->pll.dsm);
1068 		dsm_tmp = dsm_tmp - 1;
1069 		dsm_tmp ^= 0xffff;
1070 		regmap_write(samsung->regmap, PLL_CON1, dsm_tmp);
1071 	} else {
1072 		regmap_write(samsung->regmap, PLL_CON1, samsung->pll.dsm);
1073 	}
1074 
1075 	regmap_update_bits(samsung->regmap, PLL_CON2,
1076 			   M_MASK, M(samsung->pll.fbdiv));
1077 
1078 	if (samsung->pll.ssc_en) {
1079 		regmap_write(samsung->regmap, PLL_CON3,
1080 			     MRR(samsung->pll.mrr) | MFR(samsung->pll.mfr));
1081 		regmap_update_bits(samsung->regmap, PLL_CON4, SSCG_EN, SSCG_EN);
1082 	}
1083 
1084 	regmap_write(samsung->regmap, PLL_CON5, RESET_N_SEL | PLL_ENABLE_SEL);
1085 	regmap_write(samsung->regmap, PLL_CON7, PLL_LOCK_CNT(0xf000));
1086 	regmap_write(samsung->regmap, PLL_CON8, PLL_STB_CNT(0xf000));
1087 }
1088 
samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy * samsung)1089 static int samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy *samsung)
1090 {
1091 	u32 sts;
1092 	int ret;
1093 
1094 	regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, PLL_EN);
1095 
1096 	ret = regmap_read_poll_timeout(samsung->regmap, PLL_STAT0,
1097 				       sts, (sts & PLL_LOCK), 1000, 20000);
1098 	if (ret < 0)
1099 		dev_err(samsung->dev, "DC-PHY pll failed to lock\n");
1100 
1101 	return ret;
1102 }
1103 
samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy * samsung)1104 static void samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy *samsung)
1105 {
1106 	regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, 0);
1107 }
1108 
1109 static const struct samsung_mipi_dphy_timing *
samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy * samsung)1110 samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung)
1111 {
1112 	const struct samsung_mipi_dphy_timing *timings;
1113 	unsigned int num_timings;
1114 	unsigned int lane_mbps = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1115 	unsigned int i;
1116 
1117 	timings = samsung_mipi_dphy_timing_table;
1118 	num_timings = ARRAY_SIZE(samsung_mipi_dphy_timing_table);
1119 
1120 	for (i = num_timings; i > 1; i--)
1121 		if (lane_mbps <= timings[i - 1].max_lane_mbps)
1122 			break;
1123 
1124 	return &timings[i - 1];
1125 }
1126 
1127 static unsigned long
samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy * samsung,unsigned long prate,unsigned long rate,u8 * prediv,u16 * fbdiv,int * dsm,u8 * scaler)1128 samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung,
1129 				  unsigned long prate, unsigned long rate,
1130 				  u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler)
1131 {
1132 	u32 max_fout = samsung->pdata->dphy_tx_max_lane_kbps;
1133 	u64 best_freq = 0;
1134 	u64 fin, fvco, fout;
1135 	u8 min_prediv, max_prediv;
1136 	u8 _prediv, best_prediv = 1;
1137 	u16 _fbdiv, best_fbdiv = 1;
1138 	u8 _scaler, best_scaler = 0;
1139 	u32 min_delta = UINT_MAX;
1140 	long _dsm, best_dsm = 0;
1141 
1142 	if (!prate) {
1143 		dev_err(samsung->dev, "parent rate of PLL can not be zero\n");
1144 		return 0;
1145 	}
1146 
1147 	/*
1148 	 * The PLL output frequency can be calculated using a simple formula:
1149 	 * Fvco = ((m+k/65536) x 2 x Fin) / p
1150 	 * Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s)
1151 	 */
1152 	fin = div64_ul(prate, MSEC_PER_SEC);
1153 
1154 	while (!best_freq) {
1155 		fout = div64_ul(rate, MSEC_PER_SEC);
1156 		if (fout > max_fout)
1157 			fout = max_fout;
1158 
1159 		/* 0 ≤ S[2:0] ≤ 6 */
1160 		for (_scaler = 0; _scaler < 7; _scaler++) {
1161 			fvco = fout << _scaler;
1162 
1163 			/*
1164 			 * 2600MHz ≤ FVCO ≤ 6600MHz
1165 			 */
1166 			if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC)
1167 				continue;
1168 
1169 			/* 6MHz ≤ Fref(Fin / p) ≤ 30MHz */
1170 			min_prediv = DIV_ROUND_UP_ULL(fin, 30 * MSEC_PER_SEC);
1171 			max_prediv = DIV_ROUND_CLOSEST_ULL(fin, 6 * MSEC_PER_SEC);
1172 
1173 			for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
1174 				u64 delta, tmp;
1175 
1176 				_fbdiv = DIV_ROUND_CLOSEST_ULL(fvco * _prediv, 2 * fin);
1177 
1178 				 /* 64 ≤ M[9:0] ≤ 1023 */
1179 				if (_fbdiv < 64 || _fbdiv > 1023)
1180 					continue;
1181 
1182 				/* -32767 ≤ K[15:0] ≤ 32767 */
1183 				_dsm = ((_prediv * fvco) - (2 * _fbdiv * fin));
1184 				_dsm = DIV_ROUND_UP_ULL(_dsm << 15, fin);
1185 				if (abs(_dsm) > 32767)
1186 					continue;
1187 
1188 				tmp = DIV_ROUND_CLOSEST_ULL((_fbdiv * fin * 2 * 1000), _prediv);
1189 				tmp += DIV_ROUND_CLOSEST_ULL((_dsm * fin * 1000), _prediv << 15);
1190 
1191 				delta = abs(fvco * MSEC_PER_SEC - tmp);
1192 				if (delta < min_delta) {
1193 					best_prediv = _prediv;
1194 					best_fbdiv = _fbdiv;
1195 					best_dsm = _dsm;
1196 					best_scaler = _scaler;
1197 					min_delta = delta;
1198 					best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * MSEC_PER_SEC;
1199 				}
1200 			}
1201 		}
1202 
1203 		rate += 100 * MSEC_PER_SEC;
1204 	}
1205 
1206 	*prediv = best_prediv;
1207 	*fbdiv = best_fbdiv;
1208 	*dsm = (int)best_dsm & 0xffff;
1209 	*scaler = best_scaler;
1210 	dev_dbg(samsung->dev, "p: %d, m: %d, dsm:%ld, scaler: %d\n",
1211 		best_prediv, best_fbdiv, best_dsm, best_scaler);
1212 
1213 	return best_freq >> best_scaler;
1214 }
1215 
1216 static void
samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy * samsung)1217 samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung)
1218 {
1219 	const struct samsung_mipi_dphy_timing *timing;
1220 	unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1221 	u32 val, res_up, res_down;
1222 
1223 	timing = samsung_mipi_dphy_get_timing(samsung);
1224 	regmap_write(samsung->regmap, DPHY_MC_GNR_CON0, 0xf000);
1225 
1226 	/*
1227 	 * The Drive-Strength / Voltage-Amplitude is adjusted by setting
1228 	 * the Driver-Up Resistor and Driver-Down Resistor.
1229 	 */
1230 	res_up = samsung->pdata->dphy_hs_drv_res_cfg->clk_hs_drv_up_ohm;
1231 	res_down = samsung->pdata->dphy_hs_drv_res_cfg->clk_hs_drv_down_ohm;
1232 	val = EDGE_CON(7) | EDGE_CON_DIR(0) | EDGE_CON_EN |
1233 	      RES_UP(res_up) | RES_DN(res_down);
1234 	regmap_write(samsung->regmap, DPHY_MC_ANA_CON0, val);
1235 
1236 	if (lane_hs_rate >= 4500)
1237 		regmap_write(samsung->regmap, DPHY_MC_ANA_CON1, 0x0001);
1238 
1239 	val = 0;
1240 	/*
1241 	 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
1242 	 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
1243 	 */
1244 	if (lane_hs_rate < 1500)
1245 		val = HSTX_CLK_SEL;
1246 
1247 	val |= T_LPX(timing->lpx);
1248 	/*  T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
1249 	regmap_write(samsung->regmap, DPHY_MC_TIME_CON0, val);
1250 
1251 	val = T_CLK_ZERO(timing->clk_zero) | T_CLK_PREPARE(timing->clk_prepare);
1252 	regmap_write(samsung->regmap, DPHY_MC_TIME_CON1, val);
1253 
1254 	val = T_HS_EXIT(timing->hs_exit) | T_CLK_TRAIL(timing->clk_trail_eot);
1255 	regmap_write(samsung->regmap, DPHY_MC_TIME_CON2, val);
1256 
1257 	val = T_CLK_POST(timing->clk_post);
1258 	regmap_write(samsung->regmap, DPHY_MC_TIME_CON3, val);
1259 
1260 	/* Escape Clock is 20.00MHz */
1261 	regmap_write(samsung->regmap, DPHY_MC_TIME_CON4, 0x1f4);
1262 
1263 	/*
1264 	 * skew calibration should be off, if the operation data rate is
1265 	 * under 1.5Gbps or equal to 1.5Gbps.
1266 	 */
1267 	if (lane_hs_rate > 1500)
1268 		regmap_write(samsung->regmap, DPHY_MC_DESKEW_CON0, 0x9cb1);
1269 }
1270 
1271 static void
samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy * samsung)1272 samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung)
1273 {
1274 	const struct samsung_mipi_dphy_timing *timing;
1275 	unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1276 	u32 val, res_up, res_down;
1277 
1278 	timing = samsung_mipi_dphy_get_timing(samsung);
1279 
1280 	/*
1281 	 * The Drive-Strength / Voltage-Amplitude is adjusted by adjusting the
1282 	 *  Driver-Up Resistor and Driver-Down Resistor.
1283 	 */
1284 	res_up = samsung->pdata->dphy_hs_drv_res_cfg->data_hs_drv_up_ohm;
1285 	res_down = samsung->pdata->dphy_hs_drv_res_cfg->data_hs_drv_down_ohm;
1286 	val = EDGE_CON(7) | EDGE_CON_DIR(0) | EDGE_CON_EN |
1287 	      RES_UP(res_up) | RES_DN(res_down);
1288 	regmap_write(samsung->regmap, COMBO_MD0_ANA_CON0, val);
1289 	regmap_write(samsung->regmap, COMBO_MD1_ANA_CON0, val);
1290 	regmap_write(samsung->regmap, COMBO_MD2_ANA_CON0, val);
1291 	regmap_write(samsung->regmap, DPHY_MD3_ANA_CON0, val);
1292 
1293 	if (lane_hs_rate >= 4500) {
1294 		regmap_write(samsung->regmap, COMBO_MD0_ANA_CON1, 0x0001);
1295 		regmap_write(samsung->regmap, COMBO_MD1_ANA_CON1, 0x0001);
1296 		regmap_write(samsung->regmap, COMBO_MD2_ANA_CON1, 0x0001);
1297 		regmap_write(samsung->regmap, DPHY_MD3_ANA_CON1, 0x0001);
1298 	}
1299 
1300 	val = 0;
1301 	/*
1302 	 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
1303 	 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
1304 	 */
1305 	if (lane_hs_rate < 1500)
1306 		val = HSTX_CLK_SEL;
1307 
1308 	val |= T_LPX(timing->lpx);
1309 	/*  T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
1310 	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, val);
1311 	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, val);
1312 	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, val);
1313 	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON0, val);
1314 
1315 	val = T_HS_ZERO(timing->hs_zero) | T_HS_PREPARE(timing->hs_prepare);
1316 	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON1, val);
1317 	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON1, val);
1318 	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON1, val);
1319 	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON1, val);
1320 
1321 	val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->hs_trail_eot);
1322 	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON2, val);
1323 	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON2, val);
1324 	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON2, val);
1325 	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON2, val);
1326 
1327 	/* TTA-GET/TTA-GO Timing Counter register use default value */
1328 	val = T_TA_GET(0x3) | T_TA_GO(0x0);
1329 	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON3, val);
1330 	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON3, val);
1331 	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON3, val);
1332 	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON3, val);
1333 
1334 	/* Escape Clock is 20.00MHz */
1335 	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON4, 0x1f4);
1336 	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON4, 0x1f4);
1337 	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON4, 0x1f4);
1338 	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON4, 0x1f4);
1339 }
1340 
samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy * samsung)1341 static int samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung)
1342 {
1343 	int ret;
1344 
1345 	reset_control_assert(samsung->m_phy_rst);
1346 
1347 	samsung_mipi_dcphy_bias_block_enable(samsung);
1348 	samsung_mipi_dcphy_pll_configure(samsung);
1349 	samsung_mipi_dphy_clk_lane_timing_init(samsung);
1350 	samsung_mipi_dphy_data_lane_timing_init(samsung);
1351 	ret = samsung_mipi_dcphy_pll_enable(samsung);
1352 	if (ret < 0)
1353 		return ret;
1354 
1355 	samsung_mipi_dphy_lane_enable(samsung);
1356 
1357 	reset_control_deassert(samsung->m_phy_rst);
1358 
1359 	/* The TSKEWCAL maximum is 100 µsec
1360 	 * at initial calibration.
1361 	 */
1362 	usleep_range(100, 110);
1363 
1364 	return 0;
1365 }
1366 
samsung_mipi_dcphy_power_on(struct phy * phy)1367 static int samsung_mipi_dcphy_power_on(struct phy *phy)
1368 {
1369 	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1370 
1371 	reset_control_assert(samsung->apb_rst);
1372 	udelay(1);
1373 	reset_control_deassert(samsung->apb_rst);
1374 
1375 	switch (samsung->type) {
1376 	case PHY_TYPE_DPHY:
1377 		return samsung_mipi_dphy_power_on(samsung);
1378 	default:
1379 		/* CPHY part to be implemented later */
1380 		return -EOPNOTSUPP;
1381 	}
1382 
1383 	return 0;
1384 }
1385 
samsung_mipi_dcphy_power_off(struct phy * phy)1386 static int samsung_mipi_dcphy_power_off(struct phy *phy)
1387 {
1388 	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1389 
1390 	switch (samsung->type) {
1391 	case PHY_TYPE_DPHY:
1392 		samsung_mipi_dphy_lane_disable(samsung);
1393 		break;
1394 	default:
1395 		/* CPHY part to be implemented later */
1396 		return -EOPNOTSUPP;
1397 	}
1398 
1399 	samsung_mipi_dcphy_pll_disable(samsung);
1400 
1401 	return 0;
1402 }
1403 
1404 static int
samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy * samsung,u8 * mfr,u8 * mrr)1405 samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy *samsung,
1406 					   u8 *mfr, u8 *mrr)
1407 {
1408 	unsigned long fin = div64_ul(clk_get_rate(samsung->ref_clk), MSEC_PER_SEC);
1409 	u16 prediv = samsung->pll.prediv;
1410 	u16 fbdiv = samsung->pll.fbdiv;
1411 	u16 min_mfr, max_mfr;
1412 	u16 _mfr, best_mfr = 0;
1413 	u16 mr, _mrr, best_mrr = 0;
1414 
1415 	/* 20KHz ≤ MF ≤ 150KHz */
1416 	max_mfr = DIV_ROUND_UP(fin, (20 * prediv) << 5);
1417 	min_mfr = div64_ul(fin, ((150 * prediv) << 5));
1418 	/*0 ≤ mfr ≤ 255 */
1419 	if (max_mfr > 256)
1420 		max_mfr = 256;
1421 
1422 	for (_mfr = min_mfr; _mfr < max_mfr; _mfr++) {
1423 		/* 1 ≤ mrr ≤ 31 */
1424 		for (_mrr = 1; _mrr < 32; _mrr++) {
1425 			mr = DIV_ROUND_UP(_mfr * _mrr * 100, fbdiv << 6);
1426 			/* 0 ≤ MR ≤ 5% */
1427 			if (mr > 5)
1428 				continue;
1429 
1430 			if (_mfr * _mrr < 513) {
1431 				best_mfr = _mfr;
1432 				best_mrr = _mrr;
1433 				break;
1434 			}
1435 		}
1436 	}
1437 
1438 	if (best_mrr) {
1439 		*mfr = best_mfr & 0xff;
1440 		*mrr = best_mrr & 0x3f;
1441 	} else {
1442 		dev_err(samsung->dev, "failed to calc ssc parameter mfr and mrr\n");
1443 		return -EINVAL;
1444 	}
1445 
1446 	return 0;
1447 }
1448 
1449 static void
samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy * samsung,unsigned long long rate)1450 samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy *samsung,
1451 				 unsigned long long rate)
1452 {
1453 	unsigned long prate = clk_get_rate(samsung->ref_clk);
1454 	unsigned long fout;
1455 	u8 scaler = 0, mfr = 0, mrr = 0;
1456 	u16 fbdiv = 0;
1457 	u8 prediv = 1;
1458 	int dsm = 0;
1459 	int ret;
1460 
1461 	fout = samsung_mipi_dcphy_pll_round_rate(samsung, prate, rate,
1462 						 &prediv, &fbdiv, &dsm,
1463 						 &scaler);
1464 
1465 	dev_dbg(samsung->dev, "%s: fin=%lu, req_rate=%llu\n",
1466 		__func__, prate, rate);
1467 	dev_dbg(samsung->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n",
1468 		__func__, fout, prediv, fbdiv);
1469 
1470 	samsung->pll.prediv = prediv;
1471 	samsung->pll.fbdiv = fbdiv;
1472 	samsung->pll.dsm = dsm;
1473 	samsung->pll.scaler = scaler;
1474 	samsung->pll.rate = fout;
1475 
1476 	/*
1477 	 * All DPHY 2.0 compliant Transmitters shall support SSC operating above
1478 	 * 2.5 Gbps
1479 	 */
1480 	if (fout > 2500000000LL) {
1481 		ret = samsung_mipi_dcphy_pll_ssc_modulation_calc(samsung,
1482 								 &mfr, &mrr);
1483 		if (!ret) {
1484 			samsung->pll.ssc_en = true;
1485 			samsung->pll.mfr = mfr;
1486 			samsung->pll.mrr = mrr;
1487 		}
1488 	}
1489 }
1490 
samsung_mipi_dcphy_configure(struct phy * phy,union phy_configure_opts * opts)1491 static int samsung_mipi_dcphy_configure(struct phy *phy,
1492 					union phy_configure_opts *opts)
1493 {
1494 	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1495 	unsigned long long target_rate = opts->mipi_dphy.hs_clk_rate;
1496 
1497 	samsung->lanes = opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lanes;
1498 
1499 	samsung_mipi_dcphy_pll_calc_rate(samsung, target_rate);
1500 	opts->mipi_dphy.hs_clk_rate = samsung->pll.rate;
1501 
1502 	return 0;
1503 }
1504 
samsung_mipi_dcphy_init(struct phy * phy)1505 static int samsung_mipi_dcphy_init(struct phy *phy)
1506 {
1507 	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1508 
1509 	return pm_runtime_resume_and_get(samsung->dev);
1510 }
1511 
samsung_mipi_dcphy_exit(struct phy * phy)1512 static int samsung_mipi_dcphy_exit(struct phy *phy)
1513 {
1514 	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1515 
1516 	return pm_runtime_put(samsung->dev);
1517 }
1518 
1519 static const struct phy_ops samsung_mipi_dcphy_ops = {
1520 	.configure = samsung_mipi_dcphy_configure,
1521 	.power_on  = samsung_mipi_dcphy_power_on,
1522 	.power_off = samsung_mipi_dcphy_power_off,
1523 	.init = samsung_mipi_dcphy_init,
1524 	.exit = samsung_mipi_dcphy_exit,
1525 	.owner	   = THIS_MODULE,
1526 };
1527 
1528 static const struct regmap_config samsung_mipi_dcphy_regmap_config = {
1529 	.name = "dcphy",
1530 	.reg_bits = 32,
1531 	.val_bits = 32,
1532 	.reg_stride = 4,
1533 	.max_register = 0x10000,
1534 };
1535 
samsung_mipi_dcphy_xlate(struct device * dev,const struct of_phandle_args * args)1536 static struct phy *samsung_mipi_dcphy_xlate(struct device *dev,
1537 					    const struct of_phandle_args *args)
1538 {
1539 	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
1540 
1541 	if (args->args_count != 1) {
1542 		dev_err(dev, "invalid number of arguments\n");
1543 		return ERR_PTR(-EINVAL);
1544 	}
1545 
1546 	if (samsung->type != PHY_NONE && samsung->type != args->args[0])
1547 		dev_warn(dev, "phy type select %d overwriting type %d\n",
1548 			 args->args[0], samsung->type);
1549 
1550 	samsung->type = args->args[0];
1551 
1552 	return samsung->phy;
1553 }
1554 
samsung_mipi_dcphy_probe(struct platform_device * pdev)1555 static int samsung_mipi_dcphy_probe(struct platform_device *pdev)
1556 {
1557 	struct device *dev = &pdev->dev;
1558 	struct device_node *np = dev->of_node;
1559 	struct samsung_mipi_dcphy *samsung;
1560 	struct phy_provider *phy_provider;
1561 	struct resource *res;
1562 	void __iomem *regs;
1563 	int ret;
1564 
1565 	samsung = devm_kzalloc(dev, sizeof(*samsung), GFP_KERNEL);
1566 	if (!samsung)
1567 		return -ENOMEM;
1568 
1569 	samsung->dev = dev;
1570 	samsung->pdata = device_get_match_data(dev);
1571 	platform_set_drvdata(pdev, samsung);
1572 
1573 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1574 	regs = devm_ioremap_resource(dev, res);
1575 	if (IS_ERR(regs))
1576 		return PTR_ERR(regs);
1577 
1578 	samsung->regmap = devm_regmap_init_mmio(dev, regs,
1579 						&samsung_mipi_dcphy_regmap_config);
1580 	if (IS_ERR(samsung->regmap))
1581 		return dev_err_probe(dev, PTR_ERR(samsung->regmap), "Failed to init regmap\n");
1582 
1583 	samsung->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
1584 	if (IS_ERR(samsung->grf_regmap))
1585 		return dev_err_probe(dev, PTR_ERR(samsung->grf_regmap),
1586 				     "Unable to get rockchip,grf\n");
1587 
1588 	samsung->ref_clk = devm_clk_get(dev, "ref");
1589 	if (IS_ERR(samsung->ref_clk))
1590 		return dev_err_probe(dev, PTR_ERR(samsung->ref_clk),
1591 				     "Failed to get reference clock\n");
1592 
1593 	samsung->pclk = devm_clk_get(dev, "pclk");
1594 	if (IS_ERR(samsung->pclk))
1595 		return dev_err_probe(dev, PTR_ERR(samsung->pclk), "Failed to get pclk\n");
1596 
1597 	samsung->m_phy_rst = devm_reset_control_get(dev, "m_phy");
1598 	if (IS_ERR(samsung->m_phy_rst))
1599 		return dev_err_probe(dev, PTR_ERR(samsung->m_phy_rst),
1600 				     "Failed to get system m_phy_rst control\n");
1601 
1602 	samsung->s_phy_rst = devm_reset_control_get(dev, "s_phy");
1603 	if (IS_ERR(samsung->s_phy_rst))
1604 		return dev_err_probe(dev, PTR_ERR(samsung->s_phy_rst),
1605 				     "Failed to get system s_phy_rst control\n");
1606 
1607 	samsung->apb_rst = devm_reset_control_get(dev, "apb");
1608 	if (IS_ERR(samsung->apb_rst))
1609 		return dev_err_probe(dev, PTR_ERR(samsung->apb_rst),
1610 				     "Failed to get system apb_rst control\n");
1611 
1612 	samsung->grf_apb_rst = devm_reset_control_get(dev, "grf");
1613 	if (IS_ERR(samsung->grf_apb_rst))
1614 		return dev_err_probe(dev, PTR_ERR(samsung->grf_apb_rst),
1615 				     "Failed to get system grf_apb_rst control\n");
1616 
1617 	samsung->phy = devm_phy_create(dev, NULL, &samsung_mipi_dcphy_ops);
1618 	if (IS_ERR(samsung->phy))
1619 		return dev_err_probe(dev, PTR_ERR(samsung->phy), "Failed to create MIPI DC-PHY\n");
1620 
1621 	phy_set_drvdata(samsung->phy, samsung);
1622 
1623 	ret = devm_pm_runtime_enable(dev);
1624 	if (ret)
1625 		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
1626 
1627 	phy_provider = devm_of_phy_provider_register(dev, samsung_mipi_dcphy_xlate);
1628 	if (IS_ERR(phy_provider))
1629 		return dev_err_probe(dev, PTR_ERR(phy_provider),
1630 				     "Failed to register phy provider\n");
1631 
1632 	return 0;
1633 }
1634 
samsung_mipi_dcphy_runtime_suspend(struct device * dev)1635 static __maybe_unused int samsung_mipi_dcphy_runtime_suspend(struct device *dev)
1636 {
1637 	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
1638 
1639 	clk_disable_unprepare(samsung->ref_clk);
1640 	clk_disable_unprepare(samsung->pclk);
1641 
1642 	return 0;
1643 }
1644 
samsung_mipi_dcphy_runtime_resume(struct device * dev)1645 static __maybe_unused int samsung_mipi_dcphy_runtime_resume(struct device *dev)
1646 {
1647 	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
1648 	int ret;
1649 
1650 	ret = clk_prepare_enable(samsung->pclk);
1651 	if (ret) {
1652 		dev_err(samsung->dev, "Failed to enable pclk, %d\n", ret);
1653 		return ret;
1654 	}
1655 
1656 	ret = clk_prepare_enable(samsung->ref_clk);
1657 	if (ret) {
1658 		dev_err(samsung->dev, "Failed to enable reference clock, %d\n", ret);
1659 		clk_disable_unprepare(samsung->pclk);
1660 		return ret;
1661 	}
1662 
1663 	return 0;
1664 }
1665 
1666 static const struct dev_pm_ops samsung_mipi_dcphy_pm_ops = {
1667 	SET_RUNTIME_PM_OPS(samsung_mipi_dcphy_runtime_suspend,
1668 			   samsung_mipi_dcphy_runtime_resume, NULL)
1669 };
1670 
1671 static const struct hs_drv_res_cfg rk3576_dphy_hs_drv_res_cfg = {
1672 	.clk_hs_drv_up_ohm = STRENGTH_52_OHM,
1673 	.clk_hs_drv_down_ohm = STRENGTH_52_OHM,
1674 	.data_hs_drv_up_ohm = STRENGTH_39_OHM,
1675 	.data_hs_drv_down_ohm = STRENGTH_39_OHM,
1676 };
1677 
1678 static const struct hs_drv_res_cfg rk3588_dphy_hs_drv_res_cfg = {
1679 	.clk_hs_drv_up_ohm = STRENGTH_34_OHM,
1680 	.clk_hs_drv_down_ohm = STRENGTH_34_OHM,
1681 	.data_hs_drv_up_ohm = STRENGTH_43_OHM,
1682 	.data_hs_drv_down_ohm = STRENGTH_43_OHM,
1683 };
1684 
1685 static const struct samsung_mipi_dcphy_plat_data rk3576_samsung_mipi_dcphy_plat_data = {
1686 	.dphy_hs_drv_res_cfg = &rk3576_dphy_hs_drv_res_cfg,
1687 	.dphy_tx_max_lane_kbps = 2500000L,
1688 };
1689 
1690 static const struct samsung_mipi_dcphy_plat_data rk3588_samsung_mipi_dcphy_plat_data = {
1691 	.dphy_hs_drv_res_cfg = &rk3588_dphy_hs_drv_res_cfg,
1692 	.dphy_tx_max_lane_kbps = 4500000L,
1693 };
1694 
1695 static const struct of_device_id samsung_mipi_dcphy_of_match[] = {
1696 	{
1697 		.compatible = "rockchip,rk3576-mipi-dcphy",
1698 		.data = &rk3576_samsung_mipi_dcphy_plat_data,
1699 	}, {
1700 		.compatible = "rockchip,rk3588-mipi-dcphy",
1701 		.data = &rk3588_samsung_mipi_dcphy_plat_data,
1702 	},
1703 	{ /* sentinel */ }
1704 };
1705 MODULE_DEVICE_TABLE(of, samsung_mipi_dcphy_of_match);
1706 
1707 static struct platform_driver samsung_mipi_dcphy_driver = {
1708 	.driver = {
1709 		.name = "samsung-mipi-dcphy",
1710 		.of_match_table	= samsung_mipi_dcphy_of_match,
1711 		.pm = &samsung_mipi_dcphy_pm_ops,
1712 	},
1713 	.probe	= samsung_mipi_dcphy_probe,
1714 };
1715 module_platform_driver(samsung_mipi_dcphy_driver);
1716 
1717 MODULE_AUTHOR("Guochun Huang <hero.huang@rock-chips.com>");
1718 MODULE_DESCRIPTION("Samsung MIPI DCPHY Driver");
1719 MODULE_LICENSE("GPL");
1720