diff --git a/drivers/video/drm/rockchip-dw-mipi-dsi.c b/drivers/video/drm/rockchip-dw-mipi-dsi.c index 7477be576b..2e43c4fad0 100644 --- a/drivers/video/drm/rockchip-dw-mipi-dsi.c +++ b/drivers/video/drm/rockchip-dw-mipi-dsi.c @@ -188,68 +188,13 @@ #define PHY_STATUS_TIMEOUT_US 10000 #define CMD_PKT_STATUS_TIMEOUT_US 20000 -#define BYPASS_VCO_RANGE BIT(7) -#define VCO_RANGE_CON_SEL(val) (((val) & 0x7) << 3) -#define VCO_IN_CAP_CON_DEFAULT (0x0 << 1) -#define VCO_IN_CAP_CON_LOW (0x1 << 1) -#define VCO_IN_CAP_CON_HIGH (0x2 << 1) -#define REF_BIAS_CUR_SEL BIT(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, -}; +/* Test Code: 0x44 (HS RX Control of Lane 0) */ +#define HSFREQRANGE(x) UPDATE(x, 6, 1) +/* Test Code: 0x17 (PLL Input Divider Ratio) */ +#define INPUT_DIV(x) UPDATE(x, 6, 0) +/* Test Code: 0x18 (PLL Loop Divider Ratio) */ +#define FEEDBACK_DIV_LO(x) UPDATE(x, 4, 0) +#define FEEDBACK_DIV_HI(x) (BIT(7) | UPDATE(x, 3, 0)) #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; }; -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) { writel(val, dsi->base + reg); @@ -577,45 +492,44 @@ static int mipi_dphy_power_on(struct dw_mipi_dsi *dsi) 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 (testdin < 0) { - printf("failed to get testdin for %dmbps lane clock\n", - dsi->lane_mbps); - return testdin; - } + if (index == ARRAY_SIZE(hsfreqrange_table)) + --index; - testif_write(dsi, 0x10, BYPASS_VCO_RANGE | VCO_RANGE_CON_SEL(vco) | - VCO_IN_CAP_CON_LOW | REF_BIAS_CUR_SEL); - 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); + hsfreqrange = hsfreqrange_table[index].hsfreqrange; + testif_write(dsi, 0x44, HSFREQRANGE(hsfreqrange)); - 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)