File Index
Files and directories
Sign in
FILE

phy-rockchip-samsung-dcphy.c

File preview with syntax highlighting.

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