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