diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index 6115e81..775bec2 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c @@ -91,13 +91,16 @@ #define FRAME_BTA_ACK BIT(14) #define ENABLE_LOW_POWER (0x3f << 8) #define ENABLE_LOW_POWER_MASK (0x3f << 8) -#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x2 -#define VID_MODE_TYPE_MASK 0x3 +#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x0 +#define VID_MODE_TYPE_BURST_SYNC_EVENTS 0x1 +#define VID_MODE_TYPE_BURST 0x2 #define DSI_VID_PKT_SIZE 0x3c #define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0) #define VID_PKT_MAX_SIZE 0x3fff +#define DSI_VID_NUM_CHUMKS 0x40 +#define DSI_VID_NULL_PKT_SIZE 0x44 #define DSI_VID_HSA_TIME 0x48 #define DSI_VID_HBP_TIME 0x4c #define DSI_VID_HLINE_TIME 0x50 @@ -238,7 +241,7 @@ #define TER_RESISTOR_LOW 0 #define LEVEL_SHIFTERS_ON BIT(6) #define TER_CAL_DONE BIT(5) -#define SETRD_MAX (0x7 << 2) +#define SETRD_MAX (0x0 << 2) #define POWER_MANAGE BIT(1) #define TER_RESISTORS_ON BIT(0) @@ -343,7 +346,7 @@ static int max_mbps_to_testdin(unsigned int max_mbps) /* * The controller should generate 2 frames before - * preparing the peripheral. + * preparing the peripheral.. */ static void dw_mipi_dsi_wait_for_two_frames(struct dw_mipi_dsi *dsi) { @@ -413,8 +416,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) return testdin; } - dsi_write(dsi, DSI_PWR_UP, POWERUP); - if (!IS_ERR(dsi->phy_cfg_clk)) { ret = clk_prepare_enable(dsi->phy_cfg_clk); if (ret) { @@ -456,13 +457,12 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) BANDGAP_SEL(BANDGAP_96_10)); dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf); - dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x55); + dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x2d); dw_mipi_dsi_phy_write(dsi, 0x72, THS_ZERO_PROGRAM_EN | 0xa); dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK | PHY_UNRSTZ | PHY_UNSHUTDOWNZ); - ret = readx_poll_timeout(readl, dsi->base + DSI_PHY_STATUS, val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US); if (ret < 0) { @@ -477,6 +477,8 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) dev_err(dsi->dev, "failed to wait for phy clk lane stop state\n"); + dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); + phy_init_end: if (!IS_ERR(dsi->phy_cfg_clk)) clk_disable_unprepare(dsi->phy_cfg_clk); @@ -502,7 +504,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi) mpclk = DIV_ROUND_UP(dsi->mode->clock, MSEC_PER_SEC); if (mpclk) { /* take 1 / 0.9, since mbps must big than bandwidth of RGB */ - tmp = mpclk * (bpp / dsi->lanes) * 10 / 9; + tmp = mpclk * (bpp / dsi->lanes); if (tmp < max_mbps) target_mbps = tmp; else @@ -574,10 +576,12 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host, static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val) { int ret; + int sts = 0; ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, - val, !(val & GEN_CMD_FULL), 1000, + sts, !(sts & GEN_CMD_FULL), 1000, CMD_PKT_STATUS_TIMEOUT_US); + if (ret < 0) { dev_err(dsi->dev, "failed to get available command FIFO\n"); return ret; @@ -586,8 +590,9 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val) dsi_write(dsi, DSI_GEN_HDR, val); ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, - val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY), + sts, sts & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY), 1000, CMD_PKT_STATUS_TIMEOUT_US); + if (ret < 0) { dev_err(dsi->dev, "failed to write command FIFO\n"); return ret; @@ -596,8 +601,8 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val) return 0; } -static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi, - const struct mipi_dsi_msg *msg) +static int dw_mipi_dsi_short_write(struct dw_mipi_dsi *dsi, + const struct mipi_dsi_msg *msg) { const u16 *tx_buf = msg->tx_buf; u32 val = GEN_HDATA(*tx_buf) | GEN_HTYPE(msg->type); @@ -611,13 +616,14 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi, return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val); } -static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, - const struct mipi_dsi_msg *msg) +static int dw_mipi_dsi_long_write(struct dw_mipi_dsi *dsi, + const struct mipi_dsi_msg *msg) { const u32 *tx_buf = msg->tx_buf; int len = msg->tx_len, pld_data_bytes = sizeof(*tx_buf), ret; u32 val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type); u32 remainder = 0; + u32 sts = 0; if (msg->tx_len < 3) { dev_err(dsi->dev, "wrong tx buf length %zu for long write\n", @@ -637,7 +643,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, } ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, - val, !(val & GEN_PLD_W_FULL), 1000, + sts, !(sts & GEN_PLD_W_FULL), 1000, CMD_PKT_STATUS_TIMEOUT_US); if (ret < 0) { dev_err(dsi->dev, @@ -658,11 +664,15 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, switch (msg->type) { case MIPI_DSI_DCS_SHORT_WRITE: case MIPI_DSI_DCS_SHORT_WRITE_PARAM: + case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: + case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: + case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: - ret = dw_mipi_dsi_dcs_short_write(dsi, msg); + ret = dw_mipi_dsi_short_write(dsi, msg); break; case MIPI_DSI_DCS_LONG_WRITE: - ret = dw_mipi_dsi_dcs_long_write(dsi, msg); + case MIPI_DSI_GENERIC_LONG_WRITE: + ret = dw_mipi_dsi_long_write(dsi, msg); break; default: dev_err(dsi->dev, "unsupported message type\n"); @@ -682,7 +692,7 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; - val = VID_MODE_TYPE_BURST_SYNC_PULSES | ENABLE_LOW_POWER; + val = VID_MODE_TYPE_BURST | ENABLE_LOW_POWER; dsi_write(dsi, DSI_VID_MODE_CFG, val); } @@ -713,9 +723,9 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) dsi_write(dsi, DSI_PWR_UP, RESET); dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK | PHY_RSTZ | PHY_SHUTDOWNZ); + dsi_write(dsi, DSI_PWR_UP, POWERUP); dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) | TX_ESC_CLK_DIVIDSION(7)); - dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, @@ -853,7 +863,7 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder, if (dsi->dpms_mode == DRM_MODE_DPMS_ON) return; - dsi->mode = adjusted_mode; + drm_mode_copy(dsi->mode, adjusted_mode); ret = dw_mipi_dsi_get_lane_bps(dsi); if (ret < 0) @@ -940,9 +950,10 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder) dw_mipi_dsi_phy_init(dsi); dw_mipi_dsi_wait_for_two_frames(dsi); - dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE); drm_panel_enable(dsi->panel); + dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE); + clk_disable_unprepare(dsi->pclk); if (mux) @@ -1138,6 +1149,7 @@ static const struct of_device_id dw_mipi_dsi_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, dw_mipi_dsi_dt_ids); +extern int tinker_mcu_is_connected(void); static int dw_mipi_dsi_bind(struct device *dev, struct device *master, void *data) { @@ -1188,6 +1200,11 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master, return ret; } + if(!tinker_mcu_is_connected()) { + pr_info("panel is not connected\n"); + goto err_pllref; + } + ret = dw_mipi_dsi_register(drm, dsi); if (ret) { dev_err(dev, "Failed to register mipi_dsi: %d\n", ret); @@ -1236,6 +1253,9 @@ static int dw_mipi_dsi_probe(struct platform_device *pdev) dsi->pdata = pdata; dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; dsi->dsi_host.dev = &pdev->dev; + dsi->mode = devm_kzalloc(&pdev->dev, sizeof(struct drm_display_mode), GFP_KERNEL); + if (!dsi) + return -ENOMEM; ret = mipi_dsi_host_register(&dsi->dsi_host); if (ret)