android13/u-boot/drivers/video/drm/samsung_mipi_dcphy.c

1858 lines
66 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
*
* Author: Guochun Huang <hero.huang@rock-chips.com>
*/
#include <config.h>
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <div64.h>
#include <asm/io.h>
#include <asm/arch-rockchip/clock.h>
#include <linux/ioport.h>
#include <linux/iopoll.h>
#include <linux/math64.h>
#include <reset.h>
#include <regmap.h>
#include <syscon.h>
#include "rockchip_phy.h"
#define MAX_DPHY_BW 4500000L
#define MAX_CPHY_BW 2000000L
#define MSEC_PER_SEC 1000L
#define USEC_PER_SEC 1000000LL
#define PSEC_PER_SEC 1000000000000LL
#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
#define BIAS_CON0 0x0000
#define BIAS_CON1 0x0004
#define BIAS_CON2 0x0008
#define BIAS_CON4 0x0010
#define I_MUX_SEL_MASK GENMASK(6, 5)
#define I_MUX_SEL(x) UPDATE(x, 6, 5)
#define PLL_CON0 0x0100
#define PLL_EN BIT(12)
#define S_MASK GENMASK(10, 8)
#define S(x) UPDATE(x, 10, 8)
#define P_MASK GENMASK(5, 0)
#define P(x) UPDATE(x, 5, 0)
#define PLL_CON1 0x0104
#define PLL_CON2 0x0108
#define M_MASK GENMASK(9, 0)
#define M(x) UPDATE(x, 9, 0)
#define PLL_CON3 0x010c
#define MRR_MASK GENMASK(13, 8)
#define MRR(x) UPDATE(x, 13, 8)
#define MFR_MASK GENMASK(7, 0)
#define MFR(x) UPDATE(x, 7, 0)
#define PLL_CON4 0x0110
#define SSCG_EN BIT(11)
#define PLL_CON5 0x0114
#define RESET_N_SEL BIT(10)
#define PLL_ENABLE_SEL BIT(8)
#define PLL_CON6 0x0118
#define PLL_CON7 0x011c
#define PLL_LOCK_CNT(x) UPDATE(x, 15, 0)
#define PLL_CON8 0x0120
#define PLL_STB_CNT(x) UPDATE(x, 15, 0)
#define PLL_STAT0 0x0140
#define PLL_LOCK BIT(0)
#define DPHY_MC_GNR_CON0 0x0300
#define PHY_READY BIT(1)
#define PHY_ENABLE BIT(0)
#define DPHY_MC_GNR_CON1 0x0304
#define T_PHY_READY(x) UPDATE(x, 15, 0)
#define DPHY_MC_ANA_CON0 0x0308
#define DPHY_MC_ANA_CON1 0x030c
#define DPHY_MC_ANA_CON2 0x0310
#define HS_VREG_AMP_ICON(x) UPDATE(x, 1, 0)
#define DPHY_MC_TIME_CON0 0x0330
#define HSTX_CLK_SEL BIT(12)
#define T_LPX(x) UPDATE(x, 11, 4)
#define DPHY_MC_TIME_CON1 0x0334
#define T_CLK_ZERO(x) UPDATE(x, 15, 8)
#define T_CLK_PREPARE(x) UPDATE(x, 7, 0)
#define DPHY_MC_TIME_CON2 0x0338
#define T_HS_EXIT(x) UPDATE(x, 15, 8)
#define T_CLK_TRAIL(x) UPDATE(x, 7, 0)
#define DPHY_MC_TIME_CON3 0x033c
#define T_CLK_POST(x) UPDATE(x, 7, 0)
#define DPHY_MC_TIME_CON4 0x0340
#define T_ULPS_EXIT(x) UPDATE(x, 9, 0)
#define DPHY_MC_DESKEW_CON0 0x0350
#define SKEW_CAL_RUN_TIME(x) UPDATE(x, 15, 12)
#define SKEW_CAL_INIT_RUN_TIME(x) UPDATE(x, 11, 8)
#define SKEW_CAL_INIT_WAIT_TIME(x) UPDATE(x, 7, 4)
#define SKEW_CAL_EN BIT(0)
#define COMBO_MD0_GNR_CON0 0x0400
#define COMBO_MD0_GNR_CON1 0x0404
#define COMBO_MD0_ANA_CON0 0x0408
#define COMBO_MD0_ANA_CON1 0x040C
#define COMBO_MD0_ANA_CON2 0x0410
#define COMBO_MD0_TIME_CON0 0x0430
#define COMBO_MD0_TIME_CON1 0x0434
#define COMBO_MD0_TIME_CON2 0x0438
#define COMBO_MD0_TIME_CON3 0x043C
#define COMBO_MD0_TIME_CON4 0x0440
#define COMBO_MD0_DATA_CON0 0x0444
#define COMBO_MD1_GNR_CON0 0x0500
#define COMBO_MD1_GNR_CON1 0x0504
#define COMBO_MD1_ANA_CON0 0x0508
#define COMBO_MD1_ANA_CON1 0x050c
#define COMBO_MD1_ANA_CON2 0x0510
#define COMBO_MD1_TIME_CON0 0x0530
#define COMBO_MD1_TIME_CON1 0x0534
#define COMBO_MD1_TIME_CON2 0x0538
#define COMBO_MD1_TIME_CON3 0x053C
#define COMBO_MD1_TIME_CON4 0x0540
#define COMBO_MD1_DATA_CON0 0x0544
#define COMBO_MD2_GNR_CON0 0x0600
#define COMBO_MD2_GNR_CON1 0x0604
#define COMBO_MD2_ANA_CON0 0X0608
#define COMBO_MD2_ANA_CON1 0X060C
#define COMBO_MD2_ANA_CON2 0X0610
#define COMBO_MD2_TIME_CON0 0x0630
#define COMBO_MD2_TIME_CON1 0x0634
#define COMBO_MD2_TIME_CON2 0x0638
#define COMBO_MD2_TIME_CON3 0x063C
#define COMBO_MD2_TIME_CON4 0x0640
#define COMBO_MD2_DATA_CON0 0x0644
#define DPHY_MD3_GNR_CON0 0x0700
#define DPHY_MD3_GNR_CON1 0x0704
#define DPHY_MD3_ANA_CON0 0X0708
#define DPHY_MD3_ANA_CON1 0X070C
#define DPHY_MD3_ANA_CON2 0X0710
#define DPHY_MD3_TIME_CON0 0x0730
#define DPHY_MD3_TIME_CON1 0x0734
#define DPHY_MD3_TIME_CON2 0x0738
#define DPHY_MD3_TIME_CON3 0x073C
#define DPHY_MD3_TIME_CON4 0x0740
#define DPHY_MD3_DATA_CON0 0x0744
#define T_LP_EXIT_SKEW(x) UPDATE(x, 3, 2)
#define T_LP_ENTRY_SKEW(x) UPDATE(x, 1, 0)
#define T_HS_ZERO(x) UPDATE(x, 15, 8)
#define T_HS_PREPARE(x) UPDATE(x, 7, 0)
#define T_HS_EXIT(x) UPDATE(x, 15, 8)
#define T_HS_TRAIL(x) UPDATE(x, 7, 0)
#define T_TA_GET(x) UPDATE(x, 7, 4)
#define T_TA_GO(x) UPDATE(x, 3, 0)
/* MIPI_CDPHY_GRF registers */
#define MIPI_DCPHY_GRF_CON0 0x0000
#define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3)
#define M_CPHY_MODE HIWORD_UPDATE(1, 0, 0)
struct samsung_mipi_dphy_timing {
unsigned int max_lane_mbps;
u8 clk_prepare;
u8 clk_zero;
u8 clk_post;
u8 clk_trail_eot;
u8 hs_prepare;
u8 hs_zero;
u8 hs_trail_eot;
u8 lpx;
u8 hs_exit;
u8 hs_settle;
};
struct samsung_mipi_cphy_timing {
unsigned int max_lane_msps;
u8 prepare_3;
u8 prebegin_3;
u8 post_3;
u8 lpx;
u8 hs_exit;
u8 settle_3;
};
struct samsung_mipi_dcphy {
enum phy_mode mode;
void *base;
void *grf;
int lanes;
bool c_option;
struct reset_ctl m_phy_rst;
struct {
unsigned long long rate;
u8 prediv;
u16 fbdiv;
long dsm;
u8 scaler;
bool ssc_en;
u8 mfr;
u8 mrr;
} pll;
};
static const
struct samsung_mipi_dphy_timing samsung_mipi_dphy_timing_table[] = {
{6500, 32, 117, 31, 28, 30, 56, 27, 24, 44, 37},
{6490, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
{6480, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
{6470, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
{6460, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
{6450, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
{6440, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
{6430, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
{6420, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
{6410, 31, 116, 31, 27, 30, 55, 27, 24, 44, 37},
{6400, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
{6390, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
{6380, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
{6370, 31, 115, 30, 27, 30, 55, 26, 23, 43, 36},
{6360, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
{6350, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
{6340, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
{6330, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
{6320, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
{6310, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
{6300, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
{6290, 31, 113, 30, 27, 29, 54, 26, 23, 43, 36},
{6280, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
{6270, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
{6260, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
{6250, 31, 112, 30, 27, 29, 54, 26, 23, 42, 36},
{6240, 30, 113, 30, 27, 29, 54, 26, 23, 42, 36},
{6230, 30, 112, 30, 27, 29, 54, 26, 23, 42, 35},
{6220, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
{6210, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
{6200, 30, 112, 29, 27, 29, 53, 26, 23, 42, 35},
{6190, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
{6180, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
{6170, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
{6160, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
{6150, 30, 110, 29, 26, 29, 53, 26, 23, 42, 35},
{6140, 30, 110, 29, 26, 29, 52, 26, 23, 42, 35},
{6130, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
{6120, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
{6110, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
{6100, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
{6090, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
{6080, 30, 109, 29, 26, 28, 53, 25, 22, 41, 35},
{6070, 30, 109, 29, 26, 28, 52, 25, 22, 41, 34},
{6060, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
{6050, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
{6040, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
{6030, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
{6020, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
{6010, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
{6000, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
{5990, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
{5980, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
{5970, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
{5960, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
{5950, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
{5940, 29, 107, 28, 25, 28, 51, 25, 22, 40, 34},
{5930, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
{5920, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
{5910, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
{5900, 29, 106, 28, 25, 28, 50, 24, 22, 40, 33},
{5890, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
{5880, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
{5870, 29, 105, 28, 25, 27, 51, 24, 22, 40, 33},
{5860, 29, 105, 28, 25, 27, 51, 24, 21, 40, 33},
{5850, 29, 104, 28, 25, 27, 50, 24, 21, 40, 33},
{5840, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
{5830, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
{5820, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
{5810, 28, 104, 28, 25, 27, 50, 24, 21, 39, 33},
{5800, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
{5790, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
{5780, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
{5770, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
{5760, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
{5750, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
{5740, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
{5730, 28, 103, 27, 25, 27, 49, 24, 21, 39, 32},
{5720, 28, 102, 27, 25, 27, 49, 24, 21, 39, 32},
{5710, 28, 102, 27, 25, 27, 48, 24, 21, 39, 32},
{5700, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
{5690, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
{5680, 28, 101, 27, 24, 27, 48, 24, 21, 39, 32},
{5670, 28, 101, 27, 24, 27, 48, 23, 21, 38, 32},
{5660, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
{5650, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
{5640, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
{5630, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
{5620, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
{5610, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
{5600, 27, 101, 26, 24, 26, 48, 23, 20, 38, 32},
{5590, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
{5580, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
{5570, 27, 100, 26, 24, 26, 48, 23, 20, 38, 31},
{5560, 27, 100, 26, 24, 26, 47, 23, 20, 38, 31},
{5550, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
{5540, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
{5530, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31},
{5520, 27, 99, 26, 24, 26, 47, 23, 20, 37, 31},
{5510, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31},
{5500, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31},
{5490, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31},
{5480, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31},
{5470, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31},
{5460, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31},
{5450, 27, 97, 26, 23, 25, 47, 23, 20, 37, 31},
{5440, 26, 98, 26, 23, 25, 47, 23, 20, 37, 31},
{5430, 26, 98, 26, 23, 25, 47, 22, 20, 37, 31},
{5420, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31},
{5410, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31},
{5400, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30},
{5390, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30},
{5380, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
{5370, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
{5360, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
{5350, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30},
{5340, 26, 95, 25, 23, 25, 45, 22, 20, 36, 30},
{5330, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
{5320, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
{5310, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
{5300, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30},
{5290, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30},
{5280, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30},
{5270, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30},
{5260, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30},
{5250, 25, 94, 25, 23, 24, 45, 22, 19, 36, 30},
{5240, 25, 94, 25, 23, 24, 45, 22, 19, 36, 29},
{5230, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29},
{5220, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29},
{5210, 25, 93, 25, 22, 24, 45, 22, 19, 35, 29},
{5200, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
{5190, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
{5180, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29},
{5170, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
{5160, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
{5150, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
{5140, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29},
{5130, 25, 92, 24, 22, 24, 43, 21, 19, 35, 29},
{5120, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
{5110, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
{5100, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29},
{5090, 25, 91, 24, 22, 24, 43, 21, 19, 34, 29},
{5080, 25, 90, 24, 22, 24, 43, 21, 19, 34, 29},
{5070, 25, 90, 24, 22, 24, 43, 21, 19, 34, 28},
{5060, 25, 90, 24, 22, 24, 43, 21, 18, 34, 28},
{5050, 24, 91, 24, 22, 24, 42, 21, 18, 34, 28},
{5040, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
{5030, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
{5020, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
{5010, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28},
{5000, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28},
{4990, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28},
{4980, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28},
{4970, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28},
{4960, 24, 89, 23, 21, 23, 42, 20, 18, 34, 28},
{4950, 24, 88, 23, 21, 23, 42, 20, 18, 34, 28},
{4940, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
{4930, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
{4920, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28},
{4910, 24, 87, 23, 21, 23, 41, 20, 18, 33, 28},
{4900, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
{4890, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
{4880, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27},
{4870, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27},
{4860, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27},
{4850, 23, 87, 23, 21, 23, 41, 20, 18, 33, 27},
{4840, 23, 87, 23, 21, 23, 40, 20, 18, 33, 27},
{4830, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
{4820, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
{4810, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27},
{4800, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27},
{4790, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27},
{4780, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27},
{4770, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27},
{4760, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27},
{4750, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27},
{4740, 23, 84, 22, 20, 22, 40, 20, 17, 32, 26},
{4730, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
{4720, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
{4710, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26},
{4700, 23, 83, 22, 20, 22, 40, 19, 17, 32, 26},
{4690, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
{4680, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
{4670, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26},
{4660, 23, 82, 22, 20, 22, 39, 19, 17, 32, 26},
{4650, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
{4640, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
{4630, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26},
{4620, 22, 83, 22, 20, 21, 39, 19, 17, 31, 26},
{4610, 22, 82, 22, 20, 21, 39, 19, 17, 31, 26},
{4600, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
{4590, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
{4580, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26},
{4570, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25},
{4560, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25},
{4550, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25},
{4540, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25},
{4530, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
{4520, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
{4510, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25},
{4500, 22, 80, 21, 19, 21, 38, 19, 16, 30, 25},
{4490, 22, 80, 21, 19, 21, 38, 18, 16, 30, 25},
{4480, 22, 79, 21, 19, 21, 38, 18, 16, 30, 25},
{4470, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25},
{4460, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25},
{4450, 21, 80, 21, 19, 21, 37, 18, 16, 30, 25},
{4440, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
{4430, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
{4420, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25},
{4410, 21, 79, 21, 19, 20, 38, 18, 16, 30, 25},
{4400, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
{4390, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
{4380, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
{4370, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24},
{4360, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
{4350, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
{4340, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24},
{4330, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24},
{4320, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24},
{4310, 21, 76, 20, 19, 20, 36, 18, 16, 29, 24},
{4300, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
{4290, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
{4280, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24},
{4270, 21, 75, 20, 18, 20, 36, 18, 16, 29, 24},
{4260, 21, 75, 20, 18, 20, 35, 17, 15, 29, 24},
{4250, 20, 76, 20, 18, 20, 35, 17, 15, 29, 24},
{4240, 20, 76, 20, 18, 20, 35, 17, 15, 29, 23},
{4230, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23},
{4220, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23},
{4210, 20, 75, 20, 18, 20, 35, 17, 15, 28, 23},
{4200, 20, 75, 19, 18, 19, 36, 17, 15, 28, 23},
{4190, 20, 74, 19, 18, 19, 36, 17, 15, 28, 23},
{4180, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
{4170, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
{4160, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
{4150, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23},
{4140, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
{4130, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
{4120, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23},
{4110, 20, 73, 19, 18, 19, 34, 17, 15, 28, 23},
{4100, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
{4090, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
{4080, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23},
{4070, 20, 72, 19, 18, 19, 34, 17, 15, 27, 22},
{4060, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22},
{4050, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22},
{4040, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22},
{4030, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22},
{4020, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22},
{4010, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22},
{4000, 19, 71, 18, 17, 19, 33, 16, 14, 27, 22},
{3990, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22},
{3980, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22},
{3970, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
{3960, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
{3950, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
{3940, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22},
{3930, 19, 69, 18, 17, 18, 33, 16, 14, 27, 22},
{3920, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22},
{3910, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22},
{3900, 19, 69, 18, 17, 18, 33, 16, 14, 26, 21},
{3890, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
{3880, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
{3870, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21},
{3860, 18, 69, 18, 17, 18, 32, 16, 14, 26, 21},
{3850, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21},
{3840, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21},
{3830, 18, 68, 18, 16, 18, 32, 16, 14, 26, 21},
{3820, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21},
{3810, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21},
{3800, 18, 67, 17, 16, 18, 31, 16, 14, 26, 21},
{3790, 18, 67, 17, 16, 17, 32, 15, 14, 26, 21},
{3780, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21},
{3770, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21},
{3760, 18, 66, 17, 16, 17, 32, 15, 14, 25, 21},
{3750, 18, 66, 17, 16, 17, 31, 15, 14, 25, 21},
{3740, 18, 66, 17, 16, 17, 31, 15, 14, 25, 20},
{3730, 18, 66, 17, 16, 17, 31, 15, 13, 25, 20},
{3720, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
{3710, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
{3700, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
{3690, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20},
{3680, 18, 64, 17, 16, 17, 31, 15, 13, 25, 20},
{3670, 18, 64, 17, 16, 17, 30, 15, 13, 25, 20},
{3660, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
{3650, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
{3640, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20},
{3630, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
{3620, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
{3610, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20},
{3600, 17, 64, 16, 16, 17, 29, 15, 13, 24, 20},
{3590, 17, 63, 16, 15, 17, 29, 15, 13, 24, 20},
{3580, 17, 63, 16, 15, 16, 30, 15, 13, 24, 20},
{3570, 17, 63, 16, 15, 16, 30, 15, 13, 24, 19},
{3560, 17, 63, 16, 15, 16, 30, 14, 13, 24, 19},
{3550, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19},
{3540, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19},
{3530, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
{3520, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
{3510, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19},
{3500, 17, 61, 16, 15, 16, 29, 14, 13, 24, 19},
{3490, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
{3480, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
{3470, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19},
{3460, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
{3450, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
{3440, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
{3430, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19},
{3420, 16, 60, 16, 15, 16, 28, 14, 12, 23, 19},
{3410, 16, 60, 16, 15, 16, 28, 14, 12, 23, 18},
{3400, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18},
{3390, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18},
{3380, 16, 59, 15, 15, 16, 27, 14, 12, 23, 18},
{3370, 16, 59, 15, 15, 15, 28, 14, 12, 23, 18},
{3360, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18},
{3350, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18},
{3340, 16, 59, 15, 14, 15, 28, 14, 12, 22, 18},
{3330, 16, 58, 15, 14, 15, 28, 14, 12, 22, 18},
{3320, 16, 58, 15, 14, 15, 28, 13, 12, 22, 18},
{3310, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18},
{3300, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18},
{3290, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
{3280, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
{3270, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18},
{3260, 15, 58, 15, 14, 15, 27, 13, 12, 22, 18},
{3250, 15, 57, 15, 14, 15, 27, 13, 12, 22, 18},
{3240, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
{3230, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
{3220, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17},
{3210, 15, 56, 15, 14, 15, 26, 13, 12, 22, 17},
{3200, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
{3190, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
{3180, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17},
{3170, 15, 56, 14, 14, 15, 25, 13, 11, 21, 17},
{3160, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
{3150, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
{3140, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
{3130, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17},
{3120, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
{3110, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
{3100, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17},
{3090, 15, 54, 14, 13, 14, 25, 12, 11, 21, 17},
{3080, 15, 53, 14, 13, 14, 25, 12, 11, 21, 17},
{3070, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16},
{3060, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16},
{3050, 14, 54, 14, 13, 14, 25, 12, 11, 20, 16},
{3040, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16},
{3030, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16},
{3020, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16},
{3010, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16},
{3000, 14, 53, 13, 13, 14, 24, 12, 11, 20, 16},
{2990, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
{2980, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
{2970, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
{2960, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16},
{2950, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16},
{2940, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16},
{2930, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16},
{2920, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16},
{2910, 14, 50, 13, 13, 13, 24, 12, 10, 20, 15},
{2900, 14, 50, 13, 13, 13, 24, 12, 10, 19, 15},
{2890, 14, 50, 13, 12, 13, 24, 12, 10, 19, 15},
{2880, 14, 50, 13, 12, 13, 23, 12, 10, 19, 15},
{2870, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15},
{2860, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15},
{2850, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
{2840, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
{2830, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15},
{2820, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15},
{2810, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15},
{2800, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15},
{2790, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15},
{2780, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15},
{2770, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15},
{2760, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15},
{2750, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15},
{2740, 13, 47, 12, 12, 12, 23, 11, 10, 18, 14},
{2730, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
{2720, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
{2710, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
{2700, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14},
{2690, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14},
{2680, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14},
{2670, 12, 47, 12, 12, 12, 22, 11, 10, 18, 14},
{2660, 12, 47, 12, 12, 12, 21, 11, 9, 18, 14},
{2650, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
{2640, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
{2630, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14},
{2620, 12, 46, 12, 11, 12, 21, 10, 9, 18, 14},
{2610, 12, 45, 12, 11, 12, 21, 10, 9, 17, 14},
{2600, 12, 45, 11, 11, 12, 21, 10, 9, 17, 14},
{2590, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14},
{2580, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14},
{2570, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
{2560, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
{2550, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13},
{2540, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13},
{2530, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13},
{2520, 12, 43, 11, 11, 11, 21, 10, 9, 17, 13},
{2510, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
{2500, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
{2490, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13},
{2480, 12, 42, 11, 11, 11, 20, 10, 9, 17, 13},
{2470, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
{2460, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
{2450, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13},
{2440, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13},
{2430, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13},
{2420, 11, 42, 11, 10, 11, 19, 10, 9, 16, 13},
{2410, 11, 42, 11, 10, 11, 19, 10, 9, 16, 12},
{2400, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12},
{2390, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12},
{2380, 11, 41, 10, 10, 11, 19, 9, 8, 16, 12},
{2370, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12},
{2360, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12},
{2350, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12},
{2340, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12},
{2330, 11, 40, 10, 10, 10, 19, 9, 8, 16, 12},
{2320, 11, 40, 10, 10, 10, 19, 9, 8, 15, 12},
{2310, 11, 39, 10, 10, 10, 19, 9, 8, 15, 12},
{2300, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2290, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2280, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2270, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2260, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2250, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12},
{2240, 10, 39, 10, 10, 10, 18, 9, 8, 15, 11},
{2230, 10, 38, 10, 10, 10, 18, 9, 8, 15, 11},
{2220, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11},
{2210, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11},
{2200, 10, 38, 9, 10, 10, 17, 9, 8, 15, 11},
{2190, 10, 38, 9, 9, 10, 17, 9, 8, 15, 11},
{2180, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
{2170, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
{2160, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11},
{2150, 10, 37, 9, 9, 10, 16, 8, 8, 14, 11},
{2140, 10, 36, 9, 9, 10, 16, 8, 8, 14, 11},
{2130, 10, 36, 9, 9, 10, 16, 8, 7, 14, 11},
{2120, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11},
{2110, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11},
{2100, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11},
{2090, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11},
{2080, 9, 36, 9, 9, 9, 16, 8, 7, 14, 11},
{2070, 9, 36, 9, 9, 9, 16, 8, 7, 14, 10},
{2060, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
{2050, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
{2040, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10},
{2030, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10},
{2020, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10},
{2010, 9, 34, 9, 9, 9, 15, 8, 7, 13, 10},
{2000, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
{1990, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
{1980, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10},
{1970, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10},
{1960, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10},
{1950, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10},
{1940, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10},
{1930, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10},
{1920, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10},
{1910, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9},
{1900, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9},
{1890, 9, 31, 8, 8, 8, 15, 7, 7, 12, 9},
{1880, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9},
{1870, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9},
{1860, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9},
{1850, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9},
{1840, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
{1830, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
{1820, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
{1810, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9},
{1800, 8, 30, 7, 8, 8, 14, 7, 6, 12, 9},
{1790, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
{1780, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
{1770, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9},
{1760, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9},
{1750, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9},
{1740, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8},
{1730, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8},
{1720, 8, 29, 7, 7, 8, 13, 7, 6, 11, 8},
{1710, 8, 28, 7, 7, 8, 12, 7, 6, 11, 8},
{1700, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8},
{1690, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8},
{1680, 7, 29, 7, 7, 7, 13, 6, 6, 11, 8},
{1670, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
{1660, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
{1650, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8},
{1640, 7, 28, 7, 7, 7, 12, 6, 6, 11, 8},
{1630, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
{1620, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
{1610, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8},
{1600, 7, 27, 6, 7, 7, 12, 6, 5, 10, 8},
{1590, 7, 26, 6, 7, 7, 12, 6, 5, 10, 8},
{1580, 7, 26, 6, 7, 7, 12, 6, 5, 10, 7},
{1570, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
{1560, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
{1550, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7},
{1540, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
{1530, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
{1520, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
{1510, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7},
{1500, 7, 24, 6, 7, 7, 10, 6, 5, 10, 7},
{1490, 59, 25, 6, 77, 59, 10, 70, 44, 9, 73},
{1480, 59, 24, 6, 76, 58, 10, 70, 44, 9, 73},
{1470, 58, 24, 6, 76, 58, 10, 69, 44, 9, 72},
{1460, 58, 24, 6, 76, 58, 10, 69, 43, 9, 72},
{1450, 58, 24, 6, 75, 57, 10, 68, 43, 9, 71},
{1440, 57, 24, 6, 75, 57, 10, 68, 43, 9, 71},
{1430, 57, 23, 6, 75, 57, 10, 68, 43, 8, 70},
{1420, 56, 23, 6, 74, 57, 9, 67, 43, 8, 70},
{1410, 56, 23, 6, 74, 57, 9, 67, 43, 8, 69},
{1400, 56, 23, 5, 74, 55, 9, 67, 41, 8, 69},
{1390, 55, 23, 5, 73, 55, 9, 66, 41, 8, 68},
{1380, 55, 23, 5, 73, 54, 9, 66, 41, 8, 68},
{1370, 54, 22, 5, 72, 54, 9, 66, 41, 8, 67},
{1360, 54, 22, 5, 72, 54, 9, 65, 40, 8, 67},
{1350, 54, 22, 5, 72, 53, 9, 65, 40, 8, 66},
{1340, 53, 22, 5, 71, 53, 9, 65, 40, 8, 66},
{1330, 53, 22, 5, 71, 53, 9, 64, 39, 8, 65},
{1320, 52, 22, 5, 71, 53, 8, 64, 40, 8, 65},
{1310, 52, 21, 5, 70, 53, 8, 64, 40, 8, 64},
{1300, 51, 21, 5, 70, 51, 8, 63, 38, 8, 64},
{1290, 51, 21, 5, 70, 51, 8, 63, 38, 7, 64},
{1280, 51, 21, 5, 69, 51, 8, 63, 38, 7, 63},
{1270, 50, 21, 5, 69, 50, 8, 62, 38, 7, 63},
{1260, 50, 20, 5, 69, 50, 8, 62, 37, 7, 62},
{1250, 49, 20, 5, 68, 49, 8, 62, 37, 7, 62},
{1240, 49, 20, 5, 68, 49, 8, 61, 37, 7, 61},
{1230, 49, 20, 5, 68, 49, 8, 61, 36, 7, 61},
{1220, 48, 20, 5, 67, 48, 8, 61, 36, 7, 60},
{1210, 48, 19, 5, 67, 48, 7, 60, 36, 7, 60},
{1200, 49, 19, 4, 67, 49, 7, 60, 36, 7, 59},
{1190, 48, 19, 4, 66, 48, 7, 60, 36, 7, 59},
{1180, 48, 19, 4, 66, 48, 7, 59, 36, 7, 58},
{1170, 46, 19, 4, 66, 46, 7, 59, 35, 7, 58},
{1160, 46, 18, 4, 65, 46, 7, 59, 34, 7, 57},
{1150, 45, 18, 4, 65, 46, 7, 58, 34, 7, 57},
{1140, 45, 18, 4, 65, 45, 7, 58, 34, 6, 56},
{1130, 45, 18, 4, 64, 45, 7, 58, 33, 6, 56},
{1120, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55},
{1110, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55},
{1100, 43, 17, 4, 63, 44, 6, 57, 32, 6, 54},
{1090, 43, 17, 4, 63, 44, 6, 56, 33, 6, 54},
{1080, 43, 17, 4, 63, 44, 6, 56, 33, 6, 53},
{1070, 42, 17, 4, 62, 44, 6, 56, 33, 6, 53},
{1060, 42, 17, 4, 62, 42, 6, 55, 31, 6, 52},
{1050, 41, 17, 4, 62, 42, 6, 55, 31, 6, 52},
{1040, 41, 16, 4, 61, 41, 6, 54, 31, 6, 52},
{1030, 41, 16, 4, 61, 41, 6, 54, 30, 6, 51},
{1020, 40, 16, 4, 61, 41, 6, 54, 30, 6, 51},
{1010, 40, 16, 4, 60, 40, 6, 53, 30, 6, 50},
{1000, 39, 16, 3, 60, 40, 6, 53, 29, 5, 50},
{ 990, 39, 15, 3, 60, 39, 6, 53, 29, 5, 49},
{ 980, 39, 15, 3, 59, 39, 5, 52, 29, 5, 49},
{ 970, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48},
{ 960, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48},
{ 950, 37, 15, 3, 58, 39, 5, 51, 29, 5, 47},
{ 940, 37, 14, 3, 58, 39, 5, 51, 29, 5, 47},
{ 930, 37, 14, 3, 57, 37, 5, 51, 27, 5, 46},
{ 920, 36, 14, 3, 57, 37, 5, 50, 27, 5, 46},
{ 910, 36, 14, 3, 57, 36, 5, 50, 27, 5, 45},
{ 900, 35, 14, 3, 56, 36, 5, 50, 26, 5, 45},
{ 890, 35, 14, 3, 56, 36, 5, 49, 26, 5, 44},
{ 880, 35, 13, 3, 56, 35, 5, 49, 26, 5, 44},
{ 870, 34, 13, 3, 55, 35, 4, 49, 26, 5, 43},
{ 860, 34, 13, 3, 55, 35, 4, 48, 25, 5, 43},
{ 850, 33, 13, 3, 55, 35, 4, 48, 26, 4, 42},
{ 840, 33, 13, 3, 54, 35, 4, 48, 26, 4, 42},
{ 830, 33, 12, 3, 54, 33, 4, 47, 24, 4, 41},
{ 820, 32, 12, 3, 54, 33, 4, 47, 24, 4, 41},
{ 810, 32, 12, 3, 53, 33, 4, 47, 24, 4, 40},
{ 800, 31, 12, 2, 53, 32, 4, 46, 23, 4, 40},
{ 790, 31, 12, 2, 53, 32, 4, 46, 23, 4, 39},
{ 780, 30, 12, 2, 52, 31, 4, 46, 23, 4, 39},
{ 770, 30, 11, 2, 52, 31, 4, 45, 23, 4, 39},
{ 760, 30, 11, 2, 52, 31, 3, 45, 22, 4, 38},
{ 750, 29, 11, 2, 51, 30, 3, 45, 22, 4, 38},
{ 740, 29, 11, 2, 51, 30, 3, 44, 22, 4, 37},
{ 730, 28, 11, 2, 51, 31, 3, 44, 22, 4, 37},
{ 720, 28, 10, 2, 50, 30, 3, 44, 22, 4, 36},
{ 710, 28, 10, 2, 50, 30, 3, 43, 22, 4, 36},
{ 700, 27, 10, 2, 50, 28, 3, 43, 20, 3, 35},
{ 690, 27, 10, 2, 49, 28, 3, 43, 20, 3, 35},
{ 680, 26, 10, 2, 49, 28, 3, 42, 20, 3, 34},
{ 670, 26, 10, 2, 49, 27, 3, 42, 20, 3, 34},
{ 660, 26, 9, 2, 48, 27, 3, 42, 19, 3, 33},
{ 650, 25, 9, 2, 48, 26, 3, 41, 19, 3, 33},
{ 640, 25, 9, 2, 48, 26, 2, 41, 19, 3, 32},
{ 630, 24, 9, 2, 47, 26, 2, 40, 18, 3, 32},
{ 620, 24, 9, 2, 47, 26, 2, 40, 19, 3, 31},
{ 610, 24, 8, 2, 47, 26, 2, 40, 19, 3, 31},
{ 600, 23, 8, 1, 46, 26, 2, 39, 18, 3, 30},
{ 590, 23, 8, 1, 46, 24, 2, 39, 17, 3, 30},
{ 580, 22, 8, 1, 46, 24, 2, 39, 17, 3, 29},
{ 570, 22, 8, 1, 45, 23, 2, 38, 17, 3, 29},
{ 560, 22, 7, 1, 45, 23, 2, 38, 16, 2, 28},
{ 550, 21, 7, 1, 45, 23, 2, 38, 16, 2, 28},
{ 540, 21, 7, 1, 44, 22, 2, 37, 16, 2, 27},
{ 530, 20, 7, 1, 44, 22, 1, 37, 15, 2, 27},
{ 520, 20, 7, 1, 43, 21, 1, 37, 15, 2, 27},
{ 510, 20, 6, 1, 43, 21, 1, 36, 15, 2, 26},
{ 500, 19, 6, 1, 43, 22, 1, 36, 15, 2, 26},
{ 490, 19, 6, 1, 42, 21, 1, 36, 15, 2, 25},
{ 480, 18, 6, 1, 42, 21, 1, 35, 15, 2, 25},
{ 470, 18, 6, 1, 42, 21, 1, 35, 15, 2, 24},
{ 460, 18, 6, 1, 41, 19, 1, 35, 13, 2, 24},
{ 450, 17, 5, 1, 41, 19, 1, 34, 13, 2, 23},
{ 440, 17, 5, 1, 41, 18, 1, 34, 13, 2, 23},
{ 430, 16, 5, 1, 40, 18, 0, 34, 12, 2, 22},
{ 420, 16, 5, 1, 40, 18, 0, 33, 12, 2, 22},
{ 410, 16, 5, 1, 40, 17, 0, 33, 12, 1, 21},
{ 400, 15, 5, 0, 39, 17, 0, 33, 11, 1, 21},
{ 390, 15, 4, 0, 39, 17, 0, 32, 12, 1, 20},
{ 380, 14, 4, 0, 39, 17, 0, 32, 12, 1, 20},
{ 370, 14, 4, 0, 38, 17, 0, 32, 12, 1, 19},
{ 360, 14, 4, 0, 38, 15, 0, 31, 10, 1, 19},
{ 350, 13, 4, 0, 38, 15, 0, 31, 10, 1, 18},
{ 340, 13, 3, 0, 37, 15, 0, 31, 10, 1, 18},
{ 330, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17},
{ 320, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17},
{ 310, 12, 3, 0, 36, 13, 0, 30, 9, 1, 16},
{ 300, 11, 3, 0, 36, 13, 0, 29, 8, 1, 16},
{ 290, 11, 2, 0, 36, 13, 0, 29, 8, 1, 15},
{ 280, 10, 2, 0, 35, 12, 0, 29, 8, 1, 15},
{ 270, 10, 2, 0, 35, 12, 0, 28, 8, 0, 14},
{ 260, 9, 2, 0, 35, 12, 0, 28, 8, 0, 14},
{ 250, 9, 2, 0, 34, 12, 0, 28, 8, 0, 14},
{ 240, 9, 2, 0, 34, 12, 0, 27, 8, 0, 13},
{ 230, 8, 1, 0, 34, 10, 0, 27, 6, 0, 13},
{ 220, 8, 1, 0, 33, 10, 0, 27, 6, 0, 12},
{ 210, 7, 1, 0, 33, 10, 0, 26, 6, 0, 12},
{ 200, 7, 1, 0, 33, 9, 0, 26, 5, 0, 11},
{ 190, 7, 1, 0, 32, 9, 0, 25, 5, 0, 11},
{ 180, 6, 1, 0, 32, 8, 0, 25, 5, 0, 10},
{ 170, 6, 0, 0, 32, 8, 0, 25, 5, 0, 10},
{ 160, 5, 0, 0, 31, 8, 0, 24, 4, 0, 9},
{ 150, 5, 0, 0, 31, 8, 0, 24, 5, 0, 9},
{ 140, 5, 0, 0, 31, 8, 0, 24, 5, 0, 8},
{ 130, 4, 0, 0, 30, 6, 0, 23, 3, 0, 8},
{ 120, 4, 0, 0, 30, 6, 0, 23, 3, 0, 7},
{ 110, 3, 0, 0, 30, 6, 0, 23, 3, 0, 7},
{ 100, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6},
{ 90, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6},
{ 80, 2, 0, 0, 28, 5, 0, 22, 2, 0, 5},
};
static const
struct samsung_mipi_cphy_timing samsung_mipi_cphy_timing_table[] = {
{ 3500, 39, 50, 25, 29, 54, 1 },
{ 3490, 39, 50, 25, 29, 54, 1 },
{ 3480, 39, 50, 25, 29, 54, 1 },
{ 3470, 39, 50, 25, 29, 54, 1 },
{ 3460, 39, 50, 25, 29, 54, 1 },
{ 3450, 39, 50, 25, 29, 54, 1 },
{ 3440, 38, 50, 25, 29, 54, 1 },
{ 3430, 38, 50, 25, 29, 53, 1 },
{ 3420, 38, 50, 25, 29, 53, 1 },
{ 3410, 38, 50, 25, 29, 53, 1 },
{ 3400, 38, 50, 25, 29, 53, 1 },
{ 3390, 38, 50, 25, 29, 53, 1 },
{ 3380, 38, 50, 25, 28, 53, 1 },
{ 3370, 38, 50, 25, 28, 52, 1 },
{ 3360, 37, 50, 25, 28, 52, 1 },
{ 3350, 37, 50, 25, 28, 52, 1 },
{ 3340, 37, 50, 25, 28, 52, 1 },
{ 3330, 37, 50, 25, 28, 52, 1 },
{ 3320, 37, 50, 25, 28, 52, 1 },
{ 3310, 37, 50, 25, 28, 52, 1 },
{ 3300, 37, 50, 25, 28, 51, 1 },
{ 3290, 37, 50, 25, 28, 51, 1 },
{ 3280, 37, 50, 25, 28, 51, 1 },
{ 3270, 36, 50, 25, 28, 51, 1 },
{ 3260, 36, 50, 25, 27, 51, 1 },
{ 3250, 36, 50, 25, 27, 51, 1 },
{ 3240, 36, 50, 25, 27, 50, 1 },
{ 3230, 36, 50, 25, 27, 50, 1 },
{ 3220, 36, 50, 25, 27, 50, 1 },
{ 3210, 36, 50, 25, 27, 50, 1 },
{ 3200, 36, 50, 25, 27, 50, 1 },
{ 3190, 36, 50, 25, 27, 50, 1 },
{ 3180, 35, 50, 25, 27, 49, 1 },
{ 3170, 35, 50, 25, 27, 49, 1 },
{ 3160, 35, 50, 25, 27, 49, 1 },
{ 3150, 35, 50, 25, 26, 49, 1 },
{ 3140, 35, 50, 25, 26, 49, 1 },
{ 3130, 35, 50, 25, 26, 49, 1 },
{ 3120, 35, 50, 25, 26, 49, 1 },
{ 3110, 35, 50, 25, 26, 48, 1 },
{ 3100, 34, 50, 25, 26, 48, 1 },
{ 3090, 34, 50, 25, 26, 48, 1 },
{ 3080, 34, 50, 25, 26, 48, 1 },
{ 3070, 34, 50, 25, 26, 48, 1 },
{ 3060, 34, 50, 25, 26, 48, 1 },
{ 3050, 34, 50, 25, 26, 47, 1 },
{ 3040, 34, 50, 25, 26, 47, 1 },
{ 3030, 34, 50, 25, 25, 47, 1 },
{ 3020, 34, 50, 25, 25, 47, 1 },
{ 3010, 33, 50, 25, 25, 47, 1 },
{ 3000, 33, 50, 25, 25, 47, 1 },
{ 2990, 33, 50, 25, 25, 46, 1 },
{ 2980, 33, 50, 25, 25, 46, 1 },
{ 2970, 33, 50, 25, 25, 46, 1 },
{ 2960, 33, 50, 25, 25, 46, 1 },
{ 2950, 33, 50, 25, 25, 46, 1 },
{ 2940, 33, 50, 25, 25, 46, 1 },
{ 2930, 33, 50, 25, 25, 46, 1 },
{ 2920, 32, 50, 25, 25, 45, 1 },
{ 2910, 32, 50, 25, 24, 45, 1 },
{ 2900, 32, 50, 25, 24, 45, 1 },
{ 2890, 32, 50, 25, 24, 45, 1 },
{ 2880, 32, 50, 25, 24, 45, 1 },
{ 2870, 32, 50, 25, 24, 45, 1 },
{ 2860, 32, 50, 25, 24, 44, 1 },
{ 2850, 32, 50, 25, 24, 44, 1 },
{ 2840, 31, 50, 25, 24, 44, 1 },
{ 2830, 31, 50, 25, 24, 44, 1 },
{ 2820, 31, 50, 25, 24, 44, 1 },
{ 2810, 31, 50, 25, 24, 44, 1 },
{ 2800, 31, 50, 25, 23, 43, 1 },
{ 2790, 31, 50, 25, 23, 43, 1 },
{ 2780, 31, 50, 25, 23, 43, 1 },
{ 2770, 31, 50, 25, 23, 43, 1 },
{ 2760, 31, 50, 25, 23, 43, 1 },
{ 2750, 30, 50, 25, 23, 43, 1 },
{ 2740, 30, 50, 25, 23, 43, 1 },
{ 2730, 30, 50, 25, 23, 42, 1 },
{ 2720, 30, 50, 25, 23, 42, 1 },
{ 2710, 30, 50, 25, 23, 42, 1 },
{ 2700, 30, 50, 25, 23, 42, 1 },
{ 2690, 30, 50, 25, 23, 42, 1 },
{ 2680, 30, 50, 25, 22, 42, 1 },
{ 2670, 30, 50, 25, 22, 41, 1 },
{ 2660, 29, 50, 25, 22, 41, 1 },
{ 2650, 29, 50, 25, 22, 41, 1 },
{ 2640, 29, 50, 25, 22, 41, 1 },
{ 2630, 29, 50, 25, 22, 41, 1 },
{ 2620, 29, 50, 25, 22, 41, 1 },
{ 2610, 29, 50, 25, 22, 41, 1 },
{ 2600, 29, 50, 25, 22, 40, 1 },
{ 2590, 29, 50, 25, 22, 40, 1 },
{ 2580, 28, 50, 25, 22, 40, 1 },
{ 2570, 28, 50, 25, 22, 40, 1 },
{ 2560, 28, 50, 25, 21, 40, 1 },
{ 2550, 28, 50, 25, 21, 40, 1 },
{ 2540, 28, 50, 25, 21, 39, 1 },
{ 2530, 28, 50, 25, 21, 39, 1 },
{ 2520, 28, 50, 25, 21, 39, 1 },
{ 2510, 28, 50, 25, 21, 39, 1 },
{ 2500, 28, 50, 25, 21, 39, 1 },
{ 2490, 27, 50, 25, 21, 39, 1 },
{ 2480, 27, 50, 25, 21, 38, 1 },
{ 2470, 27, 50, 25, 21, 38, 1 },
{ 2460, 27, 50, 25, 21, 38, 1 },
{ 2450, 27, 50, 25, 20, 38, 1 },
{ 2440, 27, 50, 25, 20, 38, 1 },
{ 2430, 27, 50, 25, 20, 38, 1 },
{ 2420, 27, 50, 25, 20, 38, 1 },
{ 2410, 27, 50, 25, 20, 37, 1 },
{ 2400, 26, 50, 25, 20, 37, 1 },
{ 2390, 26, 50, 25, 20, 37, 1 },
{ 2380, 26, 50, 25, 20, 37, 1 },
{ 2370, 26, 50, 25, 20, 37, 1 },
{ 2360, 26, 50, 25, 20, 37, 1 },
{ 2350, 26, 50, 25, 20, 36, 1 },
{ 2340, 26, 50, 25, 20, 36, 1 },
{ 2330, 26, 50, 25, 19, 36, 1 },
{ 2320, 25, 50, 25, 19, 36, 1 },
{ 2310, 25, 50, 25, 19, 36, 1 },
{ 2300, 25, 50, 25, 19, 36, 1 },
{ 2290, 25, 50, 25, 19, 35, 1 },
{ 2280, 25, 50, 25, 19, 35, 1 },
{ 2270, 25, 50, 25, 19, 35, 1 },
{ 2260, 25, 50, 25, 19, 35, 1 },
{ 2250, 25, 50, 25, 19, 35, 1 },
{ 2240, 25, 50, 25, 19, 35, 1 },
{ 2230, 24, 50, 25, 19, 35, 1 },
{ 2220, 24, 50, 25, 19, 34, 1 },
{ 2210, 24, 50, 25, 18, 34, 1 },
{ 2200, 24, 50, 25, 18, 34, 1 },
{ 2190, 24, 50, 25, 18, 34, 1 },
{ 2180, 24, 50, 25, 18, 34, 1 },
{ 2170, 24, 50, 25, 18, 34, 1 },
{ 2160, 24, 50, 25, 18, 33, 1 },
{ 2150, 24, 50, 25, 18, 33, 1 },
{ 2140, 23, 50, 25, 18, 33, 1 },
{ 2130, 23, 50, 25, 18, 33, 1 },
{ 2120, 23, 50, 25, 18, 33, 1 },
{ 2110, 23, 50, 25, 18, 33, 1 },
{ 2100, 23, 50, 25, 17, 32, 1 },
{ 2090, 23, 50, 25, 17, 32, 1 },
{ 2080, 23, 50, 25, 17, 32, 1 },
{ 2070, 23, 50, 25, 17, 32, 1 },
{ 2060, 22, 50, 25, 17, 32, 1 },
{ 2050, 22, 50, 25, 17, 32, 1 },
{ 2040, 22, 50, 25, 17, 32, 1 },
{ 2030, 22, 50, 25, 17, 31, 1 },
{ 2020, 22, 50, 25, 17, 31, 1 },
{ 2010, 22, 50, 25, 17, 31, 1 },
{ 2000, 22, 50, 25, 17, 31, 1 },
{ 1990, 22, 50, 25, 17, 31, 1 },
{ 1980, 22, 50, 25, 16, 31, 1 },
{ 1970, 21, 50, 25, 16, 30, 1 },
{ 1960, 21, 50, 25, 16, 30, 1 },
{ 1950, 21, 50, 25, 16, 30, 1 },
{ 1940, 21, 50, 25, 16, 30, 1 },
{ 1930, 21, 50, 25, 16, 30, 1 },
{ 1920, 21, 50, 25, 16, 30, 1 },
{ 1910, 21, 50, 25, 16, 30, 1 },
{ 1900, 21, 50, 25, 16, 29, 1 },
{ 1890, 21, 50, 25, 16, 29, 1 },
{ 1880, 20, 50, 25, 16, 29, 1 },
{ 1870, 20, 50, 25, 16, 29, 1 },
{ 1860, 20, 50, 25, 15, 29, 1 },
{ 1850, 20, 50, 25, 15, 29, 1 },
{ 1840, 20, 50, 25, 15, 28, 1 },
{ 1830, 20, 50, 25, 15, 28, 1 },
{ 1820, 20, 50, 25, 15, 28, 1 },
{ 1810, 20, 50, 25, 15, 28, 1 },
{ 1800, 19, 50, 25, 15, 28, 1 },
{ 1790, 19, 50, 25, 15, 28, 1 },
{ 1780, 19, 50, 25, 15, 27, 1 },
{ 1770, 19, 50, 25, 15, 27, 1 },
{ 1760, 19, 50, 25, 15, 27, 1 },
{ 1750, 19, 50, 25, 14, 27, 1 },
{ 1740, 19, 50, 25, 14, 27, 1 },
{ 1730, 19, 50, 25, 14, 27, 1 },
{ 1720, 19, 50, 25, 14, 27, 1 },
{ 1710, 18, 50, 25, 14, 26, 1 },
{ 1700, 18, 50, 25, 14, 26, 1 },
{ 1690, 18, 50, 25, 14, 26, 1 },
{ 1680, 18, 50, 25, 14, 26, 1 },
{ 1670, 18, 50, 25, 14, 26, 1 },
{ 1660, 18, 50, 25, 14, 26, 1 },
{ 1650, 18, 50, 25, 14, 25, 1 },
{ 1640, 18, 50, 25, 14, 25, 1 },
{ 1630, 18, 50, 25, 13, 25, 1 },
{ 1620, 17, 50, 25, 13, 25, 1 },
{ 1610, 17, 50, 25, 13, 25, 1 },
{ 1600, 17, 50, 25, 13, 25, 1 },
{ 1590, 17, 50, 25, 13, 24, 1 },
{ 1580, 17, 50, 25, 13, 24, 1 },
{ 1570, 17, 50, 25, 13, 24, 1 },
{ 1560, 17, 50, 25, 13, 24, 1 },
{ 1550, 17, 50, 25, 13, 24, 1 },
{ 1540, 16, 50, 25, 13, 24, 1 },
{ 1530, 16, 50, 25, 13, 24, 1 },
{ 1520, 16, 50, 25, 13, 23, 1 },
{ 1510, 16, 50, 25, 12, 23, 1 },
{ 1500, 16, 50, 25, 12, 23, 1 },
{ 1490, 16, 50, 25, 12, 23, 1 },
{ 1480, 16, 50, 25, 12, 23, 1 },
{ 1470, 16, 50, 25, 12, 23, 1 },
{ 1460, 16, 50, 25, 12, 22, 1 },
{ 1450, 15, 50, 25, 12, 22, 1 },
{ 1440, 15, 50, 25, 12, 22, 1 },
{ 1430, 15, 50, 25, 12, 22, 1 },
{ 1420, 15, 50, 25, 12, 22, 1 },
{ 1410, 15, 50, 25, 12, 22, 1 },
{ 1400, 15, 50, 25, 11, 21, 1 },
{ 1390, 15, 50, 25, 11, 21, 1 },
{ 1380, 15, 50, 25, 11, 21, 1 },
{ 1370, 15, 50, 25, 11, 21, 1 },
{ 1360, 14, 50, 25, 11, 21, 1 },
{ 1350, 14, 50, 25, 11, 21, 1 },
{ 1340, 14, 50, 25, 11, 21, 1 },
{ 1330, 14, 50, 25, 11, 20, 1 },
{ 1320, 14, 50, 25, 11, 20, 1 },
{ 1310, 14, 50, 25, 11, 20, 1 },
{ 1300, 14, 50, 25, 11, 20, 1 },
{ 1290, 14, 50, 25, 11, 20, 1 },
{ 1280, 13, 50, 25, 10, 20, 1 },
{ 1270, 13, 50, 25, 10, 19, 1 },
{ 1260, 13, 50, 25, 10, 19, 1 },
{ 1250, 13, 50, 25, 10, 19, 1 },
{ 1240, 13, 50, 25, 10, 19, 1 },
{ 1230, 13, 50, 25, 10, 19, 1 },
{ 1220, 13, 50, 25, 10, 19, 1 },
{ 1210, 13, 50, 25, 10, 19, 1 },
{ 1200, 13, 50, 25, 10, 18, 1 },
{ 1190, 12, 50, 25, 10, 18, 1 },
{ 1180, 12, 50, 25, 10, 18, 1 },
{ 1170, 12, 50, 25, 10, 18, 1 },
{ 1160, 12, 50, 25, 9, 18, 1 },
{ 1150, 12, 50, 25, 9, 18, 1 },
{ 1140, 12, 50, 25, 9, 17, 1 },
{ 1130, 12, 50, 25, 9, 17, 1 },
{ 1120, 12, 50, 25, 9, 17, 1 },
{ 1110, 12, 50, 25, 9, 17, 1 },
{ 1100, 11, 50, 25, 9, 17, 1 },
{ 1090, 11, 50, 25, 9, 17, 1 },
{ 1080, 11, 50, 25, 9, 16, 1 },
{ 1070, 11, 50, 25, 9, 16, 1 },
{ 1060, 11, 50, 25, 9, 16, 1 },
{ 1050, 11, 50, 25, 8, 16, 1 },
{ 1040, 11, 50, 25, 8, 16, 1 },
{ 1030, 11, 50, 25, 8, 16, 1 },
{ 1020, 10, 50, 25, 8, 16, 1 },
{ 1010, 10, 50, 25, 8, 15, 1 },
{ 1000, 10, 50, 25, 8, 15, 1 },
{ 990, 10, 50, 25, 8, 15, 2 },
{ 980, 10, 50, 25, 8, 15, 2 },
{ 970, 10, 50, 25, 8, 15, 2 },
{ 960, 10, 50, 25, 8, 15, 2 },
{ 950, 10, 50, 25, 8, 14, 2 },
{ 940, 10, 50, 25, 8, 14, 2 },
{ 930, 9, 50, 25, 7, 14, 2 },
{ 920, 9, 50, 25, 7, 14, 2 },
{ 910, 9, 50, 25, 7, 14, 2 },
{ 900, 9, 50, 25, 7, 14, 2 },
{ 890, 9, 50, 25, 7, 13, 2 },
{ 880, 9, 50, 25, 7, 13, 2 },
{ 870, 9, 50, 25, 7, 13, 2 },
{ 860, 9, 50, 25, 7, 13, 2 },
{ 850, 9, 50, 25, 7, 13, 2 },
{ 840, 8, 50, 25, 7, 13, 2 },
{ 830, 8, 50, 25, 7, 13, 2 },
{ 820, 8, 50, 25, 7, 12, 2 },
{ 810, 8, 50, 25, 6, 12, 2 },
{ 800, 8, 50, 25, 6, 12, 2 },
{ 790, 8, 50, 25, 6, 12, 2 },
{ 780, 8, 50, 25, 6, 12, 2 },
{ 770, 8, 50, 25, 6, 12, 2 },
{ 760, 7, 50, 25, 6, 11, 2 },
{ 750, 7, 50, 25, 6, 11, 2 },
{ 740, 7, 50, 25, 6, 11, 2 },
{ 730, 7, 50, 25, 6, 11, 2 },
{ 720, 7, 50, 25, 6, 11, 2 },
{ 710, 7, 50, 25, 6, 11, 2 },
{ 700, 7, 50, 25, 5, 10, 2 },
{ 690, 7, 50, 25, 5, 10, 2 },
{ 680, 7, 50, 25, 5, 10, 2 },
{ 670, 6, 50, 25, 5, 10, 2 },
{ 660, 6, 50, 25, 5, 10, 2 },
{ 650, 6, 50, 25, 5, 10, 2 },
{ 640, 6, 50, 25, 5, 10, 2 },
{ 630, 6, 50, 25, 5, 9, 2 },
{ 620, 6, 50, 25, 5, 9, 2 },
{ 610, 6, 50, 25, 5, 9, 2 },
{ 600, 6, 50, 25, 5, 9, 2 },
{ 590, 6, 50, 25, 5, 9, 2 },
{ 580, 5, 50, 25, 4, 9, 2 },
{ 570, 5, 50, 25, 4, 8, 2 },
{ 560, 5, 50, 25, 4, 8, 2 },
{ 550, 5, 50, 25, 4, 8, 2 },
{ 540, 5, 50, 25, 4, 8, 2 },
{ 530, 5, 50, 25, 4, 8, 2 },
{ 520, 5, 50, 25, 4, 8, 2 },
{ 510, 5, 50, 25, 4, 8, 2 },
{ 500, 4, 50, 25, 4, 7, 2 },
{ 490, 18, 50, 25, 14, 6, 2 },
{ 480, 17, 50, 25, 14, 6, 2 },
{ 470, 17, 50, 25, 14, 6, 2 },
{ 460, 17, 50, 25, 13, 6, 2 },
{ 450, 16, 50, 25, 13, 6, 2 },
{ 440, 16, 50, 25, 13, 6, 2 },
{ 430, 15, 50, 25, 12, 6, 2 },
{ 420, 15, 50, 25, 12, 5, 2 },
{ 410, 15, 50, 25, 12, 5, 2 },
{ 400, 14, 50, 25, 11, 5, 2 },
{ 390, 14, 50, 25, 11, 5, 2 },
{ 380, 13, 50, 25, 11, 5, 2 },
{ 370, 13, 50, 25, 11, 5, 2 },
{ 360, 13, 50, 25, 10, 4, 2 },
{ 350, 12, 50, 25, 10, 4, 2 },
{ 340, 12, 50, 25, 10, 4, 2 },
{ 330, 11, 50, 25, 9, 4, 2 },
{ 320, 11, 50, 25, 9, 4, 2 },
{ 310, 11, 50, 25, 9, 4, 2 },
{ 300, 10, 50, 25, 8, 3, 2 },
{ 290, 10, 50, 25, 8, 3, 2 },
{ 280, 9, 50, 25, 8, 3, 2 },
{ 270, 9, 50, 25, 8, 3, 2 },
{ 260, 8, 50, 25, 7, 3, 2 },
{ 250, 8, 50, 25, 7, 3, 2 },
{ 240, 8, 50, 25, 7, 3, 2 },
{ 230, 7, 50, 25, 6, 2, 2 },
{ 220, 7, 50, 25, 6, 2, 2 },
{ 210, 6, 50, 25, 6, 2, 2 },
{ 200, 6, 50, 25, 5, 2, 2 },
{ 190, 6, 50, 25, 5, 2, 2 },
{ 180, 5, 50, 25, 5, 2, 2 },
{ 170, 5, 50, 25, 5, 1, 2 },
{ 160, 4, 50, 25, 4, 1, 2 },
{ 150, 4, 50, 25, 4, 1, 2 },
{ 140, 4, 50, 25, 4, 1, 2 },
{ 130, 3, 50, 25, 3, 1, 2 },
{ 120, 3, 50, 25, 3, 1, 2 },
{ 110, 2, 50, 25, 3, 1, 2 },
{ 100, 2, 50, 25, 2, 0, 2 },
{ 90, 2, 50, 25, 2, 0, 2 },
{ 80, 1, 50, 25, 2, 0, 2 },
};
static inline void
phy_write(struct samsung_mipi_dcphy *samsung, u32 reg, u32 val)
{
writel(val, samsung->base + reg);
}
static inline u32 phy_read(struct samsung_mipi_dcphy *samsung, u32 reg)
{
return readl(samsung->base + reg);
}
static inline void phy_update_bits(struct samsung_mipi_dcphy *samsung,
u32 reg, u32 mask, u32 val)
{
u32 orig, tmp;
orig = phy_read(samsung, reg);
tmp = orig & ~mask;
tmp |= val & mask;
phy_write(samsung, reg, tmp);
}
static inline void grf_write(struct samsung_mipi_dcphy *samsung,
u32 reg, u32 val)
{
regmap_write(samsung->grf, reg, val);
}
static const struct samsung_mipi_dphy_timing *
samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung)
{
const struct samsung_mipi_dphy_timing *timings;
unsigned int num_timings;
unsigned int lane_mbps = samsung->pll.rate / USEC_PER_SEC;
unsigned int i;
timings = samsung_mipi_dphy_timing_table;
num_timings = ARRAY_SIZE(samsung_mipi_dphy_timing_table);
for (i = num_timings; i > 0; i--)
if (lane_mbps <= timings[i - 1].max_lane_mbps)
break;
if (i == 0)
++i;
return &timings[i - 1];
}
static const struct samsung_mipi_cphy_timing *
samsung_mipi_cphy_get_timing(struct samsung_mipi_dcphy *samsung)
{
const struct samsung_mipi_cphy_timing *timings;
unsigned int num_timings;
unsigned int lane_msps = div64_ul(samsung->pll.rate, USEC_PER_SEC);
unsigned int i;
timings = samsung_mipi_cphy_timing_table;
num_timings = ARRAY_SIZE(samsung_mipi_cphy_timing_table);
for (i = num_timings; i > 0; i--)
if (lane_msps <= timings[i - 1].max_lane_msps)
break;
if (i == 0)
++i;
return &timings[i - 1];
}
static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, BIAS_CON0, 0x0010);
phy_write(samsung, BIAS_CON1, 0x0110);
phy_write(samsung, BIAS_CON2, 0x3223);
if (samsung->c_option)
phy_update_bits(samsung, BIAS_CON4, I_MUX_SEL_MASK, I_MUX_SEL(2));
}
static void samsung_mipi_dcphy_bias_block_disable(struct samsung_mipi_dcphy *samsung)
{
}
static void samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy *samsung)
{
phy_update_bits(samsung, PLL_CON0, S_MASK | P_MASK,
S(samsung->pll.scaler) | P(samsung->pll.prediv));
if (samsung->pll.dsm < 0) {
u16 dsm_tmp;
/* Using opposite number subtraction to find complement */
dsm_tmp = abs(samsung->pll.dsm);
dsm_tmp = dsm_tmp - 1;
dsm_tmp ^= 0xffff;
phy_write(samsung, PLL_CON1, dsm_tmp);
} else {
phy_write(samsung, PLL_CON1, samsung->pll.dsm);
}
phy_update_bits(samsung, PLL_CON2, M_MASK, M(samsung->pll.fbdiv));
if (samsung->pll.ssc_en) {
phy_write(samsung, PLL_CON3,
MRR(samsung->pll.mrr) | MFR(samsung->pll.mfr));
phy_update_bits(samsung, PLL_CON4, SSCG_EN, SSCG_EN);
}
phy_write(samsung, PLL_CON5, RESET_N_SEL | PLL_ENABLE_SEL);
phy_write(samsung, PLL_CON7, PLL_LOCK_CNT(0xf000));
phy_write(samsung, PLL_CON8, PLL_STB_CNT(0xf000));
}
static void
samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung)
{
const struct samsung_mipi_dphy_timing *timing;
unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
u32 val = 0;
timing = samsung_mipi_dphy_get_timing(samsung);
phy_write(samsung, DPHY_MC_GNR_CON0, 0xf000);
phy_write(samsung, DPHY_MC_ANA_CON0, 0x7133);
if (lane_hs_rate >= 4500)
phy_write(samsung, DPHY_MC_ANA_CON1, 0x0001);
/*
* Divide-by-2 Clock from Serial Clock. Use this when data rate is under
* 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
*/
if (lane_hs_rate < 1500)
val = HSTX_CLK_SEL;
val |= T_LPX(timing->lpx);
/* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
phy_write(samsung, DPHY_MC_TIME_CON0, val);
val = T_CLK_ZERO(timing->clk_zero) | T_CLK_PREPARE(timing->clk_prepare);
phy_write(samsung, DPHY_MC_TIME_CON1, val);
val = T_HS_EXIT(timing->hs_exit) | T_CLK_TRAIL(timing->clk_trail_eot);
phy_write(samsung, DPHY_MC_TIME_CON2, val);
val = T_CLK_POST(timing->clk_post);
phy_write(samsung, DPHY_MC_TIME_CON3, val);
/* Escape Clock is 20.00MHz */
phy_write(samsung, DPHY_MC_TIME_CON4, 0x1f4);
/*
* skew calibration should be off, if the operation data rate is
* under 1.5Gbps or equal to 1.5Gbps.
*/
if (lane_hs_rate > 1500)
phy_write(samsung, DPHY_MC_DESKEW_CON0, 0x9cb1);
}
static void
samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung)
{
const struct samsung_mipi_dphy_timing *timing;
unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
u32 val = 0;
timing = samsung_mipi_dphy_get_timing(samsung);
phy_write(samsung, COMBO_MD0_ANA_CON0, 0x7133);
phy_write(samsung, COMBO_MD1_ANA_CON0, 0x7133);
phy_write(samsung, COMBO_MD2_ANA_CON0, 0x7133);
phy_write(samsung, DPHY_MD3_ANA_CON0, 0x7133);
if (lane_hs_rate >= 1500) {
phy_write(samsung, COMBO_MD0_ANA_CON1, 0x0001);
phy_write(samsung, COMBO_MD1_ANA_CON1, 0x0001);
phy_write(samsung, COMBO_MD2_ANA_CON1, 0x0001);
phy_write(samsung, DPHY_MD3_ANA_CON1, 0x0001);
}
/*
* Divide-by-2 Clock from Serial Clock. Use this when data rate is under
* 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
*/
if (lane_hs_rate < 1500)
val = HSTX_CLK_SEL;
val |= T_LPX(timing->lpx);
/* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
phy_write(samsung, COMBO_MD0_TIME_CON0, val);
phy_write(samsung, COMBO_MD1_TIME_CON0, val);
phy_write(samsung, COMBO_MD2_TIME_CON0, val);
phy_write(samsung, DPHY_MD3_TIME_CON0, val);
val = T_HS_ZERO(timing->hs_zero) | T_HS_PREPARE(timing->hs_prepare);
phy_write(samsung, COMBO_MD0_TIME_CON1, val);
phy_write(samsung, COMBO_MD1_TIME_CON1, val);
phy_write(samsung, COMBO_MD2_TIME_CON1, val);
phy_write(samsung, DPHY_MD3_TIME_CON1, val);
val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->hs_trail_eot);
phy_write(samsung, COMBO_MD0_TIME_CON2, val);
phy_write(samsung, COMBO_MD1_TIME_CON2, val);
phy_write(samsung, COMBO_MD2_TIME_CON2, val);
phy_write(samsung, DPHY_MD3_TIME_CON2, val);
/* TTA-GET/TTA-GO Timing Counter register use default value */
val = T_TA_GET(0x3) | T_TA_GO(0x0);
phy_write(samsung, COMBO_MD0_TIME_CON3, val);
phy_write(samsung, COMBO_MD1_TIME_CON3, val);
phy_write(samsung, COMBO_MD2_TIME_CON3, val);
phy_write(samsung, DPHY_MD3_TIME_CON3, val);
/* Escape Clock is 20.00MHz */
phy_write(samsung, COMBO_MD0_TIME_CON4, 0x1f4);
phy_write(samsung, COMBO_MD1_TIME_CON4, 0x1f4);
phy_write(samsung, COMBO_MD2_TIME_CON4, 0x1f4);
phy_write(samsung, DPHY_MD3_TIME_CON4, 0x1f4);
}
static void samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy *samsung)
{
u32 sts;
int ret;
phy_update_bits(samsung, PLL_CON0, PLL_EN, PLL_EN);
ret = readl_poll_timeout(samsung->base + PLL_STAT0,
sts, (sts & PLL_LOCK), 20000);
if (ret < 0)
dev_err(samsung->dev, "DC-PHY pll is not locked\n");
}
static void samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy *samsung)
{
phy_update_bits(samsung, PLL_CON0, PLL_EN, 0);
}
static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, DPHY_MC_GNR_CON0, PHY_ENABLE, PHY_ENABLE);
switch (samsung->lanes) {
case 4:
phy_write(samsung, DPHY_MD3_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, DPHY_MD3_GNR_CON0,
PHY_ENABLE, PHY_ENABLE);
//fallthrough;
case 3:
phy_write(samsung, COMBO_MD2_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, COMBO_MD2_GNR_CON0,
PHY_ENABLE, PHY_ENABLE);
//fallthrough;
case 2:
phy_write(samsung, COMBO_MD1_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, COMBO_MD1_GNR_CON0,
PHY_ENABLE, PHY_ENABLE);
//fallthrough;
case 1:
default:
phy_write(samsung, COMBO_MD0_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, COMBO_MD0_GNR_CON0,
PHY_ENABLE, PHY_ENABLE);
break;
}
}
static void samsung_mipi_cphy_timing_init(struct samsung_mipi_dcphy *samsung)
{
const struct samsung_mipi_cphy_timing *timing;
unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
u32 val = 0;
timing = samsung_mipi_cphy_get_timing(samsung);
/*
* Divide-by-2 Clock from Serial Clock. Use this when data rate is under
* 500Msps, otherwise divide-by-16 Clock from Serial Clock
*/
if (lane_hs_rate < 500)
val = HSTX_CLK_SEL;
val |= T_LPX(timing->lpx);
/* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
phy_write(samsung, COMBO_MD0_TIME_CON0, val);
phy_write(samsung, COMBO_MD1_TIME_CON0, val);
phy_write(samsung, COMBO_MD2_TIME_CON0, val);
val = T_HS_ZERO(timing->prebegin_3) | T_HS_PREPARE(timing->prepare_3);
phy_write(samsung, COMBO_MD0_TIME_CON1, val);
phy_write(samsung, COMBO_MD1_TIME_CON1, val);
phy_write(samsung, COMBO_MD2_TIME_CON1, val);
val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->post_3);
phy_write(samsung, DPHY_MD3_TIME_CON2, val);
phy_write(samsung, COMBO_MD0_TIME_CON2, val);
phy_write(samsung, COMBO_MD1_TIME_CON2, val);
phy_write(samsung, COMBO_MD2_TIME_CON2, val);
/* TTA-GET/TTA-GO Timing Counter register use default value */
val = T_TA_GET(0x3) | T_TA_GO(0x0);
phy_write(samsung, COMBO_MD0_TIME_CON3, val);
phy_write(samsung, COMBO_MD1_TIME_CON3, val);
phy_write(samsung, COMBO_MD2_TIME_CON3, val);
/* Escape Clock is 20.00MHz */
phy_write(samsung, COMBO_MD0_TIME_CON4, 0x1f4);
phy_write(samsung, COMBO_MD1_TIME_CON4, 0x1f4);
phy_write(samsung, COMBO_MD2_TIME_CON4, 0x1f4);
/* set T_ERR_SOT_SYNC default value */
}
static void samsung_mipi_cphy_lane_enable(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, COMBO_MD0_GNR_CON1, T_PHY_READY(0x2000));
phy_write(samsung, COMBO_MD1_GNR_CON1, T_PHY_READY(0x2000));
phy_write(samsung, COMBO_MD2_GNR_CON1, T_PHY_READY(0x2000));
phy_update_bits(samsung, COMBO_MD0_GNR_CON0, PHY_ENABLE, PHY_ENABLE);
phy_update_bits(samsung, COMBO_MD1_GNR_CON0, PHY_ENABLE, PHY_ENABLE);
phy_update_bits(samsung, COMBO_MD2_GNR_CON0, PHY_ENABLE, PHY_ENABLE);
}
static void
samsung_mipi_dcphy_hs_vreg_amp_config(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, DPHY_MC_ANA_CON2, HS_VREG_AMP_ICON(2));
}
static void samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung)
{
reset_assert(&samsung->m_phy_rst);
samsung_mipi_dcphy_bias_block_enable(samsung);
samsung_mipi_dcphy_pll_configure(samsung);
samsung_mipi_dphy_clk_lane_timing_init(samsung);
samsung_mipi_dphy_data_lane_timing_init(samsung);
samsung_mipi_dcphy_pll_enable(samsung);
samsung_mipi_dphy_lane_enable(samsung);
reset_deassert(&samsung->m_phy_rst);
/* The Tskewcal maximum is 100 usec at initial calibration. */
udelay(100);
}
static void samsung_mipi_cphy_power_on(struct samsung_mipi_dcphy *samsung)
{
grf_write(samsung, MIPI_DCPHY_GRF_CON0, M_CPHY_MODE);
reset_assert(&samsung->m_phy_rst);
samsung_mipi_dcphy_bias_block_enable(samsung);
samsung_mipi_dcphy_hs_vreg_amp_config(samsung);
samsung_mipi_dcphy_pll_configure(samsung);
samsung_mipi_cphy_timing_init(samsung);
samsung_mipi_dcphy_pll_enable(samsung);
samsung_mipi_cphy_lane_enable(samsung);
reset_deassert(&samsung->m_phy_rst);
}
static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *samsung)
{
phy_update_bits(samsung, DPHY_MC_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, DPHY_MD3_GNR_CON0, PHY_ENABLE, 0);
}
static void samsung_mipi_cphy_lane_disable(struct samsung_mipi_dcphy *samsung)
{
phy_update_bits(samsung, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0);
phy_update_bits(samsung, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0);
}
static int samsung_mipi_dcphy_power_on(struct rockchip_phy *phy)
{
struct samsung_mipi_dcphy *samsung = dev_get_priv(phy->dev);
if (samsung->mode == PHY_MODE_MIPI_DPHY)
samsung_mipi_dphy_power_on(samsung);
else
samsung_mipi_cphy_power_on(samsung);
return 0;
}
static int samsung_mipi_dcphy_power_off(struct rockchip_phy *phy)
{
struct samsung_mipi_dcphy *samsung = dev_get_priv(phy->dev);
if (samsung->mode == PHY_MODE_MIPI_DPHY)
samsung_mipi_dphy_lane_disable(samsung);
else
samsung_mipi_cphy_lane_disable(samsung);
samsung_mipi_dcphy_pll_disable(samsung);
samsung_mipi_dcphy_bias_block_disable(samsung);
return 0;
}
static int
samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy *samsung,
u8 *mfr, u8 *mrr)
{
unsigned long fin = 24000;
u16 prediv = samsung->pll.prediv;
u16 fbdiv = samsung->pll.fbdiv;
u16 min_mfr, max_mfr;
u16 _mfr, best_mfr = 0;
u16 mr, _mrr, best_mrr = 0;
/* 20KHz ≤ MF ≤ 150KHz */
max_mfr = DIV_ROUND_UP(fin, (20 * prediv) << 5);
min_mfr = div64_ul(fin, ((150 * prediv) << 5));
/*0 ≤ mfr ≤ 255 */
if (max_mfr > 256)
max_mfr = 256;
for (_mfr = min_mfr; _mfr < max_mfr; _mfr++) {
/* 1 ≤ mrr ≤ 31 */
for (_mrr = 1; _mrr < 32; _mrr++) {
mr = DIV_ROUND_UP(_mfr * _mrr * 100, fbdiv << 6);
/* 0 ≤ MR ≤ 5% */
if (mr > 5)
continue;
if (_mfr * _mrr < 513) {
best_mfr = _mfr;
best_mrr = _mrr;
break;
}
}
}
if (best_mrr) {
*mfr = best_mfr & 0xff;
*mrr = best_mrr & 0x3f;
} else {
dev_err(samsung->dev, "failed to calc ssc parameter mfr and mrr\n");
return -EINVAL;
}
return 0;
}
static unsigned long
samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung,
unsigned long prate, unsigned long rate,
u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler)
{
u64 max_fout = samsung->c_option ? MAX_CPHY_BW : MAX_DPHY_BW;
u64 best_freq = 0;
u64 fin, fvco, fout;
u8 min_prediv, max_prediv;
u8 _prediv, best_prediv = 1;
u16 _fbdiv, best_fbdiv = 1;
u8 _scaler, best_scaler = 0;
long _dsm, best_dsm = 0;
u32 min_delta = 0xffffffff;
/*
* The PLL output frequency can be calculated using a simple formula:
* Fvco = ((m+k/65536) x 2 x Fin) / p
* Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s)
*/
fin = div64_ul(prate, MSEC_PER_SEC);
while (!best_freq) {
fout = div64_ul(rate, MSEC_PER_SEC);
if (fout > max_fout)
fout = max_fout;
/* 0 ≤ S[2:0] ≤ 6 */
for (_scaler = 0; _scaler < 7; _scaler++) {
fvco = fout << _scaler;
/*
* 2600MHz ≤ FVCO ≤ 6600MHz
*/
if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC)
continue;
/* 6MHz ≤ Fref(Fin / p) ≤ 30MHz */
min_prediv = DIV_ROUND_UP(fin, 30 * MSEC_PER_SEC);
max_prediv = DIV_ROUND_CLOSEST(fin, 6 * MSEC_PER_SEC);
for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
u64 delta, tmp;
_fbdiv = DIV_ROUND_CLOSEST(fvco * _prediv, 2 * fin);
/* 64 ≤ M[9:0] ≤ 1023 */
if ((_fbdiv < 64) || (_fbdiv > 1023))
continue;
/* -32767 ≤ K[15:0] ≤ 32767 */
_dsm = ((_prediv * fvco) - (2 * _fbdiv * fin));
_dsm = DIV_ROUND_UP(_dsm << 15, fin);
if (abs(_dsm) > 32767)
continue;
tmp = DIV_ROUND_CLOSEST((_fbdiv * fin * 2 * 1000), _prediv);
tmp += DIV_ROUND_CLOSEST((_dsm * fin * 1000), _prediv << 15);
delta = abs(fvco * MSEC_PER_SEC - tmp);
if (delta < min_delta) {
best_prediv = _prediv;
best_fbdiv = _fbdiv;
best_dsm = _dsm;
best_scaler = _scaler;
min_delta = delta;
best_freq = DIV_ROUND_CLOSEST(tmp, 1000) * MSEC_PER_SEC;
}
}
}
rate += 100 * MSEC_PER_SEC;
}
*prediv = best_prediv;
*fbdiv = best_fbdiv;
*dsm = (int)best_dsm & 0xffff;
*scaler = best_scaler;
dev_info(samsung->dev, "p: %d, m: %d, dsm:%ld, scaler: %d\n",
best_prediv, best_fbdiv, best_dsm, best_scaler);
return best_freq >> best_scaler;
}
static unsigned long samsung_mipi_dcphy_set_pll(struct rockchip_phy *phy,
unsigned long rate)
{
struct samsung_mipi_dcphy *samsung = dev_get_priv(phy->dev);
unsigned long fin = 24000000, fout;
u8 scaler = 0, mfr = 0, mrr = 0;
u16 fbdiv = 1;
u8 prediv = 1;
int dsm = 0;
int ret;
samsung->c_option = (samsung->mode == PHY_MODE_MIPI_DPHY) ? false : true;
fout = samsung_mipi_dcphy_pll_round_rate(samsung, fin, rate, &prediv,
&fbdiv, &dsm, &scaler);
dev_info(samsung->dev, "fin=%lu, req_rate=%lu\n", fin, rate);
dev_info(samsung->dev, "fout=%lu, prediv=%u, fbdiv=%u\n", fout, prediv, fbdiv);
samsung->pll.prediv = prediv;
samsung->pll.fbdiv = fbdiv;
samsung->pll.dsm = dsm;
samsung->pll.scaler = scaler;
samsung->pll.rate = fout;
/*
* All DPHY 2.0 compliant Transmitters shall support SSC operating above
* 2.5 Gbps
*/
if (fout > 2500000000LL) {
ret = samsung_mipi_dcphy_pll_ssc_modulation_calc(samsung,
&mfr, &mrr);
if (!ret) {
samsung->pll.ssc_en = true;
samsung->pll.mfr = mfr;
samsung->pll.mrr = mrr;
}
}
return fout;
}
static int samsung_mipi_dcphy_set_mode(struct rockchip_phy *phy,
enum phy_mode mode)
{
struct samsung_mipi_dcphy *samsung = dev_get_priv(phy->dev);
samsung->mode = mode;
return 0;
}
static int samsung_mipi_dcphy_probe(struct udevice *dev)
{
struct samsung_mipi_dcphy *samsung = dev_get_priv(dev);
struct rockchip_phy *tmp_phy;
struct rockchip_phy *phy;
struct udevice *syscon;
int ret;
phy = calloc(1, sizeof(*phy));
if (!phy)
return -ENOMEM;
tmp_phy = (struct rockchip_phy *)dev_get_driver_data(dev);
dev->driver_data = (ulong)phy;
memcpy(phy, tmp_phy, sizeof(*phy));
samsung->lanes = ofnode_read_u32_default(dev->node, "samsung,lanes", 4);
samsung->base = dev_read_addr_ptr(dev);
if (IS_ERR(samsung->base)) {
dev_err(dev, "resource \"phy\" not found\n");
return PTR_ERR(samsung->base);
}
ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf",
&syscon);
if (!ret) {
samsung->grf = syscon_get_regmap(syscon);
if (!samsung->grf)
return -ENODEV;
}
ret = reset_get_by_name(dev, "m_phy", &samsung->m_phy_rst);
if (ret) {
ret = reset_get_by_name(dev, "phy", &samsung->m_phy_rst);
if (ret) {
pr_err("reset_get_by_name(phy) failed: %d\n", ret);
return ret;
}
}
phy->dev = dev;
return 0;
}
static const struct rockchip_phy_funcs samsung_mipi_dcphy_funcs = {
.power_on = samsung_mipi_dcphy_power_on,
.power_off = samsung_mipi_dcphy_power_off,
.set_pll = samsung_mipi_dcphy_set_pll,
.set_mode = samsung_mipi_dcphy_set_mode,
};
static struct rockchip_phy rk3588_samsung_mipi_dcphy_driver_data = {
.funcs = &samsung_mipi_dcphy_funcs,
};
static const struct udevice_id samsung_mipi_dcphy_ids[] = {
{
.compatible = "rockchip,rk3588-mipi-dcphy",
.data = (ulong)&rk3588_samsung_mipi_dcphy_driver_data,
},
{}
};
U_BOOT_DRIVER(samsung_mipi_dcphy) = {
.name = "samsung-mipi-dcphy",
.id = UCLASS_PHY,
.of_match = samsung_mipi_dcphy_ids,
.probe = samsung_mipi_dcphy_probe,
.priv_auto_alloc_size = sizeof(struct samsung_mipi_dcphy),
};