summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
diff options
context:
space:
mode:
authorStephane Viau2014-11-18 18:49:49 +0100
committerRob Clark2014-11-21 14:57:19 +0100
commit0deed25b65aaf495e36818481cfc9f58dfa5cd3f (patch)
tree9cde5045561c7bf864a3c4d09c01ab59e2b1f74e /drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
parentdrm/msm/mdp5: set rate before enabling clk (diff)
downloadkernel-qcow2-linux-0deed25b65aaf495e36818481cfc9f58dfa5cd3f.tar.gz
kernel-qcow2-linux-0deed25b65aaf495e36818481cfc9f58dfa5cd3f.tar.xz
kernel-qcow2-linux-0deed25b65aaf495e36818481cfc9f58dfa5cd3f.zip
drm/msm: add multiple CRTC and overlay support
MDP5 currently support one single CRTC with its private pipe. This change allows the configuration of multiple CRTCs with the possibility to attach several public planes to these CRTCs. Signed-off-by: Stephane Viau <sviau@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c')
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index adb45419b08d..da248c2b4fe8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -28,9 +28,8 @@ static const char *iommu_ports[] = {
static int mdp5_hw_init(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- const struct mdp5_cfg_hw *hw_cfg;
struct drm_device *dev = mdp5_kms->dev;
- int i;
+ unsigned long flags;
pm_runtime_get_sync(dev->dev);
@@ -58,12 +57,11 @@ static int mdp5_hw_init(struct msm_kms *kms)
* care.
*/
+ spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0);
+ spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
- hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv);
-
- for (i = 0; i < hw_cfg->ctl.count; i++)
- mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(i), 0);
+ mdp5_ctlm_hw_reset(mdp5_kms->ctl_priv);
pm_runtime_put_sync(dev->dev);
@@ -92,6 +90,7 @@ static void mdp5_destroy(struct msm_kms *kms)
struct msm_mmu *mmu = mdp5_kms->mmu;
void *smp = mdp5_kms->smp_priv;
void *cfg = mdp5_kms->cfg_priv;
+ void *ctl = mdp5_kms->ctl_priv;
mdp5_irq_domain_fini(mdp5_kms);
@@ -99,7 +98,8 @@ static void mdp5_destroy(struct msm_kms *kms)
mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
mmu->funcs->destroy(mmu);
}
-
+ if (ctl)
+ mdp5_ctlm_destroy(ctl);
if (smp)
mdp5_smp_destroy(smp);
if (cfg)
@@ -154,6 +154,9 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
static const enum mdp5_pipe crtcs[] = {
SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
};
+ static const enum mdp5_pipe pub_planes[] = {
+ SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3,
+ };
struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private;
struct drm_encoder *encoder;
@@ -169,12 +172,13 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
if (ret)
goto fail;
- /* construct CRTCs: */
+ /* construct CRTCs and their private planes: */
for (i = 0; i < hw_cfg->pipe_rgb.count; i++) {
struct drm_plane *plane;
struct drm_crtc *crtc;
- plane = mdp5_plane_init(dev, crtcs[i], true);
+ plane = mdp5_plane_init(dev, crtcs[i], true,
+ hw_cfg->pipe_rgb.base[i]);
if (IS_ERR(plane)) {
ret = PTR_ERR(plane);
dev_err(dev->dev, "failed to construct plane for %s (%d)\n",
@@ -192,6 +196,20 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
priv->crtcs[priv->num_crtcs++] = crtc;
}
+ /* Construct public planes: */
+ for (i = 0; i < hw_cfg->pipe_vig.count; i++) {
+ struct drm_plane *plane;
+
+ plane = mdp5_plane_init(dev, pub_planes[i], false,
+ hw_cfg->pipe_vig.base[i]);
+ if (IS_ERR(plane)) {
+ ret = PTR_ERR(plane);
+ dev_err(dev->dev, "failed to construct %s plane: %d\n",
+ pipe2name(pub_planes[i]), ret);
+ goto fail;
+ }
+ }
+
/* Construct encoder for HDMI: */
encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
if (IS_ERR(encoder)) {
@@ -274,6 +292,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
goto fail;
}
+ spin_lock_init(&mdp5_kms->resource_lock);
+
mdp_kms_init(&mdp5_kms->base, &kms_funcs);
kms = &mdp5_kms->base.base;
@@ -348,6 +368,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
}
mdp5_kms->smp_priv = priv;
+ priv = mdp5_ctlm_init(dev, mdp5_kms->mmio, config->hw);
+ if (IS_ERR(priv)) {
+ ret = PTR_ERR(priv);
+ goto fail;
+ }
+ mdp5_kms->ctl_priv = priv;
+
/* make sure things are off before attaching iommu (bootloader could
* have left things on, in which case we'll start getting faults if
* we don't disable):