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