diff options
| author | Ajay Singh Parmar <aparmar@codeaurora.org> | 2016-05-16 18:02:07 -0700 |
|---|---|---|
| committer | Dhaval Patel <pdhaval@codeaurora.org> | 2016-08-01 11:58:13 -0700 |
| commit | 5edb8d288567ebb7846756f1e8086e6f2cb7ecc7 (patch) | |
| tree | 9a372f9a2c4787db7a984000776b669d4d4a2840 /drivers/gpu | |
| parent | 02bfb4e1717fe1e544fa707991f7a57f04c80152 (diff) | |
drm/msm/dsi-staging: add support for command mode panels
Add support for command mode panels. Command engine state must be
ref-counted since it is toggled in two paths, command transfer and mdp
command frame updates.
Change-Id: I9aba97465ad822c4c862f6aa5422dc47cb6664c8
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c | 39 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 62 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 5 |
7 files changed, 121 insertions, 24 deletions
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c index 114998fb8fc5..3f698cbdc8e5 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c @@ -28,6 +28,7 @@ static void dsi_catalog_14_init(struct dsi_ctrl_hw *ctrl) ctrl->ops.video_engine_setup = dsi_ctrl_hw_14_video_engine_setup; ctrl->ops.set_video_timing = dsi_ctrl_hw_14_set_video_timing; ctrl->ops.cmd_engine_setup = dsi_ctrl_hw_14_cmd_engine_setup; + ctrl->ops.setup_cmd_stream = dsi_ctrl_hw_14_setup_cmd_stream; ctrl->ops.ctrl_en = dsi_ctrl_hw_14_ctrl_en; ctrl->ops.cmd_engine_en = dsi_ctrl_hw_14_cmd_engine_en; ctrl->ops.phy_sw_reset = dsi_ctrl_hw_14_phy_sw_reset; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h index e4b33c259540..506fa28f8cd3 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h @@ -75,6 +75,11 @@ void dsi_ctrl_hw_14_cmd_engine_setup(struct dsi_ctrl_hw *ctrl, void dsi_ctrl_hw_14_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on); void dsi_ctrl_hw_14_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on); +void dsi_ctrl_hw_14_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, + u32 width_in_pixels, + u32 h_stride, + u32 height_in_lines, + u32 vc_id); void dsi_ctrl_hw_14_phy_sw_reset(struct dsi_ctrl_hw *ctrl); void dsi_ctrl_hw_14_soft_reset(struct dsi_ctrl_hw *ctrl); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c index a282fce38354..381827ece513 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c @@ -1485,23 +1485,30 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl) goto error; } - dsi_ctrl->hw.ops.set_video_timing(&dsi_ctrl->hw, - &dsi_ctrl->host_config.video_timing); - dsi_ctrl->hw.ops.setup_lane_map(&dsi_ctrl->hw, &dsi_ctrl->host_config.lane_map); dsi_ctrl->hw.ops.host_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config); - if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE) + if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE) { dsi_ctrl->hw.ops.cmd_engine_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config, &dsi_ctrl->host_config.u.cmd_engine); - else + + dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw, + dsi_ctrl->host_config.video_timing.h_active, + dsi_ctrl->host_config.video_timing.h_active * 3, + dsi_ctrl->host_config.video_timing.v_active, + 0x0); + } else { dsi_ctrl->hw.ops.video_engine_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config, &dsi_ctrl->host_config.u.video_engine); + dsi_ctrl->hw.ops.set_video_timing(&dsi_ctrl->hw, + &dsi_ctrl->host_config.video_timing); + } + dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw, 0x0); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h index b5ddfbb4ef72..a33d6d3303ef 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h @@ -272,6 +272,22 @@ struct dsi_ctrl_hw_ops { struct dsi_cmd_engine_cfg *cfg); /** + * setup_cmd_stream() - set up parameters for command pixel streams + * @ctrl: Pointer to controller host hardware. + * @width_in_pixels: Width of the stream in pixels. + * @h_stride: Horizontal stride in bytes. + * @height_inLines: Number of lines in the stream. + * @vc_id: stream_id. + * + * Setup parameters for command mode pixel stream size. + */ + void (*setup_cmd_stream)(struct dsi_ctrl_hw *ctrl, + u32 width_in_pixels, + u32 h_stride, + u32 height_in_lines, + u32 vc_id); + + /** * ctrl_en() - enable DSI controller engine * @ctrl: Pointer to the controller host hardware. * @on: turn on/off the DSI controller engine. diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c index 8326024f76ec..9d819a270894 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c @@ -85,9 +85,6 @@ void dsi_ctrl_hw_14_host_setup(struct dsi_ctrl_hw *ctrl, DSI_W32(ctrl, DSI_CTRL, reg_value); - /* Enable Timing double buffering */ - DSI_W32(ctrl, DSI_DSI_TIMING_DB_MODE, 0x1); - pr_debug("[DSI_%d]Host configuration complete\n", ctrl->index); } @@ -198,6 +195,35 @@ void dsi_ctrl_hw_14_set_video_timing(struct dsi_ctrl_hw *ctrl, } /** + * setup_cmd_stream() - set up parameters for command pixel streams + * @ctrl: Pointer to controller host hardware. + * @width_in_pixels: Width of the stream in pixels. + * @h_stride: Horizontal stride in bytes. + * @height_inLines: Number of lines in the stream. + * @vc_id: stream_id + * + * Setup parameters for command mode pixel stream size. + */ +void dsi_ctrl_hw_14_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, + u32 width_in_pixels, + u32 h_stride, + u32 height_in_lines, + u32 vc_id) +{ + u32 reg = 0; + + reg = (h_stride + 1) << 16; + reg |= (vc_id & 0x3) << 8; + reg |= 0x39; /* packet data type */ + DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_CTRL, reg); + DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_CTRL, reg); + + reg = (height_in_lines << 16) | width_in_pixels; + DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL, reg); + DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL, reg); +} + +/** * video_engine_setup() - Setup dsi host controller for video mode * @ctrl: Pointer to controller host hardware. * @common_cfg: Common configuration parameters. @@ -229,6 +255,9 @@ void dsi_ctrl_hw_14_video_engine_setup(struct dsi_ctrl_hw *ctrl, reg |= (common_cfg->bit_swap_green ? BIT(4) : 0); reg |= (common_cfg->bit_swap_blue ? BIT(8) : 0); DSI_W32(ctrl, DSI_VIDEO_MODE_DATA_CTRL, reg); + /* Enable Timing double buffering */ + DSI_W32(ctrl, DSI_DSI_TIMING_DB_MODE, 0x1); + pr_debug("[DSI_%d] Video engine setup done\n", ctrl->index); } @@ -255,6 +284,10 @@ void dsi_ctrl_hw_14_cmd_engine_setup(struct dsi_ctrl_hw *ctrl, reg |= cmd_mode_format_map[common_cfg->dst_format]; DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL, reg); + reg = DSI_R32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2); + reg |= BIT(16); + DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2, reg); + reg = cfg->wr_mem_start & 0xFF; reg |= (cfg->wr_mem_continue & 0xFF) << 8; reg |= (cfg->insert_dcs_command ? BIT(16) : 0); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 68e3b52c8605..1e2226c0e159 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -364,6 +364,11 @@ static int dsi_display_cmd_engine_enable(struct dsi_display *display) int i; struct dsi_display_ctrl *m_ctrl, *ctrl; + if (display->cmd_engine_refcount > 0) { + display->cmd_engine_refcount++; + return 0; + } + m_ctrl = &display->ctrl[display->cmd_master_idx]; rc = dsi_ctrl_set_cmd_engine_state(m_ctrl->ctrl, DSI_CTRL_ENGINE_ON); @@ -387,6 +392,7 @@ static int dsi_display_cmd_engine_enable(struct dsi_display *display) } } + display->cmd_engine_refcount++; return rc; error_disable_master: (void)dsi_ctrl_set_cmd_engine_state(m_ctrl->ctrl, DSI_CTRL_ENGINE_OFF); @@ -400,6 +406,14 @@ static int dsi_display_cmd_engine_disable(struct dsi_display *display) int i; struct dsi_display_ctrl *m_ctrl, *ctrl; + if (display->cmd_engine_refcount == 0) { + pr_err("[%s] Invalid refcount\n", display->name); + return 0; + } else if (display->cmd_engine_refcount > 1) { + display->cmd_engine_refcount--; + return 0; + } + m_ctrl = &display->ctrl[display->cmd_master_idx]; for (i = 0; i < display->ctrl_count; i++) { ctrl = &display->ctrl[i]; @@ -421,6 +435,7 @@ static int dsi_display_cmd_engine_disable(struct dsi_display *display) } error: + display->cmd_engine_refcount = 0; return rc; } @@ -1834,20 +1849,33 @@ int dsi_display_enable(struct dsi_display *display) if (rc) { pr_err("[%s] failed to enable DSI panel, rc=%d\n", display->name, rc); - goto error_disable_vid_engine; + goto error; } - rc = dsi_display_vid_engine_enable(display); - if (rc) { - pr_err("[%s] failed to enable DSI video engine, rc=%d\n", - display->name, rc); - goto error; + if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { + rc = dsi_display_vid_engine_enable(display); + if (rc) { + pr_err("[%s]failed to enable DSI video engine, rc=%d\n", + display->name, rc); + goto error_disable_panel; + } + } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { + rc = dsi_display_cmd_engine_enable(display); + if (rc) { + pr_err("[%s]failed to enable DSI cmd engine, rc=%d\n", + display->name, rc); + goto error_disable_panel; + } + } else { + pr_err("[%s] Invalid configuration\n", display->name); + rc = -EINVAL; + goto error_disable_panel; } goto error; -error_disable_vid_engine: - (void)dsi_display_vid_engine_disable(display); +error_disable_panel: + (void)dsi_panel_disable(display->panel); error: mutex_unlock(&display->display_lock); return rc; @@ -1914,10 +1942,20 @@ int dsi_display_disable(struct dsi_display *display) pr_err("[%s] failed to disable DSI panel, rc=%d\n", display->name, rc); - rc = dsi_display_vid_engine_disable(display); - if (rc) - pr_err("[%s] failed to disable video engine, rc=%d\n", - display->name, rc); + if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { + rc = dsi_display_vid_engine_disable(display); + if (rc) + pr_err("[%s]failed to disable DSI vid engine, rc=%d\n", + display->name, rc); + } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { + rc = dsi_display_cmd_engine_disable(display); + if (rc) + pr_err("[%s]failed to disable DSI cmd engine, rc=%d\n", + display->name, rc); + } else { + pr_err("[%s] Invalid configuration\n", display->name); + rc = -EINVAL; + } mutex_unlock(&display->display_lock); return rc; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index df15bb84270f..1897ce3e1bbc 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -101,10 +101,6 @@ struct dsi_display_ctrl { u32 dsi_ctrl_idx; enum dsi_power_state power_state; - bool cmd_engine_enabled; - bool video_engine_enabled; - bool ulps_enabled; - bool clamps_enabled; /* phy info */ struct msm_dsi_phy *phy; @@ -182,6 +178,7 @@ struct dsi_display { struct mipi_dsi_host host; struct dsi_connector *connector; struct dsi_bridge *bridge; + u32 cmd_engine_refcount; }; int dsi_display_dev_probe(struct platform_device *pdev); |
