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