drm/msm: DSI support on MDP4
cover drm/msm: DSI support on MDP4
This adds DSI video mode supports for the mdp4 kms driver.
The first few patches make sure mdp4's modeset_init() func works with multiple encoders. It also fixes up some issues with the way the LVDS interface is initialized.
We just support 1 DSI instance for now, and that too only DSI video mode. We also don't have proper support for the DMA_S crtc yet. So, only one of the two interfaces (DSI or LVDS) would run at a time. We can add support for DMA_S later if we need it.
Archit Taneja (4):
drm/msm/mdp4: Clean up modeset_init
drm/msm/mdp4: Initialize LCDC encoder even if panel driver isn't
available
drm/msm/mdp4: Call custom round_pixclk helper only if the encoder type
is TMDS
drm/msm/mdp4: Initialize DSI encoders
Vinay Simha BN (1):
drm/msm/dsi: Add a mdp4 encoder for DSI
drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c | 198 ++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 258 +++++++++++++-------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 13 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c | 11 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c | 23 +- 6 files changed, 392 insertions(+), 112 deletions(-) create mode 100644 drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 1/5 drm/msm/mdp4: Clean up modeset_init
modeset_init() for mdp4 isn't very flexible. That makes it hard to add more interfaces.
Split out the encoder/connector creation code in modeset_init into a separate function. This is similar to what's done in modeset_init for mdp5.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 192 ++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 83 deletions(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +109 -83
@@ -270,117 +270,143 @@ static struct drm_panel *detect_panel(struct drm_device *dev)return panel; } -static int modeset_init (struct mdp4_kms *mdp4_kms) +static int mdp4_modeset_init_intf (struct mdp4_kms *mdp4_kms, +int intf_type) {struct drm_device *dev = mdp4_kms->dev;struct msm_drm_private *priv = dev->dev_private; -struct drm_plane *plane; -struct drm_crtc *crtc;struct drm_encoder *encoder;struct drm_connector *connector;struct drm_panel *panel;int ret; -/* construct non-private planes: */ - plane =mdp4_plane_init (dev,VG1 , false); -if (IS_ERR (plane)) { -dev_err (dev->dev,"failed to construct plane for VG1\n" ); - ret =PTR_ERR (plane); - goto fail; - } - priv->planes[priv->num_planes++] = plane; +switch (intf_type) { +case DRM_MODE_ENCODER_LVDS : + panel =detect_panel (dev); +if (IS_ERR (panel)) { +dev_err (dev->dev,"failed to detect LVDS panel\n" ); +return PTR_ERR (panel); + } - plane =mdp4_plane_init (dev,VG2 , false); -if (IS_ERR (plane)) { -dev_err (dev->dev,"failed to construct plane for VG2\n" ); - ret =PTR_ERR (plane); - goto fail; - } - priv->planes[priv->num_planes++] = plane; + encoder =mdp4_lcdc_encoder_init (dev, panel); +if (IS_ERR (encoder)) { +dev_err (dev->dev,"failed to construct LCDC encoder\n" ); +return PTR_ERR (encoder); + } -/* -* Setup the LCDC/LVDS path: RGB2 -> DMA_P -> LCDC -> LVDS: -*/ +/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */ + encoder->possible_crtcs =1 <<DMA_P ; - panel =detect_panel (dev); -if (IS_ERR (panel)) { - ret =PTR_ERR (panel); -dev_err (dev->dev,"failed to detect LVDS panel: %d\n" , ret); - goto fail; - } + connector =mdp4_lvds_connector_init (dev, panel, encoder); +if (IS_ERR (connector)) { +dev_err (dev->dev,"failed to initialize LVDS connector\n" ); +return PTR_ERR (connector); + } - plane =mdp4_plane_init (dev,RGB2 , true); -if (IS_ERR (plane)) { -dev_err (dev->dev,"failed to construct plane for RGB2\n" ); - ret =PTR_ERR (plane); - goto fail; - } + priv->encoders[priv->num_encoders++] = encoder; + priv->connectors[priv->num_connectors++] = connector; - crtc =mdp4_crtc_init (dev, plane, priv->num_crtcs,0 ,DMA_P ); -if (IS_ERR (crtc)) { -dev_err (dev->dev,"failed to construct crtc for DMA_P\n" ); - ret =PTR_ERR (crtc); - goto fail; - } +break ; +case DRM_MODE_ENCODER_TMDS : + encoder =mdp4_dtv_encoder_init (dev); +if (IS_ERR (encoder)) { +dev_err (dev->dev,"failed to construct DTV encoder\n" ); +return PTR_ERR (encoder); + } - encoder =mdp4_lcdc_encoder_init (dev, panel); -if (IS_ERR (encoder)) { -dev_err (dev->dev,"failed to construct LCDC encoder\n" ); - ret =PTR_ERR (encoder); - goto fail; - } +/* DTV can be hooked to DMA_E: */ + encoder->possible_crtcs =1 <<1 ; -/* LCDC can be hooked to DMA_P: */ - encoder->possible_crtcs =1 << priv->num_crtcs; +if (priv->hdmi) { +/* Construct bridge/connector for HDMI: */ + ret =hdmi_modeset_init (priv->hdmi, dev, encoder); +if (ret) { +dev_err (dev->dev,"failed to initialize HDMI: %d\n" , ret); +return ret; + } + } - priv->crtcs[priv->num_crtcs++] = crtc; - priv->encoders[priv->num_encoders++] = encoder; + priv->encoders[priv->num_encoders++] = encoder; - connector =mdp4_lvds_connector_init (dev, panel, encoder); -if (IS_ERR (connector)) { - ret =PTR_ERR (connector); -dev_err (dev->dev,"failed to initialize LVDS connector: %d\n" , ret); - goto fail; +break ; +default : +dev_err (dev->dev,"Invalid or unsupported interface\n" ); +return -EINVAL ; } - priv->connectors[priv->num_connectors++] = connector; -/* -* Setup DTV/HDMI path: RGB1 -> DMA_E -> DTV -> HDMI: -*/ +return 0 ; +} - plane =mdp4_plane_init (dev,RGB1 , true); -if (IS_ERR (plane)) { -dev_err (dev->dev,"failed to construct plane for RGB1\n" ); - ret =PTR_ERR (plane); - goto fail; - } +static int modeset_init (struct mdp4_kms *mdp4_kms) +{ +struct drm_device *dev = mdp4_kms->dev; +struct msm_drm_private *priv = dev->dev_private; +struct drm_plane *plane; +struct drm_crtc *crtc; +int i, ret; +static const enum mdp4_pipe rgb_planes[] = { +RGB1 ,RGB2 , + }; +static const enum mdp4_pipe vg_planes[] = { +VG1 ,VG2 , + }; +static const enum mdp4_dma mdp4_crtcs[] = { +DMA_P ,DMA_E , + }; +static const char *const mdp4_crtc_names[] = { +"DMA_P" ,"DMA_E" , + }; +static const int mdp4_intfs[] = { +DRM_MODE_ENCODER_LVDS , +DRM_MODE_ENCODER_TMDS , + }; - crtc =mdp4_crtc_init (dev, plane, priv->num_crtcs,1 ,DMA_E ); -if (IS_ERR (crtc)) { -dev_err (dev->dev,"failed to construct crtc for DMA_E\n" ); - ret =PTR_ERR (crtc); - goto fail; +/* construct non-private planes: */ +for (i =0 ; i <ARRAY_SIZE (vg_planes); i++) { + plane =mdp4_plane_init (dev, vg_planes[i], false); +if (IS_ERR (plane)) { +dev_err (dev->dev, +"failed to construct plane for VG%d\n" , i +1 ); + ret =PTR_ERR (plane); + goto fail; + } + priv->planes[priv->num_planes++] = plane; } - encoder =mdp4_dtv_encoder_init (dev); -if (IS_ERR (encoder)) { -dev_err (dev->dev,"failed to construct DTV encoder\n" ); - ret =PTR_ERR (encoder); - goto fail; - } +for (i =0 ; i <ARRAY_SIZE (mdp4_crtcs); i++) { + plane =mdp4_plane_init (dev, rgb_planes[i], true); +if (IS_ERR (plane)) { +dev_err (dev->dev, +"failed to construct plane for RGB%d\n" , i +1 ); + ret =PTR_ERR (plane); + goto fail; + } -/* DTV can be hooked to DMA_E: */ - encoder->possible_crtcs =1 << priv->num_crtcs; + crtc =mdp4_crtc_init (dev, plane, priv->num_crtcs, i, + mdp4_crtcs[i]); +if (IS_ERR (crtc)) { +dev_err (dev->dev,"failed to construct crtc for %s\n" , + mdp4_crtc_names[i]); + ret =PTR_ERR (crtc); + goto fail; + } + + priv->crtcs[priv->num_crtcs++] = crtc; + } - priv->crtcs[priv->num_crtcs++] = crtc; - priv->encoders[priv->num_encoders++] = encoder; +/* +* we currently set up two relatively fixed paths: +* +* LCDC/LVDS path: RGB1 -> DMA_P -> LCDC -> LVDS +* DTV/HDMI path: RGB2 -> DMA_E -> DTV -> HDMI +*/ -if (priv->hdmi) { -/* Construct bridge/connector for HDMI: */ - ret =hdmi_modeset_init (priv->hdmi, dev, encoder); +for (i =0 ; i <ARRAY_SIZE (mdp4_intfs); i++) { + ret =mdp4_modeset_init_intf (mdp4_kms, mdp4_intfs[i]);if (ret) { -dev_err (dev->dev,"failed to initialize HDMI: %d\n" , ret); +dev_err (dev->dev,"failed to initialize intf: %d, %d\n" , + i, ret); goto fail; } }
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/5 drm/msm/mdp4: Initialize LCDC encoder even if panel driver isn't available
In reply to Archit TanejaCurrently, the driver defers if it doesn't find a drm_panel. This forces us to have a drm_panel, if not, the driver isn't usable.
Make the lcdc encoder initialization independent of the availability of the drm panel. We only check if there is a panel node specified in DT. If it isn't, then we don't initialize the encoder at all. The panel node is passed to the lcdc encoder and lvds connector drivers.
The connector driver takes the responsibility to retrieve the drm_panel from the panel node, and update the status on whether the panel is connected or not. This makes the panel usable even if the drm_panel driver is inserted as a module later on.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 38 ++++++++++------------ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 4 +-- drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c | 11 ++++--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c | 23 +++++++------ 4 files changed, 40 insertions(+), 36 deletions(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +18 -20
@@ -240,18 +240,18 @@ int mdp4_enable(struct mdp4_kms *mdp4_kms)return 0 ; } -static struct drm_panel *detect_panel (struct drm_device *dev) +static struct device_node *mdp4_detect_lcdc_panel (struct drm_device *dev) {struct device_node *endpoint, *panel_node;struct device_node *np = dev->dev->of_node; -struct drm_panel *panel =NULL ; endpoint =of_graph_get_next_endpoint (np,NULL );if (!endpoint) { -dev_err (dev->dev,"no valid endpoint\n" ); -return ERR_PTR (-ENODEV ); +DBG ("no endpoint in MDP4 to fetch LVDS panel\n" ); +return NULL ; } +/* don't proceed if we have an endpoint but no panel_node tied to it */ panel_node =of_graph_get_remote_port_parent (endpoint);if (!panel_node) {dev_err (dev->dev,"no valid panel node\n" );
@@ -261,13 +261,7 @@ static struct drm_panel *detect_panel(struct drm_device *dev)of_node_put (endpoint); - panel =of_drm_find_panel (panel_node); -if (!panel) { -of_node_put (panel_node); -return ERR_PTR (-EPROBE_DEFER ); - } - -return panel; +return panel_node; } static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
@@ -277,18 +271,22 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,struct msm_drm_private *priv = dev->dev_private;struct drm_encoder *encoder;struct drm_connector *connector; -struct drm_panel *panel; +struct device_node *panel_node;int ret;switch (intf_type) {case DRM_MODE_ENCODER_LVDS : - panel =detect_panel (dev); -if (IS_ERR (panel)) { -dev_err (dev->dev,"failed to detect LVDS panel\n" ); -return PTR_ERR (panel); - } - - encoder =mdp4_lcdc_encoder_init (dev, panel); +/* +* bail out early if: +* - there is no panel node (no need to initialize lcdc +* encoder and lvds connector), or +* - panel node is a bad pointer +*/ + panel_node =mdp4_detect_lcdc_panel (dev); +if (IS_ERR_OR_NULL (panel_node)) +return PTR_ERR (panel_node); + + encoder =mdp4_lcdc_encoder_init (dev, panel_node);if (IS_ERR (encoder)) {dev_err (dev->dev,"failed to construct LCDC encoder\n" );return PTR_ERR (encoder);
@@ -297,7 +295,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */ encoder->possible_crtcs =1 <<DMA_P ; - connector =mdp4_lvds_connector_init (dev, panel, encoder); + connector =mdp4_lvds_connector_init (dev, panel_node, encoder);if (IS_ERR (connector)) {dev_err (dev->dev,"failed to initialize LVDS connector\n" );return PTR_ERR (connector);
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +2 -2
@@ -212,10 +212,10 @@ struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);long mdp4_lcdc_round_pixclk (struct drm_encoder *encoder,unsigned long rate);struct drm_encoder *mdp4_lcdc_encoder_init (struct drm_device *dev, -struct drm_panel *panel); +struct device_node *panel_node);struct drm_connector *mdp4_lvds_connector_init (struct drm_device *dev, -struct drm_panel *panel,struct drm_encoder *encoder); +struct device_node *panel_node,struct drm_encoder *encoder);#ifdef CONFIG_COMMON_CLK struct clk *mpd4_lvds_pll_init (struct drm_device *dev);
drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c +7 -4
@@ -23,6 +23,7 @@struct mdp4_lcdc_encoder {struct drm_encoder base; +struct device_node *panel_node;struct drm_panel *panel;struct clk *lcdc_clk;unsigned long int pixclock;
@@ -338,7 +339,7 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =to_mdp4_lcdc_encoder (encoder);struct mdp4_kms *mdp4_kms =get_kms (encoder); -struct drm_panel *panel = mdp4_lcdc_encoder->panel; +struct drm_panel *panel;int i, ret;if (WARN_ON (!mdp4_lcdc_encoder->enabled))
@@ -346,6 +347,7 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)mdp4_write (mdp4_kms,REG_MDP4_LCDC_ENABLE ,0 ); + panel =of_drm_find_panel (mdp4_lcdc_encoder->panel_node);if (panel) {drm_panel_disable (panel);drm_panel_unprepare (panel);
@@ -381,7 +383,7 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)to_mdp4_lcdc_encoder (encoder);unsigned long pc = mdp4_lcdc_encoder->pixclock;struct mdp4_kms *mdp4_kms =get_kms (encoder); -struct drm_panel *panel = mdp4_lcdc_encoder->panel; +struct drm_panel *panel;int i, ret;if (WARN_ON (mdp4_lcdc_encoder->enabled))
@@ -414,6 +416,7 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)if (ret)dev_err (dev->dev,"failed to enable lcdc_clk: %d\n" , ret); + panel =of_drm_find_panel (mdp4_lcdc_encoder->panel_node);if (panel) {drm_panel_prepare (panel);drm_panel_enable (panel);
@@ -442,7 +445,7 @@ long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate)/* initialize encoder */ struct drm_encoder *mdp4_lcdc_encoder_init (struct drm_device *dev, -struct drm_panel *panel) +struct device_node *panel_node) {struct drm_encoder *encoder =NULL ;struct mdp4_lcdc_encoder *mdp4_lcdc_encoder;
@@ -455,7 +458,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, goto fail; } - mdp4_lcdc_encoder->panel = panel; + mdp4_lcdc_encoder->panel_node = panel_node; encoder = &mdp4_lcdc_encoder->base;
drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c +13 -10
@@ -23,6 +23,7 @@struct mdp4_lvds_connector {struct drm_connector base;struct drm_encoder *encoder; +struct device_node *panel_node;struct drm_panel *panel; };#define to_mdp4_lvds_connector (x) container_of(x, struct mdp4_lvds_connector, base)
@@ -33,6 +34,10 @@ static enum drm_connector_status mdp4_lvds_connector_detect(struct mdp4_lvds_connector *mdp4_lvds_connector =to_mdp4_lvds_connector (connector); +if (!mdp4_lvds_connector->panel) + mdp4_lvds_connector->panel = +of_drm_find_panel (mdp4_lvds_connector->panel_node); +return mdp4_lvds_connector->panel ? connector_status_connected : connector_status_disconnected;
@@ -42,10 +47,6 @@ static void mdp4_lvds_connector_destroy(struct drm_connector *connector) {struct mdp4_lvds_connector *mdp4_lvds_connector =to_mdp4_lvds_connector (connector); -struct drm_panel *panel = mdp4_lvds_connector->panel; - -if (panel) -drm_panel_detach (panel);drm_connector_unregister (connector);drm_connector_cleanup (connector);
@@ -60,9 +61,14 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)struct drm_panel *panel = mdp4_lvds_connector->panel;int ret =0 ; -if (panel) +if (panel) { +drm_panel_attach (panel, connector); + ret = panel->funcs->get_modes (panel); +drm_panel_detach (panel); + } +return ret; }
@@ -111,7 +117,7 @@ static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs/* initialize connector */ struct drm_connector *mdp4_lvds_connector_init (struct drm_device *dev, -struct drm_panel *panel,struct drm_encoder *encoder) +struct device_node *panel_node,struct drm_encoder *encoder) {struct drm_connector *connector =NULL ;struct mdp4_lvds_connector *mdp4_lvds_connector;
@@ -124,7 +130,7 @@ struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, } mdp4_lvds_connector->encoder = encoder; - mdp4_lvds_connector->panel = panel; + mdp4_lvds_connector->panel_node = panel_node; connector = &mdp4_lvds_connector->base;
@@ -141,9 +147,6 @@ struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,drm_mode_connector_attach_encoder (connector, encoder); -if (panel) -drm_panel_attach (panel, connector); -return connector; fail:
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 3/5 drm/msm/dsi: Add a mdp4 encoder for DSI
In reply to Archit TanejaFrom: Vinay Simha BN <[email protected]>
Create an mdp4 incoder for DSI. Only DSI video mode is supported as of now.
--- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c | 198 ++++++++++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 9 ++ 3 files changed, 208 insertions(+) create mode 100644 drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c
drivers/gpu/drm/msm/Makefile +1 -0
@@ -54,6 +54,7 @@ msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ + mdp/mdp4/mdp4_dsi_encoder.o \ dsi/dsi_cfg.o \ dsi/dsi_host.o \ dsi/dsi_manager.o \
drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c new file +198 -0
198 lines not on this page · raw message
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +9 -0
@@ -217,6 +217,15 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,struct drm_connector *mdp4_lvds_connector_init (struct drm_device *dev,struct device_node *panel_node,struct drm_encoder *encoder); +#ifdef CONFIG_DRM_MSM_DSI +struct drm_encoder *mdp4_dsi_encoder_init (struct drm_device *dev); +#else +static inline struct drm_encoder *mdp4_dsi_encoder_init (struct drm_device *dev) +{ +return ERR_PTR (-ENODEV ); +} +#endif +#ifdef CONFIG_COMMON_CLK struct clk *mpd4_lvds_pll_init (struct drm_device *dev);#else
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH 4/5 drm/msm/mdp4: Call custom round_pixclk helper only if the encoder type is TMDS
In reply to Archit TanejaThe mdp_kms round_pixclk op creates problems when we have more interfaces in use. It calls the DTV encoder's helper by default.
Check on encoder type and call the corresponding encoder's func meant for rounding pixel clock. DSI and LVDS don't require rounding, so just return rate in their case.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +8 -1
@@ -169,7 +169,14 @@ static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, struct drm_encoder *encoder) {/* if we had >1 encoder, we'd need something more clever: */ -return mdp4_dtv_round_pixclk (encoder, rate); +switch (encoder->encoder_type) { +case DRM_MODE_ENCODER_TMDS : +return mdp4_dtv_round_pixclk (encoder, rate); +case DRM_MODE_ENCODER_LVDS : +case DRM_MODE_ENCODER_DSI : +default : +return rate; + } }static void mdp4_preclose (struct msm_kms *kms,struct drm_file *file)
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 5/5 drm/msm/mdp4: Initialize DSI encoders
In reply to Archit TanejaCreate DSI encoders during modeset_init. The 2 encoders should ideally be one command mode and one video mode DSI encoder respectively, but we don't support command mode yet. We just create 2 of the same because the dsi driver expects it, we end up using only the first one.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 37 ++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +36 -1
@@ -279,6 +279,8 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,struct drm_encoder *encoder;struct drm_connector *connector;struct device_node *panel_node; +struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM ]; +int i, dsi_id;int ret;switch (intf_type) {
@@ -334,12 +336,41 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, priv->encoders[priv->num_encoders++] = encoder;break ; +case DRM_MODE_ENCODER_DSI : +/* only DSI1 supported for now */ + dsi_id =0 ; + +if (!priv->dsi[dsi_id]) +break ; + +for (i =0 ; i <MSM_DSI_ENCODER_NUM ; i++) { + dsi_encs[i] =mdp4_dsi_encoder_init (dev); +if (IS_ERR (dsi_encs[i])) { + ret =PTR_ERR (dsi_encs[i]); +dev_err (dev->dev, +"failed to construct DSI encoder: %d\n" , + ret); +return ret; + } + +/* TODO: Add DMA_S later? */ + dsi_encs[i]->possible_crtcs =1 <<DMA_P ; + priv->encoders[priv->num_encoders++] = dsi_encs[i]; + } + + ret =msm_dsi_modeset_init (priv->dsi[dsi_id], dev, dsi_encs); +if (ret) { +dev_err (dev->dev,"failed to initialize DSI: %d\n" , + ret); +return ret; + } + +break ;default :dev_err (dev->dev,"Invalid or unsupported interface\n" );return -EINVAL ; } -return 0 ; }
@@ -364,6 +395,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) };static const int mdp4_intfs[] = {DRM_MODE_ENCODER_LVDS , +DRM_MODE_ENCODER_DSI ,DRM_MODE_ENCODER_TMDS , };
@@ -404,6 +436,9 @@ static int modeset_init(struct mdp4_kms *mdp4_kms)* we currently set up two relatively fixed paths: * * LCDC/LVDS path: RGB1 -> DMA_P -> LCDC -> LVDS +* or +* DSI path: RGB1 -> DMA_P -> DSI1 -> DSI Panel +* * DTV/HDMI path: RGB2 -> DMA_E -> DTV -> HDMI */
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel