[PATCH v2 15/59] drm/kmb: Part5 of Mipi Tx Intitialization
Anitha Chrisanthus
anitha.chrisanthus at intel.com
Tue Jul 14 20:57:01 UTC 2020
This is part1 of DPHY initialization.
v2: remove kmb_write() as the function provides no benefit over
calling writel() directly.
Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus at intel.com>
Reviewed-by: Bob Paauwe <bob.j.paauwe at intel.com>
---
drivers/gpu/drm/kmb/kmb_drv.h | 5 -
drivers/gpu/drm/kmb/kmb_dsi.c | 346 ++++++++++++++++++++++++++++++++++++++---
drivers/gpu/drm/kmb/kmb_dsi.h | 10 ++
drivers/gpu/drm/kmb/kmb_regs.h | 48 +++++-
4 files changed, 376 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/kmb/kmb_drv.h b/drivers/gpu/drm/kmb/kmb_drv.h
index f1d5b3a..3996c84 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.h
+++ b/drivers/gpu/drm/kmb/kmb_drv.h
@@ -64,11 +64,6 @@ static inline void kmb_write_bits(struct kmb_drm_private *lcd,
}
#endif
-static inline void kmb_write(void *reg, u32 value)
-{
- writel(value, reg);
-}
-
static inline void kmb_write_lcd(unsigned int reg, u32 value)
{
writel(value, (LCD_BASE_ADDR + reg));
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index a255210..d15cf6f 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -27,6 +27,13 @@
#define MIPI_TX_REF_CLK_KHZ 24000
#define MIPI_TX_CFG_CLK_KHZ 24000
+/*DPHY Tx test codes*/
+#define TEST_CODE_HS_FREQ_RANGE_CFG 0x44
+#define TEST_CODE_PLL_ANALOG_PROG 0x1F
+#define TEST_CODE_SLEW_RATE_OVERRIDE_CTRL 0xA0
+#define TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL 0xA3
+#define TEST_CODE_SLEW_RATE_DDL_CYCLES 0xA4
+
/*
* These are added here only temporarily for testing,
* these will eventually go to the device tree sections,
@@ -87,6 +94,77 @@ struct mipi_ctrl_cfg mipi_tx_init_cfg = {
};
+typedef struct{
+ uint16_t default_bit_rate_mbps;
+ uint8_t hsfreqrange_code;
+} mipi_hs_freq_range_cfg;
+
+static mipi_hs_freq_range_cfg
+ mipi_hs_freq_range[MIPI_DPHY_DEFAULT_BIT_RATES] = {
+ {.default_bit_rate_mbps = 80, .hsfreqrange_code = 0x00},
+ {.default_bit_rate_mbps = 90, .hsfreqrange_code = 0x10},
+ {.default_bit_rate_mbps = 100, .hsfreqrange_code = 0x20},
+ {.default_bit_rate_mbps = 110, .hsfreqrange_code = 0x30},
+ {.default_bit_rate_mbps = 120, .hsfreqrange_code = 0x01},
+ {.default_bit_rate_mbps = 130, .hsfreqrange_code = 0x11},
+ {.default_bit_rate_mbps = 140, .hsfreqrange_code = 0x21},
+ {.default_bit_rate_mbps = 150, .hsfreqrange_code = 0x31},
+ {.default_bit_rate_mbps = 160, .hsfreqrange_code = 0x02},
+ {.default_bit_rate_mbps = 170, .hsfreqrange_code = 0x12},
+ {.default_bit_rate_mbps = 180, .hsfreqrange_code = 0x22},
+ {.default_bit_rate_mbps = 190, .hsfreqrange_code = 0x32},
+ {.default_bit_rate_mbps = 205, .hsfreqrange_code = 0x03},
+ {.default_bit_rate_mbps = 220, .hsfreqrange_code = 0x13},
+ {.default_bit_rate_mbps = 235, .hsfreqrange_code = 0x23},
+ {.default_bit_rate_mbps = 250, .hsfreqrange_code = 0x33},
+ {.default_bit_rate_mbps = 275, .hsfreqrange_code = 0x04},
+ {.default_bit_rate_mbps = 300, .hsfreqrange_code = 0x14},
+ {.default_bit_rate_mbps = 325, .hsfreqrange_code = 0x25},
+ {.default_bit_rate_mbps = 350, .hsfreqrange_code = 0x35},
+ {.default_bit_rate_mbps = 400, .hsfreqrange_code = 0x05},
+ {.default_bit_rate_mbps = 450, .hsfreqrange_code = 0x16},
+ {.default_bit_rate_mbps = 500, .hsfreqrange_code = 0x26},
+ {.default_bit_rate_mbps = 550, .hsfreqrange_code = 0x37},
+ {.default_bit_rate_mbps = 600, .hsfreqrange_code = 0x07},
+ {.default_bit_rate_mbps = 650, .hsfreqrange_code = 0x18},
+ {.default_bit_rate_mbps = 700, .hsfreqrange_code = 0x28},
+ {.default_bit_rate_mbps = 750, .hsfreqrange_code = 0x39},
+ {.default_bit_rate_mbps = 800, .hsfreqrange_code = 0x09},
+ {.default_bit_rate_mbps = 850, .hsfreqrange_code = 0x19},
+ {.default_bit_rate_mbps = 900, .hsfreqrange_code = 0x29},
+ {.default_bit_rate_mbps = 1000, .hsfreqrange_code = 0x0A},
+ {.default_bit_rate_mbps = 1050, .hsfreqrange_code = 0x1A},
+ {.default_bit_rate_mbps = 1100, .hsfreqrange_code = 0x2A},
+ {.default_bit_rate_mbps = 1150, .hsfreqrange_code = 0x3B},
+ {.default_bit_rate_mbps = 1200, .hsfreqrange_code = 0x0B},
+ {.default_bit_rate_mbps = 1250, .hsfreqrange_code = 0x1B},
+ {.default_bit_rate_mbps = 1300, .hsfreqrange_code = 0x2B},
+ {.default_bit_rate_mbps = 1350, .hsfreqrange_code = 0x3C},
+ {.default_bit_rate_mbps = 1400, .hsfreqrange_code = 0x0C},
+ {.default_bit_rate_mbps = 1450, .hsfreqrange_code = 0x1C},
+ {.default_bit_rate_mbps = 1500, .hsfreqrange_code = 0x2C},
+ {.default_bit_rate_mbps = 1550, .hsfreqrange_code = 0x3D},
+ {.default_bit_rate_mbps = 1600, .hsfreqrange_code = 0x0D},
+ {.default_bit_rate_mbps = 1650, .hsfreqrange_code = 0x1D},
+ {.default_bit_rate_mbps = 1700, .hsfreqrange_code = 0x2E},
+ {.default_bit_rate_mbps = 1750, .hsfreqrange_code = 0x3E},
+ {.default_bit_rate_mbps = 1800, .hsfreqrange_code = 0x0E},
+ {.default_bit_rate_mbps = 1850, .hsfreqrange_code = 0x1E},
+ {.default_bit_rate_mbps = 1900, .hsfreqrange_code = 0x2F},
+ {.default_bit_rate_mbps = 1950, .hsfreqrange_code = 0x3F},
+ {.default_bit_rate_mbps = 2000, .hsfreqrange_code = 0x0F},
+ {.default_bit_rate_mbps = 2050, .hsfreqrange_code = 0x40},
+ {.default_bit_rate_mbps = 2100, .hsfreqrange_code = 0x41},
+ {.default_bit_rate_mbps = 2150, .hsfreqrange_code = 0x42},
+ {.default_bit_rate_mbps = 2200, .hsfreqrange_code = 0x43},
+ {.default_bit_rate_mbps = 2250, .hsfreqrange_code = 0x44},
+ {.default_bit_rate_mbps = 2300, .hsfreqrange_code = 0x45},
+ {.default_bit_rate_mbps = 2350, .hsfreqrange_code = 0x46},
+ {.default_bit_rate_mbps = 2400, .hsfreqrange_code = 0x47},
+ {.default_bit_rate_mbps = 2450, .hsfreqrange_code = 0x48},
+ {.default_bit_rate_mbps = 2500, .hsfreqrange_code = 0x49}
+};
+
static enum drm_mode_status
kmb_dsi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
@@ -324,7 +402,7 @@ static u32 mipi_tx_fg_section_cfg_regs(struct kmb_drm_private *dev_priv,
<< MIPI_TX_SECT_DM_SHIFT); /* bits [24:25] */
cfg |= MIPI_TX_SECT_DMA_PACKED;
kmb_write_mipi((MIPI_TXm_HS_FGn_SECTo_PH(ctrl_no, frame_id,
- section)), cfg);
+ section)), cfg);
/*unpacked bytes */
/*there are 4 frame generators and each fg has 4 sections
@@ -334,8 +412,8 @@ static u32 mipi_tx_fg_section_cfg_regs(struct kmb_drm_private *dev_priv,
*REG_UNPACKED_BYTES1: [15:0]-BYTES2, [31:16]-BYTES3
*/
reg_adr = MIPI_TXm_HS_FGn_SECT_UNPACKED_BYTES0(ctrl_no, frame_id)
- + (section/2)*4;
- kmb_write_bits_mipi(reg_adr, (section % 2)*16, 16, unpacked_bytes);
+ + (section / 2) * 4;
+ kmb_write_bits_mipi(reg_adr, (section % 2) * 16, 16, unpacked_bytes);
/* line config */
reg_adr = MIPI_TXm_HS_FGn_SECTo_LINE_CFG(ctrl_no, frame_id, section);
@@ -423,20 +501,20 @@ static void mipi_tx_fg_cfg_regs(struct kmb_drm_private *dev_priv,
*REG_VSYNC_WIDTH0: [15:0]-VSA for channel0, [31:16]-VSA for channel1
*REG_VSYNC_WIDTH1: [15:0]-VSA for channel2, [31:16]-VSA for channel3
*/
- offset = (frame_gen % 2)*16;
- reg_adr = MIPI_TXm_HS_VSYNC_WIDTHn(ctrl_no, frame_gen/2);
+ offset = (frame_gen % 2) * 16;
+ reg_adr = MIPI_TXm_HS_VSYNC_WIDTHn(ctrl_no, frame_gen / 2);
kmb_write_bits_mipi(reg_adr, offset, 16, fg_cfg->vsync_width);
- /*v backporch - same register config like vsync width*/
- reg_adr = MIPI_TXm_HS_V_BACKPORCHESn(ctrl_no, frame_gen/2);
+ /*v backporch - same register config like vsync width */
+ reg_adr = MIPI_TXm_HS_V_BACKPORCHESn(ctrl_no, frame_gen / 2);
kmb_write_bits_mipi(reg_adr, offset, 16, fg_cfg->v_backporch);
- /*v frontporch - same register config like vsync width*/
- reg_adr = MIPI_TXm_HS_V_FRONTPORCHESn(ctrl_no, frame_gen/2);
+ /*v frontporch - same register config like vsync width */
+ reg_adr = MIPI_TXm_HS_V_FRONTPORCHESn(ctrl_no, frame_gen / 2);
kmb_write_bits_mipi(reg_adr, offset, 16, fg_cfg->v_frontporch);
- /*v active - same register config like vsync width*/
- reg_adr = MIPI_TXm_HS_V_ACTIVEn(ctrl_no, frame_gen/2);
+ /*v active - same register config like vsync width */
+ reg_adr = MIPI_TXm_HS_V_ACTIVEn(ctrl_no, frame_gen / 2);
kmb_write_bits_mipi(reg_adr, offset, 16, fg_cfg->v_active);
/*hsyc width */
@@ -508,7 +586,7 @@ static void mipi_tx_multichannel_fifo_cfg(u8 active_lanes, u8 vchannel_id)
u32 fifo_size, fifo_rthreshold;
u32 ctrl_no = MIPI_CTRL6;
- /*clear all mc fifo channel sizes and thresholds*/
+ /*clear all mc fifo channel sizes and thresholds */
kmb_write_mipi(MIPI_TX_HS_MC_FIFO_CTRL_EN, 0);
kmb_write_mipi(MIPI_TX_HS_MC_FIFO_CHAN_ALLOC0, 0);
kmb_write_mipi(MIPI_TX_HS_MC_FIFO_CHAN_ALLOC1, 0);
@@ -516,8 +594,7 @@ static void mipi_tx_multichannel_fifo_cfg(u8 active_lanes, u8 vchannel_id)
kmb_write_mipi(MIPI_TX_HS_MC_FIFO_RTHRESHOLD1, 0);
fifo_size = (active_lanes > MIPI_D_LANES_PER_DPHY) ?
- MIPI_CTRL_4LANE_MAX_MC_FIFO_LOC :
- MIPI_CTRL_2LANE_MAX_MC_FIFO_LOC;
+ MIPI_CTRL_4LANE_MAX_MC_FIFO_LOC : MIPI_CTRL_2LANE_MAX_MC_FIFO_LOC;
/*MC fifo size for virtual channels 0-3 */
/*
*REG_MC_FIFO_CHAN_ALLOC0: [8:0]-channel0, [24:16]-channel1
@@ -525,7 +602,7 @@ static void mipi_tx_multichannel_fifo_cfg(u8 active_lanes, u8 vchannel_id)
*/
SET_MC_FIFO_CHAN_ALLOC(ctrl_no, vchannel_id, fifo_size);
- /*set threshold to half the fifo size, actual size=size*16*/
+ /*set threshold to half the fifo size, actual size=size*16 */
fifo_rthreshold = ((fifo_size + 1) * 8) & BIT_MASK_16;
SET_MC_FIFO_RTHRESHOLD(ctrl_no, vchannel_id, fifo_rthreshold);
@@ -538,7 +615,7 @@ static void mipi_tx_ctrl_cfg(u8 fg_id, struct mipi_ctrl_cfg *ctrl_cfg)
u32 sync_cfg = 0, ctrl = 0, fg_en;
u32 ctrl_no = MIPI_CTRL6;
- /*MIPI_TX_HS_SYNC_CFG*/
+ /*MIPI_TX_HS_SYNC_CFG */
if (ctrl_cfg->tx_ctrl_cfg.line_sync_pkt_en)
sync_cfg |= LINE_SYNC_PKT_ENABLE;
if (ctrl_cfg->tx_ctrl_cfg.frame_counter_active)
@@ -567,15 +644,15 @@ static void mipi_tx_ctrl_cfg(u8 fg_id, struct mipi_ctrl_cfg *ctrl_cfg)
if (ctrl_cfg->tx_ctrl_cfg.tx_hact_wait_stop)
sync_cfg |= HACT_WAIT_STOP(fg_en);
- /* MIPI_TX_HS_CTRL*/
- ctrl = HS_CTRL_EN | TX_SOURCE; /* type:DSI,source:LCD */
+ /* MIPI_TX_HS_CTRL */
+ ctrl = HS_CTRL_EN | TX_SOURCE; /* type:DSI,source:LCD */
if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->eotp_en)
ctrl |= DSI_EOTP_EN;
if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hfp_blank_en)
ctrl |= DSI_CMD_HFP_EN;
ctrl |= LCD_VC(fg_id);
ctrl |= ACTIVE_LANES(ctrl_cfg->active_lanes - 1);
- /*67 ns stop time*/
+ /*67 ns stop time */
ctrl |= HSEXIT_CNT(0x43);
kmb_write_mipi(MIPI_TXm_HS_SYNC_CFG(ctrl_no), sync_cfg);
@@ -583,7 +660,7 @@ static void mipi_tx_ctrl_cfg(u8 fg_id, struct mipi_ctrl_cfg *ctrl_cfg)
}
static u32 mipi_tx_init_cntrl(struct kmb_drm_private *dev_priv,
- struct mipi_ctrl_cfg *ctrl_cfg)
+ struct mipi_ctrl_cfg *ctrl_cfg)
{
u32 ret;
u8 active_vchannels = 0;
@@ -624,21 +701,21 @@ static u32 mipi_tx_init_cntrl(struct kmb_drm_private *dev_priv,
/* set frame specific parameters */
mipi_tx_fg_cfg(dev_priv, frame_id, ctrl_cfg->active_lanes,
- bits_per_pclk,
- word_count, ctrl_cfg->lane_rate_mbps,
- ctrl_cfg->tx_ctrl_cfg.frames[frame_id]);
+ bits_per_pclk,
+ word_count, ctrl_cfg->lane_rate_mbps,
+ ctrl_cfg->tx_ctrl_cfg.frames[frame_id]);
active_vchannels++;
/*connect lcd to mipi */
- kmb_write(MSS_CAM_BASE_ADDR + MIPI_TX_MSS_LCD_MIPI_CFG, 1);
+ writel(1, MSS_CAM_BASE_ADDR + MIPI_TX_MSS_LCD_MIPI_CFG);
break;
}
if (active_vchannels == 0)
return -EINVAL;
- /*Multi-Channel FIFO Configuration*/
+ /*Multi-Channel FIFO Configuration */
mipi_tx_multichannel_fifo_cfg(ctrl_cfg->active_lanes, frame_id);
/*Frame Generator Enable */
@@ -646,6 +723,222 @@ static u32 mipi_tx_init_cntrl(struct kmb_drm_private *dev_priv,
return ret;
}
+static void test_mode_send(u32 dphy_no, u32 test_code, u32 test_data)
+{
+ /*send the test code first */
+ /* Steps for code:
+ * - set testclk HIGH
+ * - set testdin with test code
+ * - set testen HIGH
+ * - set testclk LOW
+ * - set testen LOW
+ */
+ SET_DPHY_TEST_CTRL1_CLK(dphy_no);
+ SET_TEST_DIN0_3(dphy_no, test_code);
+ SET_DPHY_TEST_CTRL1_EN(dphy_no);
+ CLR_DPHY_TEST_CTRL1_CLK(dphy_no);
+ CLR_DPHY_TEST_CTRL1_EN(dphy_no);
+
+ /*send the test data next */
+ /* Steps for data:
+ * - set testen LOW
+ * - set testclk LOW
+ * - set testdin with data
+ * - set testclk HIGH
+ */
+ CLR_DPHY_TEST_CTRL1_EN(dphy_no);
+ CLR_DPHY_TEST_CTRL1_CLK(dphy_no);
+ SET_TEST_DIN0_3(dphy_no, test_data);
+ SET_DPHY_TEST_CTRL1_CLK(dphy_no);
+}
+
+static inline void set_test_mode_src_osc_freq_target_low_bits(u32 dphy_no,
+ u32 freq)
+{
+ /*typical rise/fall time=166,
+ * refer Table 1207 databook,sr_osc_freq_target[7:0
+ */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_DDL_CYCLES, (freq & 0x7f));
+}
+
+static inline void set_test_mode_slew_rate_calib_en(u32 dphy_no)
+{
+ /*do not bypass slew rate calibration algorithm */
+ /*bits[1:0}=srcal_en_ovr_en, srcal_en_ovr, bit[6]=sr_range */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_OVERRIDE_CTRL,
+ (0x03 | (1 << 6)));
+}
+
+static inline void set_test_mode_src_osc_freq_target_hi_bits(u32 dphy_no,
+ u32 freq)
+{
+ u32 data;
+ /*typical rise/fall time=166, refer Table 1207 databook,
+ * sr_osc_freq_target[11:7
+ */
+ data = ((freq >> 6) & 0x1f) | (1 << 7); /*flag this as high nibble */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_DDL_CYCLES, data);
+}
+
+static void dphy_init_sequence(struct mipi_ctrl_cfg *cfg, u32 dphy_no,
+ enum dphy_mode mode)
+{
+ u32 test_code = 0;
+ u32 test_data = 0, val;
+ int i;
+
+ /*Set D-PHY in shutdown mode */
+ /*assert RSTZ signal */
+ CLR_DPHY_INIT_CTRL0(dphy_no, RESETZ);
+ /* assert SHUTDOWNZ signal */
+ CLR_DPHY_INIT_CTRL0(dphy_no, SHUTDOWNZ);
+
+ /*Init D-PHY_n */
+ /*Pulse testclear signal to make sure the d-phy configuration starts
+ * from a clean base
+ */
+ SET_DPHY_TEST_CTRL0(dphy_no);
+ /*TODO may need to add 15ns delay here */
+ CLR_DPHY_TEST_CTRL0(dphy_no);
+
+ /*Set mastermacro bit - Master or slave mode */
+ test_code = TEST_CODE_MULTIPLE_PHY_CTRL;
+ /*DPHY has its own clock lane enabled (master) */
+ if (mode == MIPI_DPHY_MASTER)
+ test_data = 0x01;
+ else
+ test_data = 0x00;
+
+ /*send the test code and data */
+ test_mode_send(dphy_no, test_code, test_data);
+
+ /*Set the lane data rate */
+ for (i = 0; i < MIPI_DPHY_DEFAULT_BIT_RATES; i++) {
+ if (mipi_hs_freq_range[i].default_bit_rate_mbps <
+ cfg->lane_rate_mbps)
+ continue;
+ /* send the test code and data */
+ /*bit[6:0] = hsfreqrange_ovr bit[7] = hsfreqrange_ovr_en */
+ test_mode_send(dphy_no, TEST_CODE_HS_FREQ_RANGE_CFG,
+ (mipi_hs_freq_range[i].hsfreqrange_code
+ & 0x7f) | (1 << 7));
+ break;
+ }
+ /*
+ * High-Speed Tx Slew Rate Calibration
+ * BitRate: > 1.5 Gbps && <= 2.5 Gbps: slew rate control OFF
+ */
+ if (cfg->lane_rate_mbps > 1500) {
+ /*bypass slew rate calibration algorithm */
+ /*bits[1:0} srcal_en_ovr_en, srcal_en_ovr */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_OVERRIDE_CTRL,
+ 0x02);
+
+ /* disable slew rate calibration */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL,
+ 0x00);
+ } else if (cfg->lane_rate_mbps > 1000) {
+ /*BitRate: > 1 Gbps && <= 1.5 Gbps: - slew rate control ON
+ * typical rise/fall times: 166 ps
+ */
+
+ /*do not bypass slew rate calibration algorithm */
+ set_test_mode_slew_rate_calib_en(dphy_no);
+
+ /* enable slew rate calibration */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL,
+ 0x01);
+
+ /*set sr_osc_freq_target[6:0] */
+ /*typical rise/fall time=166, refer Table 1207 databook */
+ set_test_mode_src_osc_freq_target_low_bits(dphy_no, 0x72f);
+ /*set sr_osc_freq_target[11:7] */
+ set_test_mode_src_osc_freq_target_hi_bits(dphy_no, 0x72f);
+ } else {
+ /*lane_rate_mbps <= 1000 Mbps */
+ /*BitRate: <= 1 Gbps:
+ * - slew rate control ON
+ * - typical rise/fall times: 225 ps
+ */
+ /*do not bypass slew rate calibration algorithm */
+ set_test_mode_slew_rate_calib_en(dphy_no);
+ /* enable slew rate calibration */
+ test_mode_send(dphy_no, TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL,
+ 0x01);
+
+ /*typical rise/fall time=255, refer Table 1207 databook */
+ set_test_mode_src_osc_freq_target_low_bits(dphy_no, 0x523);
+ /*set sr_osc_freq_target[11:7] */
+ set_test_mode_src_osc_freq_target_hi_bits(dphy_no, 0x523);
+ }
+
+ /*Set cfgclkfreqrange */
+ val = (((cfg->cfg_clk_khz / 1000) - 17) * 4) & 0x3f;
+ SET_DPHY_FREQ_CTRL0_3(dphy_no, val);
+
+ /*Enable config clk for the corresponding d-phy */
+ kmb_set_bit_mipi(DPHY_CFG_CLK_EN, dphy_no);
+
+ /* PLL setup */
+ if (mode == MIPI_DPHY_MASTER) {
+ /*Set PLL regulator in bypass */
+ test_mode_send(dphy_no, TEST_CODE_PLL_ANALOG_PROG, 0x01);
+
+ /*TODO - PLL Parameters Setup */
+ }
+
+ /*Send NORMAL OPERATION test code */
+ test_mode_send(dphy_no, 0x00, 0x00);
+
+ /* Configure BASEDIR for data lanes
+ * NOTE: basedir only applies to LANE_0 of each D-PHY.
+ * The other lanes keep their direction based on the D-PHY type,
+ * either Rx or Tx.
+ * bits[5:0] - BaseDir: 1 = Rx
+ * bits[9:6] - BaseDir: 0 = Tx
+ */
+ kmb_clr_bit_mipi(DPHY_INIT_CTRL2, dphy_no);
+
+ /* Enable CLOCK LANE - */
+ /*clock lane should be enabled regardless of the direction set for
+ * the D-PHY (Rx/Tx)
+ */
+ kmb_clr_bit_mipi(DPHY_INIT_CTRL2, 12 + dphy_no);
+
+ /* enable DATA LANES */
+ kmb_write_bits_mipi(DPHY_ENABLE, dphy_no * 2, 2,
+ ((1 << cfg->active_lanes) - 1));
+}
+
+static u32 mipi_tx_init_dphy(struct mipi_ctrl_cfg *cfg)
+{
+ u32 dphy_no = MIPI_DPHY6;
+
+ /*multiple D-PHYs needed */
+ if (cfg->active_lanes > MIPI_DPHY_D_LANES) {
+ /*
+ *Initialization for Tx aggregation mode is done according to
+ *http://dub30.ir.intel.com/bugzilla/show_bug.cgi?id=27785#c12:
+ *a. start init PHY1
+ *b. poll for PHY1 FSM state LOCK
+ * b1. reg addr 0x03[3:0] - state_main[3:0] == 5 (LOCK)
+ *c. poll for PHY1 calibrations done :
+ * c1. termination calibration lower section: addr 0x22[5]
+ * - rescal_done
+ * c2. slewrate calibration (if data rate < = 1500 Mbps):
+ * addr 0xA7[3:2] - srcal_done, sr_finished
+ *d. start init PHY0
+ *e. poll for PHY0 stopstate
+ *f. poll for PHY1 stopstate
+ */
+ /*PHY #N+1 ('slave') */
+ dphy_init_sequence(cfg, dphy_no + 1, MIPI_DPHY_SLAVE);
+ /*TODO PHY #N master */
+ }
+ /*TODO- Single DPHY */
+ return 0;
+}
+
void kmb_dsi_init(struct drm_device *dev)
{
struct kmb_dsi *kmb_dsi;
@@ -688,4 +981,7 @@ void kmb_dsi_init(struct drm_device *dev)
/* initialize mipi controller */
mipi_tx_init_cntrl(dev_priv, &mipi_tx_init_cfg);
+
+ /*d-phy initialization */
+ mipi_tx_init_dphy(&mipi_tx_init_cfg);
}
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.h b/drivers/gpu/drm/kmb/kmb_dsi.h
index d1ec5a6..deaee3e 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.h
+++ b/drivers/gpu/drm/kmb/kmb_dsi.h
@@ -38,6 +38,11 @@ struct kmb_connector {
#define MIPI_D_LANES_PER_DPHY 2
#define MIPI_CTRL_2LANE_MAX_MC_FIFO_LOC 255
#define MIPI_CTRL_4LANE_MAX_MC_FIFO_LOC 511
+#define MIPI_DPHY_D_LANES 2 /* 2 Data Lanes per D-PHY*/
+#define MIPI_DPHY_DEFAULT_BIT_RATES 63
+
+/*DPHY Tx test codes */
+#define TEST_CODE_MULTIPLE_PHY_CTRL 0x03
enum mipi_ctrl_num {
MIPI_CTRL0 = 0,
@@ -174,6 +179,11 @@ enum mipi_dsi_data_type {
DSI_LP_DT_RESERVED_3F = 0x3f
};
+enum dphy_mode {
+ MIPI_DPHY_SLAVE = 0,
+ MIPI_DPHY_MASTER
+};
+
struct mipi_data_type_params {
uint8_t size_constraint_pixels;
uint8_t size_constraint_bytes;
diff --git a/drivers/gpu/drm/kmb/kmb_regs.h b/drivers/gpu/drm/kmb/kmb_regs.h
index 381e255..899a5d3 100644
--- a/drivers/gpu/drm/kmb/kmb_regs.h
+++ b/drivers/gpu/drm/kmb/kmb_regs.h
@@ -7,6 +7,7 @@
#define __KMB_REGS_H__
#define ENABLE 1
+#define DISABLE 0
/*from Data Book section 12.5.8.1 page 4322 */
#define MIPI_BASE_ADDR (void *)(0x20900000)
/*from Data Book section 12.11.6.1 page 4972 */
@@ -380,8 +381,10 @@
#define MIPI_TX_HS_CTRL (0x0)
#define MIPI_TXm_HS_CTRL(M) (MIPI_TX_HS_CTRL + HS_OFFSET(M))
#define HS_CTRL_EN (1 << 0)
-#define HS_CTRL_CSIDSIN (1 << 2) /*1:CSI 0:DSI*/
-#define TX_SOURCE (1 << 3) /*1:LCD, 0:DMA*/
+/*1:CSI 0:DSI */
+#define HS_CTRL_CSIDSIN (1 << 2)
+/*1:LCD, 0:DMA */
+#define TX_SOURCE (1 << 3)
#define ACTIVE_LANES(n) ((n) << 4)
#define LCD_VC(ch) ((ch) << 8)
#define DSI_EOTP_EN (1 << 11)
@@ -498,6 +501,45 @@
kmb_write_bits_mipi(MIPI_TXm_HS_MC_FIFO_RTHRESHOLDn(ctrl, vc/2), \
(vc % 2)*16, 16, th)
+/* D-PHY regs */
+#define DPHY_ENABLE (0x100)
+#define DPHY_INIT_CTRL0 (0x104)
+#define SHUTDOWNZ 0
+#define RESETZ 12
+#define DPHY_INIT_CTRL2 (0x10c)
+#define SET_DPHY_INIT_CTRL0(dphy, offset) \
+ kmb_set_bit_mipi(DPHY_INIT_CTRL0, \
+ (dphy+offset))
+#define CLR_DPHY_INIT_CTRL0(dphy, offset) \
+ kmb_clr_bit_mipi(DPHY_INIT_CTRL0, \
+ (dphy+offset))
+#define DPHY_FREQ_CTRL0_3 (0x11c)
+#define SET_DPHY_FREQ_CTRL0_3(dphy, val) \
+ kmb_write_bits_mipi(DPHY_FREQ_CTRL0_3 \
+ + ((dphy/4)*4), (dphy % 4) * 8, \
+ 6, val)
+#define DPHY_TEST_CTRL0 (0x154)
+#define SET_DPHY_TEST_CTRL0(dphy) kmb_set_bit_mipi(DPHY_TEST_CTRL0, \
+ (dphy))
+#define CLR_DPHY_TEST_CTRL0(dphy) kmb_clr_bit_mipi(DPHY_TEST_CTRL0, \
+ (dphy))
+#define DPHY_TEST_CTRL1 (0x158)
+#define SET_DPHY_TEST_CTRL1_CLK(dphy) kmb_set_bit_mipi(DPHY_TEST_CTRL1, \
+ (dphy))
+#define CLR_DPHY_TEST_CTRL1_CLK(dphy) kmb_clr_bit_mipi(DPHY_TEST_CTRL1, \
+ (dphy))
+#define SET_DPHY_TEST_CTRL1_EN(dphy) kmb_set_bit_mipi(DPHY_TEST_CTRL1, \
+ (dphy+12))
+#define CLR_DPHY_TEST_CTRL1_EN(dphy) kmb_clr_bit_mipi(DPHY_TEST_CTRL1, \
+ (dphy+12))
+#define DPHY_TEST_DIN0_3 (0x15c)
+#define SET_TEST_DIN0_3(dphy, val) kmb_write_mipi(DPHY_TEST_DIN0_3 + \
+ 4, ((val) << (((dphy)%4)*8)))
+#define DPHY_TEST_DOUT0_3 (0x168)
+#define GET_TEST_DOUT0_3(dphy) (readl(DPHY_TEST_DOUT0_3 + 4) \
+ >> (((dphy)%4)*8) & 0xff)
+#define DPHY_CFG_CLK_EN (0x18c)
+
#define MIPI_TX_MSS_LCD_MIPI_CFG (0x04)
-#define BIT_MASK_16 (0xffff)
+#define BIT_MASK_16 (0xffff)
#endif /* __KMB_REGS_H__ */
--
2.7.4
More information about the dri-devel
mailing list