diff options
| author | Alan Kwong <akwong@codeaurora.org> | 2016-07-29 10:00:19 -0400 |
|---|---|---|
| committer | Alan Kwong <akwong@codeaurora.org> | 2016-08-08 16:07:27 -0400 |
| commit | 2d3d7b7c7313c7c6137d02c20a69cd8b92ca99c3 (patch) | |
| tree | f23dd121078f9df46e9fa8b1fdbda857fb575765 /drivers/gpu | |
| parent | cc2cbe997040174e69b9b852dc706a54f3090a05 (diff) | |
drm/msm/sde: enable writeback enumeration in display manager
Display manager controls the enumeration of display devices.
This patch updates enumeration to include writeback connector.
Change-Id: I8c03630ae5a7e499cc0e879448d9b0cda08ac8f4
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/display-manager/display_manager.c | 170 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/display-manager/display_manager.h | 3 |
2 files changed, 142 insertions, 31 deletions
diff --git a/drivers/gpu/drm/msm/display-manager/display_manager.c b/drivers/gpu/drm/msm/display-manager/display_manager.c index cce6ff26cddb..0b5d2f9f2ee9 100644 --- a/drivers/gpu/drm/msm/display-manager/display_manager.c +++ b/drivers/gpu/drm/msm/display-manager/display_manager.c @@ -27,6 +27,7 @@ #include "dsi_display.h" #include "dsi_drm.h" +#include "sde_wb.h" #include "display_manager.h" /** @@ -52,9 +53,14 @@ static u32 _dm_cache_active_displays(struct display_manager *disp_m) /* query dp displays */ disp_m->dp_display_count = 0; + /* query wb displays */ + disp_m->wb_display_count = sde_wb_get_num_of_displays(); + DBG("wb display count=%d", disp_m->wb_display_count); + count = disp_m->dsi_display_count + disp_m->hdmi_display_count - + disp_m->dp_display_count; + + disp_m->dp_display_count + + disp_m->wb_display_count; disp_m->displays = kcalloc(count, sizeof(void *), GFP_KERNEL); if (!disp_m->displays) { @@ -66,6 +72,9 @@ static u32 _dm_cache_active_displays(struct display_manager *disp_m) disp_m->dp_displays = 0; disp_m->dp_display_count = 0; + + disp_m->wb_displays = 0; + disp_m->wb_display_count = 0; } else { /* get final dsi display list */ disp_m->dsi_displays = disp_m->displays; @@ -82,12 +91,20 @@ static u32 _dm_cache_active_displays(struct display_manager *disp_m) disp_m->dp_displays = disp_m->hdmi_displays + disp_m->hdmi_display_count; disp_m->dp_display_count = 0; + + /* get final wb display list */ + disp_m->wb_displays = disp_m->dp_displays + + disp_m->dp_display_count; + disp_m->wb_display_count = + wb_display_get_displays(disp_m->wb_displays, + disp_m->wb_display_count); } /* set final display count */ disp_m->display_count = disp_m->dsi_display_count + disp_m->hdmi_display_count - + disp_m->dp_display_count; + + disp_m->dp_display_count + + disp_m->wb_display_count; return disp_m->display_count; } @@ -113,6 +130,10 @@ static int _dm_get_type_by_index(struct display_manager *disp_m, if (display_index < disp_m->dp_display_count) return DRM_MODE_CONNECTOR_DisplayPort; display_index -= disp_m->dp_display_count; + + if (display_index < disp_m->wb_display_count) + return DRM_MODE_CONNECTOR_VIRTUAL; + display_index -= disp_m->wb_display_count; } return DRM_MODE_CONNECTOR_Unknown; } @@ -126,25 +147,44 @@ static int _dm_init_active_displays(struct display_manager *disp_m) { void *display; int rc = 0; - int i = 0; + int dsi_idx, wb_idx; - for (i = 0; i < disp_m->dsi_display_count; i++) { - display = disp_m->dsi_displays[i]; + for (dsi_idx = 0; dsi_idx < disp_m->dsi_display_count; dsi_idx++) { + display = disp_m->dsi_displays[dsi_idx]; rc = dsi_display_dev_init(display); if (rc) { pr_err("failed to init dsi display, rc=%d\n", rc); + goto error_deinit_dsi_displays; + } + } - for (i = i - 1; i >= 0; i--) { - display = disp_m->dsi_displays[i]; - (void)dsi_display_dev_deinit(display); - } - break; + for (wb_idx = 0; wb_idx < disp_m->wb_display_count; wb_idx++) { + display = disp_m->wb_displays[wb_idx]; + + rc = sde_wb_dev_init(display); + if (rc) { + pr_err("failed to init wb display, rc=%d\n", rc); + goto error_deinit_sde_wb; } } /* TODO: INIT HDMI and DP displays here */ return rc; + +error_deinit_sde_wb: + for (wb_idx = wb_idx - 1; wb_idx >= 0; wb_idx--) { + display = disp_m->wb_displays[wb_idx]; + (void)sde_wb_dev_deinit(display); + } + +error_deinit_dsi_displays: + for (dsi_idx = dsi_idx - 1; dsi_idx >= 0; dsi_idx--) { + display = disp_m->dsi_displays[dsi_idx]; + (void)dsi_display_dev_deinit(display); + } + + return rc; } /** @@ -157,6 +197,14 @@ static void _dm_deinit_active_displays(struct display_manager *disp_m) void *display; int rc, i; + for (i = 0; i < disp_m->wb_display_count; i++) { + display = disp_m->wb_displays[i]; + + rc = sde_wb_dev_deinit(display); + if (rc) + pr_err("failed to deinit wb display, rc=%d\n", rc); + } + for (i = 0; i < disp_m->dsi_display_count; i++) { display = disp_m->dsi_displays[i]; rc = dsi_display_dev_deinit(display); @@ -175,7 +223,8 @@ static int disp_manager_comp_ops_bind(struct device *dev, struct msm_drm_private *priv; struct display_manager *disp_m; void *display; - int i, rc = -EINVAL; + int dsi_idx, wb_idx; + int rc = -EINVAL; if (master && dev) { drm = dev_get_drvdata(master); @@ -193,29 +242,46 @@ static int disp_manager_comp_ops_bind(struct device *dev, disp_m->drm_dev = drm; /* DSI displays */ - for (i = 0; i < disp_m->dsi_display_count; i++) { - display = disp_m->dsi_displays[i]; + for (dsi_idx = 0; dsi_idx < disp_m->dsi_display_count; dsi_idx++) { + display = disp_m->dsi_displays[dsi_idx]; rc = dsi_display_bind(display, drm); if (rc) { if (rc != -EPROBE_DEFER) pr_err("Failed to bind dsi display_%d, rc=%d\n", - i, rc); - - /* clean up DSI bindings */ - for (i = i - 1; i >= 0; i--) { - display = disp_m->dsi_displays[i]; - (void)dsi_display_unbind(display); - } - goto exit; + dsi_idx, rc); + goto error_unbind_dsi; + } + } + + /* WB displays */ + for (wb_idx = 0; wb_idx < disp_m->wb_display_count; wb_idx++) { + display = disp_m->wb_displays[wb_idx]; + + rc = sde_wb_bind(display, drm); + if (rc) { + pr_err("Failed to bind wb display_%d, rc=%d\n", + wb_idx, rc); + goto error_unbind_wb; } } /* TODO: BIND HDMI display here */ /* TODO: BIND DP display here */ - priv->dm = disp_m; -exit: + return rc; + +error_unbind_wb: + for (wb_idx = wb_idx - 1; wb_idx >= 0; wb_idx--) { + display = disp_m->wb_displays[wb_idx]; + (void)sde_wb_unbind(display); + } + +error_unbind_dsi: + for (dsi_idx = dsi_idx - 1; dsi_idx >= 0; dsi_idx--) { + display = disp_m->dsi_displays[dsi_idx]; + (void)dsi_display_unbind(display); + } return rc; } @@ -236,6 +302,16 @@ static void disp_manager_comp_ops_unbind(struct device *dev, disp_m = platform_get_drvdata(pdev); + /* WB displays */ + for (i = 0; i < disp_m->wb_display_count; i++) { + display = disp_m->wb_displays[i]; + + rc = sde_wb_unbind(display); + if (rc) + pr_err("failed to unbind wb display_%d, rc=%d\n", + i, rc); + } + /* DSI displays */ for (i = 0; i < disp_m->dsi_display_count; i++) { display = disp_m->dsi_displays[i]; @@ -254,6 +330,7 @@ static const struct of_device_id displays_dt_match[] = { {.compatible = "qcom,dsi-display"}, {.compatible = "qcom,hdmi-display"}, {.compatible = "qcom,dp-display"}, + {.compatible = "qcom,wb-display"}, {} }; @@ -369,7 +446,7 @@ int display_manager_get_info_by_index(struct display_manager *disp_m, void *display; int rc = 0; - if (!disp_m || !info) { + if (!disp_m || !info || (display_index >= disp_m->display_count)) { pr_err("Invalid params\n"); return -EINVAL; } @@ -378,18 +455,23 @@ int display_manager_get_info_by_index(struct display_manager *disp_m, mutex_lock(&disp_m->lock); - if (display_index < disp_m->display_count) - display = disp_m->displays[display_index]; + display = disp_m->displays[display_index]; switch (_dm_get_type_by_index(disp_m, display_index)) { case DRM_MODE_CONNECTOR_DSI: - memset(info, 0x0, sizeof(*info)); rc = dsi_display_get_info(info, display); if (rc) { pr_err("failed to get dsi info, rc=%d\n", rc); rc = -EINVAL; } break; + case DRM_MODE_CONNECTOR_VIRTUAL: + rc = sde_wb_get_info(info, display); + if (rc) { + pr_err("failed to get wb info, rc=%d\n", rc); + rc = -EINVAL; + } + break; default: pr_err("invalid index %d\n", display_index); rc = -EINVAL; @@ -410,19 +492,25 @@ int display_manager_drm_init_by_index(struct display_manager *disp_m, .mode_valid = dsi_conn_mode_valid, .get_info = dsi_display_get_info, }; + static const struct sde_connector_ops wb_ops = { + .post_init = sde_wb_connector_post_init, + .detect = sde_wb_connector_detect, + .get_modes = sde_wb_connector_get_modes, + .set_property = sde_wb_connector_set_property, + .get_info = sde_wb_get_info, + }; void *display; int rc = -EINVAL; struct drm_connector *connector; - if (!disp_m || !encoder) { + if (!disp_m || !encoder || (display_index >= disp_m->display_count)) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&disp_m->lock); - if (display_index < disp_m->display_count) - display = disp_m->displays[display_index]; + display = disp_m->displays[display_index]; switch (_dm_get_type_by_index(disp_m, display_index)) { case DRM_MODE_CONNECTOR_DSI: @@ -444,6 +532,25 @@ int display_manager_drm_init_by_index(struct display_manager *disp_m, else if (IS_ERR(connector)) rc = PTR_ERR(connector); break; + case DRM_MODE_CONNECTOR_VIRTUAL: + rc = sde_wb_drm_init(display, encoder); + if (rc) { + pr_err("writeback init failed\n"); + break; + } + + connector = sde_connector_init(disp_m->drm_dev, + encoder, + 0, + display, + &wb_ops, + DRM_CONNECTOR_POLL_HPD, + DRM_MODE_CONNECTOR_VIRTUAL); + if (!connector) + rc = -ENOMEM; + else if (IS_ERR(connector)) + rc = PTR_ERR(connector); + break; default: pr_err("invalid index %d\n", display_index); break; @@ -452,7 +559,6 @@ int display_manager_drm_init_by_index(struct display_manager *disp_m, mutex_unlock(&disp_m->lock); return rc; - } int display_manager_drm_deinit_by_index(struct display_manager *disp_m, @@ -492,11 +598,13 @@ void display_manager_register(void) dsi_phy_drv_register(); dsi_ctrl_drv_register(); dsi_display_register(); + sde_wb_register(); platform_driver_register(&disp_manager_driver); } void display_manager_unregister(void) { platform_driver_unregister(&disp_manager_driver); + sde_wb_unregister(); dsi_display_unregister(); 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 a4b6ff73642b..d220fc016a3e 100644 --- a/drivers/gpu/drm/msm/display-manager/display_manager.h +++ b/drivers/gpu/drm/msm/display-manager/display_manager.h @@ -34,6 +34,9 @@ struct display_manager { u32 dp_display_count; void **dp_displays; + u32 wb_display_count; + void **wb_displays; + /* Debug fs */ struct dentry *debugfs_root; }; |
