summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.h1
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c37
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c17
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c8
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h1
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h3
7 files changed, 69 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index ddcda8cec9a7..81971b3caf3b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -90,6 +90,7 @@ int msm_dsi_manager_phy_enable(int id,
void msm_dsi_manager_phy_disable(int id);
int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
+void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags);
int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 3819fdefcae2..eb0903d37e5c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1482,6 +1482,8 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
msm_host->format = dsi->format;
msm_host->mode_flags = dsi->mode_flags;
+ msm_dsi_manager_attach_dsi_device(msm_host->id, dsi->mode_flags);
+
/* Some gpios defined in panel DT need to be controlled by host */
ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev);
if (ret)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 19da23d8a0b1..bd4ba00d2524 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -168,6 +168,16 @@ static enum drm_connector_status dsi_mgr_connector_detect(
msm_dsi->panel = msm_dsi_host_get_panel(
other_dsi->host, NULL);
+
+ if (msm_dsi->panel && kms->funcs->set_encoder_mode) {
+ bool cmd_mode = !(msm_dsi->device_flags &
+ MIPI_DSI_MODE_VIDEO);
+ struct drm_encoder *encoder =
+ msm_dsi_get_encoder(msm_dsi);
+
+ kms->funcs->set_encoder_mode(kms, encoder, cmd_mode);
+ }
+
if (msm_dsi->panel && IS_DUAL_DSI())
drm_object_attach_property(&connector->base,
connector->dev->mode_config.tile_property, 0);
@@ -773,6 +783,33 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
return true;
}
+void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags)
+{
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+ struct drm_device *dev = msm_dsi->dev;
+ struct msm_drm_private *priv;
+ struct msm_kms *kms;
+ struct drm_encoder *encoder;
+
+ /*
+ * drm_device pointer is assigned to msm_dsi only in the modeset_init
+ * path. If mipi_dsi_attach() happens in DSI driver's probe path
+ * (generally the case when we're connected to a drm_panel of the type
+ * mipi_dsi_device), this would be NULL. In such cases, try to set the
+ * encoder mode in the DSI connector's detect() op.
+ */
+ if (!dev)
+ return;
+
+ priv = dev->dev_private;
+ kms = priv->kms;
+ encoder = msm_dsi_get_encoder(msm_dsi);
+
+ if (encoder && kms->funcs->set_encoder_mode)
+ if (!(device_flags & MIPI_DSI_MODE_VIDEO))
+ kms->funcs->set_encoder_mode(kms, encoder, true);
+}
+
int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
{
struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index fe0c22230883..1e7c99125fdd 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -342,6 +342,23 @@ int mdp5_encoder_set_split_display(struct drm_encoder *encoder,
return 0;
}
+void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
+{
+ struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+ struct mdp5_interface *intf = &mdp5_encoder->intf;
+
+ /* TODO: Expand this to set writeback modes too */
+ if (cmd_mode) {
+ WARN_ON(intf->type != INTF_DSI);
+ intf->mode = MDP5_INTF_DSI_MODE_COMMAND;
+ } else {
+ if (intf->type == INTF_DSI)
+ intf->mode = MDP5_INTF_DSI_MODE_VIDEO;
+ else
+ intf->mode = MDP5_INTF_MODE_NONE;
+ }
+}
+
/* initialize encoder */
struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
struct mdp5_interface *intf, struct mdp5_ctl *ctl)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 5bad72c9e253..f73d46756912 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -151,6 +151,13 @@ static int mdp5_set_split_display(struct msm_kms *kms,
return mdp5_encoder_set_split_display(encoder, slave_encoder);
}
+static void mdp5_set_encoder_mode(struct msm_kms *kms,
+ struct drm_encoder *encoder,
+ bool cmd_mode)
+{
+ mdp5_encoder_set_intf_mode(encoder, cmd_mode);
+}
+
static void mdp5_kms_destroy(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -230,6 +237,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.get_format = mdp_get_format,
.round_pixclk = mdp5_round_pixclk,
.set_split_display = mdp5_set_split_display,
+ .set_encoder_mode = mdp5_set_encoder_mode,
.destroy = mdp5_kms_destroy,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = mdp5_kms_debugfs_init,
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index cdfc63d90c7b..3e0baed0a8a7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -246,6 +246,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
int mdp5_encoder_set_split_display(struct drm_encoder *encoder,
struct drm_encoder *slave_encoder);
+void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode);
int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index e470f4cf8f76..117635d2b8c5 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -56,6 +56,9 @@ struct msm_kms_funcs {
struct drm_encoder *encoder,
struct drm_encoder *slave_encoder,
bool is_cmd_mode);
+ void (*set_encoder_mode)(struct msm_kms *kms,
+ struct drm_encoder *encoder,
+ bool cmd_mode);
/* cleanup: */
void (*destroy)(struct msm_kms *kms);
#ifdef CONFIG_DEBUG_FS