diff options
| author | Xiaoming Zhou <zhoux@codeaurora.org> | 2013-04-16 11:16:56 -0400 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:16:15 -0700 |
| commit | 81dafba8b34b37c8a35f2932a3f337e4858e015f (patch) | |
| tree | 06da9e78408e31612f50218f58818d863af6941b | |
| parent | ec5e0e6c17d27742fde207e4d107454325d10ba5 (diff) | |
msmfb: mdss: add request for DSI clock for DSI controller
DSI clock is the core clock for DSI controller. Turn on the DSI controller
before issuing panel on DSI commands, and switch to DSI command mode before
sending panel off commands.
Change-Id: I0cda9619ebbb61600d8f0a80668bf4b4501ac799
Signed-off-by: Xiaoming Zhou <zhoux@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_host_v2.c | 44 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_io_v2.c | 27 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_io_v2.h | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_v2.c | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_v2.h | 2 |
5 files changed, 68 insertions, 28 deletions
diff --git a/drivers/video/fbdev/msm/dsi_host_v2.c b/drivers/video/fbdev/msm/dsi_host_v2.c index 91fd7ba70fcb..abbfd8f36448 100644 --- a/drivers/video/fbdev/msm/dsi_host_v2.c +++ b/drivers/video/fbdev/msm/dsi_host_v2.c @@ -29,6 +29,7 @@ #define DSI_POLL_SLEEP_US 1000 #define DSI_POLL_TIMEOUT_US 16000 #define DSI_ESC_CLK_RATE 19200000 +#define DSI_DMA_CMD_TIMEOUT_MS 200 struct dsi_host_v2_private { struct completion dma_comp; @@ -426,18 +427,15 @@ void msm_dsi_op_mode_config(int mode, struct mdss_panel_data *pdata) dsi_ctrl = MIPI_INP(ctrl_base + DSI_CTRL); /*If Video enabled, Keep Video and Cmd mode ON */ - if (dsi_ctrl & 0x02) - dsi_ctrl &= ~0x05; - else - dsi_ctrl &= ~0x07; + + + dsi_ctrl &= ~0x06; if (mode == DSI_VIDEO_MODE) { - dsi_ctrl |= 0x03; + dsi_ctrl |= 0x02; intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK; } else { /* command mode */ - dsi_ctrl |= 0x05; - if (pdata->panel_info.type == MIPI_VIDEO_PANEL) - dsi_ctrl |= 0x02; + dsi_ctrl |= 0x04; intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK | DSI_INTR_CMD_MDP_DONE_MASK; @@ -480,7 +478,7 @@ int msm_dsi_cmd_reg_tx(u32 data) int msm_dsi_cmd_dma_tx(struct dsi_buf *tp) { - int len; + int len, rc; unsigned long size, addr; unsigned char *ctrl_base = dsi_host_private->dsi_base; @@ -505,12 +503,17 @@ int msm_dsi_cmd_dma_tx(struct dsi_buf *tp) MIPI_OUTP(ctrl_base + DSI_CMD_MODE_DMA_SW_TRIGGER, 0x01); wmb(); - wait_for_completion_interruptible(&dsi_host_private->dma_comp); + rc = wait_for_completion_timeout(&dsi_host_private->dma_comp, + msecs_to_jiffies(DSI_DMA_CMD_TIMEOUT_MS)); + if (rc == 0) { + pr_err("DSI command transaction time out\n"); + rc = -ETIME; + } dma_unmap_single(&dsi_host_private->dis_dev, tp->dmap, size, DMA_TO_DEVICE); tp->dmap = 0; - return 0; + return rc; } int msm_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen) @@ -723,6 +726,7 @@ int msm_dsi_cmds_rx(struct mdss_panel_data *pdata, static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, u32 *bitclk_rate, + u32 *dsiclk_rate, u32 *byteclk_rate, u32 *pclk_rate) { @@ -761,10 +765,11 @@ static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, *bitclk_rate /= lanes; *byteclk_rate = *bitclk_rate / 8; + *dsiclk_rate = *byteclk_rate * lanes; *pclk_rate = *byteclk_rate * lanes * 8 / pdata->panel_info.bpp; - pr_debug("bitclk=%u, byteclk=%u, pck_=%u\n", - *bitclk_rate, *byteclk_rate, *pclk_rate); + pr_debug("dsiclk_rate=%u, byteclk=%u, pck_=%u\n", + *dsiclk_rate, *byteclk_rate, *pclk_rate); return 0; } @@ -777,7 +782,7 @@ static int msm_dsi_on(struct mdss_panel_data *pdata) u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, data; u32 dummy_xres, dummy_yres; - u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0; + u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0, dsiclk_rate = 0; unsigned char *ctrl_base = dsi_host_private->dsi_base; pr_debug("msm_dsi_on\n"); @@ -794,8 +799,10 @@ static int msm_dsi_on(struct mdss_panel_data *pdata) msm_dsi_phy_sw_reset(dsi_host_private->dsi_base); msm_dsi_phy_init(dsi_host_private->dsi_base, pdata); - msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &byteclk_rate, &pclk_rate); - msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, byteclk_rate, pclk_rate); + msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &dsiclk_rate, + &byteclk_rate, &pclk_rate); + msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, dsiclk_rate, + byteclk_rate, pclk_rate); msm_dsi_prepare_clocks(); msm_dsi_clk_enable(); @@ -879,12 +886,11 @@ static int msm_dsi_off(struct mdss_panel_data *pdata) int ret = 0; pr_debug("msm_dsi_off\n"); - msm_dsi_clk_set_rate(0, 0, 0); + msm_dsi_controller_cfg(0); + msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, 0, 0, 0); msm_dsi_clk_disable(); msm_dsi_unprepare_clocks(); - /* disable DSI controller */ - msm_dsi_controller_cfg(0); msm_dsi_ahb_ctrl(0); ret = msm_dsi_regulator_disable(); diff --git a/drivers/video/fbdev/msm/dsi_io_v2.c b/drivers/video/fbdev/msm/dsi_io_v2.c index 0486c4c3e79c..93f2c7671b3e 100644 --- a/drivers/video/fbdev/msm/dsi_io_v2.c +++ b/drivers/video/fbdev/msm/dsi_io_v2.c @@ -29,6 +29,7 @@ struct msm_dsi_io_private { struct clk *dsi_esc_clk; struct clk *dsi_pixel_clk; struct clk *dsi_ahb_clk; + struct clk *dsi_clk; int msm_dsi_clk_on; int msm_dsi_ahb_clk_on; }; @@ -97,6 +98,13 @@ int msm_dsi_clk_init(struct platform_device *dev) { int rc = 0; + dsi_io_private->dsi_clk = clk_get(&dev->dev, "dsi_clk"); + if (IS_ERR(dsi_io_private->dsi_clk)) { + pr_err("can't find dsi core_clk\n"); + rc = PTR_ERR(dsi_io_private->dsi_clk); + dsi_io_private->dsi_clk = NULL; + return rc; + } dsi_io_private->dsi_byte_clk = clk_get(&dev->dev, "byte_clk"); if (IS_ERR(dsi_io_private->dsi_byte_clk)) { pr_err("can't find dsi byte_clk\n"); @@ -135,6 +143,10 @@ int msm_dsi_clk_init(struct platform_device *dev) void msm_dsi_clk_deinit(void) { + if (dsi_io_private->dsi_clk) { + clk_put(dsi_io_private->dsi_clk); + dsi_io_private->dsi_clk = NULL; + } if (dsi_io_private->dsi_byte_clk) { clk_put(dsi_io_private->dsi_byte_clk); dsi_io_private->dsi_byte_clk = NULL; @@ -156,6 +168,7 @@ void msm_dsi_clk_deinit(void) int msm_dsi_prepare_clocks(void) { + clk_prepare(dsi_io_private->dsi_clk); clk_prepare(dsi_io_private->dsi_byte_clk); clk_prepare(dsi_io_private->dsi_esc_clk); clk_prepare(dsi_io_private->dsi_pixel_clk); @@ -164,16 +177,24 @@ int msm_dsi_prepare_clocks(void) int msm_dsi_unprepare_clocks(void) { + clk_unprepare(dsi_io_private->dsi_clk); clk_unprepare(dsi_io_private->dsi_esc_clk); clk_unprepare(dsi_io_private->dsi_byte_clk); clk_unprepare(dsi_io_private->dsi_pixel_clk); return 0; } -int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate, +int msm_dsi_clk_set_rate(unsigned long esc_rate, + unsigned long dsi_rate, + unsigned long byte_rate, unsigned long pixel_rate) { int rc; + rc = clk_set_rate(dsi_io_private->dsi_clk, dsi_rate); + if (rc) { + pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc); + return rc; + } rc = clk_set_rate(dsi_io_private->dsi_esc_clk, esc_rate); if (rc) { @@ -202,6 +223,7 @@ int msm_dsi_clk_enable(void) return 0; } + clk_enable(dsi_io_private->dsi_clk); clk_enable(dsi_io_private->dsi_esc_clk); clk_enable(dsi_io_private->dsi_byte_clk); clk_enable(dsi_io_private->dsi_pixel_clk); @@ -217,6 +239,7 @@ int msm_dsi_clk_disable(void) return 0; } + clk_disable(dsi_io_private->dsi_clk); clk_disable(dsi_io_private->dsi_byte_clk); clk_disable(dsi_io_private->dsi_esc_clk); clk_disable(dsi_io_private->dsi_pixel_clk); @@ -246,7 +269,7 @@ int msm_dsi_regulator_init(struct platform_device *dev) void msm_dsi_regulator_deinit(void) { - if (dsi_io_private->vdda_vreg) { + if (!IS_ERR(dsi_io_private->vdda_vreg)) { devm_regulator_put(dsi_io_private->vdda_vreg); dsi_io_private->vdda_vreg = NULL; } diff --git a/drivers/video/fbdev/msm/dsi_io_v2.h b/drivers/video/fbdev/msm/dsi_io_v2.h index 25ecd7f0b3ee..285bf30de1f2 100644 --- a/drivers/video/fbdev/msm/dsi_io_v2.h +++ b/drivers/video/fbdev/msm/dsi_io_v2.h @@ -29,7 +29,9 @@ int msm_dsi_prepare_clocks(void); int msm_dsi_unprepare_clocks(void); -int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate, +int msm_dsi_clk_set_rate(unsigned long esc_rate, + unsigned long dsi_rate, + unsigned long byte_rate, unsigned long pixel_rate); int msm_dsi_clk_enable(void); diff --git a/drivers/video/fbdev/msm/dsi_v2.c b/drivers/video/fbdev/msm/dsi_v2.c index 5e46bf503361..583379696230 100644 --- a/drivers/video/fbdev/msm/dsi_v2.c +++ b/drivers/video/fbdev/msm/dsi_v2.c @@ -29,6 +29,14 @@ static int dsi_off(struct mdss_panel_data *pdata) if (!panel_common_data || !pdata) return -ENODEV; + if (dsi_intf.op_mode_config) + dsi_intf.op_mode_config(DSI_CMD_MODE, pdata); + + pr_debug("panel off commands\n"); + if (panel_common_data->off) + panel_common_data->off(pdata); + + pr_debug("turn off dsi controller\n"); if (dsi_intf.off) rc = dsi_intf.off(pdata); @@ -37,9 +45,9 @@ static int dsi_off(struct mdss_panel_data *pdata) return rc; } - pr_debug("dsi_off reset\n"); - if (panel_common_data->off) - panel_common_data->off(pdata); + pr_debug("turn off panel power\n"); + if (panel_common_data->reset) + panel_common_data->reset(pdata, 0); return rc; } @@ -53,8 +61,6 @@ static int dsi_on(struct mdss_panel_data *pdata) if (!panel_common_data || !pdata) return -ENODEV; - if (panel_common_data->reset) - panel_common_data->reset(1); pr_debug("dsi_on DSI controller ont\n"); if (dsi_intf.on) @@ -64,6 +70,9 @@ static int dsi_on(struct mdss_panel_data *pdata) pr_err("mdss_dsi_on DSI failed %d\n", rc); return rc; } + pr_debug("dsi_on power on panel\n"); + if (panel_common_data->reset) + panel_common_data->reset(pdata, 1); pr_debug("dsi_on DSI panel ont\n"); if (panel_common_data->on) diff --git a/drivers/video/fbdev/msm/dsi_v2.h b/drivers/video/fbdev/msm/dsi_v2.h index fa868ab7f1c8..f68527cf89fa 100644 --- a/drivers/video/fbdev/msm/dsi_v2.h +++ b/drivers/video/fbdev/msm/dsi_v2.h @@ -189,7 +189,7 @@ struct dsi_panel_common_pdata { struct mdss_panel_info panel_info; int (*on) (struct mdss_panel_data *pdata); int (*off) (struct mdss_panel_data *pdata); - void (*reset)(int enable); + void (*reset)(struct mdss_panel_data *pdata, int enable); void (*bl_fnc) (struct mdss_panel_data *pdata, u32 bl_level); struct dsi_panel_cmds_list *dsi_panel_on_cmds; struct dsi_panel_cmds_list *dsi_panel_off_cmds; |
