video/drm: dsi: Don't hardcode/bypass phy default parameters

Change-Id: If8670bee99c1397647323b34acd3e3da028549c3
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
(sync from rk/kernel:develop-4.4:bd920c36fc56d00a24d3688510c84c62d7921c6a)
This commit is contained in:
Wyon Bi 2019-01-19 10:09:02 +08:00 committed by Jianhong Chen
parent 374e75505b
commit 2612c8202d
1 changed files with 40 additions and 126 deletions

View File

@ -188,68 +188,13 @@
#define PHY_STATUS_TIMEOUT_US 10000 #define PHY_STATUS_TIMEOUT_US 10000
#define CMD_PKT_STATUS_TIMEOUT_US 20000 #define CMD_PKT_STATUS_TIMEOUT_US 20000
#define BYPASS_VCO_RANGE BIT(7) /* Test Code: 0x44 (HS RX Control of Lane 0) */
#define VCO_RANGE_CON_SEL(val) (((val) & 0x7) << 3) #define HSFREQRANGE(x) UPDATE(x, 6, 1)
#define VCO_IN_CAP_CON_DEFAULT (0x0 << 1) /* Test Code: 0x17 (PLL Input Divider Ratio) */
#define VCO_IN_CAP_CON_LOW (0x1 << 1) #define INPUT_DIV(x) UPDATE(x, 6, 0)
#define VCO_IN_CAP_CON_HIGH (0x2 << 1) /* Test Code: 0x18 (PLL Loop Divider Ratio) */
#define REF_BIAS_CUR_SEL BIT(0) #define FEEDBACK_DIV_LO(x) UPDATE(x, 4, 0)
#define FEEDBACK_DIV_HI(x) (BIT(7) | UPDATE(x, 3, 0))
#define CP_CURRENT_3MA BIT(3)
#define CP_PROGRAM_EN BIT(7)
#define LPF_PROGRAM_EN BIT(6)
#define LPF_RESISTORS_20_KOHM 0
#define HSFREQRANGE_SEL(val) (((val) & 0x3f) << 1)
#define INPUT_DIVIDER(val) ((val - 1) & 0x7f)
#define LOW_PROGRAM_EN 0
#define HIGH_PROGRAM_EN BIT(7)
#define LOOP_DIV_LOW_SEL(val) ((val - 1) & 0x1f)
#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0x1f)
#define PLL_LOOP_DIV_EN BIT(5)
#define PLL_INPUT_DIV_EN BIT(4)
#define POWER_CONTROL BIT(6)
#define INTERNAL_REG_CURRENT BIT(3)
#define BIAS_BLOCK_ON BIT(2)
#define BANDGAP_ON BIT(0)
#define TER_RESISTOR_HIGH BIT(7)
#define TER_RESISTOR_LOW 0
#define LEVEL_SHIFTERS_ON BIT(6)
#define TER_CAL_DONE BIT(5)
#define SETRD_MAX (0x7 << 2)
#define POWER_MANAGE BIT(1)
#define TER_RESISTORS_ON BIT(0)
#define BIASEXTR_SEL(val) ((val) & 0x7)
#define BANDGAP_SEL(val) ((val) & 0x7)
#define TLP_PROGRAM_EN BIT(7)
#define THS_PRE_PROGRAM_EN BIT(7)
#define THS_ZERO_PROGRAM_EN BIT(6)
enum {
BANDGAP_97_07,
BANDGAP_98_05,
BANDGAP_99_02,
BANDGAP_100_00,
BANDGAP_93_17,
BANDGAP_94_15,
BANDGAP_95_12,
BANDGAP_96_10,
};
enum {
BIASEXTR_87_1,
BIASEXTR_91_5,
BIASEXTR_95_9,
BIASEXTR_100,
BIASEXTR_105_94,
BIASEXTR_111_88,
BIASEXTR_118_8,
BIASEXTR_127_7,
};
#define GRF_REG_FIELD(reg, lsb, msb) ((reg << 16) | (lsb << 8) | (msb)) #define GRF_REG_FIELD(reg, lsb, msb) ((reg << 16) | (lsb << 8) | (msb))
@ -305,36 +250,6 @@ struct dw_mipi_dsi {
const struct dw_mipi_dsi_plat_data *pdata; const struct dw_mipi_dsi_plat_data *pdata;
}; };
struct dphy_pll_testdin_map {
unsigned int max_mbps;
u8 testdin;
};
/* The table is based on 27MHz DPHY pll reference clock. */
static const struct dphy_pll_testdin_map dptdin_map[] = {
{ 90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
{ 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
{ 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
{ 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
{ 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
{ 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
{ 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
};
static int max_mbps_to_testdin(unsigned int max_mbps)
{
int i;
for (i = 0; i < ARRAY_SIZE(dptdin_map); i++)
if (dptdin_map[i].max_mbps > max_mbps)
return dptdin_map[i].testdin;
return -EINVAL;
}
static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val) static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
{ {
writel(val, dsi->base + reg); writel(val, dsi->base + reg);
@ -577,45 +492,44 @@ static int mipi_dphy_power_on(struct dw_mipi_dsi *dsi)
return 0; return 0;
} }
static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) static void dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
{ {
int testdin, vco, val; /* Table 5-1 Frequency Ranges */
const struct {
unsigned long max_lane_mbps;
u8 hsfreqrange;
} hsfreqrange_table[] = {
{ 90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
{ 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
{ 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
{ 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
{ 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
{ 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
{ 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
};
u8 hsfreqrange;
unsigned int index;
u16 n, m;
vco = (dsi->lane_mbps < 200) ? 0 : (dsi->lane_mbps + 100) / 200; for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++)
if (dsi->lane_mbps <= hsfreqrange_table[index].max_lane_mbps)
break;
testdin = max_mbps_to_testdin(dsi->lane_mbps); if (index == ARRAY_SIZE(hsfreqrange_table))
if (testdin < 0) { --index;
printf("failed to get testdin for %dmbps lane clock\n",
dsi->lane_mbps);
return testdin;
}
testif_write(dsi, 0x10, BYPASS_VCO_RANGE | VCO_RANGE_CON_SEL(vco) | hsfreqrange = hsfreqrange_table[index].hsfreqrange;
VCO_IN_CAP_CON_LOW | REF_BIAS_CUR_SEL); testif_write(dsi, 0x44, HSFREQRANGE(hsfreqrange));
testif_write(dsi, 0x11, CP_CURRENT_3MA);
testif_write(dsi, 0x12, CP_PROGRAM_EN | LPF_PROGRAM_EN |
LPF_RESISTORS_20_KOHM);
testif_write(dsi, 0x44, HSFREQRANGE_SEL(testdin));
testif_write(dsi, 0x17, INPUT_DIVIDER(dsi->dphy.input_div));
val = LOOP_DIV_LOW_SEL(dsi->dphy.feedback_div) | LOW_PROGRAM_EN;
testif_write(dsi, 0x18, val);
testif_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
val = LOOP_DIV_HIGH_SEL(dsi->dphy.feedback_div) | HIGH_PROGRAM_EN;
testif_write(dsi, 0x18, val);
testif_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
testif_write(dsi, 0x20, POWER_CONTROL | INTERNAL_REG_CURRENT |
BIAS_BLOCK_ON | BANDGAP_ON);
testif_write(dsi, 0x21, TER_RESISTOR_LOW | TER_CAL_DONE |
SETRD_MAX | TER_RESISTORS_ON);
testif_write(dsi, 0x21, TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
SETRD_MAX | POWER_MANAGE | TER_RESISTORS_ON);
testif_write(dsi, 0x22, LOW_PROGRAM_EN | BIASEXTR_SEL(BIASEXTR_127_7));
testif_write(dsi, 0x22, HIGH_PROGRAM_EN | BANDGAP_SEL(BANDGAP_96_10));
testif_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf);
testif_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x2d);
testif_write(dsi, 0x72, THS_ZERO_PROGRAM_EN | 0xa);
return 0; n = dsi->dphy.input_div - 1;
m = dsi->dphy.feedback_div - 1;
testif_write(dsi, 0x19, 0x30);
testif_write(dsi, 0x17, INPUT_DIV(n));
testif_write(dsi, 0x18, FEEDBACK_DIV_LO(m));
testif_write(dsi, 0x18, FEEDBACK_DIV_HI(m >> 5));
} }
static unsigned long dw_mipi_dsi_calc_bandwidth(struct dw_mipi_dsi *dsi) static unsigned long dw_mipi_dsi_calc_bandwidth(struct dw_mipi_dsi *dsi)