[Freedreno] [DPU PATCH 5/6] drm/msm: hook up DPU with upstream DSI
Jeykumar Sankaran
jsanka at codeaurora.org
Mon Apr 16 18:22:20 UTC 2018
Switch DPU from dsi-staging to upstream dsi driver. To make
the switch atomic, this change includes:
- remove dpu connector layers
- clean up dpu connector dependencies in encoder/crtc
- compile out writeback and display port drivers
- compile out dsi-staging driver (separate patch submitted to
remove the driver)
- adapt upstream device hierarchy
Signed-off-by: Jeykumar Sankaran <jsanka at codeaurora.org>
---
.../config/arm64/chromiumos-arm64.flavour.config | 4 +-
.../arm64/chromiumos-qualcomm.flavour.config | 4 +-
drivers/gpu/drm/msm/Makefile | 1 -
drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c | 1184 --------------------
drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h | 555 ---------
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 9 -
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 173 +--
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 8 +-
.../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 6 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 220 +---
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 54 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 11 +
drivers/gpu/drm/msm/dpu_dbg.c | 3 -
drivers/gpu/drm/msm/msm_drv.c | 41 +-
drivers/gpu/drm/msm/msm_drv.h | 39 -
16 files changed, 158 insertions(+), 2164 deletions(-)
delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c
delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h
diff --git a/chromeos/config/arm64/chromiumos-arm64.flavour.config b/chromeos/config/arm64/chromiumos-arm64.flavour.config
index c676a69..7b20c8b 100644
--- a/chromeos/config/arm64/chromiumos-arm64.flavour.config
+++ b/chromeos/config/arm64/chromiumos-arm64.flavour.config
@@ -117,14 +117,14 @@ CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_MSM=y
CONFIG_DRM_MSM_DPU=y
CONFIG_DRM_MSM_DSI=y
-CONFIG_DRM_MSM_DSI_STAGING=y
+# CONFIG_DRM_MSM_DSI_STAGING is not set
# CONFIG_DRM_MSM_HDCP is not set
# CONFIG_DRM_MSM_HDMI is not set
# CONFIG_DRM_MSM_HDMI_HDCP is not set
# CONFIG_DRM_MSM_MDP4 is not set
# CONFIG_DRM_MSM_MDP5 is not set
# CONFIG_DRM_MSM_REGISTER_LOGGING is not set
-CONFIG_DRM_MSM_WRITEBACK=y
+# CONFIG_DRM_MSM_WRITEBACK is not set
# CONFIG_DRM_NOUVEAU is not set
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y
# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
diff --git a/chromeos/config/arm64/chromiumos-qualcomm.flavour.config b/chromeos/config/arm64/chromiumos-qualcomm.flavour.config
index e7f45f3..aad22a7 100644
--- a/chromeos/config/arm64/chromiumos-qualcomm.flavour.config
+++ b/chromeos/config/arm64/chromiumos-qualcomm.flavour.config
@@ -30,14 +30,14 @@ CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_MSM=y
CONFIG_DRM_MSM_DPU=y
CONFIG_DRM_MSM_DSI=y
-CONFIG_DRM_MSM_DSI_STAGING=y
+# CONFIG_DRM_MSM_DSI_STAGING is not set
# CONFIG_DRM_MSM_HDCP is not set
# CONFIG_DRM_MSM_HDMI is not set
# CONFIG_DRM_MSM_HDMI_HDCP is not set
# CONFIG_DRM_MSM_MDP4 is not set
# CONFIG_DRM_MSM_MDP5 is not set
# CONFIG_DRM_MSM_REGISTER_LOGGING is not set
-CONFIG_DRM_MSM_WRITEBACK=y
+# CONFIG_DRM_MSM_WRITEBACK is not set
CONFIG_DRM_PANEL_TRULY_WQXGA=y
# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index b23a001..a8d8ad9 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -48,7 +48,6 @@ msm-y := \
disp/mdp5/mdp5_plane.o \
disp/mdp5/mdp5_smp.o \
disp/dpu1/dpu_color_processing.o \
- disp/dpu1/dpu_connector.o \
disp/dpu1/dpu_core_irq.o \
disp/dpu1/dpu_core_perf.o \
disp/dpu1/dpu_crtc.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c
deleted file mode 100644
index dc0978d..0000000
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c
+++ /dev/null
@@ -1,1184 +0,0 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
-#include "msm_drv.h"
-#include "dpu_dbg.h"
-
-#include "dpu_kms.h"
-#include "dpu_connector.h"
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-#include <linux/backlight.h>
-#include "dsi_drm.h"
-#include "dsi_display.h"
-#endif
-
-#define BL_NODE_NAME_SIZE 32
-
-#define DPU_DEBUG_CONN(c, fmt, ...) DPU_DEBUG("conn%d " fmt,\
- (c) ? (c)->base.base.id : -1, ##__VA_ARGS__)
-
-#define DPU_ERROR_CONN(c, fmt, ...) DPU_ERROR("conn%d " fmt,\
- (c) ? (c)->base.base.id : -1, ##__VA_ARGS__)
-static u32 dither_matrix[DITHER_MATRIX_SZ] = {
- 15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
-};
-
-static const struct drm_prop_enum_list e_topology_name[] = {
- {DPU_RM_TOPOLOGY_NONE, "dpu_none"},
- {DPU_RM_TOPOLOGY_SINGLEPIPE, "dpu_singlepipe"},
- {DPU_RM_TOPOLOGY_DUALPIPE, "dpu_dualpipe"},
- {DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE, "dpu_dualpipemerge"},
-};
-
-static const struct drm_prop_enum_list e_topology_control[] = {
- {DPU_RM_TOPCTL_RESERVE_LOCK, "reserve_lock"},
- {DPU_RM_TOPCTL_RESERVE_CLEAR, "reserve_clear"},
- {DPU_RM_TOPCTL_DSPP, "dspp"},
-};
-static const struct drm_prop_enum_list e_power_mode[] = {
- {DPU_MODE_DPMS_ON, "ON"},
- {DPU_MODE_DPMS_LP1, "LP1"},
- {DPU_MODE_DPMS_LP2, "LP2"},
- {DPU_MODE_DPMS_OFF, "OFF"},
-};
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-static int dpu_backlight_device_update_status(struct backlight_device *bd)
-{
- int brightness;
- struct dsi_display *display;
- struct dpu_connector *c_conn;
- int bl_lvl;
- struct drm_event event;
-
- brightness = bd->props.brightness;
-
- if ((bd->props.power != FB_BLANK_UNBLANK) ||
- (bd->props.state & BL_CORE_FBBLANK) ||
- (bd->props.state & BL_CORE_SUSPENDED))
- brightness = 0;
-
- c_conn = bl_get_data(bd);
- display = (struct dsi_display *) c_conn->display;
- if (brightness > display->panel->bl_config.bl_max_level)
- brightness = display->panel->bl_config.bl_max_level;
-
- /* map UI brightness into driver backlight level with rounding */
- bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
- display->panel->bl_config.brightness_max_level);
-
- if (!bl_lvl && brightness)
- bl_lvl = 1;
-
- if (c_conn->ops.set_backlight) {
- event.type = DRM_EVENT_SYS_BACKLIGHT;
- event.length = sizeof(u32);
- msm_mode_object_event_notify(&c_conn->base.base,
- c_conn->base.dev, &event, (u8 *)&brightness);
- c_conn->ops.set_backlight(c_conn->display, bl_lvl);
- }
-
- return 0;
-}
-
-static int dpu_backlight_device_get_brightness(struct backlight_device *bd)
-{
- return 0;
-}
-
-static const struct backlight_ops dpu_backlight_device_ops = {
- .update_status = dpu_backlight_device_update_status,
- .get_brightness = dpu_backlight_device_get_brightness,
-};
-
-static int dpu_backlight_setup(struct dpu_connector *c_conn,
- struct drm_device *dev)
-{
- struct backlight_properties props;
- struct dsi_display *display;
- struct dsi_backlight_config *bl_config;
- static int display_count;
- char bl_node_name[BL_NODE_NAME_SIZE];
-
- if (!c_conn || !dev || !dev->dev) {
- DPU_ERROR("invalid param\n");
- return -EINVAL;
- } else if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI) {
- return 0;
- }
-
- memset(&props, 0, sizeof(props));
- props.type = BACKLIGHT_RAW;
- props.power = FB_BLANK_UNBLANK;
-
- display = (struct dsi_display *) c_conn->display;
- bl_config = &display->panel->bl_config;
- props.max_brightness = bl_config->brightness_max_level;
- props.brightness = bl_config->brightness_max_level;
- snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight",
- display_count);
- c_conn->bl_device = backlight_device_register(bl_node_name, dev->dev,
- c_conn, &dpu_backlight_device_ops, &props);
- if (IS_ERR_OR_NULL(c_conn->bl_device)) {
- DPU_ERROR("Failed to register backlight: %ld\n",
- PTR_ERR(c_conn->bl_device));
- c_conn->bl_device = NULL;
- return -ENODEV;
- }
- display_count++;
-
- return 0;
-}
-#endif
-
-int dpu_connector_trigger_event(void *drm_connector,
- uint32_t event_idx, uint32_t instance_idx,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3)
-{
- struct dpu_connector *c_conn;
- unsigned long irq_flags;
- void (*cb_func)(uint32_t event_idx,
- uint32_t instance_idx, void *usr,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3);
- void *usr;
- int rc = 0;
-
- /*
- * This function may potentially be called from an ISR context, so
- * avoid excessive logging/etc.
- */
- if (!drm_connector)
- return -EINVAL;
- else if (event_idx >= DPU_CONN_EVENT_COUNT)
- return -EINVAL;
- c_conn = to_dpu_connector(drm_connector);
-
- spin_lock_irqsave(&c_conn->event_lock, irq_flags);
- cb_func = c_conn->event_table[event_idx].cb_func;
- usr = c_conn->event_table[event_idx].usr;
- spin_unlock_irqrestore(&c_conn->event_lock, irq_flags);
-
- if (cb_func)
- cb_func(event_idx, instance_idx, usr,
- data0, data1, data2, data3);
- else
- rc = -EAGAIN;
-
- return rc;
-}
-
-int dpu_connector_register_event(struct drm_connector *connector,
- uint32_t event_idx,
- void (*cb_func)(uint32_t event_idx,
- uint32_t instance_idx, void *usr,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3),
- void *usr)
-{
- struct dpu_connector *c_conn;
- unsigned long irq_flags;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return -EINVAL;
- } else if (event_idx >= DPU_CONN_EVENT_COUNT) {
- DPU_ERROR("conn%d, invalid event %d\n",
- connector->base.id, event_idx);
- return -EINVAL;
- }
- c_conn = to_dpu_connector(connector);
-
- spin_lock_irqsave(&c_conn->event_lock, irq_flags);
- c_conn->event_table[event_idx].cb_func = cb_func;
- c_conn->event_table[event_idx].usr = usr;
- spin_unlock_irqrestore(&c_conn->event_lock, irq_flags);
-
- /* optionally notify display of event registration */
- if (c_conn->ops.enable_event && c_conn->display)
- c_conn->ops.enable_event(connector, event_idx,
- cb_func != NULL, c_conn->display);
- return 0;
-}
-
-void dpu_connector_unregister_event(struct drm_connector *connector,
- uint32_t event_idx)
-{
- (void)dpu_connector_register_event(connector, event_idx, 0, 0);
-}
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-static int _dpu_connector_get_default_dither_cfg_v1(
- struct dpu_connector *c_conn, void *cfg)
-{
- struct drm_msm_dither *dither_cfg = (struct drm_msm_dither *)cfg;
- enum dsi_pixel_format dst_format = DSI_PIXEL_FORMAT_MAX;
-
- if (!c_conn || !cfg) {
- DPU_ERROR("invalid argument(s), c_conn %pK, cfg %pK\n",
- c_conn, cfg);
- return -EINVAL;
- }
-
- if (!c_conn->ops.get_dst_format) {
- DPU_DEBUG("get_dst_format is unavailable\n");
- return 0;
- }
-
- dst_format = c_conn->ops.get_dst_format(c_conn->display);
- switch (dst_format) {
- case DSI_PIXEL_FORMAT_RGB888:
- dither_cfg->c0_bitdepth = 8;
- dither_cfg->c1_bitdepth = 8;
- dither_cfg->c2_bitdepth = 8;
- dither_cfg->c3_bitdepth = 8;
- break;
- case DSI_PIXEL_FORMAT_RGB666:
- case DSI_PIXEL_FORMAT_RGB666_LOOSE:
- dither_cfg->c0_bitdepth = 6;
- dither_cfg->c1_bitdepth = 6;
- dither_cfg->c2_bitdepth = 6;
- dither_cfg->c3_bitdepth = 6;
- break;
- default:
- DPU_DEBUG("no default dither config for dst_format %d\n",
- dst_format);
- return -ENODATA;
- }
-
- memcpy(&dither_cfg->matrix, dither_matrix,
- sizeof(u32) * DITHER_MATRIX_SZ);
- dither_cfg->temporal_en = 0;
- return 0;
-}
-
-static void _dpu_connector_install_dither_property(struct drm_device *dev,
- struct dpu_kms *dpu_kms, struct dpu_connector *c_conn)
-{
- char prop_name[DRM_PROP_NAME_LEN];
- struct dpu_mdss_cfg *catalog = NULL;
- struct drm_property_blob *blob_ptr;
- void *cfg;
- int ret = 0;
- u32 version = 0, len = 0;
- bool defalut_dither_needed = false;
-
- if (!dev || !dpu_kms || !c_conn) {
- DPU_ERROR("invld args (s), dev %pK, dpu_kms %pK, c_conn %pK\n",
- dev, dpu_kms, c_conn);
- return;
- }
-
- catalog = dpu_kms->catalog;
- version = DPU_COLOR_PROCESS_MAJOR(
- catalog->pingpong[0].sblk->dither.version);
- snprintf(prop_name, ARRAY_SIZE(prop_name), "%s%d",
- "DPU_PP_DITHER_V", version);
- switch (version) {
- case 1:
- msm_property_install_blob(&c_conn->property_info, prop_name,
- DRM_MODE_PROP_BLOB,
- CONNECTOR_PROP_PP_DITHER);
- len = sizeof(struct drm_msm_dither);
- cfg = kzalloc(len, GFP_KERNEL);
- if (!cfg)
- return;
-
- ret = _dpu_connector_get_default_dither_cfg_v1(c_conn, cfg);
- if (!ret)
- defalut_dither_needed = true;
- break;
- default:
- DPU_ERROR("unsupported dither version %d\n", version);
- return;
- }
-
- if (defalut_dither_needed) {
- blob_ptr = drm_property_create_blob(dev, len, cfg);
- if (IS_ERR_OR_NULL(blob_ptr))
- goto exit;
- c_conn->blob_dither = blob_ptr;
- }
-exit:
- kfree(cfg);
-}
-#endif
-
-int dpu_connector_get_dither_cfg(struct drm_connector *conn,
- struct drm_connector_state *state, void **cfg,
- size_t *len)
-{
- struct dpu_connector *c_conn = NULL;
- struct dpu_connector_state *c_state = NULL;
- size_t dither_sz = 0;
-
- if (!conn || !state || !(*cfg))
- return -EINVAL;
-
- c_conn = to_dpu_connector(conn);
- c_state = to_dpu_connector_state(state);
-
- /* try to get user config data first */
- *cfg = msm_property_get_blob(&c_conn->property_info,
- &c_state->property_state,
- &dither_sz,
- CONNECTOR_PROP_PP_DITHER);
- /* if user config data doesn't exist, use default dither blob */
- if (*cfg == NULL && c_conn->blob_dither) {
- *cfg = &c_conn->blob_dither->data;
- dither_sz = c_conn->blob_dither->length;
- }
- *len = dither_sz;
- return 0;
-}
-
-int dpu_connector_get_info(struct drm_connector *connector,
- struct msm_display_info *info)
-{
- struct dpu_connector *c_conn;
-
- if (!connector || !info) {
- DPU_ERROR("invalid argument(s), conn %pK, info %pK\n",
- connector, info);
- return -EINVAL;
- }
-
- c_conn = to_dpu_connector(connector);
-
- if (!c_conn->display || !c_conn->ops.get_info) {
- DPU_ERROR("display info not supported for %pK\n",
- c_conn->display);
- return -EINVAL;
- }
-
- return c_conn->ops.get_info(info, c_conn->display);
-}
-
-static int _dpu_connector_update_power_locked(struct dpu_connector *c_conn)
-{
- struct drm_connector *connector;
- void *display;
- int (*set_power)(struct drm_connector *, int, void *);
- int mode, rc = 0;
-
- if (!c_conn)
- return -EINVAL;
- connector = &c_conn->base;
-
- switch (c_conn->dpms_mode) {
- case DRM_MODE_DPMS_ON:
- mode = c_conn->lp_mode;
- break;
- case DRM_MODE_DPMS_STANDBY:
- mode = DPU_MODE_DPMS_STANDBY;
- break;
- case DRM_MODE_DPMS_SUSPEND:
- mode = DPU_MODE_DPMS_SUSPEND;
- break;
- case DRM_MODE_DPMS_OFF:
- mode = DPU_MODE_DPMS_OFF;
- break;
- default:
- mode = c_conn->lp_mode;
- DPU_ERROR("conn %d dpms set to unrecognized mode %d\n",
- connector->base.id, mode);
- break;
- }
-
- DPU_EVT32(connector->base.id, c_conn->dpms_mode, c_conn->lp_mode, mode);
- DPU_DEBUG("conn %d - dpms %d, lp %d, panel %d\n", connector->base.id,
- c_conn->dpms_mode, c_conn->lp_mode, mode);
-
- if (mode != c_conn->last_panel_power_mode && c_conn->ops.set_power) {
- display = c_conn->display;
- set_power = c_conn->ops.set_power;
-
- mutex_unlock(&c_conn->lock);
- rc = set_power(connector, mode, display);
- mutex_lock(&c_conn->lock);
- }
- c_conn->last_panel_power_mode = mode;
-
- return rc;
-}
-
-int dpu_connector_pre_kickoff(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
- struct dpu_connector_state *c_state;
- int idx, rc = 0;
-
- if (!connector) {
- DPU_ERROR("invalid argument\n");
- return -EINVAL;
- }
-
- c_conn = to_dpu_connector(connector);
- c_state = to_dpu_connector_state(connector->state);
-
- if (!c_conn->display) {
- DPU_ERROR("invalid argument\n");
- return -EINVAL;
- }
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- if (c_conn->ops.set_backlight) {
- DPU_DEBUG("conn%d: Set backlight to 255\n", connector->base.id);
- c_conn->ops.set_backlight(c_conn->display, 255);
- }
-#endif
-
- while ((idx = msm_property_pop_dirty(&c_conn->property_info,
- &c_state->property_state)) >= 0) {
- switch (idx) {
- case CONNECTOR_PROP_LP:
- mutex_lock(&c_conn->lock);
- c_conn->lp_mode = dpu_connector_get_property(
- connector->state, CONNECTOR_PROP_LP);
- _dpu_connector_update_power_locked(c_conn);
- mutex_unlock(&c_conn->lock);
- break;
- default:
- /* nothing to do for most properties */
- break;
- }
- }
-
- DPU_EVT32_VERBOSE(connector->base.id);
-
- return rc;
-}
-
-void dpu_connector_clk_ctrl(struct drm_connector *connector, bool enable)
-{
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- struct dpu_connector *c_conn;
- struct dsi_display *display;
- u32 state = enable ? DSI_CLK_ON : DSI_CLK_OFF;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return;
- }
-
- c_conn = to_dpu_connector(connector);
- display = (struct dsi_display *) c_conn->display;
-
- if (display && c_conn->ops.clk_ctrl)
- c_conn->ops.clk_ctrl(display->mdp_clk_handle,
- DSI_ALL_CLKS, state);
-#endif
-}
-
-static void dpu_connector_destroy(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return;
- }
-
- c_conn = to_dpu_connector(connector);
-
- if (c_conn->ops.put_modes)
- c_conn->ops.put_modes(connector, c_conn->display);
-
- if (c_conn->blob_caps)
- drm_property_blob_put(c_conn->blob_caps);
- if (c_conn->blob_hdr)
- drm_property_blob_put(c_conn->blob_hdr);
- if (c_conn->blob_dither)
- drm_property_blob_put(c_conn->blob_dither);
- msm_property_destroy(&c_conn->property_info);
-
- if (c_conn->bl_device)
- backlight_device_unregister(c_conn->bl_device);
- drm_connector_unregister(connector);
- mutex_destroy(&c_conn->lock);
- drm_connector_cleanup(connector);
- kfree(c_conn);
-}
-
-/**
- * _dpu_connector_destroy_fb - clean up connector state's out_fb buffer
- * @c_conn: Pointer to dpu connector structure
- * @c_state: Pointer to dpu connector state structure
- */
-static void _dpu_connector_destroy_fb(struct dpu_connector *c_conn,
- struct dpu_connector_state *c_state)
-{
- if (!c_state || !c_state->out_fb) {
- DPU_ERROR("invalid state %pK\n", c_state);
- return;
- }
-
- drm_framebuffer_put(c_state->out_fb);
- c_state->out_fb = NULL;
-
- if (c_conn)
- c_state->property_values[CONNECTOR_PROP_OUT_FB].value =
- msm_property_get_default(&c_conn->property_info,
- CONNECTOR_PROP_OUT_FB);
- else
- c_state->property_values[CONNECTOR_PROP_OUT_FB].value = ~0;
-}
-
-static void dpu_connector_atomic_destroy_state(struct drm_connector *connector,
- struct drm_connector_state *state)
-{
- struct dpu_connector *c_conn = NULL;
- struct dpu_connector_state *c_state = NULL;
-
- if (!state) {
- DPU_ERROR("invalid state\n");
- return;
- }
-
- /*
- * The base DRM framework currently always passes in a NULL
- * connector pointer. This is not correct, but attempt to
- * handle that case as much as possible.
- */
- if (connector)
- c_conn = to_dpu_connector(connector);
- c_state = to_dpu_connector_state(state);
-
- if (c_state->out_fb)
- _dpu_connector_destroy_fb(c_conn, c_state);
-
- if (!c_conn) {
- kfree(c_state);
- } else {
- /* destroy value helper */
- msm_property_destroy_state(&c_conn->property_info, c_state,
- &c_state->property_state);
- }
-}
-
-static void dpu_connector_atomic_reset(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
- struct dpu_connector_state *c_state;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return;
- }
-
- c_conn = to_dpu_connector(connector);
-
- if (connector->state) {
- dpu_connector_atomic_destroy_state(connector, connector->state);
- connector->state = 0;
- }
-
- c_state = msm_property_alloc_state(&c_conn->property_info);
- if (!c_state) {
- DPU_ERROR("state alloc failed\n");
- return;
- }
-
- /* reset value helper, zero out state structure and reset properties */
- msm_property_reset_state(&c_conn->property_info, c_state,
- &c_state->property_state,
- c_state->property_values);
-
- c_state->base.connector = connector;
- connector->state = &c_state->base;
-}
-
-static struct drm_connector_state *
-dpu_connector_atomic_duplicate_state(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
- struct dpu_connector_state *c_state, *c_oldstate;
-
- if (!connector || !connector->state) {
- DPU_ERROR("invalid connector %pK\n", connector);
- return NULL;
- }
-
- c_conn = to_dpu_connector(connector);
- c_oldstate = to_dpu_connector_state(connector->state);
- c_state = msm_property_alloc_state(&c_conn->property_info);
- if (!c_state) {
- DPU_ERROR("state alloc failed\n");
- return NULL;
- }
-
- /* duplicate value helper */
- msm_property_duplicate_state(&c_conn->property_info,
- c_oldstate, c_state,
- &c_state->property_state, c_state->property_values);
-
- /* additional handling for drm framebuffer objects */
- if (c_state->out_fb)
- drm_framebuffer_get(c_state->out_fb);
-
- return &c_state->base;
-}
-
-static int _dpu_connector_update_bl_scale(struct dpu_connector *c_conn,
- int idx,
- uint64_t value)
-{
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- struct dsi_display *dsi_display = c_conn->display;
- struct dsi_backlight_config *bl_config;
- int rc = 0;
-
- if (!dsi_display || !dsi_display->panel) {
- pr_err("Invalid params(s) dsi_display %pK, panel %pK\n",
- dsi_display,
- ((dsi_display) ? dsi_display->panel : NULL));
- return -EINVAL;
- }
-
- bl_config = &dsi_display->panel->bl_config;
- if (idx == CONNECTOR_PROP_BL_SCALE) {
- bl_config->bl_scale = value;
- if (value > MAX_BL_SCALE_LEVEL)
- bl_config->bl_scale = MAX_BL_SCALE_LEVEL;
- DPU_DEBUG("set to panel: bl_scale = %u, bl_level = %u\n",
- bl_config->bl_scale, bl_config->bl_level);
- rc = c_conn->ops.set_backlight(dsi_display,
- bl_config->bl_level);
- } else if (idx == CONNECTOR_PROP_AD_BL_SCALE) {
- bl_config->bl_scale_ad = value;
- if (value > MAX_AD_BL_SCALE_LEVEL)
- bl_config->bl_scale_ad = MAX_AD_BL_SCALE_LEVEL;
- DPU_DEBUG("set to panel: bl_scale_ad = %u, bl_level = %u\n",
- bl_config->bl_scale_ad, bl_config->bl_level);
- rc = c_conn->ops.set_backlight(dsi_display,
- bl_config->bl_level);
- }
- return rc;
-#else
- return 0;
-#endif
-}
-
-static int dpu_connector_atomic_set_property(struct drm_connector *connector,
- struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t val)
-{
- struct dpu_connector *c_conn;
- struct dpu_connector_state *c_state;
- int idx, rc;
-
- if (!connector || !state || !property) {
- DPU_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
- connector, state, property);
- return -EINVAL;
- }
-
- c_conn = to_dpu_connector(connector);
- c_state = to_dpu_connector_state(state);
-
- /* generic property handling */
- rc = msm_property_atomic_set(&c_conn->property_info,
- &c_state->property_state, property, val);
- if (rc)
- goto end;
-
- /* connector-specific property handling */
- idx = msm_property_index(&c_conn->property_info, property);
- switch (idx) {
- case CONNECTOR_PROP_OUT_FB:
- /* clear old fb, if present */
- if (c_state->out_fb)
- _dpu_connector_destroy_fb(c_conn, c_state);
-
- /* convert fb val to drm framebuffer and prepare it */
- c_state->out_fb =
- drm_framebuffer_lookup(connector->dev, NULL, val);
- if (!c_state->out_fb && val) {
- DPU_ERROR("failed to look up fb %lld\n", val);
- rc = -EFAULT;
- } else if (!c_state->out_fb && !val) {
- DPU_DEBUG("cleared fb_id\n");
- rc = 0;
- }
- break;
- case CONNECTOR_PROP_BL_SCALE:
- case CONNECTOR_PROP_AD_BL_SCALE:
- rc = _dpu_connector_update_bl_scale(c_conn, idx, val);
- break;
- default:
- break;
- }
-
- /* check for custom property handling */
- if (!rc && c_conn->ops.set_property) {
- rc = c_conn->ops.set_property(connector,
- state,
- idx,
- val,
- c_conn->display);
-
- /* potentially clean up out_fb if rc != 0 */
- if ((idx == CONNECTOR_PROP_OUT_FB) && rc)
- _dpu_connector_destroy_fb(c_conn, c_state);
- }
-end:
- return rc;
-}
-
-static int dpu_connector_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t val)
-{
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return -EINVAL;
- }
-
- return dpu_connector_atomic_set_property(connector,
- connector->state, property, val);
-}
-
-static int dpu_connector_atomic_get_property(struct drm_connector *connector,
- const struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t *val)
-{
- struct dpu_connector *c_conn;
- struct dpu_connector_state *c_state;
- int idx, rc = -EINVAL;
-
- if (!connector || !state) {
- DPU_ERROR("invalid argument(s), conn %pK, state %pK\n",
- connector, state);
- return -EINVAL;
- }
-
- c_conn = to_dpu_connector(connector);
- c_state = to_dpu_connector_state(state);
-
- idx = msm_property_index(&c_conn->property_info, property);
- /* get cached property value */
- rc = msm_property_atomic_get(&c_conn->property_info,
- &c_state->property_state, property, val);
-
- /* allow for custom override */
- if (c_conn->ops.get_property)
- rc = c_conn->ops.get_property(connector,
- (struct drm_connector_state *)state,
- idx,
- val,
- c_conn->display);
- return rc;
-}
-
-static enum drm_connector_status
-dpu_connector_detect(struct drm_connector *connector, bool force)
-{
- enum drm_connector_status status = connector_status_unknown;
- struct dpu_connector *c_conn;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return status;
- }
-
- c_conn = to_dpu_connector(connector);
-
- if (c_conn->ops.detect)
- status = c_conn->ops.detect(connector,
- force,
- c_conn->display);
-
- return status;
-}
-
-int dpu_connector_get_dpms(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
- int rc;
-
- if (!connector) {
- DPU_DEBUG("invalid connector\n");
- return DRM_MODE_DPMS_OFF;
- }
-
- c_conn = to_dpu_connector(connector);
-
- mutex_lock(&c_conn->lock);
- rc = c_conn->dpms_mode;
- mutex_unlock(&c_conn->lock);
-
- return rc;
-}
-
-int dpu_connector_set_property_for_commit(struct drm_connector *connector,
- struct drm_atomic_state *atomic_state,
- uint32_t property_idx, uint64_t value)
-{
- struct drm_connector_state *state;
- struct drm_property *property;
- struct dpu_connector *c_conn;
-
- if (!connector || !atomic_state) {
- DPU_ERROR("invalid argument(s), conn %d, state %d\n",
- connector != NULL, atomic_state != NULL);
- return -EINVAL;
- }
-
- c_conn = to_dpu_connector(connector);
- property = msm_property_index_to_drm_property(
- &c_conn->property_info, property_idx);
- if (!property) {
- DPU_ERROR("invalid property index %d\n", property_idx);
- return -EINVAL;
- }
-
- state = drm_atomic_get_connector_state(atomic_state, connector);
- if (IS_ERR_OR_NULL(state)) {
- DPU_ERROR("failed to get conn %d state\n",
- connector->base.id);
- return -EINVAL;
- }
-
- return dpu_connector_atomic_set_property(
- connector, state, property, value);
-}
-
-#ifdef CONFIG_DEBUG_FS
-/**
- * dpu_connector_init_debugfs - initialize connector debugfs
- * @connector: Pointer to drm connector
- */
-static int dpu_connector_init_debugfs(struct drm_connector *connector)
-{
- struct dpu_connector *dpu_connector;
-
- if (!connector || !connector->debugfs_entry) {
- DPU_ERROR("invalid connector\n");
- return -EINVAL;
- }
-
- dpu_connector = to_dpu_connector(connector);
-
- if (!debugfs_create_bool("fb_kmap", 0600, connector->debugfs_entry,
- &dpu_connector->fb_kmap)) {
- DPU_ERROR("failed to create connector fb_kmap\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-#else
-static int dpu_connector_init_debugfs(struct drm_connector *connector)
-{
- return 0;
-}
-#endif
-
-static int dpu_connector_late_register(struct drm_connector *connector)
-{
- return dpu_connector_init_debugfs(connector);
-}
-
-static void dpu_connector_early_unregister(struct drm_connector *connector)
-{
- /* debugfs under connector->debugfs are deleted by drm_debugfs */
-}
-
-static const struct drm_connector_funcs dpu_connector_ops = {
- .reset = dpu_connector_atomic_reset,
- .detect = dpu_connector_detect,
- .destroy = dpu_connector_destroy,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .atomic_duplicate_state = dpu_connector_atomic_duplicate_state,
- .atomic_destroy_state = dpu_connector_atomic_destroy_state,
- .atomic_set_property = dpu_connector_atomic_set_property,
- .atomic_get_property = dpu_connector_atomic_get_property,
- .set_property = dpu_connector_set_property,
- .late_register = dpu_connector_late_register,
- .early_unregister = dpu_connector_early_unregister,
-};
-
-static int dpu_connector_get_modes(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return 0;
- }
-
- c_conn = to_dpu_connector(connector);
- if (!c_conn->ops.get_modes) {
- DPU_DEBUG("missing get_modes callback\n");
- return 0;
- }
-
- return c_conn->ops.get_modes(connector, c_conn->display);
-}
-
-static enum drm_mode_status
-dpu_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- struct dpu_connector *c_conn;
-
- if (!connector || !mode) {
- DPU_ERROR("invalid argument(s), conn %pK, mode %pK\n",
- connector, mode);
- return MODE_ERROR;
- }
-
- c_conn = to_dpu_connector(connector);
-
- if (c_conn->ops.mode_valid)
- return c_conn->ops.mode_valid(connector, mode, c_conn->display);
-
- /* assume all modes okay by default */
- return MODE_OK;
-}
-
-static struct drm_encoder *
-dpu_connector_best_encoder(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn = to_dpu_connector(connector);
-
- if (!connector) {
- DPU_ERROR("invalid connector\n");
- return NULL;
- }
-
- /*
- * This is true for now, revisit this code when multiple encoders are
- * supported.
- */
- return c_conn->encoder;
-}
-
-static const struct drm_connector_helper_funcs dpu_connector_helper_ops = {
- .get_modes = dpu_connector_get_modes,
- .mode_valid = dpu_connector_mode_valid,
- .best_encoder = dpu_connector_best_encoder,
-};
-
-struct drm_connector *dpu_connector_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- struct drm_panel *panel,
- void *display,
- const struct dpu_connector_ops *ops,
- int connector_poll,
- int connector_type)
-{
- struct msm_drm_private *priv;
- struct dpu_kms *dpu_kms;
- struct dpu_kms_info *info;
- struct dpu_connector *c_conn = NULL;
- struct msm_display_info display_info;
- int rc;
-
- if (!dev || !dev->dev_private || !encoder) {
- DPU_ERROR("invalid argument(s), dev %pK, enc %pK\n",
- dev, encoder);
- return ERR_PTR(-EINVAL);
- }
-
- priv = dev->dev_private;
- if (!priv->kms) {
- DPU_ERROR("invalid kms reference\n");
- return ERR_PTR(-EINVAL);
- }
-
- c_conn = kzalloc(sizeof(*c_conn), GFP_KERNEL);
- if (!c_conn) {
- DPU_ERROR("failed to alloc dpu connector\n");
- return ERR_PTR(-ENOMEM);
- }
-
- memset(&display_info, 0, sizeof(display_info));
-
- rc = drm_connector_init(dev,
- &c_conn->base,
- &dpu_connector_ops,
- connector_type);
- if (rc)
- goto error_free_conn;
-
- spin_lock_init(&c_conn->event_lock);
-
- c_conn->connector_type = connector_type;
- c_conn->encoder = encoder;
- c_conn->panel = panel;
- c_conn->display = display;
-
- c_conn->dpms_mode = DRM_MODE_DPMS_ON;
- c_conn->lp_mode = 0;
- c_conn->last_panel_power_mode = DPU_MODE_DPMS_ON;
-
- dpu_kms = to_dpu_kms(priv->kms);
-
- if (ops)
- c_conn->ops = *ops;
-
- c_conn->base.helper_private = &dpu_connector_helper_ops;
- c_conn->base.polled = connector_poll;
- c_conn->base.interlace_allowed = 0;
- c_conn->base.doublescan_allowed = 0;
-
- snprintf(c_conn->name,
- DPU_CONNECTOR_NAME_SIZE,
- "conn%u",
- c_conn->base.base.id);
-
- mutex_init(&c_conn->lock);
-
- rc = drm_mode_connector_attach_encoder(&c_conn->base, encoder);
- if (rc) {
- DPU_ERROR("failed to attach encoder to connector, %d\n", rc);
- goto error_cleanup_conn;
- }
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- rc = dpu_backlight_setup(c_conn, dev);
- if (rc) {
- DPU_ERROR("failed to setup backlight, rc=%d\n", rc);
- goto error_cleanup_conn;
- }
-#endif
-
- /* create properties */
- msm_property_init(&c_conn->property_info, &c_conn->base.base, dev,
- priv->conn_property, c_conn->property_data,
- CONNECTOR_PROP_COUNT, CONNECTOR_PROP_BLOBCOUNT,
- sizeof(struct dpu_connector_state));
-
- if (c_conn->ops.post_init) {
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
- DPU_ERROR("failed to allocate info buffer\n");
- rc = -ENOMEM;
- goto error_cleanup_conn;
- }
-
- dpu_kms_info_reset(info);
- rc = c_conn->ops.post_init(&c_conn->base, info, display);
- if (rc) {
- DPU_ERROR("post-init failed, %d\n", rc);
- kfree(info);
- goto error_cleanup_conn;
- }
-
- msm_property_install_blob(&c_conn->property_info,
- "capabilities",
- DRM_MODE_PROP_IMMUTABLE,
- CONNECTOR_PROP_DPU_INFO);
-
- msm_property_set_blob(&c_conn->property_info,
- &c_conn->blob_caps,
- DPU_KMS_INFO_DATA(info),
- DPU_KMS_INFO_DATALEN(info),
- CONNECTOR_PROP_DPU_INFO);
- kfree(info);
- }
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- if (connector_type == DRM_MODE_CONNECTOR_DSI) {
- struct dsi_display *dsi_display;
-
- dsi_display = (struct dsi_display *)(display);
- if (dsi_display && dsi_display->panel &&
- dsi_display->panel->hdr_props.hdr_enabled == true) {
- msm_property_install_blob(&c_conn->property_info,
- "hdr_properties",
- DRM_MODE_PROP_IMMUTABLE,
- CONNECTOR_PROP_HDR_INFO);
-
- msm_property_set_blob(&c_conn->property_info,
- &c_conn->blob_hdr,
- &dsi_display->panel->hdr_props,
- sizeof(dsi_display->panel->hdr_props),
- CONNECTOR_PROP_HDR_INFO);
- }
- }
-
- /* install PP_DITHER properties */
- _dpu_connector_install_dither_property(dev, dpu_kms, c_conn);
-
- msm_property_install_range(&c_conn->property_info, "bl_scale",
- 0x0, 0, MAX_BL_SCALE_LEVEL, MAX_BL_SCALE_LEVEL,
- CONNECTOR_PROP_BL_SCALE);
-
- msm_property_install_range(&c_conn->property_info, "ad_bl_scale",
- 0x0, 0, MAX_AD_BL_SCALE_LEVEL, MAX_AD_BL_SCALE_LEVEL,
- CONNECTOR_PROP_AD_BL_SCALE);
-#endif
-
- /* enum/bitmask properties */
- msm_property_install_enum(&c_conn->property_info, "topology_name",
- DRM_MODE_PROP_IMMUTABLE, 0, e_topology_name,
- ARRAY_SIZE(e_topology_name),
- CONNECTOR_PROP_TOPOLOGY_NAME);
- msm_property_install_enum(&c_conn->property_info, "topology_control",
- 0, 1, e_topology_control,
- ARRAY_SIZE(e_topology_control),
- CONNECTOR_PROP_TOPOLOGY_CONTROL);
- msm_property_install_enum(&c_conn->property_info, "LP",
- 0, 0, e_power_mode,
- ARRAY_SIZE(e_power_mode),
- CONNECTOR_PROP_LP);
-
- rc = msm_property_install_get_status(&c_conn->property_info);
- if (rc) {
- DPU_ERROR("failed to create one or more properties\n");
- goto error_destroy_property;
- }
-
- DPU_DEBUG("connector %d attach encoder %d\n",
- c_conn->base.base.id, encoder->base.id);
-
- priv->connectors[priv->num_connectors++] = &c_conn->base;
-
- return &c_conn->base;
-
-error_destroy_property:
- if (c_conn->blob_caps)
- drm_property_blob_put(c_conn->blob_caps);
- if (c_conn->blob_hdr)
- drm_property_blob_put(c_conn->blob_hdr);
- if (c_conn->blob_dither)
- drm_property_blob_put(c_conn->blob_dither);
-
- msm_property_destroy(&c_conn->property_info);
-error_cleanup_conn:
- mutex_destroy(&c_conn->lock);
- drm_connector_cleanup(&c_conn->base);
-error_free_conn:
- kfree(c_conn);
-
- return ERR_PTR(rc);
-}
-
-int dpu_connector_register_custom_event(struct dpu_kms *kms,
- struct drm_connector *conn_drm, u32 event, bool val)
-{
- int ret = -EINVAL;
-
- switch (event) {
- case DRM_EVENT_SYS_BACKLIGHT:
- ret = 0;
- break;
- default:
- break;
- }
- return ret;
-}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h
deleted file mode 100644
index ed516fb..0000000
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h
+++ /dev/null
@@ -1,555 +0,0 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _DPU_CONNECTOR_H_
-#define _DPU_CONNECTOR_H_
-
-#include <uapi/drm/msm_drm_pp.h>
-#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_panel.h>
-
-#include "msm_drv.h"
-#include "msm_prop.h"
-#include "dpu_kms.h"
-
-#define DPU_CONNECTOR_NAME_SIZE 16
-
-struct dpu_connector;
-struct dpu_connector_state;
-
-/**
- * struct dpu_connector_ops - callback functions for generic dpu connector
- * Individual callbacks documented below.
- */
-struct dpu_connector_ops {
- /**
- * post_init - perform additional initialization steps
- * @connector: Pointer to drm connector structure
- * @info: Pointer to dpu connector info structure
- * @display: Pointer to private display handle
- * Returns: Zero on success
- */
- int (*post_init)(struct drm_connector *connector,
- void *info,
- void *display);
-
- /**
- * detect - determine if connector is connected
- * @connector: Pointer to drm connector structure
- * @force: Force detect setting from drm framework
- * @display: Pointer to private display handle
- * Returns: Connector 'is connected' status
- */
- enum drm_connector_status (*detect)(struct drm_connector *connector,
- bool force,
- void *display);
-
- /**
- * get_modes - add drm modes via drm_mode_probed_add()
- * @connector: Pointer to drm connector structure
- * @display: Pointer to private display handle
- * Returns: Number of modes added
- */
- int (*get_modes)(struct drm_connector *connector,
- void *display);
-
- /**
- * put_modes - free up drm modes of the connector
- * @connector: Pointer to drm connector structure
- * @display: Pointer to private display handle
- */
- void (*put_modes)(struct drm_connector *connector,
- void *display);
-
- /**
- * update_pps - update pps command for the display panel
- * @pps_cmd: Pointer to pps command
- * @display: Pointer to private display handle
- * Returns: Zero on success
- */
- int (*update_pps)(char *pps_cmd, void *display);
-
- /**
- * mode_valid - determine if specified mode is valid
- * @connector: Pointer to drm connector structure
- * @mode: Pointer to drm mode structure
- * @display: Pointer to private display handle
- * Returns: Validity status for specified mode
- */
- enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
- struct drm_display_mode *mode,
- void *display);
-
- /**
- * set_property - set property value
- * @connector: Pointer to drm connector structure
- * @state: Pointer to drm connector state structure
- * @property_index: DRM property index
- * @value: Incoming property value
- * @display: Pointer to private display structure
- * Returns: Zero on success
- */
- int (*set_property)(struct drm_connector *connector,
- struct drm_connector_state *state,
- int property_index,
- uint64_t value,
- void *display);
-
- /**
- * get_property - get property value
- * @connector: Pointer to drm connector structure
- * @state: Pointer to drm connector state structure
- * @property_index: DRM property index
- * @value: Pointer to variable for accepting property value
- * @display: Pointer to private display structure
- * Returns: Zero on success
- */
- int (*get_property)(struct drm_connector *connector,
- struct drm_connector_state *state,
- int property_index,
- uint64_t *value,
- void *display);
-
- /**
- * get_info - get display information
- * @info: Pointer to msm display info structure
- * @display: Pointer to private display structure
- * Returns: Zero on success
- */
- int (*get_info)(struct msm_display_info *info, void *display);
-
- /**
- * get_mode_info - retrieve mode information
- * @drm_mode: Display mode set for the display
- * @mode_info: Out parameter. information of the display mode
- * @max_mixer_width: max width supported by HW layer mixer
- * Returns: Zero on success
- */
- int (*get_mode_info)(const struct drm_display_mode *drm_mode,
- struct msm_mode_info *mode_info,
- u32 max_mixer_width);
-
- /**
- * enable_event - notify display of event registration/unregistration
- * @connector: Pointer to drm connector structure
- * @event_idx: DPU connector event index
- * @enable: Whether the event is being enabled/disabled
- * @display: Pointer to private display structure
- */
- void (*enable_event)(struct drm_connector *connector,
- uint32_t event_idx, bool enable, void *display);
-
- int (*set_backlight)(void *display, u32 bl_lvl);
-
- /**
- * soft_reset - perform a soft reset on the connector
- * @display: Pointer to private display structure
- * Return: Zero on success, -ERROR otherwise
- */
- int (*soft_reset)(void *display);
-
- /**
- * pre_kickoff - trigger display to program kickoff-time features
- * @connector: Pointer to drm connector structure
- * @display: Pointer to private display structure
- * Returns: Zero on success
- */
- int (*pre_kickoff)(struct drm_connector *connector,
- void *display);
-
- /**
- * clk_ctrl - perform clk enable/disable on the connector
- * @handle: Pointer to clk handle
- * @type: Type of clks
- * @enable: State of clks
- */
- int (*clk_ctrl)(void *handle, u32 type, u32 state);
-
- /**
- * set_power - update dpms setting
- * @connector: Pointer to drm connector structure
- * @power_mode: One of the following,
- * DPU_MODE_DPMS_ON
- * DPU_MODE_DPMS_LP1
- * DPU_MODE_DPMS_LP2
- * DPU_MODE_DPMS_OFF
- * @display: Pointer to private display structure
- * Returns: Zero on success
- */
- int (*set_power)(struct drm_connector *connector,
- int power_mode, void *display);
-
- /**
- * get_dst_format - get dst_format from display
- * @display: Pointer to private display handle
- * Returns: dst_format of display
- */
- enum dsi_pixel_format (*get_dst_format)(void *display);
-
- /**
- * post_kickoff - display to program post kickoff-time features
- * @connector: Pointer to drm connector structure
- * Returns: Zero on success
- */
- int (*post_kickoff)(struct drm_connector *connector);
-
- /**
- * send_hpd_event - send HPD uevent notification to userspace
- * @display: Pointer to private display structure
- */
- void (*send_hpd_event)(void *display);
-};
-
-/**
- * enum dpu_connector_events - list of recognized connector events
- */
-enum dpu_connector_events {
- DPU_CONN_EVENT_VID_DONE, /* video mode frame done */
- DPU_CONN_EVENT_CMD_DONE, /* command mode frame done */
- DPU_CONN_EVENT_COUNT,
-};
-
-/**
- * struct dpu_connector_evt - local event registration entry structure
- * @cb_func: Pointer to desired callback function
- * @usr: User pointer to pass to callback on event trigger
- */
-struct dpu_connector_evt {
- void (*cb_func)(uint32_t event_idx,
- uint32_t instance_idx, void *usr,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3);
- void *usr;
-};
-
-/**
- * struct dpu_connector - local dpu connector structure
- * @base: Base drm connector structure
- * @connector_type: Set to one of DRM_MODE_CONNECTOR_ types
- * @encoder: Pointer to preferred drm encoder
- * @panel: Pointer to drm panel, if present
- * @display: Pointer to private display data structure
- * @mmu_secure: MMU id for secure buffers
- * @mmu_unsecure: MMU id for unsecure buffers
- * @name: ASCII name of connector
- * @lock: Mutex lock object for this structure
- * @ops: Local callback function pointer table
- * @dpms_mode: DPMS property setting from user space
- * @lp_mode: LP property setting from user space
- * @last_panel_power_mode: Last consolidated dpms/lp mode setting
- * @property_info: Private structure for generic property handling
- * @property_data: Array of private data for generic property handling
- * @blob_caps: Pointer to blob structure for 'capabilities' property
- * @blob_hdr: Pointer to blob structure for 'hdr_properties' property
- * @blob_dither: Pointer to blob structure for default dither config
- * @fb_kmap: true if kernel mapping of framebuffer is requested
- * @event_table: Array of registered events
- * @event_lock: Lock object for event_table
- * @bl_device: backlight device node
- */
-struct dpu_connector {
- struct drm_connector base;
-
- int connector_type;
-
- struct drm_encoder *encoder;
- struct drm_panel *panel;
- void *display;
-
- struct msm_gem_address_space *aspace[DPU_IOMMU_DOMAIN_MAX];
-
- char name[DPU_CONNECTOR_NAME_SIZE];
-
- struct mutex lock;
- struct dpu_connector_ops ops;
- int dpms_mode;
- int lp_mode;
- int last_panel_power_mode;
-
- struct msm_property_info property_info;
- struct msm_property_data property_data[CONNECTOR_PROP_COUNT];
- struct drm_property_blob *blob_caps;
- struct drm_property_blob *blob_hdr;
- struct drm_property_blob *blob_dither;
-
- bool fb_kmap;
- struct dpu_connector_evt event_table[DPU_CONN_EVENT_COUNT];
- spinlock_t event_lock;
-
- struct backlight_device *bl_device;
-};
-
-/**
- * to_dpu_connector - convert drm_connector pointer to dpu connector pointer
- * @X: Pointer to drm_connector structure
- * Returns: Pointer to dpu_connector structure
- */
-#define to_dpu_connector(x) container_of((x), struct dpu_connector, base)
-
-/**
- * dpu_connector_get_display - get dpu connector's private display pointer
- * @C: Pointer to drm connector structure
- * Returns: Pointer to associated private display structure
- */
-#define dpu_connector_get_display(C) \
- ((C) ? to_dpu_connector((C))->display : 0)
-
-/**
- * dpu_connector_get_panel - get dpu connector's private panel pointer
- * @C: Pointer to drm connector structure
- * Returns: Pointer to associated private display structure
- */
-#define dpu_connector_get_panel(C) \
- ((C) ? to_dpu_connector((C))->panel : NULL)
-
-/**
- * dpu_connector_get_encoder - get dpu connector's private encoder pointer
- * @C: Pointer to drm connector structure
- * Returns: Pointer to associated private encoder structure
- */
-#define dpu_connector_get_encoder(C) \
- ((C) ? to_dpu_connector((C))->encoder : 0)
-
-/**
- * dpu_connector_get_propinfo - get dpu connector's property info pointer
- * @C: Pointer to drm connector structure
- * Returns: Pointer to associated private property info structure
- */
-#define dpu_connector_get_propinfo(C) \
- ((C) ? &to_dpu_connector((C))->property_info : 0)
-
-/**
- * struct dpu_connector_state - private connector status structure
- * @base: Base drm connector structure
- * @out_fb: Pointer to output frame buffer, if applicable
- * @property_state: Local storage for msm_prop properties
- * @property_values: Local cache of current connector property values
- * @property_blobs: blob properties
- */
-struct dpu_connector_state {
- struct drm_connector_state base;
- struct drm_framebuffer *out_fb;
- struct msm_property_state property_state;
- struct msm_property_value property_values[CONNECTOR_PROP_COUNT];
-
- struct drm_property_blob *property_blobs[CONNECTOR_PROP_BLOBCOUNT];
-};
-
-/**
- * to_dpu_connector_state - convert drm_connector_state pointer to
- * dpu connector state pointer
- * @X: Pointer to drm_connector_state structure
- * Returns: Pointer to dpu_connector_state structure
- */
-#define to_dpu_connector_state(x) \
- container_of((x), struct dpu_connector_state, base)
-
-/**
- * dpu_connector_get_property - query integer value of connector property
- * @S: Pointer to drm connector state
- * @X: Property index, from enum msm_mdp_connector_property
- * Returns: Integer value of requested property
- */
-#define dpu_connector_get_property(S, X) \
- ((S) && ((X) < CONNECTOR_PROP_COUNT) ? \
- (to_dpu_connector_state((S))->property_values[(X)].value) : 0)
-
-/**
- * dpu_connector_get_property_state - retrieve property state cache
- * @S: Pointer to drm connector state
- * Returns: Pointer to local property state structure
- */
-#define dpu_connector_get_property_state(S) \
- ((S) ? (&to_dpu_connector_state((S))->property_state) : NULL)
-
-/**
- * dpu_connector_get_out_fb - query out_fb value from dpu connector state
- * @S: Pointer to drm connector state
- * Returns: Output fb associated with specified connector state
- */
-#define dpu_connector_get_out_fb(S) \
- ((S) ? to_dpu_connector_state((S))->out_fb : 0)
-
-/**
- * dpu_connector_get_topology_name - helper accessor to retrieve topology_name
- * @connector: pointer to drm connector
- * Returns: value of the CONNECTOR_PROP_TOPOLOGY_NAME property or 0
- */
-static inline uint64_t dpu_connector_get_topology_name(
- struct drm_connector *connector)
-{
- if (!connector || !connector->state)
- return 0;
- return dpu_connector_get_property(connector->state,
- CONNECTOR_PROP_TOPOLOGY_NAME);
-}
-
-/**
- * dpu_connector_get_lp - helper accessor to retrieve LP state
- * @connector: pointer to drm connector
- * Returns: value of the CONNECTOR_PROP_LP property or 0
- */
-static inline uint64_t dpu_connector_get_lp(
- struct drm_connector *connector)
-{
- if (!connector || !connector->state)
- return 0;
- return dpu_connector_get_property(connector->state,
- CONNECTOR_PROP_LP);
-}
-
-/**
- * dpu_connector_set_property_for_commit - add property set to atomic state
- * Add a connector state property update for the specified property index
- * to the atomic state in preparation for a drm_atomic_commit.
- * @connector: Pointer to drm connector
- * @atomic_state: Pointer to DRM atomic state structure for commit
- * @property_idx: Connector property index
- * @value: Updated property value
- * Returns: Zero on success
- */
-int dpu_connector_set_property_for_commit(struct drm_connector *connector,
- struct drm_atomic_state *atomic_state,
- uint32_t property_idx, uint64_t value);
-
-/**
- * dpu_connector_init - create drm connector object for a given display
- * @dev: Pointer to drm device struct
- * @encoder: Pointer to associated encoder
- * @panel: Pointer to associated panel, can be NULL
- * @display: Pointer to associated display object
- * @ops: Pointer to callback operations function table
- * @connector_poll: Set to appropriate DRM_CONNECTOR_POLL_ setting
- * @connector_type: Set to appropriate DRM_MODE_CONNECTOR_ type
- * Returns: Pointer to newly created drm connector struct
- */
-struct drm_connector *dpu_connector_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- struct drm_panel *panel,
- void *display,
- const struct dpu_connector_ops *ops,
- int connector_poll,
- int connector_type);
-
-/**
- * dpu_connector_get_info - query display specific information
- * @connector: Pointer to drm connector object
- * @info: Pointer to msm display information structure
- * Returns: Zero on success
- */
-int dpu_connector_get_info(struct drm_connector *connector,
- struct msm_display_info *info);
-
-/**
- * dpu_connector_clk_ctrl - enables/disables the connector clks
- * @connector: Pointer to drm connector object
- * @enable: true/false to enable/disable
- */
-void dpu_connector_clk_ctrl(struct drm_connector *connector, bool enable);
-
-/**
- * dpu_connector_get_dpms - query dpms setting
- * @connector: Pointer to drm connector structure
- * Returns: Current DPMS setting for connector
- */
-int dpu_connector_get_dpms(struct drm_connector *connector);
-
-/**
- * dpu_connector_trigger_event - indicate that an event has occurred
- * Any callbacks that have been registered against this event will
- * be called from the same thread context.
- * @connector: Pointer to drm connector structure
- * @event_idx: Index of event to trigger
- * @instance_idx: Event-specific "instance index" to pass to callback
- * @data0: Event-specific "data" to pass to callback
- * @data1: Event-specific "data" to pass to callback
- * @data2: Event-specific "data" to pass to callback
- * @data3: Event-specific "data" to pass to callback
- * Returns: Zero on success
- */
-int dpu_connector_trigger_event(void *drm_connector,
- uint32_t event_idx, uint32_t instance_idx,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3);
-
-/**
- * dpu_connector_register_event - register a callback function for an event
- * @connector: Pointer to drm connector structure
- * @event_idx: Index of event to register
- * @cb_func: Pointer to desired callback function
- * @usr: User pointer to pass to callback on event trigger
- * Returns: Zero on success
- */
-int dpu_connector_register_event(struct drm_connector *connector,
- uint32_t event_idx,
- void (*cb_func)(uint32_t event_idx,
- uint32_t instance_idx, void *usr,
- uint32_t data0, uint32_t data1,
- uint32_t data2, uint32_t data3),
- void *usr);
-
-/**
- * dpu_connector_unregister_event - unregister all callbacks for an event
- * @connector: Pointer to drm connector structure
- * @event_idx: Index of event to register
- */
-void dpu_connector_unregister_event(struct drm_connector *connector,
- uint32_t event_idx);
-
-/**
- * dpu_connector_register_custom_event - register for async events
- * @kms: Pointer to dpu_kms
- * @conn_drm: Pointer to drm connector object
- * @event: Event for which request is being sent
- * @en: Flag to enable/disable the event
- * Returns: Zero on success
- */
-int dpu_connector_register_custom_event(struct dpu_kms *kms,
- struct drm_connector *conn_drm, u32 event, bool en);
-
-/**
- * dpu_connector_pre_kickoff - trigger kickoff time feature programming
- * @connector: Pointer to drm connector object
- * Returns: Zero on success
- */
-int dpu_connector_pre_kickoff(struct drm_connector *connector);
-
-/**
- * dpu_connector_needs_offset - adjust the output fence offset based on
- * display type
- * @connector: Pointer to drm connector object
- * Returns: true if offset is required, false for all other cases.
- */
-static inline bool dpu_connector_needs_offset(struct drm_connector *connector)
-{
- struct dpu_connector *c_conn;
-
- if (!connector)
- return false;
-
- c_conn = to_dpu_connector(connector);
- return (c_conn->connector_type != DRM_MODE_CONNECTOR_VIRTUAL);
-}
-
-/**
- * dpu_connector_get_dither_cfg - get dither property data
- * @conn: Pointer to drm_connector struct
- * @state: Pointer to drm_connector_state struct
- * @cfg: Pointer to pointer to dither cfg
- * @len: length of the dither data
- * Returns: Zero on success
- */
-int dpu_connector_get_dither_cfg(struct drm_connector *conn,
- struct drm_connector_state *state, void **cfg, size_t *len);
-
-#endif /* _DPU_CONNECTOR_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 387919a..ad195d5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -33,7 +33,6 @@
#include "dpu_plane.h"
#include "dpu_color_processing.h"
#include "dpu_encoder.h"
-#include "dpu_connector.h"
#include "dpu_vbif.h"
#include "dpu_power_handle.h"
#include "dpu_core_perf.h"
@@ -3359,7 +3358,6 @@ static int dpu_crtc_atomic_get_property(struct drm_crtc *crtc,
struct dpu_crtc_state *cstate;
struct drm_encoder *encoder;
int i, ret = -EINVAL;
- bool conn_offset = 0;
bool is_cmd = true;
if (!crtc || !state) {
@@ -3368,13 +3366,6 @@ static int dpu_crtc_atomic_get_property(struct drm_crtc *crtc,
dpu_crtc = to_dpu_crtc(crtc);
cstate = to_dpu_crtc_state(state);
- for (i = 0; i < cstate->num_connectors; ++i) {
- conn_offset = dpu_connector_needs_offset(
- cstate->connectors[i]);
- if (conn_offset)
- break;
- }
-
/**
* set the cmd flag only when all the encoders attached
* to the crtc are in cmd mode. Consider all other cases
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3004569..1b21987 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -70,6 +70,8 @@
#define IDLE_SHORT_TIMEOUT 1
+#define MAX_VDISPLAY_SPLIT 1080
+
/**
* enum dpu_enc_rc_events - events for resource control state machine
* @DPU_ENC_RC_EVENT_KICKOFF:
@@ -172,7 +174,6 @@ enum dpu_enc_rc_states {
* @frame_done_timer: watchdog timer for frame done event
* @vsync_event_timer: vsync timer
* @disp_info: local copy of msm_display_info struct
- * @mode_info: local copy of msm_mode_info struct
* @misr_enable: misr enable/disable status
* @misr_frame_count: misr frame count before start capturing the data
* @idle_pc_supported: indicate if idle power collaps is supported
@@ -214,7 +215,6 @@ struct dpu_encoder_virt {
struct timer_list vsync_event_timer;
struct msm_display_info disp_info;
- struct msm_mode_info mode_info;
bool misr_enable;
u32 misr_frame_count;
@@ -497,8 +497,6 @@ void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc,
if (phys && phys->ops.get_hw_resources)
phys->ops.get_hw_resources(phys, hw_res, conn_state);
}
-
- hw_res->topology = dpu_enc->mode_info.topology;
}
void dpu_encoder_destroy(struct drm_encoder *drm_enc)
@@ -605,6 +603,25 @@ static void _dpu_encoder_adjust_mode(struct drm_connector *connector,
}
}
+static struct msm_display_topology dpu_encoder_get_topology(
+ struct dpu_encoder_virt *dpu_enc,
+ struct dpu_kms *dpu_kms,
+ struct drm_display_mode *mode)
+{
+ struct msm_display_topology topology;
+ int i, intf_count = 0;
+
+ for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
+ if (dpu_enc->phys_encs[i])
+ intf_count++;
+
+ /* User split topology for width > 1080 */
+ topology.num_lm = (mode->vdisplay > MAX_VDISPLAY_SPLIT) ? 2 : 1;
+ topology.num_enc = 0;
+ topology.num_intf = intf_count;
+
+ return topology;
+}
static int dpu_encoder_virt_atomic_check(
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,
@@ -615,6 +632,7 @@ static int dpu_encoder_virt_atomic_check(
struct dpu_kms *dpu_kms;
const struct drm_display_mode *mode;
struct drm_display_mode *adj_mode;
+ struct msm_display_topology topology;
int i = 0;
int ret = 0;
@@ -660,6 +678,8 @@ static int dpu_encoder_virt_atomic_check(
}
}
+ topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
+
/* Reserve dynamic resources now. Indicating AtomicTest phase */
if (!ret) {
/*
@@ -669,7 +689,7 @@ static int dpu_encoder_virt_atomic_check(
if (drm_atomic_crtc_needs_modeset(crtc_state)
&& dpu_enc->mode_set_complete) {
ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, crtc_state,
- conn_state, true);
+ conn_state, topology, true);
dpu_enc->mode_set_complete = false;
}
}
@@ -690,7 +710,6 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms;
struct dpu_hw_mdp *hw_mdptop;
struct drm_encoder *drm_enc;
- struct msm_mode_info *mode_info;
int i;
if (!dpu_enc || !disp_info) {
@@ -720,19 +739,12 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
return;
}
- mode_info = &dpu_enc->mode_info;
- if (!mode_info) {
- DPU_ERROR("invalid mode info\n");
- return;
- }
-
if (hw_mdptop->ops.setup_vsync_source &&
disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
for (i = 0; i < dpu_enc->num_phys_encs; i++)
vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
vsync_cfg.pp_count = dpu_enc->num_phys_encs;
- vsync_cfg.frame_rate = mode_info->frame_rate;
if (disp_info->is_te_using_watchdog_timer)
vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
else
@@ -791,9 +803,6 @@ static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
dpu_power_resource_enable(&priv->phandle,
dpu_kms->core_client, true);
- /* enable DSI clks */
- dpu_connector_clk_ctrl(dpu_enc->cur_master->connector, true);
-
/* enable all the irq */
_dpu_encoder_irq_control(drm_enc, true);
@@ -801,9 +810,6 @@ static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
/* disable all the irq */
_dpu_encoder_irq_control(drm_enc, false);
- /* disable DSI clks */
- dpu_connector_clk_ctrl(dpu_enc->cur_master->connector, false);
-
/* disable DPU core clks */
dpu_power_resource_enable(&priv->phandle,
dpu_kms->core_client, false);
@@ -815,7 +821,6 @@ static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
u32 sw_event)
{
- unsigned int lp, idle_timeout;
struct dpu_encoder_virt *dpu_enc;
struct msm_drm_private *priv;
struct msm_drm_thread *disp_thread;
@@ -921,25 +926,13 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
return 0;
}
- /* set idle timeout based on master connector's lp value */
- if (dpu_enc->cur_master)
- lp = dpu_connector_get_lp(
- dpu_enc->cur_master->connector);
- else
- lp = DPU_MODE_DPMS_ON;
-
- if (lp == DPU_MODE_DPMS_LP2)
- idle_timeout = IDLE_SHORT_TIMEOUT;
- else
- idle_timeout = dpu_enc->idle_timeout;
-
kthread_queue_delayed_work(
&disp_thread->worker,
&dpu_enc->delayed_off_work,
- msecs_to_jiffies(idle_timeout));
+ msecs_to_jiffies(dpu_enc->idle_timeout));
DPU_EVT32(DRMID(drm_enc), sw_event, dpu_enc->rc_state,
- idle_timeout, DPU_EVTLOG_FUNC_CASE2);
+ dpu_enc->idle_timeout, DPU_EVTLOG_FUNC_CASE2);
DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work scheduled\n",
sw_event);
break;
@@ -1134,8 +1127,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct dpu_kms *dpu_kms;
struct list_head *connector_list;
struct drm_connector *conn = NULL, *conn_iter;
- struct dpu_connector *dpu_conn = NULL;
struct dpu_rm_hw_iter pp_iter;
+ struct msm_display_topology topology;
+ enum dpu_rm_topology_name topology_name;
int i = 0, ret;
if (!drm_enc) {
@@ -1164,33 +1158,11 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
return;
}
- dpu_conn = to_dpu_connector(conn);
- if (dpu_conn) {
- ret = dpu_conn->ops.get_mode_info(adj_mode, &dpu_enc->mode_info,
- dpu_kms->catalog->caps->max_mixer_width);
- if (ret) {
- DPU_ERROR_ENC(dpu_enc,
- "invalid topology for the mode\n");
- return;
- }
- }
-
- /* release resources before seamless mode change */
- if (msm_is_mode_seamless_dms(adj_mode)) {
- /* restore resource state before releasing them */
- ret = dpu_encoder_resource_control(drm_enc,
- DPU_ENC_RC_EVENT_PRE_MODESET);
- if (ret) {
- DPU_ERROR_ENC(dpu_enc,
- "dpu resource control failed: %d\n",
- ret);
- return;
- }
- }
+ topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
/* Reserve dynamic resources now. Indicating non-AtomicTest phase */
ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_enc->crtc->state,
- conn->state, false);
+ conn->state, topology, false);
if (ret) {
DPU_ERROR_ENC(dpu_enc,
"failed to reserve hw resources, %d\n", ret);
@@ -1205,6 +1177,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) pp_iter.hw;
}
+ topology_name = dpu_rm_get_topology_name(topology);
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
@@ -1216,6 +1189,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
}
phys->hw_pp = dpu_enc->hw_pp[i];
phys->connector = conn->state->connector;
+ phys->topology_name = topology_name;
if (phys->ops.mode_set)
phys->ops.mode_set(phys, mode, adj_mode);
}
@@ -1713,8 +1687,6 @@ int dpu_encoder_helper_wait_event_timeout(
void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_virt *dpu_enc;
- struct dpu_connector *dpu_con;
- void *dpu_con_disp;
struct dpu_hw_ctl *ctl;
int rc;
@@ -1731,22 +1703,6 @@ void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
DPU_DEBUG_ENC(dpu_enc, "ctl %d reset\n", ctl->idx);
DPU_EVT32(DRMID(phys_enc->parent), ctl->idx);
- if (phys_enc->ops.is_master && phys_enc->ops.is_master(phys_enc) &&
- phys_enc->connector) {
- dpu_con = to_dpu_connector(phys_enc->connector);
- dpu_con_disp = dpu_connector_get_display(phys_enc->connector);
-
- if (dpu_con->ops.soft_reset) {
- rc = dpu_con->ops.soft_reset(dpu_con_disp);
- if (rc) {
- DPU_ERROR_ENC(dpu_enc,
- "connector soft reset failure\n");
- DPU_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus",
- "panic");
- }
- }
- }
-
rc = ctl->ops.reset(ctl);
if (rc) {
DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n", ctl->idx);
@@ -1864,22 +1820,6 @@ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
}
}
-static void _dpu_encoder_setup_dither(struct dpu_encoder_phys *phys)
-{
- void *dither_cfg;
- int ret = 0;
- size_t len = 0;
-
- if (!phys || !phys->connector || !phys->hw_pp ||
- !phys->hw_pp->ops.setup_dither)
- return;
-
- ret = dpu_connector_get_dither_cfg(phys->connector,
- phys->connector->state, &dither_cfg, &len);
- if (!ret)
- phys->hw_pp->ops.setup_dither(phys->hw_pp, dither_cfg, len);
-}
-
static u32 _dpu_encoder_calculate_linetime(struct dpu_encoder_virt *dpu_enc,
struct drm_display_mode *mode)
{
@@ -2030,7 +1970,6 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phys;
bool needs_hw_reset = false;
unsigned int i;
- int rc;
if (!drm_enc || !params) {
DPU_ERROR("invalid args\n");
@@ -2050,7 +1989,6 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
phys->ops.prepare_for_kickoff(phys, params);
if (phys->enable_state == DPU_ENC_ERR_NEEDS_HW_RESET)
needs_hw_reset = true;
- _dpu_encoder_setup_dither(phys);
}
}
DPU_ATRACE_END("enc_prepare_for_kickoff");
@@ -2066,14 +2004,6 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
phys->ops.hw_reset(phys);
}
}
-
- if (dpu_enc->cur_master && dpu_enc->cur_master->connector) {
- rc = dpu_connector_pre_kickoff(dpu_enc->cur_master->connector);
- if (rc)
- DPU_ERROR_ENC(dpu_enc, "kickoff conn%d failed rc %d\n",
- dpu_enc->cur_master->connector->base.id,
- rc);
- }
}
void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
@@ -2706,8 +2636,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
.early_unregister = dpu_encoder_early_unregister,
};
-struct drm_encoder *dpu_encoder_init(
- struct drm_device *dev,
+int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
struct msm_display_info *disp_info)
{
struct msm_drm_private *priv = dev->dev_private;
@@ -2717,11 +2646,7 @@ struct drm_encoder *dpu_encoder_init(
int drm_enc_mode = DRM_MODE_ENCODER_NONE;
int ret = 0;
- dpu_enc = kzalloc(sizeof(*dpu_enc), GFP_KERNEL);
- if (!dpu_enc) {
- ret = -ENOMEM;
- goto fail;
- }
+ dpu_enc = to_dpu_encoder_virt(enc);
mutex_init(&dpu_enc->enc_lock);
ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info,
@@ -2731,16 +2656,12 @@ struct drm_encoder *dpu_encoder_init(
dpu_enc->cur_master = NULL;
spin_lock_init(&dpu_enc->enc_spinlock);
- drm_enc = &dpu_enc->base;
- drm_encoder_init(dev, drm_enc, &dpu_encoder_funcs, drm_enc_mode, NULL);
- drm_encoder_helper_add(drm_enc, &dpu_encoder_helper_funcs);
atomic_set(&dpu_enc->frame_done_timeout, 0);
timer_setup(&dpu_enc->frame_done_timer,
dpu_encoder_frame_done_timeout, 0);
- if ((disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) &&
- disp_info->is_primary)
+ if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI)
timer_setup(&dpu_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
@@ -2758,14 +2679,32 @@ struct drm_encoder *dpu_encoder_init(
DPU_DEBUG_ENC(dpu_enc, "created\n");
- return drm_enc;
+ return ret;
fail:
DPU_ERROR("failed to create encoder\n");
if (drm_enc)
dpu_encoder_destroy(drm_enc);
- return ERR_PTR(ret);
+ return ret;
+
+
+}
+
+struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
+ int drm_enc_mode)
+{
+ struct dpu_encoder_virt *dpu_enc = NULL;
+
+ dpu_enc = kzalloc(sizeof(*dpu_enc), GFP_KERNEL);
+ if (!dpu_enc)
+ return ERR_PTR(ENOMEM);
+
+ drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
+ drm_enc_mode, NULL);
+ drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
+
+ return &dpu_enc->base;
}
int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index b25619d..d853ad9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -45,7 +45,6 @@ struct dpu_encoder_hw_resources {
enum dpu_intf_mode wbs[WB_MAX];
bool needs_cdm;
u32 display_num_of_h_tiles;
- struct msm_display_topology topology;
};
/**
@@ -160,6 +159,15 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_encoder,
*/
struct drm_encoder *dpu_encoder_init(
struct drm_device *dev,
+ int drm_enc_mode);
+
+/**
+ * dpu_encoder_setup - setup dpu_encoder for the display probed
+ * @dev: Pointer to drm device structure
+ * @enc: Pointer to the drm_encoder
+ * @disp_info: Pointer to the display info
+ */
+int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
struct msm_display_info *disp_info);
/**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index d3bfc99..bb63ae5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -25,7 +25,6 @@
#include "dpu_hw_wb.h"
#include "dpu_hw_cdm.h"
#include "dpu_encoder.h"
-#include "dpu_connector.h"
#define DPU_ENCODER_NAME_MAX 16
@@ -221,6 +220,7 @@ struct dpu_encoder_irq {
* @split_role: Role to play in a split-panel configuration
* @intf_mode: Interface mode
* @intf_idx: Interface index on dpu hardware
+ * @topology_name: topology selected for the display
* @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
* @enable_state: Enable state tracking
* @vblank_refcount: Reference count of vblank request
@@ -250,6 +250,7 @@ struct dpu_encoder_phys {
enum dpu_enc_split_role split_role;
enum dpu_intf_mode intf_mode;
enum dpu_intf intf_idx;
+ enum dpu_rm_topology_name topology_name;
spinlock_t *enc_spinlock;
enum dpu_enc_enable_state enable_state;
atomic_t vblank_refcount;
@@ -443,14 +444,11 @@ int dpu_encoder_helper_wait_event_timeout(
static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
struct dpu_encoder_phys *phys_enc)
{
- enum dpu_rm_topology_name topology;
-
if (!phys_enc || phys_enc->enable_state == DPU_ENC_DISABLING)
return BLEND_3D_NONE;
- topology = dpu_connector_get_topology_name(phys_enc->connector);
if (phys_enc->split_role == ENC_ROLE_SOLO &&
- topology == DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE)
+ phys_enc->topology_name == DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE)
return BLEND_3D_H_ROW_INT;
return BLEND_3D_NONE;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index b680718..73e5938 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -15,7 +15,6 @@
#include "dpu_hw_interrupts.h"
#include "dpu_core_irq.h"
#include "dpu_formats.h"
-#include "dsi_display.h"
#include "dpu_trace.h"
#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
@@ -356,13 +355,10 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
static bool _dpu_encoder_phys_is_dual_ctl(struct dpu_encoder_phys *phys_enc)
{
- enum dpu_rm_topology_name topology;
-
if (!phys_enc)
return false;
- topology = dpu_connector_get_topology_name(phys_enc->connector);
- if (topology == DPU_RM_TOPOLOGY_DUALPIPE)
+ if (phys_enc->topology_name == DPU_RM_TOPOLOGY_DUALPIPE)
return true;
return false;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 5b07f77..cb8e541 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -27,10 +27,6 @@
#include "msm_mmu.h"
#include "msm_gem.h"
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-#include "dsi_display.h"
-#include "dsi_drm.h"
-#endif
#ifdef CONFIG_DRM_MSM_WRITEBACK
#include "dpu_wb.h"
#endif
@@ -38,7 +34,6 @@
#include "dp/dp_display.h"
#include "dp_drm.h"
#endif
-#include "dpu_connector.h"
#include "dpu_kms.h"
#include "dpu_core_irq.h"
#include "dpu_formats.h"
@@ -468,9 +463,7 @@ static void dpu_kms_complete_commit(struct msm_kms *kms,
struct msm_drm_private *priv;
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
- struct drm_connector *conn;
- struct drm_connector_state *old_conn_state;
- int i, rc = 0;
+ int i;
if (!kms || !old_state)
return;
@@ -483,19 +476,6 @@ static void dpu_kms_complete_commit(struct msm_kms *kms,
for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)
dpu_crtc_complete_commit(crtc, old_crtc_state);
- for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
- struct dpu_connector *c_conn;
-
- c_conn = to_dpu_connector(conn);
- if (!c_conn->ops.post_kickoff)
- continue;
- rc = c_conn->ops.post_kickoff(conn);
- if (rc) {
- pr_err("Connector Post kickoff failed rc=%d\n",
- rc);
- }
- }
-
dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
pm_runtime_put_sync(dpu_kms->dev->dev);
@@ -562,24 +542,6 @@ static int _dpu_kms_get_displays(struct dpu_kms *dpu_kms)
return -EINVAL;
}
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- /* dsi */
- dpu_kms->dsi_displays = NULL;
- dpu_kms->dsi_display_count = dsi_display_get_num_of_displays();
- if (dpu_kms->dsi_display_count) {
- dpu_kms->dsi_displays = kcalloc(dpu_kms->dsi_display_count,
- sizeof(void *),
- GFP_KERNEL);
- if (!dpu_kms->dsi_displays) {
- DPU_ERROR("failed to allocate dsi displays\n");
- goto exit_deinit_dsi;
- }
- dpu_kms->dsi_display_count =
- dsi_display_get_active_displays(dpu_kms->dsi_displays,
- dpu_kms->dsi_display_count);
- }
-#endif
-
#ifdef CONFIG_DRM_MSM_WRITEBACK
/* wb */
dpu_kms->wb_displays = NULL;
@@ -629,15 +591,7 @@ static int _dpu_kms_get_displays(struct dpu_kms *dpu_kms)
dpu_kms->wb_display_count = 0;
dpu_kms->wb_displays = NULL;
#endif
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-exit_deinit_dsi:
- kfree(dpu_kms->dsi_displays);
- dpu_kms->dsi_display_count = 0;
- dpu_kms->dsi_displays = NULL;
return rc;
-#else
- return rc;
-#endif
}
/**
@@ -654,88 +608,44 @@ static void _dpu_kms_release_displays(struct dpu_kms *dpu_kms)
kfree(dpu_kms->wb_displays);
dpu_kms->wb_displays = NULL;
dpu_kms->wb_display_count = 0;
-
- kfree(dpu_kms->dsi_displays);
- dpu_kms->dsi_displays = NULL;
- dpu_kms->dsi_display_count = 0;
}
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
static void _dpu_kms_initialize_dsi(struct drm_device *dev,
struct msm_drm_private *priv,
- struct dpu_kms *dpu_kms,
- unsigned max_encoders)
+ struct dpu_kms *dpu_kms)
{
- static const struct dpu_connector_ops dsi_ops = {
- .post_init = dsi_conn_post_init,
- .detect = dsi_conn_detect,
- .get_modes = dsi_connector_get_modes,
- .put_modes = dsi_connector_put_modes,
- .mode_valid = dsi_conn_mode_valid,
- .get_info = dsi_display_get_info,
- .set_backlight = dsi_display_set_backlight,
- .soft_reset = dsi_display_soft_reset,
- .pre_kickoff = dsi_conn_pre_kickoff,
- .clk_ctrl = dsi_display_clk_ctrl,
- .set_power = dsi_display_set_power,
- .get_mode_info = dsi_conn_get_mode_info,
- .get_dst_format = dsi_display_get_dst_format,
- .post_kickoff = dsi_conn_post_kickoff
- };
- struct msm_display_info info;
- struct drm_encoder *encoder;
- void *display, *connector;
+ struct drm_encoder *encoder = NULL;
int i, rc;
- /* dsi */
- for (i = 0; i < dpu_kms->dsi_display_count &&
- priv->num_encoders < max_encoders; ++i) {
- display = dpu_kms->dsi_displays[i];
- encoder = NULL;
+ /*TODO: Support two independent DSI connectors */
+ encoder = dpu_encoder_init(dev, DRM_MODE_CONNECTOR_DSI);
+ if (IS_ERR_OR_NULL(encoder)) {
+ DPU_ERROR("encoder init failed for dsi %d\n", i);
+ return;
+ }
- memset(&info, 0x0, sizeof(info));
- rc = dsi_display_get_info(&info, display);
- if (rc) {
- DPU_ERROR("dsi get_info %d failed\n", i);
- continue;
- }
+ priv->encoders[priv->num_encoders++] = encoder;
- encoder = dpu_encoder_init(dev, &info);
- if (IS_ERR_OR_NULL(encoder)) {
- DPU_ERROR("encoder init failed for dsi %d\n", i);
- continue;
+ for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
+ if (!priv->dsi[i]) {
+ DPU_DEBUG("invalid msm_dsi for ctrl %d\n", i);
+ return;
}
- rc = dsi_display_drm_bridge_init(display, encoder);
+ rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder);
if (rc) {
- DPU_ERROR("dsi bridge %d init failed, %d\n", i, rc);
- dpu_encoder_destroy(encoder);
+ DPU_ERROR("modeset_init failed for dsi[%d]\n", i);
continue;
}
-
- connector = dpu_connector_init(dev,
- encoder,
- 0,
- display,
- &dsi_ops,
- DRM_CONNECTOR_POLL_HPD,
- DRM_MODE_CONNECTOR_DSI);
- if (connector) {
- priv->encoders[priv->num_encoders++] = encoder;
- } else {
- DPU_ERROR("dsi %d connector init failed\n", i);
- dsi_display_drm_bridge_deinit(display);
- dpu_encoder_destroy(encoder);
- }
}
}
-#endif
+
#ifdef CONFIG_DRM_MSM_WRITEBACK
static void _dpu_kms_initialize_wb(struct drm_device *dev,
struct msm_drm_private *priv,
struct dpu_kms *dpu_kms,
- unsigned max_encoders)
+ unsigned int max_encoders)
{
static const struct dpu_connector_ops wb_ops = {
.post_init = dpu_wb_connector_post_init,
@@ -800,7 +710,7 @@ static void _dpu_kms_initialize_wb(struct drm_device *dev,
static void _dpu_kms_initialize_dp(struct drm_device *dev,
struct msm_drm_private *priv,
struct dpu_kms *dpu_kms,
- unsigned max_encoders)
+ unsigned int max_encoders)
{
static const struct dpu_connector_ops dp_ops = {
.post_init = dp_connector_post_init,
@@ -872,18 +782,7 @@ static void _dpu_kms_setup_displays(struct drm_device *dev,
struct msm_drm_private *priv,
struct dpu_kms *dpu_kms)
{
- unsigned max_encoders;
-
- max_encoders = dpu_kms->dsi_display_count + dpu_kms->wb_display_count +
- dpu_kms->dp_display_count;
- if (max_encoders > ARRAY_SIZE(priv->encoders)) {
- max_encoders = ARRAY_SIZE(priv->encoders);
- DPU_ERROR("capping number of displays to %d", max_encoders);
- }
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- _dpu_kms_initialize_dsi(dev, priv, dpu_kms, max_encoders);
-#endif
+ _dpu_kms_initialize_dsi(dev, priv, dpu_kms);
#ifdef CONFIG_DRM_MSM_WRITEBACK
_dpu_kms_initialize_wb(dev, priv, dpu_kms, max_encoders);
@@ -1521,6 +1420,7 @@ static int dpu_kms_atomic_check(struct msm_kms *kms,
dpu_kms->aspace[domain] : NULL;
}
+#ifdef CONFIG_DRM_MSM_DISPLAYPORT
static void _dpu_kms_post_open(struct msm_kms *kms, struct drm_file *file)
{
struct drm_device *dev = NULL;
@@ -1561,13 +1461,12 @@ static void _dpu_kms_post_open(struct msm_kms *kms, struct drm_file *file)
mutex_unlock(&dev->mode_config.mutex);
}
+#endif
static int dpu_kms_pm_suspend(struct device *dev)
{
struct drm_device *ddev;
struct drm_modeset_acquire_ctx ctx;
- struct drm_connector *conn;
- struct drm_connector_list_iter conn_iter;
struct drm_atomic_state *state;
struct dpu_kms *dpu_kms;
int ret = 0, num_crtcs = 0;
@@ -1611,45 +1510,6 @@ static int dpu_kms_pm_suspend(struct device *dev)
}
state->acquire_ctx = &ctx;
- drm_connector_list_iter_begin(ddev, &conn_iter);
- drm_for_each_connector_iter(conn, &conn_iter) {
- struct drm_crtc_state *crtc_state;
- uint64_t lp;
-
- if (!conn->state || !conn->state->crtc ||
- conn->dpms != DRM_MODE_DPMS_ON)
- continue;
-
- lp = dpu_connector_get_lp(conn);
- if (lp == DPU_MODE_DPMS_LP1) {
- /* transition LP1->LP2 on pm suspend */
- ret = dpu_connector_set_property_for_commit(conn, state,
- CONNECTOR_PROP_LP, DPU_MODE_DPMS_LP2);
- if (ret) {
- DRM_ERROR("failed to set lp2 for conn %d\n",
- conn->base.id);
- drm_atomic_state_put(state);
- goto unlock;
- }
- }
-
- if (lp != DPU_MODE_DPMS_LP2) {
- /* force CRTC to be inactive */
- crtc_state = drm_atomic_get_crtc_state(state,
- conn->state->crtc);
- if (IS_ERR_OR_NULL(crtc_state)) {
- DRM_ERROR("failed to get crtc %d state\n",
- conn->state->crtc->base.id);
- drm_atomic_state_put(state);
- goto unlock;
- }
-
- if (lp != DPU_MODE_DPMS_LP1)
- crtc_state->active = false;
- ++num_crtcs;
- }
- }
- drm_connector_list_iter_end(&conn_iter);
/* check for nothing to do */
if (num_crtcs == 0) {
@@ -1721,6 +1581,34 @@ static int dpu_kms_pm_resume(struct device *dev)
return 0;
}
+void _dpu_kms_set_encoder_mode(struct msm_kms *kms,
+ struct drm_encoder *encoder,
+ bool cmd_mode)
+{
+ struct msm_display_info info;
+ struct msm_drm_private *priv = encoder->dev->dev_private;
+ int i, rc = 0;
+
+ memset(&info, 0, sizeof(info));
+
+ info.intf_type = encoder->encoder_type;
+ info.capabilities = cmd_mode ? MSM_DISPLAY_CAP_CMD_MODE :
+ MSM_DISPLAY_CAP_VID_MODE;
+
+ /* TODO: No support for DSI swap */
+ for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
+ if (priv->dsi[i]) {
+ info.h_tile_instance[info.num_of_h_tiles] = i;
+ info.num_of_h_tiles++;
+ }
+ }
+
+ rc = dpu_encoder_setup(encoder->dev, encoder, &info);
+ if (rc)
+ DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
+ encoder->base.id, rc);
+}
+
static const struct msm_kms_funcs kms_funcs = {
.hw_init = dpu_kms_hw_init,
.postinit = dpu_kms_postinit,
@@ -1744,7 +1632,10 @@ static int dpu_kms_pm_resume(struct device *dev)
.pm_resume = dpu_kms_pm_resume,
.destroy = dpu_kms_destroy,
.get_address_space = _dpu_kms_get_address_space,
+#ifdef CONFIG_DRM_MSM_DISPLAYPORT
.postopen = _dpu_kms_post_open,
+#endif
+ .set_encoder_mode = _dpu_kms_set_encoder_mode,
};
/* the caller api needs to turn on clock before calling it */
@@ -1832,8 +1723,6 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
goto fail;
}
- dpu_kms->aspace[0] = aspace;
-
ret = aspace->mmu->funcs->attach(aspace->mmu,
(const char **)iommu_ports,
ARRAY_SIZE(iommu_ports));
@@ -1843,6 +1732,7 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
goto fail;
}
aspace->domain_attached = true;
+ dpu_kms->aspace[0] = aspace;
#endif
return 0;
fail:
@@ -2001,6 +1891,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
goto power_error;
}
+ if (dpu_kms->aspace[0])
+ kms->aspace = dpu_kms->aspace[0];
#ifdef CONFIG_CHROME_REGDMA
/* Initialize reg dma block which is a singleton */
rc = dpu_reg_dma_init(dpu_kms->reg_dma, dpu_kms->catalog,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index c8c12d3..af8205f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -23,7 +23,6 @@
#include "dpu_hw_intf.h"
#include "dpu_hw_wb.h"
#include "dpu_encoder.h"
-#include "dpu_connector.h"
#define RESERVED_BY_OTHER(h, r) \
((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id))
@@ -158,6 +157,18 @@ struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm)
return rm->hw_mdp;
}
+enum dpu_rm_topology_name
+dpu_rm_get_topology_name(struct msm_display_topology topology)
+{
+ int i;
+
+ for (i = 0; i < DPU_RM_TOPOLOGY_MAX; i++)
+ if (RM_IS_TOPOLOGY_MATCH(g_top_table[i], topology))
+ return g_top_table[i].top_name;
+
+ return DPU_RM_TOPOLOGY_NONE;
+}
+
void dpu_rm_init_hw_iter(
struct dpu_rm_hw_iter *iter,
uint32_t enc_id,
@@ -954,20 +965,19 @@ static int _dpu_rm_populate_requirements(
struct drm_encoder *enc,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
- struct dpu_rm_requirements *reqs)
+ struct dpu_rm_requirements *reqs,
+ struct msm_display_topology req_topology)
{
const struct drm_display_mode *mode = &crtc_state->mode;
int i;
memset(reqs, 0, sizeof(*reqs));
- reqs->top_ctrl = dpu_connector_get_property(conn_state,
- CONNECTOR_PROP_TOPOLOGY_CONTROL);
dpu_encoder_get_hw_resources(enc, &reqs->hw_res, conn_state);
for (i = 0; i < DPU_RM_TOPOLOGY_MAX; i++) {
if (RM_IS_TOPOLOGY_MATCH(g_top_table[i],
- reqs->hw_res.topology)) {
+ req_topology)) {
reqs->topology = &g_top_table[i];
break;
}
@@ -978,10 +988,6 @@ static int _dpu_rm_populate_requirements(
return -EINVAL;
}
- /* DSC blocks are hardwired for control path 0 and 1 */
- if (reqs->topology->num_comp_enc)
- reqs->top_ctrl |= BIT(DPU_RM_TOPCTL_DSPP);
-
/**
* Set the requirement based on caps if not set from user space
* This will ensure to select LM tied with DS blocks
@@ -1110,9 +1116,6 @@ void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc)
goto end;
}
- top_ctrl = dpu_connector_get_property(conn->state,
- CONNECTOR_PROP_TOPOLOGY_CONTROL);
-
if (top_ctrl & BIT(DPU_RM_TOPCTL_RESERVE_LOCK)) {
DPU_DEBUG("rsvp[s%de%d] not releasing locked resources\n",
rsvp->seq, rsvp->enc_id);
@@ -1120,12 +1123,6 @@ void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc)
DPU_DEBUG("release rsvp[s%de%d]\n", rsvp->seq,
rsvp->enc_id);
_dpu_rm_release_rsvp(rm, rsvp, conn);
-
- (void) msm_property_set_property(
- dpu_connector_get_propinfo(conn),
- dpu_connector_get_property_state(conn->state),
- CONNECTOR_PROP_TOPOLOGY_NAME,
- DPU_RM_TOPOLOGY_NONE);
}
end:
@@ -1141,18 +1138,6 @@ static int _dpu_rm_commit_rsvp(
enum dpu_hw_blk_type type;
int ret = 0;
- ret = msm_property_set_property(
- dpu_connector_get_propinfo(conn_state->connector),
- dpu_connector_get_property_state(conn_state),
- CONNECTOR_PROP_TOPOLOGY_NAME,
- rsvp->topology);
- if (ret) {
- DPU_ERROR("failed to set topology name property, ret %d\n",
- ret);
- _dpu_rm_release_rsvp(rm, rsvp, conn_state->connector);
- return ret;
- }
-
/* Swap next rsvp to be the active */
for (type = 0; type < DPU_HW_BLK_MAX; type++) {
list_for_each_entry(blk, &rm->hw_blks[type], list) {
@@ -1177,6 +1162,7 @@ int dpu_rm_reserve(
struct drm_encoder *enc,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
+ struct msm_display_topology topology,
bool test_only)
{
struct dpu_rm_rsvp *rsvp_cur, *rsvp_nxt;
@@ -1202,7 +1188,7 @@ int dpu_rm_reserve(
_dpu_rm_print_rsvps(rm, DPU_RM_STAGE_BEGIN);
ret = _dpu_rm_populate_requirements(rm, enc, crtc_state,
- conn_state, &reqs);
+ conn_state, &reqs, topology);
if (ret) {
DPU_ERROR("failed to populate hw requirements\n");
goto end;
@@ -1237,12 +1223,6 @@ int dpu_rm_reserve(
_dpu_rm_release_rsvp(rm, rsvp_cur, conn_state->connector);
rsvp_cur = NULL;
_dpu_rm_print_rsvps(rm, DPU_RM_STAGE_AFTER_CLEAR);
- (void) msm_property_set_property(
- dpu_connector_get_propinfo(
- conn_state->connector),
- dpu_connector_get_property_state(conn_state),
- CONNECTOR_PROP_TOPOLOGY_NAME,
- DPU_RM_TOPOLOGY_NONE);
}
/* Check the proposed reservation, store it in hw's "next" field */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 8a6cbcf..4c77874 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -128,6 +128,7 @@ int dpu_rm_init(struct dpu_rm *rm,
* @drm_enc: DRM Encoder handle
* @crtc_state: Proposed Atomic DRM CRTC State handle
* @conn_state: Proposed Atomic DRM Connector State handle
+ * @topology: Pointer to topology info for the display
* @test_only: Atomic-Test phase, discard results (unless property overrides)
* @Return: 0 on Success otherwise -ERROR
*/
@@ -135,6 +136,7 @@ int dpu_rm_reserve(struct dpu_rm *rm,
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
+ struct msm_display_topology topology,
bool test_only);
/**
@@ -187,4 +189,13 @@ void dpu_rm_init_hw_iter(
*/
int dpu_rm_check_property_topctl(uint64_t val);
+/**
+ * dpu_rm_get_topology_name - returns the name of the the given topology
+ * definition
+ * @topology: topology definition
+ * @Return: name of the topology
+ */
+enum dpu_rm_topology_name
+dpu_rm_get_topology_name(struct msm_display_topology topology);
+
#endif /* __DPU_RM_H__ */
diff --git a/drivers/gpu/drm/msm/dpu_dbg.c b/drivers/gpu/drm/msm/dpu_dbg.c
index 341b596..5c62339 100644
--- a/drivers/gpu/drm/msm/dpu_dbg.c
+++ b/drivers/gpu/drm/msm/dpu_dbg.c
@@ -2545,9 +2545,6 @@ static void _dpu_dump_array(struct dpu_dbg_reg_base *blk_arr[],
if (dump_dbgbus_vbif_rt)
_dpu_dbg_dump_vbif_dbg_bus(&dpu_dbg_base.dbgbus_vbif_rt);
- if (dpu_dbg_base.dsi_dbg_bus || dump_all)
- dsi_ctrl_debug_dump();
-
if (do_panic && dpu_dbg_base.panic_on_err)
panic(name);
}
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a710b63..013793e 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -50,9 +50,6 @@
#ifdef CONFIG_DRM_MSM_WRITEBACK
#include "dpu_wb.h"
#endif
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
-#include "dsi_display.h"
-#endif
#ifdef CONFIG_DRM_MSM_DPU
#include "dpu_dbg.h"
#endif
@@ -1639,42 +1636,6 @@ static int add_display_components(struct device *dev,
struct device *mdp_dev = NULL;
int ret;
-#ifdef CONFIG_DRM_MSM_DPU
- struct device_node *node;
- const char *name;
-
- if (of_device_is_compatible(dev->of_node, "qcom,dpu-kms")) {
- struct device_node *np = dev->of_node;
- unsigned int i;
- bool found = false;
-
-#ifdef CONFIG_DRM_MSM_DSI_STAGING
- for (i = 0; i < MAX_DSI_ACTIVE_DISPLAY; i++) {
- node = dsi_display_get_boot_display(i);
-
- if (node != NULL) {
- name = of_get_property(node, "label", NULL);
- component_match_add(dev, matchptr, compare_of,
- node);
- pr_debug("Added component = %s\n", name);
- found = true;
- }
- }
- if (!found)
- return -EPROBE_DEFER;
-#endif
-
- for (i = 0; ; i++) {
- node = of_parse_phandle(np, "connectors", i);
- if (!node)
- break;
-
- component_match_add(dev, matchptr, compare_of, node);
- }
- return 0;
- }
-#endif
-
/*
* MDP5 based devices don't have a flat hierarchy. There is a top level
* parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
@@ -1698,7 +1659,7 @@ static int add_display_components(struct device *dev,
put_device(mdp_dev);
/* add the MDP component itself */
- component_match_add(dev, matchptr, compare_of,
+ drm_of_component_match_add(dev, matchptr, compare_of,
mdp_dev->of_node);
} else {
/* MDP4 */
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index f98c4ef..fde6751 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -159,8 +159,6 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_AD_BL_SCALE,
/* enum/bitmask properties */
- CONNECTOR_PROP_TOPOLOGY_NAME,
- CONNECTOR_PROP_TOPOLOGY_CONTROL,
CONNECTOR_PROP_AUTOREFRESH,
CONNECTOR_PROP_LP,
@@ -331,57 +329,20 @@ struct msm_display_topology {
};
/**
- * struct msm_mode_info - defines all msm custom mode info
- * @frame_rate: frame_rate of the mode
- * @vtotal: vtotal calculated for the mode
- * @prefill_lines: prefill lines based on porches.
- * @jitter_numer: display panel jitter numerator configuration
- * @jitter_denom: display panel jitter denominator configuration
- * @topology: supported topology for the mode
- */
-struct msm_mode_info {
- uint32_t frame_rate;
- uint32_t vtotal;
- uint32_t prefill_lines;
- uint32_t jitter_numer;
- uint32_t jitter_denom;
- struct msm_display_topology topology;
-};
-
-/**
* struct msm_display_info - defines display properties
* @intf_type: DRM_MODE_CONNECTOR_ display type
* @capabilities: Bitmask of display flags
* @num_of_h_tiles: Number of horizontal tiles in case of split interface
* @h_tile_instance: Controller instance used per tile. Number of elements is
* based on num_of_h_tiles
- * @is_connected: Set to true if display is connected
- * @width_mm: Physical width
- * @height_mm: Physical height
- * @max_width: Max width of display. In case of hot pluggable display
- * this is max width supported by controller
- * @max_height: Max height of display. In case of hot pluggable display
- * this is max height supported by controller
- * @is_primary: Set to true if display is primary display
* @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is
* used instead of panel TE in cmd mode panels
*/
struct msm_display_info {
int intf_type;
uint32_t capabilities;
-
uint32_t num_of_h_tiles;
uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
-
- bool is_connected;
-
- unsigned int width_mm;
- unsigned int height_mm;
-
- uint32_t max_width;
- uint32_t max_height;
-
- bool is_primary;
bool is_te_using_watchdog_timer;
};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
More information about the Freedreno
mailing list