1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) Rockchip Electronics Co.Ltd
4 * Author:
5 * Guochun Huang <hero.huang@rock-chips.com>
6 */
7
8 #include <linux/clk.h>
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/phy/phy.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/reset.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-fwnode.h>
21 #include <media/v4l2-subdev.h>
22 #include <media/v4l2-device.h>
23 #include "phy-rockchip-csi2-dphy-common.h"
24 #include "phy-rockchip-samsung-dcphy.h"
25
26 #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
27 #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
28
29 #define BIAS_CON0 0x0000
30 #define BIAS_CON1 0x0004
31 #define BIAS_CON2 0x0008
32 #define BIAS_CON4 0x0010
33 #define I_MUX_SEL_MASK GENMASK(6, 5)
34 #define I_MUX_SEL(x) UPDATE(x, 6, 5)
35
36 #define PLL_CON0 0x0100
37 #define PLL_EN BIT(12)
38 #define S_MASK GENMASK(10, 8)
39 #define S(x) UPDATE(x, 10, 8)
40 #define P_MASK GENMASK(5, 0)
41 #define P(x) UPDATE(x, 5, 0)
42 #define PLL_CON1 0x0104
43 #define PLL_CON2 0x0108
44 #define M_MASK GENMASK(9, 0)
45 #define M(x) UPDATE(x, 9, 0)
46 #define PLL_CON3 0x010c
47 #define MRR_MASK GENMASK(13, 8)
48 #define MRR(x) UPDATE(x, 13, 8)
49 #define MFR_MASK GENMASK(7, 0)
50 #define MFR(x) UPDATE(x, 7, 0)
51 #define PLL_CON4 0x0110
52 #define SSCG_EN BIT(11)
53 #define PLL_CON5 0x0114
54 #define RESET_N_SEL BIT(10)
55 #define PLL_ENABLE_SEL BIT(8)
56 #define PLL_CON6 0x0118
57 #define PLL_CON7 0x011c
58 #define PLL_LOCK_CNT(x) UPDATE(x, 15, 0)
59 #define PLL_CON8 0x0120
60 #define PLL_STB_CNT(x) UPDATE(x, 15, 0)
61 #define PLL_STAT0 0x0140
62 #define PLL_LOCK BIT(0)
63
64 #define DPHY_MC_GNR_CON0 0x0300
65 #define PHY_READY BIT(1)
66 #define PHY_ENABLE BIT(0)
67 #define DPHY_MC_GNR_CON1 0x0304
68 #define T_PHY_READY(x) UPDATE(x, 15, 0)
69 #define DPHY_MC_ANA_CON0 0x0308
70 #define DPHY_MC_ANA_CON1 0x030c
71 #define DPHY_MC_ANA_CON2 0x0310
72 #define HS_VREG_AMP_ICON(x) UPDATE(x, 1, 0)
73 #define DPHY_MC_TIME_CON0 0x0330
74 #define HSTX_CLK_SEL BIT(12)
75 #define T_LPX(x) UPDATE(x, 11, 4)
76 #define DPHY_MC_TIME_CON1 0x0334
77 #define T_CLK_ZERO(x) UPDATE(x, 15, 8)
78 #define T_CLK_PREPARE(x) UPDATE(x, 7, 0)
79 #define DPHY_MC_TIME_CON2 0x0338
80 #define T_HS_EXIT(x) UPDATE(x, 15, 8)
81 #define T_CLK_TRAIL(x) UPDATE(x, 7, 0)
82 #define DPHY_MC_TIME_CON3 0x033c
83 #define T_CLK_POST(x) UPDATE(x, 7, 0)
84 #define DPHY_MC_TIME_CON4 0x0340
85 #define T_ULPS_EXIT(x) UPDATE(x, 9, 0)
86 #define DPHY_MC_DESKEW_CON0 0x0350
87 #define SKEW_CAL_RUN_TIME(x) UPDATE(x, 15, 12)
88
89 #define SKEW_CAL_INIT_RUN_TIME(x) UPDATE(x, 11, 8)
90 #define SKEW_CAL_INIT_WAIT_TIME(x) UPDATE(x, 7, 4)
91 #define SKEW_CAL_EN BIT(0)
92
93 #define COMBO_MD0_GNR_CON0 0x0400
94 #define COMBO_MD0_GNR_CON1 0x0404
95 #define COMBO_MD0_ANA_CON0 0x0408
96 #define COMBO_MD0_ANA_CON1 0x040C
97 #define COMBO_MD0_ANA_CON2 0x0410
98
99 #define COMBO_MD0_TIME_CON0 0x0430
100 #define COMBO_MD0_TIME_CON1 0x0434
101 #define COMBO_MD0_TIME_CON2 0x0438
102 #define COMBO_MD0_TIME_CON3 0x043C
103 #define COMBO_MD0_TIME_CON4 0x0440
104 #define COMBO_MD0_DATA_CON0 0x0444
105
106 #define COMBO_MD1_GNR_CON0 0x0500
107 #define COMBO_MD1_GNR_CON1 0x0504
108 #define COMBO_MD1_ANA_CON0 0x0508
109 #define COMBO_MD1_ANA_CON1 0x050c
110 #define COMBO_MD1_ANA_CON2 0x0510
111 #define COMBO_MD1_TIME_CON0 0x0530
112 #define COMBO_MD1_TIME_CON1 0x0534
113 #define COMBO_MD1_TIME_CON2 0x0538
114 #define COMBO_MD1_TIME_CON3 0x053C
115 #define COMBO_MD1_TIME_CON4 0x0540
116 #define COMBO_MD1_DATA_CON0 0x0544
117
118 #define COMBO_MD2_GNR_CON0 0x0600
119 #define COMBO_MD2_GNR_CON1 0x0604
120 #define COMBO_MD2_ANA_CON0 0X0608
121 #define COMBO_MD2_ANA_CON1 0X060C
122 #define COMBO_MD2_ANA_CON2 0X0610
123 #define COMBO_MD2_TIME_CON0 0x0630
124 #define COMBO_MD2_TIME_CON1 0x0634
125 #define COMBO_MD2_TIME_CON2 0x0638
126 #define COMBO_MD2_TIME_CON3 0x063C
127 #define COMBO_MD2_TIME_CON4 0x0640
128 #define COMBO_MD2_DATA_CON0 0x0644
129
130 #define DPHY_MD3_GNR_CON0 0x0700
131 #define DPHY_MD3_GNR_CON1 0x0704
132 #define DPHY_MD3_ANA_CON0 0X0708
133 #define DPHY_MD3_ANA_CON1 0X070C
134 #define DPHY_MD3_ANA_CON2 0X0710
135 #define DPHY_MD3_TIME_CON0 0x0730
136 #define DPHY_MD3_TIME_CON1 0x0734
137 #define DPHY_MD3_TIME_CON2 0x0738
138 #define DPHY_MD3_TIME_CON3 0x073C
139 #define DPHY_MD3_TIME_CON4 0x0740
140 #define DPHY_MD3_DATA_CON0 0x0744
141
142 #define T_LP_EXIT_SKEW(x) UPDATE(x, 3, 2)
143 #define T_LP_ENTRY_SKEW(x) UPDATE(x, 1, 0)
144 #define T_HS_ZERO(x) UPDATE(x, 15, 8)
145 #define T_HS_PREPARE(x) UPDATE(x, 7, 0)
146 #define T_HS_EXIT(x) UPDATE(x, 15, 8)
147 #define T_HS_TRAIL(x) UPDATE(x, 7, 0)
148 #define T_TA_GET(x) UPDATE(x, 7, 4)
149 #define T_TA_GO(x) UPDATE(x, 3, 0)
150
151 /* MIPI_CDPHY_GRF registers */
152 #define MIPI_DCPHY_GRF_CON0 0x0000
153 #define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3)
154 #define M_CPHY_MODE HIWORD_UPDATE(1, 0, 0)
155
156 #define MAX_DPHY_BW 4500000L
157 #define MAX_CPHY_BW 2000000L
158
159 #define RX_CLK_THS_SETTLE (0xb30)
160 #define RX_LANE0_THS_SETTLE (0xC30)
161 #define RX_LANE0_ERR_SOT_SYNC (0xC34)
162 #define RX_LANE1_THS_SETTLE (0xD30)
163 #define RX_LANE1_ERR_SOT_SYNC (0xD34)
164 #define RX_LANE2_THS_SETTLE (0xE30)
165 #define RX_LANE2_ERR_SOT_SYNC (0xE34)
166 #define RX_LANE3_THS_SETTLE (0xF30)
167 #define RX_LANE3_ERR_SOT_SYNC (0xF34)
168 #define RX_CLK_LANE_ENABLE (0xB00)
169 #define RX_DATA_LANE0_ENABLE (0xC00)
170 #define RX_DATA_LANE1_ENABLE (0xD00)
171 #define RX_DATA_LANE2_ENABLE (0xE00)
172 #define RX_DATA_LANE3_ENABLE (0xF00)
173
174 #define RX_S0C_GNR_CON1 (0xB04)
175 #define RX_S0C_ANA_CON1 (0xB0c)
176 #define RX_S0C_ANA_CON2 (0xB10)
177 #define RX_S0C_ANA_CON3 (0xB14)
178 #define RX_COMBO_S0D0_GNR_CON1 (0xC04)
179 #define RX_COMBO_S0D0_ANA_CON1 (0xC0c)
180 #define RX_COMBO_S0D0_ANA_CON2 (0xC10)
181 #define RX_COMBO_S0D0_ANA_CON3 (0xC14)
182 #define RX_COMBO_S0D0_ANA_CON6 (0xC20)
183 #define RX_COMBO_S0D0_ANA_CON7 (0xC24)
184 #define RX_COMBO_S0D0_DESKEW_CON0 (0xC40)
185 #define RX_COMBO_S0D0_DESKEW_CON2 (0xC48)
186 #define RX_COMBO_S0D0_DESKEW_CON4 (0xC50)
187 #define RX_COMBO_S0D0_CRC_CON1 (0xC64)
188 #define RX_COMBO_S0D0_CRC_CON2 (0xC68)
189 #define RX_COMBO_S0D1_GNR_CON1 (0xD04)
190 #define RX_COMBO_S0D1_ANA_CON1 (0xD0c)
191 #define RX_COMBO_S0D1_ANA_CON2 (0xD10)
192 #define RX_COMBO_S0D1_ANA_CON3 (0xD14)
193 #define RX_COMBO_S0D1_ANA_CON6 (0xD20)
194 #define RX_COMBO_S0D1_ANA_CON7 (0xD24)
195 #define RX_COMBO_S0D1_DESKEW_CON0 (0xD40)
196 #define RX_COMBO_S0D1_DESKEW_CON2 (0xD48)
197 #define RX_COMBO_S0D1_DESKEW_CON4 (0xD50)
198 #define RX_COMBO_S0D1_CRC_CON1 (0xD64)
199 #define RX_COMBO_S0D1_CRC_CON2 (0xD68)
200 #define RX_COMBO_S0D2_GNR_CON1 (0xE04)
201 #define RX_COMBO_S0D2_ANA_CON1 (0xE0c)
202 #define RX_COMBO_S0D2_ANA_CON2 (0xE10)
203 #define RX_COMBO_S0D2_ANA_CON3 (0xE14)
204 #define RX_COMBO_S0D2_ANA_CON6 (0xE20)
205 #define RX_COMBO_S0D2_ANA_CON7 (0xE24)
206 #define RX_COMBO_S0D2_DESKEW_CON0 (0xE40)
207 #define RX_COMBO_S0D2_DESKEW_CON2 (0xE48)
208 #define RX_COMBO_S0D2_DESKEW_CON4 (0xE50)
209 #define RX_COMBO_S0D2_CRC_CON1 (0xE64)
210 #define RX_COMBO_S0D2_CRC_CON2 (0xE68)
211 #define RX_S0D3_GNR_CON1 (0xF04)
212 #define RX_S0D3_ANA_CON1 (0xF0c)
213 #define RX_S0D3_ANA_CON2 (0xF10)
214 #define RX_S0D3_ANA_CON3 (0xF14)
215 #define RX_S0D3_DESKEW_CON0 (0xF40)
216 #define RX_S0D3_DESKEW_CON2 (0xF48)
217 #define RX_S0D3_DESKEW_CON4 (0xF50)
218
219 struct samsung_mipi_dphy_timing {
220 unsigned int max_lane_mbps;
221 u8 clk_prepare;
222 u8 clk_zero;
223 u8 clk_post;
224 u8 clk_trail_eot;
225 u8 hs_prepare;
226 u8 hs_zero;
227 u8 hs_trail_eot;
228 u8 lpx;
229 u8 hs_exit;
230 u8 hs_settle;
231 };
232
233 struct samsung_mipi_cphy_timing {
234 unsigned int max_lane_msps;
235 u8 prepare_3;
236 u8 prebegin_3;
237 u8 post_3;
238 u8 lpx;
239 u8 hs_exit;
240 u8 settle_3;
241 };
242
243 static const
244 struct samsung_mipi_dphy_timing samsung_mipi_dphy_timing_table[] = {
245 {6500, 32, 117, 31, 28, 30, 56, 27, 24, 44, 37},
246 {6490, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
247 {6480, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
248 {6470, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
249 {6460, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
250 {6450, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
251 {6440, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
252 {6430, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
253 {6420, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
254 {6410, 31, 116, 31, 27, 30, 55, 27, 24, 44, 37},
255 {6400, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
256 {6390, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
257 {6380, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
258 {6370, 31, 115, 30, 27, 30, 55, 26, 23, 43, 36},
259 {6360, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
260 {6350, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
261 {6340, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
262 {6330, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
263 {6320, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
264 {6310, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
265 {6300, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
266 {6290, 31, 113, 30, 27, 29, 54, 26, 23, 43, 36},
267 {6280, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
268 {6270, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
269 {6260, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
270 {6250, 31, 112, 30, 27, 29, 54, 26, 23, 42, 36},
271 {6240, 30, 113, 30, 27, 29, 54, 26, 23, 42, 36},
272 {6230, 30, 112, 30, 27, 29, 54, 26, 23, 42, 35},
273 {6220, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
274 {6210, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
275 {6200, 30, 112, 29, 27, 29, 53, 26, 23, 42, 35},
276 {6190, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
277 {6180, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
278 {6170, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
279 {6160, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
280 {6150, 30, 110, 29, 26, 29, 53, 26, 23, 42, 35},
281 {6140, 30, 110, 29, 26, 29, 52, 26, 23, 42, 35},
282 {6130, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
283 {6120, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
284 {6110, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
285 {6100, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
286 {6090, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
287 {6080, 30, 109, 29, 26, 28, 53, 25, 22, 41, 35},
288 {6070, 30, 109, 29, 26, 28, 52, 25, 22, 41, 34},
289 {6060, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
290 {6050, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
291 {6040, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
292 {6030, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
293 {6020, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
294 {6010, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
295 {6000, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
296 {5990, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
297 {5980, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
298 {5970, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
299 {5960, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
300 {5950, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
301 {5940, 29, 107, 28, 25, 28, 51, 25, 22, 40, 34},
302 {5930, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
303 {5920, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
304 {5910, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
305 {5900, 29, 106, 28, 25, 28, 50, 24, 22, 40, 33},
306 {5890, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
307 {5880, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
308 {5870, 29, 105, 28, 25, 27, 51, 24, 22, 40, 33},
309 {5860, 29, 105, 28, 25, 27, 51, 24, 21, 40, 33},
310 {5850, 29, 104, 28, 25, 27, 50, 24, 21, 40, 33},
311 {5840, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
312 {5830, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
313 {5820, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
314 {5810, 28, 104, 28, 25, 27, 50, 24, 21, 39, 33},
315 {5800, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
316 {5790, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
317 {5780, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
318 {5770, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
319 {5760, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
320 {5750, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
321 {5740, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
322 {5730, 28, 103, 27, 25, 27, 49, 24, 21, 39, 32},
323 {5720, 28, 102, 27, 25, 27, 49, 24, 21, 39, 32},
324 {5710, 28, 102, 27, 25, 27, 48, 24, 21, 39, 32},
325 {5700, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
326 {5690, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
327 {5680, 28, 101, 27, 24, 27, 48, 24, 21, 39, 32},
328 {5670, 28, 101, 27, 24, 27, 48, 23, 21, 38, 32},
329 {5660, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
330 {5650, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
331 {5640, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
332 {5630, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
333 {5620, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
334 {5610, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
335 {5600, 27, 101, 26, 24, 26, 48, 23, 20, 38, 32},
336 {5590, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
337 {5580, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
338 {5570, 27, 100, 26, 24, 26, 48, 23, 20, 38, 31},
339 {5560, 27, 100, 26, 24, 26, 47, 23, 20, 38, 31},
340 {5550, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
341 {5540, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
342 {5530, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
343 {5520, 27, 99, 26, 24, 26, 47, 23, 20, 37, 31},
344 {5510, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31},
345 {5500, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31},
346 {5490, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31},
347 {5480, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31},
348 {5470, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31},
349 {5460, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31},
350 {5450, 27, 97, 26, 23, 25, 47, 23, 20, 37, 31},
351 {5440, 26, 98, 26, 23, 25, 47, 23, 20, 37, 31},
352 {5430, 26, 98, 26, 23, 25, 47, 22, 20, 37, 31},
353 {5420, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31},
354 {5410, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31},
355 {5400, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30},
356 {5390, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30},
357 {5380, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
358 {5370, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
359 {5360, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
360 {5350, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
361 {5340, 26, 95, 25, 23, 25, 45, 22, 20, 36, 30},
362 {5330, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
363 {5320, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
364 {5310, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
365 {5300, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
366 {5290, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30},
367 {5280, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30},
368 {5270, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30},
369 {5260, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30},
370 {5250, 25, 94, 25, 23, 24, 45, 22, 19, 36, 30},
371 {5240, 25, 94, 25, 23, 24, 45, 22, 19, 36, 29},
372 {5230, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29},
373 {5220, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29},
374 {5210, 25, 93, 25, 22, 24, 45, 22, 19, 35, 29},
375 {5200, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
376 {5190, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
377 {5180, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
378 {5170, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
379 {5160, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
380 {5150, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
381 {5140, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
382 {5130, 25, 92, 24, 22, 24, 43, 21, 19, 35, 29},
383 {5120, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
384 {5110, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
385 {5100, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
386 {5090, 25, 91, 24, 22, 24, 43, 21, 19, 34, 29},
387 {5080, 25, 90, 24, 22, 24, 43, 21, 19, 34, 29},
388 {5070, 25, 90, 24, 22, 24, 43, 21, 19, 34, 28},
389 {5060, 25, 90, 24, 22, 24, 43, 21, 18, 34, 28},
390 {5050, 24, 91, 24, 22, 24, 42, 21, 18, 34, 28},
391 {5040, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
392 {5030, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
393 {5020, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
394 {5010, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
395 {5000, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28},
396 {4990, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28},
397 {4980, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28},
398 {4970, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28},
399 {4960, 24, 89, 23, 21, 23, 42, 20, 18, 34, 28},
400 {4950, 24, 88, 23, 21, 23, 42, 20, 18, 34, 28},
401 {4940, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
402 {4930, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
403 {4920, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
404 {4910, 24, 87, 23, 21, 23, 41, 20, 18, 33, 28},
405 {4900, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
406 {4890, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
407 {4880, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
408 {4870, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27},
409 {4860, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27},
410 {4850, 23, 87, 23, 21, 23, 41, 20, 18, 33, 27},
411 {4840, 23, 87, 23, 21, 23, 40, 20, 18, 33, 27},
412 {4830, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
413 {4820, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
414 {4810, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
415 {4800, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27},
416 {4790, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27},
417 {4780, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27},
418 {4770, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27},
419 {4760, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27},
420 {4750, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27},
421 {4740, 23, 84, 22, 20, 22, 40, 20, 17, 32, 26},
422 {4730, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
423 {4720, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
424 {4710, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
425 {4700, 23, 83, 22, 20, 22, 40, 19, 17, 32, 26},
426 {4690, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
427 {4680, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
428 {4670, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
429 {4660, 23, 82, 22, 20, 22, 39, 19, 17, 32, 26},
430 {4650, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
431 {4640, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
432 {4630, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
433 {4620, 22, 83, 22, 20, 21, 39, 19, 17, 31, 26},
434 {4610, 22, 82, 22, 20, 21, 39, 19, 17, 31, 26},
435 {4600, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
436 {4590, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
437 {4580, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
438 {4570, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25},
439 {4560, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25},
440 {4550, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25},
441 {4540, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25},
442 {4530, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
443 {4520, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
444 {4510, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
445 {4500, 22, 80, 21, 19, 21, 38, 19, 16, 30, 25},
446 {4490, 22, 80, 21, 19, 21, 38, 18, 16, 30, 25},
447 {4480, 22, 79, 21, 19, 21, 38, 18, 16, 30, 25},
448 {4470, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25},
449 {4460, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25},
450 {4450, 21, 80, 21, 19, 21, 37, 18, 16, 30, 25},
451 {4440, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
452 {4430, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
453 {4420, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
454 {4410, 21, 79, 21, 19, 20, 38, 18, 16, 30, 25},
455 {4400, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
456 {4390, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
457 {4380, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
458 {4370, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
459 {4360, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
460 {4350, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
461 {4340, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
462 {4330, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24},
463 {4320, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24},
464 {4310, 21, 76, 20, 19, 20, 36, 18, 16, 29, 24},
465 {4300, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
466 {4290, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
467 {4280, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
468 {4270, 21, 75, 20, 18, 20, 36, 18, 16, 29, 24},
469 {4260, 21, 75, 20, 18, 20, 35, 17, 15, 29, 24},
470 {4250, 20, 76, 20, 18, 20, 35, 17, 15, 29, 24},
471 {4240, 20, 76, 20, 18, 20, 35, 17, 15, 29, 23},
472 {4230, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23},
473 {4220, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23},
474 {4210, 20, 75, 20, 18, 20, 35, 17, 15, 28, 23},
475 {4200, 20, 75, 19, 18, 19, 36, 17, 15, 28, 23},
476 {4190, 20, 74, 19, 18, 19, 36, 17, 15, 28, 23},
477 {4180, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
478 {4170, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
479 {4160, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
480 {4150, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
481 {4140, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
482 {4130, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
483 {4120, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
484 {4110, 20, 73, 19, 18, 19, 34, 17, 15, 28, 23},
485 {4100, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
486 {4090, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
487 {4080, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
488 {4070, 20, 72, 19, 18, 19, 34, 17, 15, 27, 22},
489 {4060, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22},
490 {4050, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22},
491 {4040, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22},
492 {4030, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22},
493 {4020, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22},
494 {4010, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22},
495 {4000, 19, 71, 18, 17, 19, 33, 16, 14, 27, 22},
496 {3990, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22},
497 {3980, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22},
498 {3970, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
499 {3960, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
500 {3950, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
501 {3940, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
502 {3930, 19, 69, 18, 17, 18, 33, 16, 14, 27, 22},
503 {3920, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22},
504 {3910, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22},
505 {3900, 19, 69, 18, 17, 18, 33, 16, 14, 26, 21},
506 {3890, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
507 {3880, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
508 {3870, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
509 {3860, 18, 69, 18, 17, 18, 32, 16, 14, 26, 21},
510 {3850, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21},
511 {3840, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21},
512 {3830, 18, 68, 18, 16, 18, 32, 16, 14, 26, 21},
513 {3820, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21},
514 {3810, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21},
515 {3800, 18, 67, 17, 16, 18, 31, 16, 14, 26, 21},
516 {3790, 18, 67, 17, 16, 17, 32, 15, 14, 26, 21},
517 {3780, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21},
518 {3770, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21},
519 {3760, 18, 66, 17, 16, 17, 32, 15, 14, 25, 21},
520 {3750, 18, 66, 17, 16, 17, 31, 15, 14, 25, 21},
521 {3740, 18, 66, 17, 16, 17, 31, 15, 14, 25, 20},
522 {3730, 18, 66, 17, 16, 17, 31, 15, 13, 25, 20},
523 {3720, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
524 {3710, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
525 {3700, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
526 {3690, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
527 {3680, 18, 64, 17, 16, 17, 31, 15, 13, 25, 20},
528 {3670, 18, 64, 17, 16, 17, 30, 15, 13, 25, 20},
529 {3660, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
530 {3650, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
531 {3640, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
532 {3630, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
533 {3620, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
534 {3610, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
535 {3600, 17, 64, 16, 16, 17, 29, 15, 13, 24, 20},
536 {3590, 17, 63, 16, 15, 17, 29, 15, 13, 24, 20},
537 {3580, 17, 63, 16, 15, 16, 30, 15, 13, 24, 20},
538 {3570, 17, 63, 16, 15, 16, 30, 15, 13, 24, 19},
539 {3560, 17, 63, 16, 15, 16, 30, 14, 13, 24, 19},
540 {3550, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19},
541 {3540, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19},
542 {3530, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
543 {3520, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
544 {3510, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
545 {3500, 17, 61, 16, 15, 16, 29, 14, 13, 24, 19},
546 {3490, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
547 {3480, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
548 {3470, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
549 {3460, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
550 {3450, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
551 {3440, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
552 {3430, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
553 {3420, 16, 60, 16, 15, 16, 28, 14, 12, 23, 19},
554 {3410, 16, 60, 16, 15, 16, 28, 14, 12, 23, 18},
555 {3400, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18},
556 {3390, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18},
557 {3380, 16, 59, 15, 15, 16, 27, 14, 12, 23, 18},
558 {3370, 16, 59, 15, 15, 15, 28, 14, 12, 23, 18},
559 {3360, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18},
560 {3350, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18},
561 {3340, 16, 59, 15, 14, 15, 28, 14, 12, 22, 18},
562 {3330, 16, 58, 15, 14, 15, 28, 14, 12, 22, 18},
563 {3320, 16, 58, 15, 14, 15, 28, 13, 12, 22, 18},
564 {3310, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18},
565 {3300, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18},
566 {3290, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
567 {3280, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
568 {3270, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
569 {3260, 15, 58, 15, 14, 15, 27, 13, 12, 22, 18},
570 {3250, 15, 57, 15, 14, 15, 27, 13, 12, 22, 18},
571 {3240, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
572 {3230, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
573 {3220, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
574 {3210, 15, 56, 15, 14, 15, 26, 13, 12, 22, 17},
575 {3200, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
576 {3190, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
577 {3180, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
578 {3170, 15, 56, 14, 14, 15, 25, 13, 11, 21, 17},
579 {3160, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
580 {3150, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
581 {3140, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
582 {3130, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
583 {3120, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
584 {3110, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
585 {3100, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
586 {3090, 15, 54, 14, 13, 14, 25, 12, 11, 21, 17},
587 {3080, 15, 53, 14, 13, 14, 25, 12, 11, 21, 17},
588 {3070, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16},
589 {3060, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16},
590 {3050, 14, 54, 14, 13, 14, 25, 12, 11, 20, 16},
591 {3040, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16},
592 {3030, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16},
593 {3020, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16},
594 {3010, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16},
595 {3000, 14, 53, 13, 13, 14, 24, 12, 11, 20, 16},
596 {2990, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
597 {2980, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
598 {2970, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
599 {2960, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
600 {2950, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16},
601 {2940, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16},
602 {2930, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16},
603 {2920, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16},
604 {2910, 14, 50, 13, 13, 13, 24, 12, 10, 20, 15},
605 {2900, 14, 50, 13, 13, 13, 24, 12, 10, 19, 15},
606 {2890, 14, 50, 13, 12, 13, 24, 12, 10, 19, 15},
607 {2880, 14, 50, 13, 12, 13, 23, 12, 10, 19, 15},
608 {2870, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15},
609 {2860, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15},
610 {2850, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
611 {2840, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
612 {2830, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
613 {2820, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15},
614 {2810, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15},
615 {2800, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15},
616 {2790, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15},
617 {2780, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15},
618 {2770, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15},
619 {2760, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15},
620 {2750, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15},
621 {2740, 13, 47, 12, 12, 12, 23, 11, 10, 18, 14},
622 {2730, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
623 {2720, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
624 {2710, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
625 {2700, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
626 {2690, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14},
627 {2680, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14},
628 {2670, 12, 47, 12, 12, 12, 22, 11, 10, 18, 14},
629 {2660, 12, 47, 12, 12, 12, 21, 11, 9, 18, 14},
630 {2650, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
631 {2640, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
632 {2630, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
633 {2620, 12, 46, 12, 11, 12, 21, 10, 9, 18, 14},
634 {2610, 12, 45, 12, 11, 12, 21, 10, 9, 17, 14},
635 {2600, 12, 45, 11, 11, 12, 21, 10, 9, 17, 14},
636 {2590, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14},
637 {2580, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14},
638 {2570, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
639 {2560, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
640 {2550, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
641 {2540, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13},
642 {2530, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13},
643 {2520, 12, 43, 11, 11, 11, 21, 10, 9, 17, 13},
644 {2510, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
645 {2500, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
646 {2490, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
647 {2480, 12, 42, 11, 11, 11, 20, 10, 9, 17, 13},
648 {2470, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
649 {2460, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
650 {2450, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
651 {2440, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13},
652 {2430, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13},
653 {2420, 11, 42, 11, 10, 11, 19, 10, 9, 16, 13},
654 {2410, 11, 42, 11, 10, 11, 19, 10, 9, 16, 12},
655 {2400, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12},
656 {2390, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12},
657 {2380, 11, 41, 10, 10, 11, 19, 9, 8, 16, 12},
658 {2370, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12},
659 {2360, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12},
660 {2350, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12},
661 {2340, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12},
662 {2330, 11, 40, 10, 10, 10, 19, 9, 8, 16, 12},
663 {2320, 11, 40, 10, 10, 10, 19, 9, 8, 15, 12},
664 {2310, 11, 39, 10, 10, 10, 19, 9, 8, 15, 12},
665 {2300, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
666 {2290, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
667 {2280, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
668 {2270, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
669 {2260, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
670 {2250, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
671 {2240, 10, 39, 10, 10, 10, 18, 9, 8, 15, 11},
672 {2230, 10, 38, 10, 10, 10, 18, 9, 8, 15, 11},
673 {2220, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11},
674 {2210, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11},
675 {2200, 10, 38, 9, 10, 10, 17, 9, 8, 15, 11},
676 {2190, 10, 38, 9, 9, 10, 17, 9, 8, 15, 11},
677 {2180, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
678 {2170, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
679 {2160, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
680 {2150, 10, 37, 9, 9, 10, 16, 8, 8, 14, 11},
681 {2140, 10, 36, 9, 9, 10, 16, 8, 8, 14, 11},
682 {2130, 10, 36, 9, 9, 10, 16, 8, 7, 14, 11},
683 {2120, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11},
684 {2110, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11},
685 {2100, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11},
686 {2090, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11},
687 {2080, 9, 36, 9, 9, 9, 16, 8, 7, 14, 11},
688 {2070, 9, 36, 9, 9, 9, 16, 8, 7, 14, 10},
689 {2060, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
690 {2050, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
691 {2040, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
692 {2030, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10},
693 {2020, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10},
694 {2010, 9, 34, 9, 9, 9, 15, 8, 7, 13, 10},
695 {2000, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
696 {1990, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
697 {1980, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
698 {1970, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10},
699 {1960, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10},
700 {1950, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10},
701 {1940, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10},
702 {1930, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10},
703 {1920, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10},
704 {1910, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9},
705 {1900, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9},
706 {1890, 9, 31, 8, 8, 8, 15, 7, 7, 12, 9},
707 {1880, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9},
708 {1870, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9},
709 {1860, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9},
710 {1850, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9},
711 {1840, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
712 {1830, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
713 {1820, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
714 {1810, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
715 {1800, 8, 30, 7, 8, 8, 14, 7, 6, 12, 9},
716 {1790, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
717 {1780, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
718 {1770, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
719 {1760, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9},
720 {1750, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9},
721 {1740, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8},
722 {1730, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8},
723 {1720, 8, 29, 7, 7, 8, 13, 7, 6, 11, 8},
724 {1710, 8, 28, 7, 7, 8, 12, 7, 6, 11, 8},
725 {1700, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8},
726 {1690, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8},
727 {1680, 7, 29, 7, 7, 7, 13, 6, 6, 11, 8},
728 {1670, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
729 {1660, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
730 {1650, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
731 {1640, 7, 28, 7, 7, 7, 12, 6, 6, 11, 8},
732 {1630, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
733 {1620, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
734 {1610, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
735 {1600, 7, 27, 6, 7, 7, 12, 6, 5, 10, 8},
736 {1590, 7, 26, 6, 7, 7, 12, 6, 5, 10, 8},
737 {1580, 7, 26, 6, 7, 7, 12, 6, 5, 10, 7},
738 {1570, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
739 {1560, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
740 {1550, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
741 {1540, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
742 {1530, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
743 {1520, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
744 {1510, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
745 {1500, 7, 24, 6, 7, 7, 10, 6, 5, 10, 7},
746 {1490, 59, 25, 6, 77, 59, 10, 70, 44, 9, 73},
747 {1480, 59, 24, 6, 76, 58, 10, 70, 44, 9, 73},
748 {1470, 58, 24, 6, 76, 58, 10, 69, 44, 9, 72},
749 {1460, 58, 24, 6, 76, 58, 10, 69, 43, 9, 72},
750 {1450, 58, 24, 6, 75, 57, 10, 68, 43, 9, 71},
751 {1440, 57, 24, 6, 75, 57, 10, 68, 43, 9, 71},
752 {1430, 57, 23, 6, 75, 57, 10, 68, 43, 8, 70},
753 {1420, 56, 23, 6, 74, 57, 9, 67, 43, 8, 70},
754 {1410, 56, 23, 6, 74, 57, 9, 67, 43, 8, 69},
755 {1400, 56, 23, 5, 74, 55, 9, 67, 41, 8, 69},
756 {1390, 55, 23, 5, 73, 55, 9, 66, 41, 8, 68},
757 {1380, 55, 23, 5, 73, 54, 9, 66, 41, 8, 68},
758 {1370, 54, 22, 5, 72, 54, 9, 66, 41, 8, 67},
759 {1360, 54, 22, 5, 72, 54, 9, 65, 40, 8, 67},
760 {1350, 54, 22, 5, 72, 53, 9, 65, 40, 8, 66},
761 {1340, 53, 22, 5, 71, 53, 9, 65, 40, 8, 66},
762 {1330, 53, 22, 5, 71, 53, 9, 64, 39, 8, 65},
763 {1320, 52, 22, 5, 71, 53, 8, 64, 40, 8, 65},
764 {1310, 52, 21, 5, 70, 53, 8, 64, 40, 8, 64},
765 {1300, 51, 21, 5, 70, 51, 8, 63, 38, 8, 64},
766 {1290, 51, 21, 5, 70, 51, 8, 63, 38, 7, 64},
767 {1280, 51, 21, 5, 69, 51, 8, 63, 38, 7, 63},
768 {1270, 50, 21, 5, 69, 50, 8, 62, 38, 7, 63},
769 {1260, 50, 20, 5, 69, 50, 8, 62, 37, 7, 62},
770 {1250, 49, 20, 5, 68, 49, 8, 62, 37, 7, 62},
771 {1240, 49, 20, 5, 68, 49, 8, 61, 37, 7, 61},
772 {1230, 49, 20, 5, 68, 49, 8, 61, 36, 7, 61},
773 {1220, 48, 20, 5, 67, 48, 8, 61, 36, 7, 60},
774 {1210, 48, 19, 5, 67, 48, 7, 60, 36, 7, 60},
775 {1200, 49, 19, 4, 67, 49, 7, 60, 36, 7, 59},
776 {1190, 48, 19, 4, 66, 48, 7, 60, 36, 7, 59},
777 {1180, 48, 19, 4, 66, 48, 7, 59, 36, 7, 58},
778 {1170, 46, 19, 4, 66, 46, 7, 59, 35, 7, 58},
779 {1160, 46, 18, 4, 65, 46, 7, 59, 34, 7, 57},
780 {1150, 45, 18, 4, 65, 46, 7, 58, 34, 7, 57},
781 {1140, 45, 18, 4, 65, 45, 7, 58, 34, 6, 56},
782 {1130, 45, 18, 4, 64, 45, 7, 58, 33, 6, 56},
783 {1120, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55},
784 {1110, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55},
785 {1100, 43, 17, 4, 63, 44, 6, 57, 32, 6, 54},
786 {1090, 43, 17, 4, 63, 44, 6, 56, 33, 6, 54},
787 {1080, 43, 17, 4, 63, 44, 6, 56, 33, 6, 53},
788 {1070, 42, 17, 4, 62, 44, 6, 56, 33, 6, 53},
789 {1060, 42, 17, 4, 62, 42, 6, 55, 31, 6, 52},
790 {1050, 41, 17, 4, 62, 42, 6, 55, 31, 6, 52},
791 {1040, 41, 16, 4, 61, 41, 6, 54, 31, 6, 52},
792 {1030, 41, 16, 4, 61, 41, 6, 54, 30, 6, 51},
793 {1020, 40, 16, 4, 61, 41, 6, 54, 30, 6, 51},
794 {1010, 40, 16, 4, 60, 40, 6, 53, 30, 6, 50},
795 {1000, 39, 16, 3, 60, 40, 6, 53, 29, 5, 50},
796 { 990, 39, 15, 3, 60, 39, 6, 53, 29, 5, 49},
797 { 980, 39, 15, 3, 59, 39, 5, 52, 29, 5, 49},
798 { 970, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48},
799 { 960, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48},
800 { 950, 37, 15, 3, 58, 39, 5, 51, 29, 5, 47},
801 { 940, 37, 14, 3, 58, 39, 5, 51, 29, 5, 47},
802 { 930, 37, 14, 3, 57, 37, 5, 51, 27, 5, 46},
803 { 920, 36, 14, 3, 57, 37, 5, 50, 27, 5, 46},
804 { 910, 36, 14, 3, 57, 36, 5, 50, 27, 5, 45},
805 { 900, 35, 14, 3, 56, 36, 5, 50, 26, 5, 45},
806 { 890, 35, 14, 3, 56, 36, 5, 49, 26, 5, 44},
807 { 880, 35, 13, 3, 56, 35, 5, 49, 26, 5, 44},
808 { 870, 34, 13, 3, 55, 35, 4, 49, 26, 5, 43},
809 { 860, 34, 13, 3, 55, 35, 4, 48, 25, 5, 43},
810 { 850, 33, 13, 3, 55, 35, 4, 48, 26, 4, 42},
811 { 840, 33, 13, 3, 54, 35, 4, 48, 26, 4, 42},
812 { 830, 33, 12, 3, 54, 33, 4, 47, 24, 4, 41},
813 { 820, 32, 12, 3, 54, 33, 4, 47, 24, 4, 41},
814 { 810, 32, 12, 3, 53, 33, 4, 47, 24, 4, 40},
815 { 800, 31, 12, 2, 53, 32, 4, 46, 23, 4, 40},
816 { 790, 31, 12, 2, 53, 32, 4, 46, 23, 4, 39},
817 { 780, 30, 12, 2, 52, 31, 4, 46, 23, 4, 39},
818 { 770, 30, 11, 2, 52, 31, 4, 45, 23, 4, 39},
819 { 760, 30, 11, 2, 52, 31, 3, 45, 22, 4, 38},
820 { 750, 29, 11, 2, 51, 30, 3, 45, 22, 4, 38},
821 { 740, 29, 11, 2, 51, 30, 3, 44, 22, 4, 37},
822 { 730, 28, 11, 2, 51, 31, 3, 44, 22, 4, 37},
823 { 720, 28, 10, 2, 50, 30, 3, 44, 22, 4, 36},
824 { 710, 28, 10, 2, 50, 30, 3, 43, 22, 4, 36},
825 { 700, 27, 10, 2, 50, 28, 3, 43, 20, 3, 35},
826 { 690, 27, 10, 2, 49, 28, 3, 43, 20, 3, 35},
827 { 680, 26, 10, 2, 49, 28, 3, 42, 20, 3, 34},
828 { 670, 26, 10, 2, 49, 27, 3, 42, 20, 3, 34},
829 { 660, 26, 9, 2, 48, 27, 3, 42, 19, 3, 33},
830 { 650, 25, 9, 2, 48, 26, 3, 41, 19, 3, 33},
831 { 640, 25, 9, 2, 48, 26, 2, 41, 19, 3, 32},
832 { 630, 24, 9, 2, 47, 26, 2, 40, 18, 3, 32},
833 { 620, 24, 9, 2, 47, 26, 2, 40, 19, 3, 31},
834 { 610, 24, 8, 2, 47, 26, 2, 40, 19, 3, 31},
835 { 600, 23, 8, 1, 46, 26, 2, 39, 18, 3, 30},
836 { 590, 23, 8, 1, 46, 24, 2, 39, 17, 3, 30},
837 { 580, 22, 8, 1, 46, 24, 2, 39, 17, 3, 29},
838 { 570, 22, 8, 1, 45, 23, 2, 38, 17, 3, 29},
839 { 560, 22, 7, 1, 45, 23, 2, 38, 16, 2, 28},
840 { 550, 21, 7, 1, 45, 23, 2, 38, 16, 2, 28},
841 { 540, 21, 7, 1, 44, 22, 2, 37, 16, 2, 27},
842 { 530, 20, 7, 1, 44, 22, 1, 37, 15, 2, 27},
843 { 520, 20, 7, 1, 43, 21, 1, 37, 15, 2, 27},
844 { 510, 20, 6, 1, 43, 21, 1, 36, 15, 2, 26},
845 { 500, 19, 6, 1, 43, 22, 1, 36, 15, 2, 26},
846 { 490, 19, 6, 1, 42, 21, 1, 36, 15, 2, 25},
847 { 480, 18, 6, 1, 42, 21, 1, 35, 15, 2, 25},
848 { 470, 18, 6, 1, 42, 21, 1, 35, 15, 2, 24},
849 { 460, 18, 6, 1, 41, 19, 1, 35, 13, 2, 24},
850 { 450, 17, 5, 1, 41, 19, 1, 34, 13, 2, 23},
851 { 440, 17, 5, 1, 41, 18, 1, 34, 13, 2, 23},
852 { 430, 16, 5, 1, 40, 18, 0, 34, 12, 2, 22},
853 { 420, 16, 5, 1, 40, 18, 0, 33, 12, 2, 22},
854 { 410, 16, 5, 1, 40, 17, 0, 33, 12, 1, 21},
855 { 400, 15, 5, 0, 39, 17, 0, 33, 11, 1, 21},
856 { 390, 15, 4, 0, 39, 17, 0, 32, 12, 1, 20},
857 { 380, 14, 4, 0, 39, 17, 0, 32, 12, 1, 20},
858 { 370, 14, 4, 0, 38, 17, 0, 32, 12, 1, 19},
859 { 360, 14, 4, 0, 38, 15, 0, 31, 10, 1, 19},
860 { 350, 13, 4, 0, 38, 15, 0, 31, 10, 1, 18},
861 { 340, 13, 3, 0, 37, 15, 0, 31, 10, 1, 18},
862 { 330, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17},
863 { 320, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17},
864 { 310, 12, 3, 0, 36, 13, 0, 30, 9, 1, 16},
865 { 300, 11, 3, 0, 36, 13, 0, 29, 8, 1, 16},
866 { 290, 11, 2, 0, 36, 13, 0, 29, 8, 1, 15},
867 { 280, 10, 2, 0, 35, 12, 0, 29, 8, 1, 15},
868 { 270, 10, 2, 0, 35, 12, 0, 28, 8, 0, 14},
869 { 260, 9, 2, 0, 35, 12, 0, 28, 8, 0, 14},
870 { 250, 9, 2, 0, 34, 12, 0, 28, 8, 0, 14},
871 { 240, 9, 2, 0, 34, 12, 0, 27, 8, 0, 13},
872 { 230, 8, 1, 0, 34, 10, 0, 27, 6, 0, 13},
873 { 220, 8, 1, 0, 33, 10, 0, 27, 6, 0, 12},
874 { 210, 7, 1, 0, 33, 10, 0, 26, 6, 0, 12},
875 { 200, 7, 1, 0, 33, 9, 0, 26, 5, 0, 11},
876 { 190, 7, 1, 0, 32, 9, 0, 25, 5, 0, 11},
877 { 180, 6, 1, 0, 32, 8, 0, 25, 5, 0, 10},
878 { 170, 6, 0, 0, 32, 8, 0, 25, 5, 0, 10},
879 { 160, 5, 0, 0, 31, 8, 0, 24, 4, 0, 9},
880 { 150, 5, 0, 0, 31, 8, 0, 24, 5, 0, 9},
881 { 140, 5, 0, 0, 31, 8, 0, 24, 5, 0, 8},
882 { 130, 4, 0, 0, 30, 6, 0, 23, 3, 0, 8},
883 { 120, 4, 0, 0, 30, 6, 0, 23, 3, 0, 7},
884 { 110, 3, 0, 0, 30, 6, 0, 23, 3, 0, 7},
885 { 100, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6},
886 { 90, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6},
887 { 80, 2, 0, 0, 28, 5, 0, 22, 2, 0, 5},
888 };
889
890 static const
891 struct samsung_mipi_cphy_timing samsung_mipi_cphy_timing_table[] = {
892 { 3500, 39, 50, 25, 29, 54, 1 },
893 { 3490, 39, 50, 25, 29, 54, 1 },
894 { 3480, 39, 50, 25, 29, 54, 1 },
895 { 3470, 39, 50, 25, 29, 54, 1 },
896 { 3460, 39, 50, 25, 29, 54, 1 },
897 { 3450, 39, 50, 25, 29, 54, 1 },
898 { 3440, 38, 50, 25, 29, 54, 1 },
899 { 3430, 38, 50, 25, 29, 53, 1 },
900 { 3420, 38, 50, 25, 29, 53, 1 },
901 { 3410, 38, 50, 25, 29, 53, 1 },
902 { 3400, 38, 50, 25, 29, 53, 1 },
903 { 3390, 38, 50, 25, 29, 53, 1 },
904 { 3380, 38, 50, 25, 28, 53, 1 },
905 { 3370, 38, 50, 25, 28, 52, 1 },
906 { 3360, 37, 50, 25, 28, 52, 1 },
907 { 3350, 37, 50, 25, 28, 52, 1 },
908 { 3340, 37, 50, 25, 28, 52, 1 },
909 { 3330, 37, 50, 25, 28, 52, 1 },
910 { 3320, 37, 50, 25, 28, 52, 1 },
911 { 3310, 37, 50, 25, 28, 52, 1 },
912 { 3300, 37, 50, 25, 28, 51, 1 },
913 { 3290, 37, 50, 25, 28, 51, 1 },
914 { 3280, 37, 50, 25, 28, 51, 1 },
915 { 3270, 36, 50, 25, 28, 51, 1 },
916 { 3260, 36, 50, 25, 27, 51, 1 },
917 { 3250, 36, 50, 25, 27, 51, 1 },
918 { 3240, 36, 50, 25, 27, 50, 1 },
919 { 3230, 36, 50, 25, 27, 50, 1 },
920 { 3220, 36, 50, 25, 27, 50, 1 },
921 { 3210, 36, 50, 25, 27, 50, 1 },
922 { 3200, 36, 50, 25, 27, 50, 1 },
923 { 3190, 36, 50, 25, 27, 50, 1 },
924 { 3180, 35, 50, 25, 27, 49, 1 },
925 { 3170, 35, 50, 25, 27, 49, 1 },
926 { 3160, 35, 50, 25, 27, 49, 1 },
927 { 3150, 35, 50, 25, 26, 49, 1 },
928 { 3140, 35, 50, 25, 26, 49, 1 },
929 { 3130, 35, 50, 25, 26, 49, 1 },
930 { 3120, 35, 50, 25, 26, 49, 1 },
931 { 3110, 35, 50, 25, 26, 48, 1 },
932 { 3100, 34, 50, 25, 26, 48, 1 },
933 { 3090, 34, 50, 25, 26, 48, 1 },
934 { 3080, 34, 50, 25, 26, 48, 1 },
935 { 3070, 34, 50, 25, 26, 48, 1 },
936 { 3060, 34, 50, 25, 26, 48, 1 },
937 { 3050, 34, 50, 25, 26, 47, 1 },
938 { 3040, 34, 50, 25, 26, 47, 1 },
939 { 3030, 34, 50, 25, 25, 47, 1 },
940 { 3020, 34, 50, 25, 25, 47, 1 },
941 { 3010, 33, 50, 25, 25, 47, 1 },
942 { 3000, 33, 50, 25, 25, 47, 1 },
943 { 2990, 33, 50, 25, 25, 46, 1 },
944 { 2980, 33, 50, 25, 25, 46, 1 },
945 { 2970, 33, 50, 25, 25, 46, 1 },
946 { 2960, 33, 50, 25, 25, 46, 1 },
947 { 2950, 33, 50, 25, 25, 46, 1 },
948 { 2940, 33, 50, 25, 25, 46, 1 },
949 { 2930, 33, 50, 25, 25, 46, 1 },
950 { 2920, 32, 50, 25, 25, 45, 1 },
951 { 2910, 32, 50, 25, 24, 45, 1 },
952 { 2900, 32, 50, 25, 24, 45, 1 },
953 { 2890, 32, 50, 25, 24, 45, 1 },
954 { 2880, 32, 50, 25, 24, 45, 1 },
955 { 2870, 32, 50, 25, 24, 45, 1 },
956 { 2860, 32, 50, 25, 24, 44, 1 },
957 { 2850, 32, 50, 25, 24, 44, 1 },
958 { 2840, 31, 50, 25, 24, 44, 1 },
959 { 2830, 31, 50, 25, 24, 44, 1 },
960 { 2820, 31, 50, 25, 24, 44, 1 },
961 { 2810, 31, 50, 25, 24, 44, 1 },
962 { 2800, 31, 50, 25, 23, 43, 1 },
963 { 2790, 31, 50, 25, 23, 43, 1 },
964 { 2780, 31, 50, 25, 23, 43, 1 },
965 { 2770, 31, 50, 25, 23, 43, 1 },
966 { 2760, 31, 50, 25, 23, 43, 1 },
967 { 2750, 30, 50, 25, 23, 43, 1 },
968 { 2740, 30, 50, 25, 23, 43, 1 },
969 { 2730, 30, 50, 25, 23, 42, 1 },
970 { 2720, 30, 50, 25, 23, 42, 1 },
971 { 2710, 30, 50, 25, 23, 42, 1 },
972 { 2700, 30, 50, 25, 23, 42, 1 },
973 { 2690, 30, 50, 25, 23, 42, 1 },
974 { 2680, 30, 50, 25, 22, 42, 1 },
975 { 2670, 30, 50, 25, 22, 41, 1 },
976 { 2660, 29, 50, 25, 22, 41, 1 },
977 { 2650, 29, 50, 25, 22, 41, 1 },
978 { 2640, 29, 50, 25, 22, 41, 1 },
979 { 2630, 29, 50, 25, 22, 41, 1 },
980 { 2620, 29, 50, 25, 22, 41, 1 },
981 { 2610, 29, 50, 25, 22, 41, 1 },
982 { 2600, 29, 50, 25, 22, 40, 1 },
983 { 2590, 29, 50, 25, 22, 40, 1 },
984 { 2580, 28, 50, 25, 22, 40, 1 },
985 { 2570, 28, 50, 25, 22, 40, 1 },
986 { 2560, 28, 50, 25, 21, 40, 1 },
987 { 2550, 28, 50, 25, 21, 40, 1 },
988 { 2540, 28, 50, 25, 21, 39, 1 },
989 { 2530, 28, 50, 25, 21, 39, 1 },
990 { 2520, 28, 50, 25, 21, 39, 1 },
991 { 2510, 28, 50, 25, 21, 39, 1 },
992 { 2500, 28, 50, 25, 21, 39, 1 },
993 { 2490, 27, 50, 25, 21, 39, 1 },
994 { 2480, 27, 50, 25, 21, 38, 1 },
995 { 2470, 27, 50, 25, 21, 38, 1 },
996 { 2460, 27, 50, 25, 21, 38, 1 },
997 { 2450, 27, 50, 25, 20, 38, 1 },
998 { 2440, 27, 50, 25, 20, 38, 1 },
999 { 2430, 27, 50, 25, 20, 38, 1 },
1000 { 2420, 27, 50, 25, 20, 38, 1 },
1001 { 2410, 27, 50, 25, 20, 37, 1 },
1002 { 2400, 26, 50, 25, 20, 37, 1 },
1003 { 2390, 26, 50, 25, 20, 37, 1 },
1004 { 2380, 26, 50, 25, 20, 37, 1 },
1005 { 2370, 26, 50, 25, 20, 37, 1 },
1006 { 2360, 26, 50, 25, 20, 37, 1 },
1007 { 2350, 26, 50, 25, 20, 36, 1 },
1008 { 2340, 26, 50, 25, 20, 36, 1 },
1009 { 2330, 26, 50, 25, 19, 36, 1 },
1010 { 2320, 25, 50, 25, 19, 36, 1 },
1011 { 2310, 25, 50, 25, 19, 36, 1 },
1012 { 2300, 25, 50, 25, 19, 36, 1 },
1013 { 2290, 25, 50, 25, 19, 35, 1 },
1014 { 2280, 25, 50, 25, 19, 35, 1 },
1015 { 2270, 25, 50, 25, 19, 35, 1 },
1016 { 2260, 25, 50, 25, 19, 35, 1 },
1017 { 2250, 25, 50, 25, 19, 35, 1 },
1018 { 2240, 25, 50, 25, 19, 35, 1 },
1019 { 2230, 24, 50, 25, 19, 35, 1 },
1020 { 2220, 24, 50, 25, 19, 34, 1 },
1021 { 2210, 24, 50, 25, 18, 34, 1 },
1022 { 2200, 24, 50, 25, 18, 34, 1 },
1023 { 2190, 24, 50, 25, 18, 34, 1 },
1024 { 2180, 24, 50, 25, 18, 34, 1 },
1025 { 2170, 24, 50, 25, 18, 34, 1 },
1026 { 2160, 24, 50, 25, 18, 33, 1 },
1027 { 2150, 24, 50, 25, 18, 33, 1 },
1028 { 2140, 23, 50, 25, 18, 33, 1 },
1029 { 2130, 23, 50, 25, 18, 33, 1 },
1030 { 2120, 23, 50, 25, 18, 33, 1 },
1031 { 2110, 23, 50, 25, 18, 33, 1 },
1032 { 2100, 23, 50, 25, 17, 32, 1 },
1033 { 2090, 23, 50, 25, 17, 32, 1 },
1034 { 2080, 23, 50, 25, 17, 32, 1 },
1035 { 2070, 23, 50, 25, 17, 32, 1 },
1036 { 2060, 22, 50, 25, 17, 32, 1 },
1037 { 2050, 22, 50, 25, 17, 32, 1 },
1038 { 2040, 22, 50, 25, 17, 32, 1 },
1039 { 2030, 22, 50, 25, 17, 31, 1 },
1040 { 2020, 22, 50, 25, 17, 31, 1 },
1041 { 2010, 22, 50, 25, 17, 31, 1 },
1042 { 2000, 22, 50, 25, 17, 31, 1 },
1043 { 1990, 22, 50, 25, 17, 31, 1 },
1044 { 1980, 22, 50, 25, 16, 31, 1 },
1045 { 1970, 21, 50, 25, 16, 30, 1 },
1046 { 1960, 21, 50, 25, 16, 30, 1 },
1047 { 1950, 21, 50, 25, 16, 30, 1 },
1048 { 1940, 21, 50, 25, 16, 30, 1 },
1049 { 1930, 21, 50, 25, 16, 30, 1 },
1050 { 1920, 21, 50, 25, 16, 30, 1 },
1051 { 1910, 21, 50, 25, 16, 30, 1 },
1052 { 1900, 21, 50, 25, 16, 29, 1 },
1053 { 1890, 21, 50, 25, 16, 29, 1 },
1054 { 1880, 20, 50, 25, 16, 29, 1 },
1055 { 1870, 20, 50, 25, 16, 29, 1 },
1056 { 1860, 20, 50, 25, 15, 29, 1 },
1057 { 1850, 20, 50, 25, 15, 29, 1 },
1058 { 1840, 20, 50, 25, 15, 28, 1 },
1059 { 1830, 20, 50, 25, 15, 28, 1 },
1060 { 1820, 20, 50, 25, 15, 28, 1 },
1061 { 1810, 20, 50, 25, 15, 28, 1 },
1062 { 1800, 19, 50, 25, 15, 28, 1 },
1063 { 1790, 19, 50, 25, 15, 28, 1 },
1064 { 1780, 19, 50, 25, 15, 27, 1 },
1065 { 1770, 19, 50, 25, 15, 27, 1 },
1066 { 1760, 19, 50, 25, 15, 27, 1 },
1067 { 1750, 19, 50, 25, 14, 27, 1 },
1068 { 1740, 19, 50, 25, 14, 27, 1 },
1069 { 1730, 19, 50, 25, 14, 27, 1 },
1070 { 1720, 19, 50, 25, 14, 27, 1 },
1071 { 1710, 18, 50, 25, 14, 26, 1 },
1072 { 1700, 18, 50, 25, 14, 26, 1 },
1073 { 1690, 18, 50, 25, 14, 26, 1 },
1074 { 1680, 18, 50, 25, 14, 26, 1 },
1075 { 1670, 18, 50, 25, 14, 26, 1 },
1076 { 1660, 18, 50, 25, 14, 26, 1 },
1077 { 1650, 18, 50, 25, 14, 25, 1 },
1078 { 1640, 18, 50, 25, 14, 25, 1 },
1079 { 1630, 18, 50, 25, 13, 25, 1 },
1080 { 1620, 17, 50, 25, 13, 25, 1 },
1081 { 1610, 17, 50, 25, 13, 25, 1 },
1082 { 1600, 17, 50, 25, 13, 25, 1 },
1083 { 1590, 17, 50, 25, 13, 24, 1 },
1084 { 1580, 17, 50, 25, 13, 24, 1 },
1085 { 1570, 17, 50, 25, 13, 24, 1 },
1086 { 1560, 17, 50, 25, 13, 24, 1 },
1087 { 1550, 17, 50, 25, 13, 24, 1 },
1088 { 1540, 16, 50, 25, 13, 24, 1 },
1089 { 1530, 16, 50, 25, 13, 24, 1 },
1090 { 1520, 16, 50, 25, 13, 23, 1 },
1091 { 1510, 16, 50, 25, 12, 23, 1 },
1092 { 1500, 16, 50, 25, 12, 23, 1 },
1093 { 1490, 16, 50, 25, 12, 23, 1 },
1094 { 1480, 16, 50, 25, 12, 23, 1 },
1095 { 1470, 16, 50, 25, 12, 23, 1 },
1096 { 1460, 16, 50, 25, 12, 22, 1 },
1097 { 1450, 15, 50, 25, 12, 22, 1 },
1098 { 1440, 15, 50, 25, 12, 22, 1 },
1099 { 1430, 15, 50, 25, 12, 22, 1 },
1100 { 1420, 15, 50, 25, 12, 22, 1 },
1101 { 1410, 15, 50, 25, 12, 22, 1 },
1102 { 1400, 15, 50, 25, 11, 21, 1 },
1103 { 1390, 15, 50, 25, 11, 21, 1 },
1104 { 1380, 15, 50, 25, 11, 21, 1 },
1105 { 1370, 15, 50, 25, 11, 21, 1 },
1106 { 1360, 14, 50, 25, 11, 21, 1 },
1107 { 1350, 14, 50, 25, 11, 21, 1 },
1108 { 1340, 14, 50, 25, 11, 21, 1 },
1109 { 1330, 14, 50, 25, 11, 20, 1 },
1110 { 1320, 14, 50, 25, 11, 20, 1 },
1111 { 1310, 14, 50, 25, 11, 20, 1 },
1112 { 1300, 14, 50, 25, 11, 20, 1 },
1113 { 1290, 14, 50, 25, 11, 20, 1 },
1114 { 1280, 13, 50, 25, 10, 20, 1 },
1115 { 1270, 13, 50, 25, 10, 19, 1 },
1116 { 1260, 13, 50, 25, 10, 19, 1 },
1117 { 1250, 13, 50, 25, 10, 19, 1 },
1118 { 1240, 13, 50, 25, 10, 19, 1 },
1119 { 1230, 13, 50, 25, 10, 19, 1 },
1120 { 1220, 13, 50, 25, 10, 19, 1 },
1121 { 1210, 13, 50, 25, 10, 19, 1 },
1122 { 1200, 13, 50, 25, 10, 18, 1 },
1123 { 1190, 12, 50, 25, 10, 18, 1 },
1124 { 1180, 12, 50, 25, 10, 18, 1 },
1125 { 1170, 12, 50, 25, 10, 18, 1 },
1126 { 1160, 12, 50, 25, 9, 18, 1 },
1127 { 1150, 12, 50, 25, 9, 18, 1 },
1128 { 1140, 12, 50, 25, 9, 17, 1 },
1129 { 1130, 12, 50, 25, 9, 17, 1 },
1130 { 1120, 12, 50, 25, 9, 17, 1 },
1131 { 1110, 12, 50, 25, 9, 17, 1 },
1132 { 1100, 11, 50, 25, 9, 17, 1 },
1133 { 1090, 11, 50, 25, 9, 17, 1 },
1134 { 1080, 11, 50, 25, 9, 16, 1 },
1135 { 1070, 11, 50, 25, 9, 16, 1 },
1136 { 1060, 11, 50, 25, 9, 16, 1 },
1137 { 1050, 11, 50, 25, 8, 16, 1 },
1138 { 1040, 11, 50, 25, 8, 16, 1 },
1139 { 1030, 11, 50, 25, 8, 16, 1 },
1140 { 1020, 10, 50, 25, 8, 16, 1 },
1141 { 1010, 10, 50, 25, 8, 15, 1 },
1142 { 1000, 10, 50, 25, 8, 15, 1 },
1143 { 990, 10, 50, 25, 8, 15, 2 },
1144 { 980, 10, 50, 25, 8, 15, 2 },
1145 { 970, 10, 50, 25, 8, 15, 2 },
1146 { 960, 10, 50, 25, 8, 15, 2 },
1147 { 950, 10, 50, 25, 8, 14, 2 },
1148 { 940, 10, 50, 25, 8, 14, 2 },
1149 { 930, 9, 50, 25, 7, 14, 2 },
1150 { 920, 9, 50, 25, 7, 14, 2 },
1151 { 910, 9, 50, 25, 7, 14, 2 },
1152 { 900, 9, 50, 25, 7, 14, 2 },
1153 { 890, 9, 50, 25, 7, 13, 2 },
1154 { 880, 9, 50, 25, 7, 13, 2 },
1155 { 870, 9, 50, 25, 7, 13, 2 },
1156 { 860, 9, 50, 25, 7, 13, 2 },
1157 { 850, 9, 50, 25, 7, 13, 2 },
1158 { 840, 8, 50, 25, 7, 13, 2 },
1159 { 830, 8, 50, 25, 7, 13, 2 },
1160 { 820, 8, 50, 25, 7, 12, 2 },
1161 { 810, 8, 50, 25, 6, 12, 2 },
1162 { 800, 8, 50, 25, 6, 12, 2 },
1163 { 790, 8, 50, 25, 6, 12, 2 },
1164 { 780, 8, 50, 25, 6, 12, 2 },
1165 { 770, 8, 50, 25, 6, 12, 2 },
1166 { 760, 7, 50, 25, 6, 11, 2 },
1167 { 750, 7, 50, 25, 6, 11, 2 },
1168 { 740, 7, 50, 25, 6, 11, 2 },
1169 { 730, 7, 50, 25, 6, 11, 2 },
1170 { 720, 7, 50, 25, 6, 11, 2 },
1171 { 710, 7, 50, 25, 6, 11, 2 },
1172 { 700, 7, 50, 25, 5, 10, 2 },
1173 { 690, 7, 50, 25, 5, 10, 2 },
1174 { 680, 7, 50, 25, 5, 10, 2 },
1175 { 670, 6, 50, 25, 5, 10, 2 },
1176 { 660, 6, 50, 25, 5, 10, 2 },
1177 { 650, 6, 50, 25, 5, 10, 2 },
1178 { 640, 6, 50, 25, 5, 10, 2 },
1179 { 630, 6, 50, 25, 5, 9, 2 },
1180 { 620, 6, 50, 25, 5, 9, 2 },
1181 { 610, 6, 50, 25, 5, 9, 2 },
1182 { 600, 6, 50, 25, 5, 9, 2 },
1183 { 590, 6, 50, 25, 5, 9, 2 },
1184 { 580, 5, 50, 25, 4, 9, 2 },
1185 { 570, 5, 50, 25, 4, 8, 2 },
1186 { 560, 5, 50, 25, 4, 8, 2 },
1187 { 550, 5, 50, 25, 4, 8, 2 },
1188 { 540, 5, 50, 25, 4, 8, 2 },
1189 { 530, 5, 50, 25, 4, 8, 2 },
1190 { 520, 5, 50, 25, 4, 8, 2 },
1191 { 510, 5, 50, 25, 4, 8, 2 },
1192 { 500, 4, 50, 25, 4, 7, 2 },
1193 { 490, 18, 50, 25, 14, 6, 2 },
1194 { 480, 17, 50, 25, 14, 6, 2 },
1195 { 470, 17, 50, 25, 14, 6, 2 },
1196 { 460, 17, 50, 25, 13, 6, 2 },
1197 { 450, 16, 50, 25, 13, 6, 2 },
1198 { 440, 16, 50, 25, 13, 6, 2 },
1199 { 430, 15, 50, 25, 12, 6, 2 },
1200 { 420, 15, 50, 25, 12, 5, 2 },
1201 { 410, 15, 50, 25, 12, 5, 2 },
1202 { 400, 14, 50, 25, 11, 5, 2 },
1203 { 390, 14, 50, 25, 11, 5, 2 },
1204 { 380, 13, 50, 25, 11, 5, 2 },
1205 { 370, 13, 50, 25, 11, 5, 2 },
1206 { 360, 13, 50, 25, 10, 4, 2 },
1207 { 350, 12, 50, 25, 10, 4, 2 },
1208 { 340, 12, 50, 25, 10, 4, 2 },
1209 { 330, 11, 50, 25, 9, 4, 2 },
1210 { 320, 11, 50, 25, 9, 4, 2 },
1211 { 310, 11, 50, 25, 9, 4, 2 },
1212 { 300, 10, 50, 25, 8, 3, 2 },
1213 { 290, 10, 50, 25, 8, 3, 2 },
1214 { 280, 9, 50, 25, 8, 3, 2 },
1215 { 270, 9, 50, 25, 8, 3, 2 },
1216 { 260, 8, 50, 25, 7, 3, 2 },
1217 { 250, 8, 50, 25, 7, 3, 2 },
1218 { 240, 8, 50, 25, 7, 3, 2 },
1219 { 230, 7, 50, 25, 6, 2, 2 },
1220 { 220, 7, 50, 25, 6, 2, 2 },
1221 { 210, 6, 50, 25, 6, 2, 2 },
1222 { 200, 6, 50, 25, 5, 2, 2 },
1223 { 190, 6, 50, 25, 5, 2, 2 },
1224 { 180, 5, 50, 25, 5, 2, 2 },
1225 { 170, 5, 50, 25, 5, 1, 2 },
1226 { 160, 4, 50, 25, 4, 1, 2 },
1227 { 150, 4, 50, 25, 4, 1, 2 },
1228 { 140, 4, 50, 25, 4, 1, 2 },
1229 { 130, 3, 50, 25, 3, 1, 2 },
1230 { 120, 3, 50, 25, 3, 1, 2 },
1231 { 110, 2, 50, 25, 3, 1, 2 },
1232 { 100, 2, 50, 25, 2, 0, 2 },
1233 { 90, 2, 50, 25, 2, 0, 2 },
1234 { 80, 1, 50, 25, 2, 0, 2 },
1235 };
1236
1237 struct hsfreq_range {
1238 u32 range_h;
1239 u16 cfg_bit;
1240 };
1241 /* These tables must be sorted by .range_h ascending. */
1242 static const struct hsfreq_range samsung_dphy_rx_hsfreq_ranges[] = {
1243 { 80, 0x105}, { 100, 0x106}, { 120, 0x107}, { 140, 0x108},
1244 { 160, 0x109}, { 180, 0x10a}, { 200, 0x10b}, { 220, 0x10c},
1245 { 240, 0x10d}, { 270, 0x10e}, { 290, 0x10f}, { 310, 0x110},
1246 { 330, 0x111}, { 350, 0x112}, { 370, 0x113}, { 390, 0x114},
1247 { 410, 0x115}, { 430, 0x116}, { 450, 0x117}, { 470, 0x118},
1248 { 490, 0x119}, { 510, 0x11a}, { 540, 0x11b}, { 560, 0x11c},
1249 { 580, 0x11d}, { 600, 0x11e}, { 620, 0x11f}, { 640, 0x120},
1250 { 660, 0x121}, { 680, 0x122}, { 700, 0x123}, { 720, 0x124},
1251 { 740, 0x125}, { 760, 0x126}, { 790, 0x127}, { 810, 0x128},
1252 { 830, 0x129}, { 850, 0x12a}, { 870, 0x12b}, { 890, 0x12c},
1253 { 910, 0x12d}, { 930, 0x12e}, { 950, 0x12f}, { 970, 0x130},
1254 { 990, 0x131}, {1010, 0x132}, {1030, 0x133}, {1060, 0x134},
1255 {1080, 0x135}, {1100, 0x136}, {1120, 0x137}, {1140, 0x138},
1256 {1160, 0x139}, {1180, 0x13a}, {1200, 0x13b}, {1220, 0x13c},
1257 {1240, 0x13d}, {1260, 0x13e}, {1280, 0x13f}, {1310, 0x140},
1258 {1330, 0x141}, {1350, 0x142}, {1370, 0x143}, {1390, 0x144},
1259 {1410, 0x145}, {1430, 0x146}, {1450, 0x147}, {1470, 0x148},
1260 {1490, 0x149}, {1580, 0x007}, {1740, 0x008}, {1910, 0x009},
1261 {2070, 0x00a}, {2240, 0x00b}, {2410, 0x00c}, {2570, 0x00d},
1262 {2740, 0x00e}, {2910, 0x00f}, {3070, 0x010}, {3240, 0x011},
1263 {3410, 0x012}, {3570, 0x013}, {3740, 0x014}, {3890, 0x015},
1264 {4070, 0x016}, {4240, 0x017}, {4400, 0x018}, {4500, 0x019},
1265 };
1266
1267 /* These tables must be sorted by .range_h ascending. */
1268 static const struct hsfreq_range samsung_cphy_rx_hsfreq_ranges[] = {
1269 { 500, 0x102}, { 990, 0x002}, { 2500, 0x001},
1270 };
1271
samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy * samsung,struct csi2_dphy * csi_dphy)1272 static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung,
1273 struct csi2_dphy *csi_dphy)
1274 {
1275 u32 bias_con2 = 0x3223;
1276
1277 if (csi_dphy &&
1278 csi_dphy->dphy_param.lp_vol_ref != 3 &&
1279 csi_dphy->dphy_param.lp_vol_ref < 0x7) {
1280 bias_con2 &= 0xfffffff8;
1281 bias_con2 |= csi_dphy->dphy_param.lp_vol_ref;
1282 dev_info(samsung->dev,
1283 "rx change lp_vol_ref to %d, it may cause tx exception\n",
1284 csi_dphy->dphy_param.lp_vol_ref);
1285 }
1286 regmap_write(samsung->regmap, BIAS_CON0, 0x0010);
1287 regmap_write(samsung->regmap, BIAS_CON1, 0x0110);
1288 regmap_write(samsung->regmap, BIAS_CON2, bias_con2);
1289
1290 /* default output voltage select:
1291 * dphy: 400mv
1292 * cphy: 530mv
1293 */
1294 if (samsung->c_option)
1295 regmap_update_bits(samsung->regmap, BIAS_CON4,
1296 I_MUX_SEL_MASK, I_MUX_SEL(2));
1297 }
1298
samsung_mipi_dcphy_bias_block_disable(struct samsung_mipi_dcphy * samsung)1299 static void samsung_mipi_dcphy_bias_block_disable(struct samsung_mipi_dcphy *samsung)
1300 {
1301 }
1302
samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy * samsung)1303 static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsung)
1304 {
1305 regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000));
1306 regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0,
1307 PHY_ENABLE, PHY_ENABLE);
1308
1309 switch (samsung->lanes) {
1310 case 4:
1311 regmap_write(samsung->regmap, DPHY_MD3_GNR_CON1,
1312 T_PHY_READY(0x2000));
1313 regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0,
1314 PHY_ENABLE, PHY_ENABLE);
1315 fallthrough;
1316 case 3:
1317 regmap_write(samsung->regmap, COMBO_MD2_GNR_CON1,
1318 T_PHY_READY(0x2000));
1319 regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0,
1320 PHY_ENABLE, PHY_ENABLE);
1321 fallthrough;
1322 case 2:
1323 regmap_write(samsung->regmap, COMBO_MD1_GNR_CON1,
1324 T_PHY_READY(0x2000));
1325 regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0,
1326 PHY_ENABLE, PHY_ENABLE);
1327 fallthrough;
1328 case 1:
1329 default:
1330 regmap_write(samsung->regmap, COMBO_MD0_GNR_CON1,
1331 T_PHY_READY(0x2000));
1332 regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0,
1333 PHY_ENABLE, PHY_ENABLE);
1334 break;
1335 }
1336 }
1337
samsung_mipi_cphy_lane_enable(struct samsung_mipi_dcphy * samsung)1338 static void samsung_mipi_cphy_lane_enable(struct samsung_mipi_dcphy *samsung)
1339 {
1340 regmap_write(samsung->regmap, COMBO_MD0_GNR_CON1, T_PHY_READY(0x2000));
1341 regmap_write(samsung->regmap, COMBO_MD1_GNR_CON1, T_PHY_READY(0x2000));
1342 regmap_write(samsung->regmap, COMBO_MD2_GNR_CON1, T_PHY_READY(0x2000));
1343
1344 regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0,
1345 PHY_ENABLE, PHY_ENABLE);
1346 regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0,
1347 PHY_ENABLE, PHY_ENABLE);
1348 regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0,
1349 PHY_ENABLE, PHY_ENABLE);
1350 }
1351
samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy * samsung)1352 static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *samsung)
1353 {
1354 regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, PHY_ENABLE, 0);
1355 regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0);
1356 regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0);
1357 regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0);
1358 regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0, PHY_ENABLE, 0);
1359 }
1360
samsung_mipi_cphy_lane_disable(struct samsung_mipi_dcphy * samsung)1361 static void samsung_mipi_cphy_lane_disable(struct samsung_mipi_dcphy *samsung)
1362 {
1363 regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0);
1364 regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0);
1365 regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0);
1366 }
1367
samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy * samsung)1368 static void samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy *samsung)
1369 {
1370 regmap_update_bits(samsung->regmap, PLL_CON0, S_MASK | P_MASK,
1371 S(samsung->pll.scaler) | P(samsung->pll.prediv));
1372
1373 if (samsung->pll.dsm < 0) {
1374 u16 dsm_tmp;
1375
1376 /* Using opposite number subtraction to find complement */
1377 dsm_tmp = abs(samsung->pll.dsm);
1378 dsm_tmp = dsm_tmp - 1;
1379 dsm_tmp ^= 0xffff;
1380 regmap_write(samsung->regmap, PLL_CON1, dsm_tmp);
1381 } else {
1382 regmap_write(samsung->regmap, PLL_CON1, samsung->pll.dsm);
1383 }
1384
1385 regmap_update_bits(samsung->regmap, PLL_CON2,
1386 M_MASK, M(samsung->pll.fbdiv));
1387
1388 if (samsung->pll.ssc_en) {
1389 regmap_write(samsung->regmap, PLL_CON3,
1390 MRR(samsung->pll.mrr) | MFR(samsung->pll.mfr));
1391 regmap_update_bits(samsung->regmap, PLL_CON4, SSCG_EN, SSCG_EN);
1392 }
1393
1394 regmap_write(samsung->regmap, PLL_CON5, RESET_N_SEL | PLL_ENABLE_SEL);
1395 regmap_write(samsung->regmap, PLL_CON7, PLL_LOCK_CNT(0xf000));
1396 regmap_write(samsung->regmap, PLL_CON8, PLL_STB_CNT(0xf000));
1397 }
1398
samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy * samsung)1399 static void samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy *samsung)
1400 {
1401 u32 sts;
1402 int ret;
1403
1404 regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, PLL_EN);
1405
1406 ret = regmap_read_poll_timeout(samsung->regmap, PLL_STAT0,
1407 sts, (sts & PLL_LOCK), 1000, 20000);
1408 if (ret < 0)
1409 dev_err(samsung->dev, "DC-PHY pll is not locked\n");
1410 }
1411
samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy * samsung)1412 static void samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy *samsung)
1413 {
1414 regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, 0);
1415 }
1416
1417 static const struct samsung_mipi_dphy_timing *
samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy * samsung)1418 samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung)
1419 {
1420 const struct samsung_mipi_dphy_timing *timings;
1421 unsigned int num_timings;
1422 unsigned int lane_mbps = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1423 unsigned int i;
1424
1425 timings = samsung_mipi_dphy_timing_table;
1426 num_timings = ARRAY_SIZE(samsung_mipi_dphy_timing_table);
1427
1428 for (i = num_timings; i > 0; i--)
1429 if (lane_mbps <= timings[i - 1].max_lane_mbps)
1430 break;
1431
1432 if (i == 0)
1433 ++i;
1434
1435 return &timings[i - 1];
1436 }
1437
1438 static const struct samsung_mipi_cphy_timing *
samsung_mipi_cphy_get_timing(struct samsung_mipi_dcphy * samsung)1439 samsung_mipi_cphy_get_timing(struct samsung_mipi_dcphy *samsung)
1440 {
1441 const struct samsung_mipi_cphy_timing *timings;
1442 unsigned int num_timings;
1443 unsigned int lane_msps = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1444 unsigned int i;
1445
1446 timings = samsung_mipi_cphy_timing_table;
1447 num_timings = ARRAY_SIZE(samsung_mipi_cphy_timing_table);
1448
1449 for (i = num_timings; i > 0; i--)
1450 if (lane_msps <= timings[i - 1].max_lane_msps)
1451 break;
1452
1453 if (i == 0)
1454 ++i;
1455
1456 return &timings[i - 1];
1457 }
1458
samsung_mipi_cphy_timing_init(struct samsung_mipi_dcphy * samsung)1459 static void samsung_mipi_cphy_timing_init(struct samsung_mipi_dcphy *samsung)
1460 {
1461 const struct samsung_mipi_cphy_timing *timing;
1462 unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1463 u32 val = 0;
1464
1465 timing = samsung_mipi_cphy_get_timing(samsung);
1466
1467 /*
1468 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
1469 * 500Msps, otherwise divide-by-16 Clock from Serial Clock
1470 */
1471 if (lane_hs_rate < 500)
1472 val = HSTX_CLK_SEL;
1473
1474 val |= T_LPX(timing->lpx);
1475 /* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
1476 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, val);
1477 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, val);
1478 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, val);
1479
1480 val = T_HS_ZERO(timing->prebegin_3) | T_HS_PREPARE(timing->prepare_3);
1481 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON1, val);
1482 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON1, val);
1483 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON1, val);
1484
1485 val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->post_3);
1486 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON2, val);
1487 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON2, val);
1488 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON2, val);
1489
1490 /* TTA-GET/TTA-GO Timing Counter register use default value */
1491 val = T_TA_GET(0x3) | T_TA_GO(0x0);
1492 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON3, val);
1493 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON3, val);
1494 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON3, val);
1495
1496 /* Escape Clock is 20.00MHz */
1497 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON4, 0x1f4);
1498 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON4, 0x1f4);
1499 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON4, 0x1f4);
1500
1501 /* set T_ERR_SOT_SYNC default value */
1502 }
1503
1504 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)1505 samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung,
1506 unsigned long prate, unsigned long rate,
1507 u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler)
1508 {
1509 u64 max_fout = samsung->c_option ? MAX_CPHY_BW : MAX_DPHY_BW;
1510 u64 best_freq = 0;
1511 u64 fin, fvco, fout;
1512 u8 min_prediv, max_prediv;
1513 u8 _prediv, best_prediv = 1;
1514 u16 _fbdiv, best_fbdiv = 1;
1515 u8 _scaler, best_scaler = 0;
1516 u32 min_delta = UINT_MAX;
1517 long _dsm, best_dsm = 0;
1518
1519 /*
1520 * The PLL output frequency can be calculated using a simple formula:
1521 * Fvco = ((m+k/65536) x 2 x Fin) / p
1522 * Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s)
1523 */
1524 fin = div64_ul(prate, MSEC_PER_SEC);
1525
1526 while (!best_freq) {
1527 fout = div64_ul(rate, MSEC_PER_SEC);
1528 if (fout > max_fout)
1529 fout = max_fout;
1530
1531 /* 0 ≤ S[2:0] ≤ 6 */
1532 for (_scaler = 0; _scaler < 7; _scaler++) {
1533 fvco = fout << _scaler;
1534
1535 /*
1536 * 2600MHz ≤ FVCO ≤ 6600MHz
1537 */
1538 if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC)
1539 continue;
1540
1541 /* 6MHz ≤ Fref(Fin / p) ≤ 30MHz */
1542 min_prediv = DIV_ROUND_UP_ULL(fin, 30 * MSEC_PER_SEC);
1543 max_prediv = DIV_ROUND_CLOSEST_ULL(fin, 6 * MSEC_PER_SEC);
1544
1545 for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
1546 u64 delta, tmp;
1547
1548 _fbdiv = DIV_ROUND_CLOSEST_ULL(fvco * _prediv, 2 * fin);
1549
1550 /* 64 ≤ M[9:0] ≤ 1023 */
1551 if ((_fbdiv < 64) || (_fbdiv > 1023))
1552 continue;
1553
1554 /* -32767 ≤ K[15:0] ≤ 32767 */
1555 _dsm = ((_prediv * fvco) - (2 * _fbdiv * fin));
1556 _dsm = DIV_ROUND_UP_ULL(_dsm << 15, fin);
1557 if (abs(_dsm) > 32767)
1558 continue;
1559
1560 tmp = DIV_ROUND_CLOSEST_ULL((_fbdiv * fin * 2 * 1000), _prediv);
1561 tmp += DIV_ROUND_CLOSEST_ULL((_dsm * fin * 1000), _prediv << 15);
1562
1563 delta = abs(fvco * MSEC_PER_SEC - tmp);
1564 if (delta < min_delta) {
1565 best_prediv = _prediv;
1566 best_fbdiv = _fbdiv;
1567 best_dsm = _dsm;
1568 best_scaler = _scaler;
1569 min_delta = delta;
1570 best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * MSEC_PER_SEC;
1571 }
1572 }
1573 }
1574
1575 rate += 100 * MSEC_PER_SEC;
1576 }
1577
1578 *prediv = best_prediv;
1579 *fbdiv = best_fbdiv;
1580 *dsm = (int)best_dsm & 0xffff;
1581 *scaler = best_scaler;
1582 dev_dbg(samsung->dev, "p: %d, m: %d, dsm:%ld, scaler: %d\n",
1583 best_prediv, best_fbdiv, best_dsm, best_scaler);
1584
1585 return best_freq >> best_scaler;
1586 }
1587
1588 static void
samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy * samsung)1589 samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung)
1590 {
1591 const struct samsung_mipi_dphy_timing *timing;
1592 unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1593 u32 val = 0;
1594
1595 timing = samsung_mipi_dphy_get_timing(samsung);
1596 regmap_write(samsung->regmap, DPHY_MC_GNR_CON0, 0xf000);
1597 regmap_write(samsung->regmap, DPHY_MC_ANA_CON0, 0x7133);
1598
1599 if (lane_hs_rate >= 4500)
1600 regmap_write(samsung->regmap, DPHY_MC_ANA_CON1, 0x0001);
1601
1602 /*
1603 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
1604 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
1605 */
1606 if (lane_hs_rate < 1500)
1607 val = HSTX_CLK_SEL;
1608
1609 val |= T_LPX(timing->lpx);
1610 /* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
1611 regmap_write(samsung->regmap, DPHY_MC_TIME_CON0, val);
1612
1613 val = T_CLK_ZERO(timing->clk_zero) | T_CLK_PREPARE(timing->clk_prepare);
1614 regmap_write(samsung->regmap, DPHY_MC_TIME_CON1, val);
1615
1616 val = T_HS_EXIT(timing->hs_exit) | T_CLK_TRAIL(timing->clk_trail_eot);
1617 regmap_write(samsung->regmap, DPHY_MC_TIME_CON2, val);
1618
1619 val = T_CLK_POST(timing->clk_post);
1620 regmap_write(samsung->regmap, DPHY_MC_TIME_CON3, val);
1621
1622 /* Escape Clock is 20.00MHz */
1623 regmap_write(samsung->regmap, DPHY_MC_TIME_CON4, 0x1f4);
1624
1625 /*
1626 * skew calibration should be off, if the operation data rate is
1627 * under 1.5Gbps or equal to 1.5Gbps.
1628 */
1629 if (lane_hs_rate > 1500)
1630 regmap_write(samsung->regmap, DPHY_MC_DESKEW_CON0, 0x9cb1);
1631 }
1632
1633 static void
samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy * samsung)1634 samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung)
1635 {
1636 const struct samsung_mipi_dphy_timing *timing;
1637 unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
1638 u32 val = 0;
1639
1640 timing = samsung_mipi_dphy_get_timing(samsung);
1641
1642 regmap_write(samsung->regmap, COMBO_MD0_ANA_CON0, 0x7133);
1643 regmap_write(samsung->regmap, COMBO_MD1_ANA_CON0, 0x7133);
1644 regmap_write(samsung->regmap, COMBO_MD2_ANA_CON0, 0x7133);
1645 regmap_write(samsung->regmap, DPHY_MD3_ANA_CON0, 0x7133);
1646
1647 if (lane_hs_rate >= 4500) {
1648 regmap_write(samsung->regmap, COMBO_MD0_ANA_CON1, 0x0001);
1649 regmap_write(samsung->regmap, COMBO_MD1_ANA_CON1, 0x0001);
1650 regmap_write(samsung->regmap, COMBO_MD2_ANA_CON1, 0x0001);
1651 regmap_write(samsung->regmap, DPHY_MD3_ANA_CON1, 0x0001);
1652 }
1653
1654 /*
1655 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
1656 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
1657 */
1658 if (lane_hs_rate < 1500)
1659 val = HSTX_CLK_SEL;
1660
1661 val |= T_LPX(timing->lpx);
1662 /* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
1663 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, val);
1664 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, val);
1665 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, val);
1666 regmap_write(samsung->regmap, DPHY_MD3_TIME_CON0, val);
1667
1668 val = T_HS_ZERO(timing->hs_zero) | T_HS_PREPARE(timing->hs_prepare);
1669 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON1, val);
1670 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON1, val);
1671 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON1, val);
1672 regmap_write(samsung->regmap, DPHY_MD3_TIME_CON1, val);
1673
1674 val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->hs_trail_eot);
1675 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON2, val);
1676 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON2, val);
1677 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON2, val);
1678 regmap_write(samsung->regmap, DPHY_MD3_TIME_CON2, val);
1679
1680 /* TTA-GET/TTA-GO Timing Counter register use default value */
1681 val = T_TA_GET(0x3) | T_TA_GO(0x0);
1682 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON3, val);
1683 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON3, val);
1684 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON3, val);
1685 regmap_write(samsung->regmap, DPHY_MD3_TIME_CON3, val);
1686
1687 /* Escape Clock is 20.00MHz */
1688 regmap_write(samsung->regmap, COMBO_MD0_TIME_CON4, 0x1f4);
1689 regmap_write(samsung->regmap, COMBO_MD1_TIME_CON4, 0x1f4);
1690 regmap_write(samsung->regmap, COMBO_MD2_TIME_CON4, 0x1f4);
1691 regmap_write(samsung->regmap, DPHY_MD3_TIME_CON4, 0x1f4);
1692 }
1693
1694 static void
samsung_mipi_dcphy_hs_vreg_amp_configure(struct samsung_mipi_dcphy * samsung)1695 samsung_mipi_dcphy_hs_vreg_amp_configure(struct samsung_mipi_dcphy *samsung)
1696 {
1697 regmap_write(samsung->regmap, DPHY_MC_ANA_CON2, HS_VREG_AMP_ICON(2));
1698 }
1699
samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy * samsung)1700 static void samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung)
1701 {
1702 reset_control_assert(samsung->m_phy_rst);
1703
1704 samsung_mipi_dcphy_bias_block_enable(samsung, NULL);
1705 samsung_mipi_dcphy_pll_configure(samsung);
1706 samsung_mipi_dphy_clk_lane_timing_init(samsung);
1707 samsung_mipi_dphy_data_lane_timing_init(samsung);
1708 samsung_mipi_dcphy_pll_enable(samsung);
1709 samsung_mipi_dphy_lane_enable(samsung);
1710
1711 reset_control_deassert(samsung->m_phy_rst);
1712
1713 /* The TSKEWCAL maximum is 100 µsec
1714 * at initial calibration.
1715 */
1716 usleep_range(100, 110);
1717 }
1718
samsung_mipi_cphy_power_on(struct samsung_mipi_dcphy * samsung)1719 static void samsung_mipi_cphy_power_on(struct samsung_mipi_dcphy *samsung)
1720 {
1721 regmap_write(samsung->grf_regmap, MIPI_DCPHY_GRF_CON0, M_CPHY_MODE);
1722 reset_control_assert(samsung->m_phy_rst);
1723
1724 samsung_mipi_dcphy_bias_block_enable(samsung, NULL);
1725 samsung_mipi_dcphy_hs_vreg_amp_configure(samsung);
1726 samsung_mipi_dcphy_pll_configure(samsung);
1727 samsung_mipi_cphy_timing_init(samsung);
1728 samsung_mipi_dcphy_pll_enable(samsung);
1729 samsung_mipi_cphy_lane_enable(samsung);
1730
1731 reset_control_deassert(samsung->m_phy_rst);
1732 }
1733
1734 static struct v4l2_subdev *get_remote_sensor(struct v4l2_subdev *sd);
1735
samsung_mipi_dcphy_power_on(struct phy * phy)1736 static int samsung_mipi_dcphy_power_on(struct phy *phy)
1737 {
1738 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1739 enum phy_mode mode = phy_get_mode(phy);
1740 int on = 0;
1741 struct v4l2_subdev *sensor_sd = NULL;
1742
1743 pm_runtime_get_sync(samsung->dev);
1744 reset_control_assert(samsung->apb_rst);
1745 udelay(1);
1746 reset_control_deassert(samsung->apb_rst);
1747 if (atomic_read(&samsung->stream_cnt)) {
1748 sensor_sd = get_remote_sensor(&samsung->dphy_dev[0]->sd);
1749 samsung->stream_off(samsung->dphy_dev[0], &samsung->dphy_dev[0]->sd);
1750 if (sensor_sd)
1751 v4l2_subdev_call(sensor_sd, core, ioctl,
1752 RKMODULE_SET_QUICK_STREAM, &on);
1753 samsung->stream_on(samsung->dphy_dev[0], &samsung->dphy_dev[0]->sd);
1754 on = 1;
1755 if (sensor_sd)
1756 v4l2_subdev_call(sensor_sd, core, ioctl,
1757 RKMODULE_SET_QUICK_STREAM, &on);
1758 }
1759
1760 switch (mode) {
1761 case PHY_MODE_MIPI_DPHY:
1762 samsung_mipi_dphy_power_on(samsung);
1763 break;
1764 default:
1765 samsung_mipi_cphy_power_on(samsung);
1766 }
1767
1768 return 0;
1769 }
1770
samsung_mipi_dcphy_power_off(struct phy * phy)1771 static int samsung_mipi_dcphy_power_off(struct phy *phy)
1772 {
1773 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1774 enum phy_mode mode = phy_get_mode(phy);
1775
1776 switch (mode) {
1777 case PHY_MODE_MIPI_DPHY:
1778 samsung_mipi_dphy_lane_disable(samsung);
1779 break;
1780 default:
1781 samsung_mipi_cphy_lane_disable(samsung);
1782 }
1783
1784 samsung_mipi_dcphy_pll_disable(samsung);
1785 samsung_mipi_dcphy_bias_block_disable(samsung);
1786
1787 pm_runtime_put(samsung->dev);
1788
1789 return 0;
1790 }
1791
samsung_mipi_dcphy_set_mode(struct phy * phy,enum phy_mode mode,int submode)1792 static int samsung_mipi_dcphy_set_mode(struct phy *phy, enum phy_mode mode,
1793 int submode)
1794 {
1795 return 0;
1796 }
1797
1798 static int
samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy * samsung,u8 * mfr,u8 * mrr)1799 samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy *samsung,
1800 u8 *mfr, u8 *mrr)
1801 {
1802 unsigned long fin = div64_ul(clk_get_rate(samsung->ref_clk), MSEC_PER_SEC);
1803 u16 prediv = samsung->pll.prediv;
1804 u16 fbdiv = samsung->pll.fbdiv;
1805 u16 min_mfr, max_mfr;
1806 u16 _mfr, best_mfr = 0;
1807 u16 mr, _mrr, best_mrr = 0;
1808
1809 /* 20KHz ≤ MF ≤ 150KHz */
1810 max_mfr = DIV_ROUND_UP(fin, (20 * prediv) << 5);
1811 min_mfr = div64_ul(fin, ((150 * prediv) << 5));
1812 /*0 ≤ mfr ≤ 255 */
1813 if (max_mfr > 256)
1814 max_mfr = 256;
1815
1816 for (_mfr = min_mfr; _mfr < max_mfr; _mfr++) {
1817 /* 1 ≤ mrr ≤ 31 */
1818 for (_mrr = 1; _mrr < 32; _mrr++) {
1819 mr = DIV_ROUND_UP(_mfr * _mrr * 100, fbdiv << 6);
1820 /* 0 ≤ MR ≤ 5% */
1821 if (mr > 5)
1822 continue;
1823
1824 if (_mfr * _mrr < 513) {
1825 best_mfr = _mfr;
1826 best_mrr = _mrr;
1827 break;
1828 }
1829 }
1830 }
1831
1832 if (best_mrr) {
1833 *mfr = best_mfr & 0xff;
1834 *mrr = best_mrr & 0x3f;
1835 } else {
1836 dev_err(samsung->dev, "failed to calc ssc parameter mfr and mrr\n");
1837 return -EINVAL;
1838 }
1839
1840 return 0;
1841 }
1842
1843 static void
samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy * samsung,unsigned long long rate)1844 samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy *samsung,
1845 unsigned long long rate)
1846 {
1847 unsigned long prate = clk_get_rate(samsung->ref_clk);
1848 unsigned long fout;
1849 u8 scaler = 0, mfr = 0, mrr = 0;
1850 u16 fbdiv = 1;
1851 u8 prediv = 1;
1852 int dsm = 0;
1853 int ret;
1854
1855 fout = samsung_mipi_dcphy_pll_round_rate(samsung, prate, rate,
1856 &prediv, &fbdiv, &dsm,
1857 &scaler);
1858
1859 dev_dbg(samsung->dev, "%s: fin=%lu, req_rate=%llu\n",
1860 __func__, prate, rate);
1861 dev_dbg(samsung->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n",
1862 __func__, fout, prediv, fbdiv);
1863
1864 samsung->pll.prediv = prediv;
1865 samsung->pll.fbdiv = fbdiv;
1866 samsung->pll.dsm = dsm;
1867 samsung->pll.scaler = scaler;
1868 samsung->pll.rate = fout;
1869
1870 /*
1871 * All DPHY 2.0 compliant Transmitters shall support SSC operating above
1872 * 2.5 Gbps
1873 */
1874 if (fout > 2500000000LL) {
1875 ret = samsung_mipi_dcphy_pll_ssc_modulation_calc(samsung,
1876 &mfr, &mrr);
1877 if (!ret) {
1878 samsung->pll.ssc_en = true;
1879 samsung->pll.mfr = mfr;
1880 samsung->pll.mrr = mrr;
1881 }
1882 }
1883 }
1884
samsung_mipi_dcphy_configure(struct phy * phy,union phy_configure_opts * opts)1885 static int samsung_mipi_dcphy_configure(struct phy *phy,
1886 union phy_configure_opts *opts)
1887 {
1888 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
1889 unsigned long long target_rate = opts->mipi_dphy.hs_clk_rate;
1890 enum phy_mode mode = phy_get_mode(phy);
1891
1892 samsung->c_option = (mode == PHY_MODE_MIPI_DPHY) ? false : true;
1893
1894 samsung->lanes = opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lanes;
1895
1896 samsung_mipi_dcphy_pll_calc_rate(samsung, target_rate);
1897 opts->mipi_dphy.hs_clk_rate = samsung->pll.rate;
1898
1899 return 0;
1900 }
1901
get_remote_sensor(struct v4l2_subdev * sd)1902 static struct v4l2_subdev *get_remote_sensor(struct v4l2_subdev *sd)
1903 {
1904 struct media_pad *local, *remote;
1905 struct media_entity *sensor_me;
1906
1907 local = &sd->entity.pads[CSI2_DPHY_RX_PAD_SINK];
1908 remote = media_entity_remote_pad(local);
1909 if (!remote) {
1910 v4l2_warn(sd, "No link between dphy and sensor\n");
1911 return NULL;
1912 }
1913
1914 sensor_me = media_entity_remote_pad(local)->entity;
1915 return media_entity_to_v4l2_subdev(sensor_me);
1916 }
1917
sd_to_sensor(struct csi2_dphy * dphy,struct v4l2_subdev * sd)1918 static struct csi2_sensor *sd_to_sensor(struct csi2_dphy *dphy,
1919 struct v4l2_subdev *sd)
1920 {
1921 int i;
1922
1923 for (i = 0; i < dphy->num_sensors; ++i)
1924 if (dphy->sensors[i].sd == sd)
1925 return &dphy->sensors[i];
1926
1927 return NULL;
1928 }
1929
samsung_dcphy_rx_config_settle(struct csi2_dphy * dphy,struct csi2_sensor * sensor)1930 static void samsung_dcphy_rx_config_settle(struct csi2_dphy *dphy,
1931 struct csi2_sensor *sensor)
1932 {
1933 struct samsung_mipi_dcphy *samsung = dphy->samsung_phy;
1934 const struct hsfreq_range *hsfreq_ranges = NULL;
1935 int num_hsfreq_ranges = 0;
1936 int i, hsfreq = 0;
1937 u32 sot_sync = 0;
1938
1939 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
1940 hsfreq_ranges = samsung_dphy_rx_hsfreq_ranges;
1941 num_hsfreq_ranges = ARRAY_SIZE(samsung_dphy_rx_hsfreq_ranges);
1942 sot_sync = 0x03;
1943 } else if (sensor->mbus.type == V4L2_MBUS_CSI2_CPHY) {
1944 hsfreq_ranges = samsung_cphy_rx_hsfreq_ranges;
1945 num_hsfreq_ranges = ARRAY_SIZE(samsung_cphy_rx_hsfreq_ranges);
1946 sot_sync = 0x32;
1947 } else {
1948 dev_err(dphy->dev, "mbus type %d is not support",
1949 sensor->mbus.type);
1950 return;
1951 }
1952 /* set data lane */
1953 for (i = 0; i < num_hsfreq_ranges; i++) {
1954 if (hsfreq_ranges[i].range_h >= dphy->data_rate_mbps) {
1955 hsfreq = hsfreq_ranges[i].cfg_bit;
1956 break;
1957 }
1958 }
1959
1960 if (i == num_hsfreq_ranges) {
1961 i = num_hsfreq_ranges - 1;
1962 dev_warn(dphy->dev, "data rate: %lld mbps, max support %d mbps",
1963 dphy->data_rate_mbps, hsfreq_ranges[i].range_h + 1);
1964 hsfreq = hsfreq_ranges[i].cfg_bit;
1965 }
1966 /*clk settle fix to 0x301*/
1967 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY)
1968 regmap_write(samsung->regmap, RX_CLK_THS_SETTLE, 0x301);
1969
1970 if (sensor->lanes > 0x00) {
1971 regmap_update_bits(samsung->regmap, RX_LANE0_THS_SETTLE, 0x1ff, hsfreq);
1972 regmap_update_bits(samsung->regmap, RX_LANE0_ERR_SOT_SYNC, 0xff, sot_sync);
1973 }
1974 if (sensor->lanes > 0x01) {
1975 regmap_update_bits(samsung->regmap, RX_LANE1_THS_SETTLE, 0x1ff, hsfreq);
1976 regmap_update_bits(samsung->regmap, RX_LANE1_ERR_SOT_SYNC, 0xff, sot_sync);
1977 }
1978 if (sensor->lanes > 0x02) {
1979 regmap_update_bits(samsung->regmap, RX_LANE2_THS_SETTLE, 0x1ff, hsfreq);
1980 regmap_update_bits(samsung->regmap, RX_LANE2_ERR_SOT_SYNC, 0xff, sot_sync);
1981 }
1982 if (sensor->lanes > 0x03) {
1983 regmap_update_bits(samsung->regmap, RX_LANE3_THS_SETTLE, 0x1ff, hsfreq);
1984 regmap_update_bits(samsung->regmap, RX_LANE3_ERR_SOT_SYNC, 0xff, sot_sync);
1985 }
1986 }
1987
samsung_dcphy_rx_config_common(struct csi2_dphy * dphy,struct csi2_sensor * sensor)1988 static int samsung_dcphy_rx_config_common(struct csi2_dphy *dphy,
1989 struct csi2_sensor *sensor)
1990 {
1991 struct samsung_mipi_dcphy *samsung = dphy->samsung_phy;
1992 u32 dlysel = 0;
1993 int i = 0;
1994
1995 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
1996 if (dphy->data_rate_mbps < 1500)
1997 dlysel = 0;
1998 else if (dphy->data_rate_mbps < 2000)
1999 dlysel = 3 << 8;
2000 else if (dphy->data_rate_mbps < 3000)
2001 dlysel = 2 << 8;
2002 else if (dphy->data_rate_mbps < 4000)
2003 dlysel = 1 << 8;
2004 else if (dphy->data_rate_mbps < 6500)
2005 dlysel = 0;
2006 if (dphy->dphy_param.clk_hs_term_sel > 0x7) {
2007 dev_err(dphy->dev, "clk_hs_term_sel error param %d\n",
2008 dphy->dphy_param.clk_hs_term_sel);
2009 return -EINVAL;
2010 }
2011 for (i = 0; i < sensor->lanes; i++) {
2012 if (dphy->dphy_param.data_hs_term_sel[i] > 0x7) {
2013 dev_err(dphy->dev, "data_hs_term_sel[%d] error param %d\n",
2014 i,
2015 dphy->dphy_param.data_hs_term_sel[i]);
2016 return -EINVAL;
2017 }
2018 if (dphy->dphy_param.lp_hys_sw[i] > 0x3) {
2019 dev_err(dphy->dev, "lp_hys_sw[%d] error param %d\n",
2020 i,
2021 dphy->dphy_param.lp_hys_sw[i]);
2022 return -EINVAL;
2023 }
2024 if (dphy->dphy_param.lp_escclk_pol_sel[i] > 0x1) {
2025 dev_err(dphy->dev, "lp_escclk_pol_sel[%d] error param %d\n",
2026 i,
2027 dphy->dphy_param.lp_escclk_pol_sel[i]);
2028 return -EINVAL;
2029 }
2030 if (dphy->dphy_param.skew_data_cal_clk[i] > 0x1f) {
2031 dev_err(dphy->dev, "skew_data_cal_clk[%d] error param %d\n",
2032 i,
2033 dphy->dphy_param.skew_data_cal_clk[i]);
2034 return -EINVAL;
2035 }
2036 }
2037 regmap_write(samsung->regmap, RX_S0C_GNR_CON1, 0x1450);
2038 regmap_write(samsung->regmap, RX_S0C_ANA_CON1, 0x8000);
2039 regmap_write(samsung->regmap, RX_S0C_ANA_CON2, dphy->dphy_param.clk_hs_term_sel);
2040 regmap_write(samsung->regmap, RX_S0C_ANA_CON3, 0x0600);
2041 if (sensor->lanes > 0x00) {
2042 regmap_write(samsung->regmap, RX_COMBO_S0D0_GNR_CON1, 0x1450);
2043 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON1, 0x8000);
2044 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON2, dlysel |
2045 dphy->dphy_param.data_hs_term_sel[0]);
2046 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON3, 0x0600 |
2047 (dphy->dphy_param.lp_hys_sw[0] << 4) |
2048 (dphy->dphy_param.lp_escclk_pol_sel[0] << 11));
2049 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON7, 0x40);
2050 regmap_write(samsung->regmap, RX_COMBO_S0D0_DESKEW_CON2,
2051 dphy->dphy_param.skew_data_cal_clk[0]);
2052 }
2053 if (sensor->lanes > 0x01) {
2054 regmap_write(samsung->regmap, RX_COMBO_S0D1_GNR_CON1, 0x1450);
2055 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON1, 0x8000);
2056 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON2, dlysel |
2057 dphy->dphy_param.data_hs_term_sel[1]);
2058 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON3, 0x0600 |
2059 (dphy->dphy_param.lp_hys_sw[1] << 4) |
2060 (dphy->dphy_param.lp_escclk_pol_sel[1] << 11));
2061 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON7, 0x40);
2062 regmap_write(samsung->regmap, RX_COMBO_S0D1_DESKEW_CON2,
2063 dphy->dphy_param.skew_data_cal_clk[1]);
2064 }
2065 if (sensor->lanes > 0x02) {
2066 regmap_write(samsung->regmap, RX_COMBO_S0D2_GNR_CON1, 0x1450);
2067 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON1, 0x8000);
2068 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON2, dlysel |
2069 dphy->dphy_param.data_hs_term_sel[2]);
2070 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON3, 0x0600 |
2071 (dphy->dphy_param.lp_hys_sw[2] << 4) |
2072 (dphy->dphy_param.lp_escclk_pol_sel[2] << 11));
2073 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON7, 0x40);
2074 regmap_write(samsung->regmap, RX_COMBO_S0D2_DESKEW_CON2,
2075 dphy->dphy_param.skew_data_cal_clk[2]);
2076 }
2077 if (sensor->lanes > 0x03) {
2078 regmap_write(samsung->regmap, RX_S0D3_GNR_CON1, 0x1450);
2079 regmap_write(samsung->regmap, RX_S0D3_ANA_CON1, 0x8000);
2080 regmap_write(samsung->regmap, RX_S0D3_ANA_CON2, dlysel |
2081 dphy->dphy_param.data_hs_term_sel[3]);
2082 regmap_write(samsung->regmap, RX_S0D3_ANA_CON3, 0x0600 |
2083 (dphy->dphy_param.lp_hys_sw[3] << 4) |
2084 (dphy->dphy_param.lp_escclk_pol_sel[3] << 11));
2085 regmap_write(samsung->regmap, RX_S0D3_DESKEW_CON2,
2086 dphy->dphy_param.skew_data_cal_clk[3]);
2087 }
2088 } else {
2089 if (sensor->lanes > 0x00) {
2090 regmap_write(samsung->regmap, RX_COMBO_S0D0_GNR_CON1, 0x1450);
2091 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON1, 0x8000);
2092 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON2, 0x5);
2093 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON3, 0x600);
2094 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON6, 0x608);
2095 regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON7, 0x40);
2096 regmap_write(samsung->regmap, RX_COMBO_S0D0_CRC_CON1, 0x1500);
2097 regmap_write(samsung->regmap, RX_COMBO_S0D0_CRC_CON2, 0x30);
2098 }
2099 if (sensor->lanes > 0x01) {
2100 regmap_write(samsung->regmap, RX_COMBO_S0D1_GNR_CON1, 0x1450);
2101 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON1, 0x8000);
2102 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON2, 0x5);
2103 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON3, 0x600);
2104 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON6, 0x608);
2105 regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON7, 0x40);
2106 regmap_write(samsung->regmap, RX_COMBO_S0D1_CRC_CON1, 0x1500);
2107 regmap_write(samsung->regmap, RX_COMBO_S0D1_CRC_CON2, 0x30);
2108 }
2109 if (sensor->lanes > 0x02) {
2110 regmap_write(samsung->regmap, RX_COMBO_S0D2_GNR_CON1, 0x1450);
2111 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON1, 0x8000);
2112 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON2, 0x5);
2113 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON3, 0x600);
2114 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON6, 0x608);
2115 regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON7, 0x40);
2116 regmap_write(samsung->regmap, RX_COMBO_S0D2_CRC_CON1, 0x1500);
2117 regmap_write(samsung->regmap, RX_COMBO_S0D2_CRC_CON2, 0x30);
2118 }
2119 }
2120 return 0;
2121 }
2122
samsung_dcphy_rx_lane_enable(struct csi2_dphy * dphy,struct csi2_sensor * sensor)2123 static int samsung_dcphy_rx_lane_enable(struct csi2_dphy *dphy,
2124 struct csi2_sensor *sensor)
2125 {
2126 struct samsung_mipi_dcphy *samsung = dphy->samsung_phy;
2127 u32 sts;
2128 int ret = 0;
2129
2130 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY)
2131 regmap_update_bits(samsung->regmap, RX_CLK_LANE_ENABLE, PHY_ENABLE, PHY_ENABLE);
2132
2133 if (sensor->lanes > 0x00)
2134 regmap_update_bits(samsung->regmap, RX_DATA_LANE0_ENABLE, PHY_ENABLE, PHY_ENABLE);
2135 if (sensor->lanes > 0x01)
2136 regmap_update_bits(samsung->regmap, RX_DATA_LANE1_ENABLE, PHY_ENABLE, PHY_ENABLE);
2137 if (sensor->lanes > 0x02)
2138 regmap_update_bits(samsung->regmap, RX_DATA_LANE2_ENABLE, PHY_ENABLE, PHY_ENABLE);
2139 if (sensor->lanes > 0x03)
2140 regmap_update_bits(samsung->regmap, RX_DATA_LANE3_ENABLE, PHY_ENABLE, PHY_ENABLE);
2141
2142 /*wait for clk lane ready*/
2143 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
2144 ret = regmap_read_poll_timeout(samsung->regmap, RX_CLK_LANE_ENABLE,
2145 sts, (sts & PHY_READY), 200, 4000);
2146 if (ret < 0) {
2147 dev_err(samsung->dev, "phy rx clk lane is not locked\n");
2148 return -EINVAL;
2149 }
2150 }
2151
2152 /*wait for data lane ready*/
2153 if (sensor->lanes > 0x00) {
2154 ret = regmap_read_poll_timeout(samsung->regmap, RX_DATA_LANE0_ENABLE,
2155 sts, (sts & PHY_READY), 200, 2000);
2156 if (ret < 0) {
2157 dev_err(samsung->dev, "phy rx data lane 0 is not locked\n");
2158 return -EINVAL;
2159 }
2160 }
2161 if (sensor->lanes > 0x01) {
2162 ret = regmap_read_poll_timeout(samsung->regmap, RX_DATA_LANE1_ENABLE,
2163 sts, (sts & PHY_READY), 200, 2000);
2164 if (ret < 0) {
2165 dev_err(samsung->dev, "phy rx data lane 1 is not locked\n");
2166 return -EINVAL;
2167 }
2168 }
2169 if (sensor->lanes > 0x02) {
2170 ret = regmap_read_poll_timeout(samsung->regmap, RX_DATA_LANE2_ENABLE,
2171 sts, (sts & PHY_READY), 200, 2000);
2172 if (ret < 0) {
2173 dev_err(samsung->dev, "phy rx data lane 2 is not locked\n");
2174 return -EINVAL;
2175 }
2176 }
2177
2178 if (sensor->lanes > 0x03) {
2179 ret = regmap_read_poll_timeout(samsung->regmap, RX_DATA_LANE3_ENABLE,
2180 sts, (sts & PHY_READY), 200, 2000);
2181 if (ret < 0) {
2182 dev_err(samsung->dev, "phy rx data lane 3 is not locked\n");
2183 return -EINVAL;
2184 }
2185 }
2186 return 0;
2187 }
2188
samsung_dcphy_rx_stream_on(struct csi2_dphy * dphy,struct v4l2_subdev * sd)2189 static int samsung_dcphy_rx_stream_on(struct csi2_dphy *dphy,
2190 struct v4l2_subdev *sd)
2191 {
2192 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
2193 struct csi2_sensor *sensor;
2194 struct samsung_mipi_dcphy *samsung = dphy->samsung_phy;
2195 int ret = 0;
2196
2197 if (!sensor_sd)
2198 return -ENODEV;
2199 sensor = sd_to_sensor(dphy, sensor_sd);
2200 if (!sensor)
2201 return -ENODEV;
2202
2203 mutex_lock(&samsung->mutex);
2204 if (sensor->mbus.type == V4L2_MBUS_CSI2_CPHY)
2205 regmap_write(samsung->grf_regmap, MIPI_DCPHY_GRF_CON0, S_CPHY_MODE);
2206
2207 if (samsung->s_phy_rst)
2208 reset_control_assert(samsung->s_phy_rst);
2209
2210 samsung_mipi_dcphy_bias_block_enable(samsung, dphy);
2211 ret = samsung_dcphy_rx_config_common(dphy, sensor);
2212 if (ret)
2213 goto out_streamon;
2214 samsung_dcphy_rx_config_settle(dphy, sensor);
2215
2216 ret = samsung_dcphy_rx_lane_enable(dphy, sensor);
2217 if (ret)
2218 goto out_streamon;
2219
2220 if (samsung->s_phy_rst)
2221 reset_control_deassert(samsung->s_phy_rst);
2222
2223 atomic_inc(&samsung->stream_cnt);
2224 mutex_unlock(&samsung->mutex);
2225
2226 return 0;
2227 out_streamon:
2228 if (samsung->s_phy_rst)
2229 reset_control_deassert(samsung->s_phy_rst);
2230 mutex_unlock(&samsung->mutex);
2231 dev_err(dphy->dev, "stream on error\n");
2232 return -EINVAL;
2233
2234 }
2235
samsung_dcphy_rx_stream_off(struct csi2_dphy * dphy,struct v4l2_subdev * sd)2236 static int samsung_dcphy_rx_stream_off(struct csi2_dphy *dphy,
2237 struct v4l2_subdev *sd)
2238 {
2239 struct samsung_mipi_dcphy *samsung = dphy->samsung_phy;
2240 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
2241 struct csi2_sensor *sensor;
2242
2243 if (!sensor_sd)
2244 return -ENODEV;
2245 sensor = sd_to_sensor(dphy, sensor_sd);
2246 if (!sensor)
2247 return -ENODEV;
2248
2249 if (atomic_dec_return(&samsung->stream_cnt))
2250 return 0;
2251
2252 mutex_lock(&samsung->mutex);
2253 if (samsung->s_phy_rst)
2254 reset_control_assert(samsung->s_phy_rst);
2255
2256 if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY)
2257 regmap_update_bits(samsung->regmap, RX_CLK_LANE_ENABLE, PHY_ENABLE, 0);
2258
2259 if (sensor->lanes > 0x00)
2260 regmap_update_bits(samsung->regmap, RX_DATA_LANE0_ENABLE, PHY_ENABLE, 0);
2261 if (sensor->lanes > 0x01)
2262 regmap_update_bits(samsung->regmap, RX_DATA_LANE1_ENABLE, PHY_ENABLE, 0);
2263 if (sensor->lanes > 0x02)
2264 regmap_update_bits(samsung->regmap, RX_DATA_LANE2_ENABLE, PHY_ENABLE, 0);
2265 if (sensor->lanes > 0x03)
2266 regmap_update_bits(samsung->regmap, RX_DATA_LANE3_ENABLE, PHY_ENABLE, 0);
2267
2268 if (samsung->s_phy_rst)
2269 reset_control_deassert(samsung->s_phy_rst);
2270 usleep_range(500, 1000);
2271
2272 mutex_unlock(&samsung->mutex);
2273
2274 return 0;
2275 }
2276
samsung_mipi_dcphy_init(struct phy * phy)2277 static int samsung_mipi_dcphy_init(struct phy *phy)
2278 {
2279 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
2280
2281 pm_runtime_get_sync(samsung->dev);
2282
2283 return 0;
2284 }
2285
samsung_mipi_dcphy_exit(struct phy * phy)2286 static int samsung_mipi_dcphy_exit(struct phy *phy)
2287 {
2288 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
2289
2290 pm_runtime_put(samsung->dev);
2291
2292 return 0;
2293 }
2294 static const struct phy_ops samsung_mipi_dcphy_ops = {
2295 .configure = samsung_mipi_dcphy_configure,
2296 .set_mode = samsung_mipi_dcphy_set_mode,
2297 .power_on = samsung_mipi_dcphy_power_on,
2298 .power_off = samsung_mipi_dcphy_power_off,
2299 .init = samsung_mipi_dcphy_init,
2300 .exit = samsung_mipi_dcphy_exit,
2301 .owner = THIS_MODULE,
2302 };
2303
2304 static const struct regmap_config samsung_mipi_dcphy_regmap_config = {
2305 .name = "dcphy",
2306 .reg_bits = 32,
2307 .val_bits = 32,
2308 .reg_stride = 4,
2309 .max_register = 0x10000,
2310 };
2311
samsung_mipi_dcphy_probe(struct platform_device * pdev)2312 static int samsung_mipi_dcphy_probe(struct platform_device *pdev)
2313 {
2314 struct device *dev = &pdev->dev;
2315 struct device_node *np = dev->of_node;
2316 struct samsung_mipi_dcphy *samsung;
2317 struct phy_provider *phy_provider;
2318 struct phy *phy;
2319 struct resource *res;
2320 void __iomem *regs;
2321 int ret;
2322
2323 samsung = devm_kzalloc(dev, sizeof(*samsung), GFP_KERNEL);
2324 if (!samsung)
2325 return -ENOMEM;
2326
2327 samsung->dev = dev;
2328 platform_set_drvdata(pdev, samsung);
2329
2330 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2331 regs = devm_ioremap_resource(dev, res);
2332 if (IS_ERR(regs))
2333 return PTR_ERR(regs);
2334
2335 samsung->regmap = devm_regmap_init_mmio(dev, regs,
2336 &samsung_mipi_dcphy_regmap_config);
2337 if (IS_ERR(samsung->regmap)) {
2338 ret = PTR_ERR(samsung->regmap);
2339 dev_err(dev, "failed to init regmap: %d\n", ret);
2340 return ret;
2341 }
2342
2343 samsung->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
2344 if (IS_ERR(samsung->grf_regmap)) {
2345 dev_err(dev, "Unable to get rockchip,grf\n");
2346 return PTR_ERR(samsung->grf_regmap);
2347 }
2348
2349 samsung->ref_clk = devm_clk_get(dev, "ref");
2350 if (IS_ERR(samsung->ref_clk)) {
2351 dev_err(dev, "failed to get reference clock\n");
2352 return PTR_ERR(samsung->ref_clk);
2353 }
2354
2355 samsung->pclk = devm_clk_get(dev, "pclk");
2356 if (IS_ERR(samsung->pclk)) {
2357 dev_err(dev, "failed to get pclk\n");
2358 return PTR_ERR(samsung->pclk);
2359 }
2360
2361 samsung->m_phy_rst = devm_reset_control_get(dev, "m_phy");
2362 if (IS_ERR(samsung->m_phy_rst)) {
2363 dev_err(dev, "failed to get system m_phy_rst control\n");
2364 return PTR_ERR(samsung->m_phy_rst);
2365 }
2366
2367 samsung->s_phy_rst = devm_reset_control_get(dev, "s_phy");
2368 if (IS_ERR(samsung->s_phy_rst)) {
2369 dev_err(dev, "failed to get system s_phy_rst control\n");
2370 return PTR_ERR(samsung->s_phy_rst);
2371 }
2372
2373 samsung->apb_rst = devm_reset_control_get(dev, "apb");
2374 if (IS_ERR(samsung->apb_rst)) {
2375 dev_err(dev, "failed to get system apb_rst control\n");
2376 return PTR_ERR(samsung->apb_rst);
2377 }
2378
2379 samsung->grf_apb_rst = devm_reset_control_get(dev, "grf");
2380 if (IS_ERR(samsung->grf_apb_rst)) {
2381 dev_err(dev, "failed to get system grf_apb_rst control\n");
2382 return PTR_ERR(samsung->grf_apb_rst);
2383 }
2384
2385 phy = devm_phy_create(dev, NULL, &samsung_mipi_dcphy_ops);
2386 if (IS_ERR(phy)) {
2387 dev_err(dev, "failed to create MIPI Dc-PHY\n");
2388 return PTR_ERR(phy);
2389 }
2390
2391 phy_set_drvdata(phy, samsung);
2392
2393 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
2394 if (IS_ERR(phy_provider)) {
2395 dev_err(dev, "failed to register phy provider\n");
2396 return PTR_ERR(phy_provider);
2397 }
2398
2399 samsung->stream_on = samsung_dcphy_rx_stream_on;
2400 samsung->stream_off = samsung_dcphy_rx_stream_off;
2401 mutex_init(&samsung->mutex);
2402 pm_runtime_enable(dev);
2403
2404 return 0;
2405 }
2406
samsung_mipi_dcphy_remove(struct platform_device * pdev)2407 static int samsung_mipi_dcphy_remove(struct platform_device *pdev)
2408 {
2409 struct samsung_mipi_dcphy *samsung = platform_get_drvdata(pdev);
2410
2411 pm_runtime_disable(samsung->dev);
2412 mutex_destroy(&samsung->mutex);
2413
2414 return 0;
2415 }
2416
samsung_mipi_dcphy_runtime_suspend(struct device * dev)2417 static __maybe_unused int samsung_mipi_dcphy_runtime_suspend(struct device *dev)
2418 {
2419 struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
2420
2421 clk_disable_unprepare(samsung->pclk);
2422 clk_disable_unprepare(samsung->ref_clk);
2423
2424 return 0;
2425 }
2426
samsung_mipi_dcphy_runtime_resume(struct device * dev)2427 static __maybe_unused int samsung_mipi_dcphy_runtime_resume(struct device *dev)
2428 {
2429 struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
2430
2431 clk_prepare_enable(samsung->pclk);
2432 clk_prepare_enable(samsung->ref_clk);
2433
2434 return 0;
2435 }
2436
2437 static const struct dev_pm_ops samsung_mipi_dcphy_pm_ops = {
2438 SET_RUNTIME_PM_OPS(samsung_mipi_dcphy_runtime_suspend,
2439 samsung_mipi_dcphy_runtime_resume, NULL)
2440 };
2441
2442 static const struct of_device_id samsung_mipi_dcphy_of_match[] = {
2443 {
2444 .compatible = "rockchip,rk3588-mipi-dcphy",
2445 },
2446 {}
2447 };
2448 MODULE_DEVICE_TABLE(of, samsung_mipi_dcphy_of_match);
2449
2450 static struct platform_driver samsung_mipi_dcphy_driver = {
2451 .driver = {
2452 .name = "samsung-mipi-dcphy",
2453 .of_match_table = of_match_ptr(samsung_mipi_dcphy_of_match),
2454 .pm = &samsung_mipi_dcphy_pm_ops,
2455 },
2456 .probe = samsung_mipi_dcphy_probe,
2457 .remove = samsung_mipi_dcphy_remove,
2458 };
2459 module_platform_driver(samsung_mipi_dcphy_driver);
2460
2461 MODULE_AUTHOR("Guochun Huang<hero.huang@rock-chips.com>");
2462 MODULE_DESCRIPTION("Samsung MIPI DCPHY Driver");
2463 MODULE_LICENSE("GPL v2");
2464