diff options
| author | Lloyd Atkinson <latkinso@codeaurora.org> | 2016-07-13 17:26:45 -0400 |
|---|---|---|
| committer | Dhaval Patel <pdhaval@codeaurora.org> | 2016-08-01 12:35:44 -0700 |
| commit | deecbb11da75c0dec5b585e3aef29e741f45b333 (patch) | |
| tree | 54f437a084d1d2a162a66c123ebf5fa3a00da870 /drivers/gpu | |
| parent | 6dad51ec34d798f00fc0e6fe3c0151e2ceb2275d (diff) | |
drm/msm/dsi-staging: add dsi cmd/vid mode to display info
Need the ability to communicate which modes the DSI panel is
operating capable of operating in, command or video mode.
Change-Id: I44a5f01c7dad4af6a14590fdbf2349b675f65393
Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/display-manager/display_manager.c | 63 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/display-manager/display_manager.h | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_drm.c | 41 |
5 files changed, 90 insertions, 38 deletions
diff --git a/drivers/gpu/drm/msm/display-manager/display_manager.c b/drivers/gpu/drm/msm/display-manager/display_manager.c index 9816dc97a5a0..af891dcd0ca8 100644 --- a/drivers/gpu/drm/msm/display-manager/display_manager.c +++ b/drivers/gpu/drm/msm/display-manager/display_manager.c @@ -100,16 +100,17 @@ static int disp_manager_comp_ops_bind(struct device *dev, int rc = 0; struct drm_device *drm = dev_get_drvdata(master); struct platform_device *pdev = to_platform_device(dev); - struct msm_drm_private *priv = drm->dev_private; + struct msm_drm_private *priv; struct display_manager *disp_m; struct dsi_display *dsi_display; - int i = 0; + int i; - if (!pdev || !drm) { + if (!master || !dev || !drm->dev_private) { pr_err("Invalid params\n"); return -EINVAL; } + priv = drm->dev_private; disp_m = platform_get_drvdata(pdev); /* DSI displays */ @@ -152,13 +153,12 @@ static void disp_manager_comp_ops_unbind(struct device *dev, void *data) { int rc = 0; - struct drm_device *drm = dev_get_drvdata(master); struct platform_device *pdev = to_platform_device(dev); struct display_manager *disp_m; struct dsi_display *dsi_display; - int i = 0; + int i; - if (!pdev || !drm) { + if (!dev) { pr_err("Invalid params\n"); return; } @@ -252,6 +252,19 @@ error_free_disp_m: static int disp_manager_dev_remove(struct platform_device *pdev) { + struct display_manager *disp_m; + + if (!pdev) { + pr_err("invalid pdev argument\n"); + return -ENODEV; + } + + disp_m = platform_get_drvdata(pdev); + + (void)dm_deinit_active_displays(disp_m); + of_platform_depopulate(&pdev->dev); + devm_kfree(&pdev->dev, disp_m); + return 0; } @@ -292,7 +305,7 @@ int display_manager_get_info_by_index(struct display_manager *disp_m, struct display_info *info) { int rc = 0; - int i = 0, j = 0; + int i, j; struct dsi_display *display; struct dsi_display_info dsi_info; @@ -301,6 +314,8 @@ int display_manager_get_info_by_index(struct display_manager *disp_m, return -EINVAL; } + memset(info, 0, sizeof(*info)); + mutex_lock(&disp_m->lock); for (i = 0; i < disp_m->dsi_display_count; i++) { @@ -327,6 +342,15 @@ int display_manager_get_info_by_index(struct display_manager *disp_m, info->max_width = 1920; /* TODO: */ info->max_height = 1080; /* TODO: */ info->compression = DISPLAY_COMPRESSION_NONE; + if (dsi_info.op_mode == DSI_OP_VIDEO_MODE) { + info->intf_mode |= DISPLAY_INTF_MODE_VID; + } else if (dsi_info.op_mode == DSI_OP_CMD_MODE) { + info->intf_mode |= DISPLAY_INTF_MODE_CMD; + } else { + pr_err("unknwown dsi op_mode %d\n", dsi_info.op_mode); + rc = -EINVAL; + goto error; + } break; } @@ -340,7 +364,7 @@ int display_manager_drm_init_by_index(struct display_manager *disp_m, struct drm_encoder *encoder) { int rc = 0; - int i = 0; + int i; struct dsi_display *display; if (!disp_m || !encoder) { @@ -368,6 +392,27 @@ int display_manager_drm_init_by_index(struct display_manager *disp_m, int display_manager_drm_deinit_by_index(struct display_manager *disp_m, u32 display_index) { + int i; + struct dsi_display *display; + + if (!disp_m) { + pr_err("Invalid params\n"); + return -EINVAL; + } + + mutex_lock(&disp_m->lock); + + for (i = 0; i < disp_m->dsi_display_count; i++) { + display = dsi_display_get_display_by_index(i); + if (!display || !dsi_display_is_active(display)) + continue; + + dsi_display_drm_deinit(display); + break; + } + + mutex_unlock(&disp_m->lock); + return 0; } @@ -383,6 +428,6 @@ void display_manager_unregister(void) { platform_driver_unregister(&disp_manager_driver); dsi_display_unregister(); - dsi_ctrl_drv_register(); + dsi_ctrl_drv_unregister(); dsi_phy_drv_unregister(); } diff --git a/drivers/gpu/drm/msm/display-manager/display_manager.h b/drivers/gpu/drm/msm/display-manager/display_manager.h index 0b7462b7bb53..c1484243d946 100644 --- a/drivers/gpu/drm/msm/display-manager/display_manager.h +++ b/drivers/gpu/drm/msm/display-manager/display_manager.h @@ -43,6 +43,15 @@ enum display_compression_type { DISPLAY_COMPRESISON_MAX }; +/** + * enum display_interface_mode - interface modes supported by the display + * @DISPLAY_INTF_MODE_VID: Display supports video or "active" mode + * @DISPLAY_INTF_MODE_CMD: Display supports command mode + */ +enum display_interface_mode { + DISPLAY_INTF_MODE_VID = BIT(0), + DISPLAY_INTF_MODE_CMD = BIT(1), +}; /** * struct display_info - defines display properties @@ -58,6 +67,7 @@ enum display_compression_type { * @max_height: Max height of display. In case of hot pluggable display, * this is max height supported by controller. * @compression: Compression supported by the display. + * @intf_mode: Bitmask of interface modes supported by the display */ struct display_info { enum display_interface_type intf; @@ -73,6 +83,7 @@ struct display_info { u32 max_height; enum display_compression_type compression; + enum display_interface_mode intf_mode; }; struct display_manager { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 7be9bb0f6a70..1e90d46c1950 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -2005,6 +2005,9 @@ int dsi_display_get_info(struct dsi_display *display, info->height_mm = phy_props.panel_height_mm; strlcpy(info->display_type, display->display_type, sizeof(display->display_type)); + + info->op_mode = display->panel->mode.panel_mode; + error: 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 6d563550af7d..0631bac5cd9e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -67,6 +67,7 @@ enum dsi_display_type { * @is_edid_supported: Does panel support reading EDID information. * @width_mm: Physical width of panel in millimeters. * @height_mm: Physical height of panel in millimeters. + * @dsi_op_mode: dsi operation mode, video or cmd mode */ struct dsi_display_info { char display_type[20]; @@ -85,6 +86,9 @@ struct dsi_display_info { /* Physical properties */ u32 width_mm; u32 height_mm; + + /* Operation properties */ + enum dsi_op_mode op_mode; }; /** @@ -93,10 +97,6 @@ struct dsi_display_info { * @ctrl_of_node: pHandle to the DSI controller device. * @dsi_ctrl_idx: DSI controller instance id. * @power_state: Current power state of the DSI controller. - * @cmd_engine_enabled: Command engine status. - * @video_engine_enabled: Video engine status. - * @ulps_enabled: ULPS status for the controller. - * @clamps_enabled: Clamps status for the controller. * @phy: Handle to the DSI PHY device. * @phy_of_node: pHandle to the DSI PHY device. * @phy_enabled: PHY power status. @@ -153,6 +153,8 @@ struct dsi_display_clk_info { * @host: DRM MIPI DSI Host. * @connector: Pointer to DRM connector object. * @bridge: Pointer to DRM bridge object. + * @cmd_engine_refcount: Reference count enforcing single instance of cmd eng + * @root: Debugfs root directory */ struct dsi_display { struct platform_device *pdev; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c index 2ae523b08edd..8f5e6664621f 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c @@ -95,7 +95,7 @@ static int dsi_bridge_attach(struct drm_bridge *bridge) { struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge) { + if (!bridge) { pr_err("Invalid params\n"); return -EINVAL; } @@ -111,13 +111,11 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge) int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge) { + if (!bridge) { pr_err("Invalid params\n"); return; } - pr_debug(""); - /* By this point mode should have been validated through mode_fixup */ rc = dsi_display_set_mode(c_bridge->display, &(c_bridge->dsi_mode), 0x0); @@ -152,7 +150,7 @@ static void dsi_bridge_enable(struct drm_bridge *bridge) int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge) { + if (!bridge) { pr_err("Invalid params\n"); return; } @@ -173,20 +171,16 @@ static void dsi_bridge_disable(struct drm_bridge *bridge) int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge) { + if (!bridge) { pr_err("Invalid params\n"); - rc = -EINVAL; - goto error; + return; } rc = dsi_display_pre_disable(c_bridge->display); if (rc) { pr_err("[%d] DSI display pre disable failed, rc=%d\n", c_bridge->id, rc); - goto error; } -error: - pr_debug(""); } static void dsi_bridge_post_disable(struct drm_bridge *bridge) @@ -194,7 +188,7 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge) int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge) { + if (!bridge) { pr_err("Invalid params\n"); return; } @@ -203,18 +197,15 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge) if (rc) { pr_err("[%d] DSI display disable failed, rc=%d\n", c_bridge->id, rc); - goto error; + return; } rc = dsi_display_unprepare(c_bridge->display); if (rc) { pr_err("[%d] DSI display unprepare failed, rc=%d\n", c_bridge->id, rc); - goto error; + return; } - -error: - pr_debug("[%d] DSI bridge post disable done\n", c_bridge->id); } static void dsi_bridge_mode_set(struct drm_bridge *bridge, @@ -223,15 +214,17 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge, { struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); - if (!c_bridge || !mode || !adjusted_mode) { + if (!bridge || !mode || !adjusted_mode) { pr_err("Invalid params\n"); return; } - pr_debug(""); - memset(&(c_bridge->dsi_mode), 0x0, sizeof(struct dsi_display_mode)); convert_to_dsi_mode(adjusted_mode, &(c_bridge->dsi_mode)); + + pr_debug("note: using panel cmd/vid mode instead of user val\n"); + c_bridge->dsi_mode.panel_mode = + c_bridge->display->panel->mode.panel_mode; } static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, @@ -243,7 +236,7 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); struct dsi_display_mode dsi_mode; - if (!c_bridge || !mode || !adjusted_mode) { + if (!bridge || !mode || !adjusted_mode) { pr_err("Invalid params\n"); return false; } @@ -584,10 +577,8 @@ error: void dsi_drm_bridge_cleanup(struct dsi_bridge *bridge) { - struct drm_encoder *encoder = bridge->base.encoder; - - if (!encoder) - encoder->bridge = NULL; + if (bridge && bridge->base.encoder) + bridge->base.encoder->bridge = NULL; kfree(bridge); } |
