summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-01-28 00:47:17 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-28 00:47:16 -0800
commitc619082d26a71475d8d97edb573f7fc879982e65 (patch)
treec4b8720c877cdc8e01176d37bf8cff91fa751885
parentff528055ec669b0db90a7f5dae00fd101e57f4c8 (diff)
parentdf131b2a71acd57e96e23fe2c2bbd4867159cf48 (diff)
Merge "Revert "drm/msm: add smmu handler""
-rw-r--r--drivers/gpu/drm/msm/Makefile9
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c5
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c24
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h3
-rw-r--r--drivers/gpu/drm/msm/msm_mmu.h18
-rw-r--r--drivers/gpu/drm/msm/msm_smmu.c432
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c618
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.h79
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder.c556
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys.h93
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c25
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c559
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.h11
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c24
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_interrupts.c969
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_interrupts.h245
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_intf.c36
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_intf.h4
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_lm.c8
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c54
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h45
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c110
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h66
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_mdss.h62
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_sspp.c58
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_sspp.h18
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hwio.h3
-rw-r--r--drivers/gpu/drm/msm/sde/sde_irq.c240
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c287
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.h232
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms_utils.c173
-rw-r--r--drivers/gpu/drm/msm/sde/sde_mdp_formats.c134
-rw-r--r--drivers/gpu/drm/msm/sde/sde_mdp_formats.h123
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c720
34 files changed, 402 insertions, 5641 deletions
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 05b6ca9b5c55..f8984d673ff0 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -40,10 +40,7 @@ msm-y := \
mdp/mdp5/mdp5_smp.o \
sde/sde_crtc.o \
sde/sde_encoder.o \
- sde/sde_encoder_phys_vid.o \
- sde/sde_encoder_phys_cmd.o \
sde/sde_irq.o \
- sde/sde_kms_utils.o \
sde/sde_kms.o \
sde/sde_plane.o \
msm_atomic.o \
@@ -54,7 +51,6 @@ msm-y := \
msm_gem_submit.o \
msm_gpu.o \
msm_iommu.o \
- msm_smmu.o \
msm_perf.o \
msm_rd.o \
msm_ringbuffer.o
@@ -89,7 +85,4 @@ obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \
sde/sde_hw_mdp_util.o \
sde/sde_hw_sspp.o \
sde/sde_hw_wb.o \
- sde/sde_hw_pingpong.o \
- sde/sde_hw_mdp_top.o \
- sde/sde_hw_interrupts.o \
- sde/sde_mdp_formats.o
+ sde/sde_hw_pingpong.o
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 210cedb8134d..b532faa8026d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -595,8 +595,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
mdelay(16);
if (config->platform.iommu) {
- mmu = msm_smmu_new(&pdev->dev,
- MSM_SMMU_DOMAIN_UNSECURE);
+ mmu = msm_iommu_new(&pdev->dev, config->platform.iommu);
if (IS_ERR(mmu)) {
ret = PTR_ERR(mmu);
dev_err(dev->dev, "failed to init iommu: %d\n", ret);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 6fa56abf0c78..c76cc853b08a 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -295,23 +295,16 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
if (iommu_present(&platform_bus_type)) {
struct msm_mmu *mmu = priv->mmus[id];
+ uint32_t offset;
if (WARN_ON(!mmu))
return -EINVAL;
- if (obj->import_attach && mmu->funcs->map_dma_buf) {
- ret = mmu->funcs->map_dma_buf(mmu, msm_obj->sgt,
- obj->import_attach->dmabuf,
- DMA_BIDIRECTIONAL);
- if (ret) {
- DRM_ERROR("Unable to map dma buf\n");
- return ret;
- }
- }
- msm_obj->domain[id].iova =
- sg_dma_address(msm_obj->sgt->sgl);
+ offset = (uint32_t)mmap_offset(obj);
+ ret = mmu->funcs->map(mmu, offset, msm_obj->sgt,
+ obj->size, IOMMU_READ | IOMMU_WRITE);
+ msm_obj->domain[id].iova = offset;
} else {
- WARN_ONCE(1, "physical address being used\n");
msm_obj->domain[id].iova = physaddr(obj);
}
}
@@ -531,11 +524,8 @@ void msm_gem_free_object(struct drm_gem_object *obj)
for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) {
struct msm_mmu *mmu = priv->mmus[id];
if (mmu && msm_obj->domain[id].iova) {
- if (obj->import_attach && mmu->funcs->unmap_dma_buf) {
- mmu->funcs->unmap_dma_buf(mmu, msm_obj->sgt,
- obj->import_attach->dmabuf,
- DMA_BIDIRECTIONAL);
- }
+ uint32_t offset = msm_obj->domain[id].iova;
+ mmu->funcs->unmap(mmu, offset, msm_obj->sgt, obj->size);
}
}
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 2e4ae6b1c5d0..6fc59bfeedeb 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -53,7 +53,8 @@ struct msm_gem_object {
void *vaddr;
struct {
- dma_addr_t iova;
+ // XXX
+ uint32_t iova;
} domain[NUM_DOMAINS];
/* normally (resv == &_resv) except for imported bo's */
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 6d2f5627bfae..7cd88d9dc155 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -20,14 +20,6 @@
#include <linux/iommu.h>
-struct msm_mmu;
-struct msm_gpu;
-
-enum msm_mmu_domain_type {
- MSM_SMMU_DOMAIN_UNSECURE,
- MSM_SMMU_DOMAIN_MAX,
-};
-
struct msm_mmu_funcs {
int (*attach)(struct msm_mmu *mmu, const char **names, int cnt);
void (*detach)(struct msm_mmu *mmu, const char **names, int cnt);
@@ -35,14 +27,6 @@ struct msm_mmu_funcs {
unsigned len, int prot);
int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt,
unsigned len);
- int (*map_sg)(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir);
- void (*unmap_sg)(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir);
- int (*map_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir);
- void (*unmap_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir);
void (*destroy)(struct msm_mmu *mmu);
};
@@ -60,7 +44,5 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain);
struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu);
-struct msm_mmu *msm_smmu_new(struct device *dev,
- enum msm_mmu_domain_type domain);
#endif /* __MSM_MMU_H__ */
diff --git a/drivers/gpu/drm/msm/msm_smmu.c b/drivers/gpu/drm/msm/msm_smmu.c
deleted file mode 100644
index d51fbedf90c6..000000000000
--- a/drivers/gpu/drm/msm/msm_smmu.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/* Copyright (c) 2015-2017, 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.
- */
-
-#include <linux/module.h>
-#include <linux/of_platform.h>
-#include <linux/pm_runtime.h>
-#include <linux/msm_dma_iommu_mapping.h>
-
-#include <asm/dma-iommu.h>
-#include <soc/qcom/secure_buffer.h>
-
-#include "msm_drv.h"
-#include "msm_mmu.h"
-
-struct msm_smmu_client {
- struct device *dev;
- struct dma_iommu_mapping *mmu_mapping;
- bool domain_attached;
-};
-
-struct msm_smmu {
- struct msm_mmu base;
- struct device *client_dev;
- struct msm_smmu_client client;
-};
-
-struct msm_smmu_domain {
- const char *label;
- size_t va_start;
- size_t va_size;
- bool secure;
-};
-
-#define to_msm_smmu(x) container_of(x, struct msm_smmu, base)
-#define msm_smmu_to_client(smmu) (&smmu->client)
-
-static int _msm_smmu_create_mapping(struct msm_smmu_client *client,
- const struct msm_smmu_domain *domain);
-
-static int msm_smmu_attach(struct msm_mmu *mmu, const char **names, int cnt)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- int rc = 0;
-
- /* domain attach only once */
- if (client->domain_attached)
- return 0;
-
- rc = arm_iommu_attach_device(client->dev,
- client->mmu_mapping);
- if (rc) {
- dev_err(client->dev, "iommu attach dev failed (%d)\n",
- rc);
- return rc;
- }
-
- client->domain_attached = true;
-
- dev_dbg(client->dev, "iommu domain attached\n");
-
- return 0;
-}
-
-static void msm_smmu_detach(struct msm_mmu *mmu, const char **names, int cnt)
-{
- DBG("detaching");
-}
-
-static int msm_smmu_map(struct msm_mmu *mmu, uint32_t iova,
- struct sg_table *sgt, unsigned len, int prot)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- struct iommu_domain *domain;
- struct scatterlist *sg;
- unsigned int da = iova;
- unsigned int i, j;
- int ret;
-
- if (!client)
- return -ENODEV;
-
- domain = client->mmu_mapping->domain;
- if (!domain || !sgt)
- return -EINVAL;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- u32 pa = sg_phys(sg) - sg->offset;
- size_t bytes = sg->length + sg->offset;
-
- VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes);
-
- ret = iommu_map(domain, da, pa, bytes, prot);
- if (ret)
- goto fail;
-
- da += bytes;
- }
-
- return 0;
-
-fail:
- da = iova;
-
- for_each_sg(sgt->sgl, sg, i, j) {
- size_t bytes = sg->length + sg->offset;
-
- iommu_unmap(domain, da, bytes);
- da += bytes;
- }
- return ret;
-}
-
-static int msm_smmu_map_sg(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- int ret;
-
- ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, dir);
- if (ret != sgt->nents)
- return -ENOMEM;
-
- return 0;
-}
-
-static void msm_smmu_unmap_sg(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
-
- dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir);
-}
-
-static int msm_smmu_unmap(struct msm_mmu *mmu, uint32_t iova,
- struct sg_table *sgt, unsigned len)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- struct iommu_domain *domain;
- struct scatterlist *sg;
- unsigned int da = iova;
- int i;
-
- if (!client)
- return -ENODEV;
-
- domain = client->mmu_mapping->domain;
- if (!domain || !sgt)
- return -EINVAL;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes = sg->length + sg->offset;
- size_t unmapped;
-
- unmapped = iommu_unmap(domain, da, bytes);
- if (unmapped < bytes)
- return unmapped;
-
- VERB("unmap[%d]: %08x(%zx)", i, iova, bytes);
-
- WARN_ON(!PAGE_ALIGNED(bytes));
-
- da += bytes;
- }
-
- return 0;
-}
-
-static void msm_smmu_destroy(struct msm_mmu *mmu)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct platform_device *pdev = to_platform_device(smmu->client_dev);
-
- platform_device_unregister(pdev);
- kfree(smmu);
-}
-
-static int msm_smmu_map_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- int ret;
-
- ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, dir,
- dma_buf);
- if (ret != sgt->nents) {
- DRM_ERROR("dma map sg failed\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-
-static void msm_smmu_unmap_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
-
- msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir, dma_buf);
-}
-
-static const struct msm_mmu_funcs funcs = {
- .attach = msm_smmu_attach,
- .detach = msm_smmu_detach,
- .map = msm_smmu_map,
- .map_sg = msm_smmu_map_sg,
- .unmap_sg = msm_smmu_unmap_sg,
- .unmap = msm_smmu_unmap,
- .map_dma_buf = msm_smmu_map_dma_buf,
- .unmap_dma_buf = msm_smmu_unmap_dma_buf,
- .destroy = msm_smmu_destroy,
-};
-
-static struct msm_smmu_domain msm_smmu_domains[MSM_SMMU_DOMAIN_MAX] = {
- [MSM_SMMU_DOMAIN_UNSECURE] = {
- .label = "mdp_ns",
- .va_start = SZ_1M,
- .va_size = SZ_2G,
- },
-};
-
-static const struct of_device_id msm_smmu_dt_match[] = {
- { .compatible = "qcom,smmu_mdp_unsec",
- .data = &msm_smmu_domains[MSM_SMMU_DOMAIN_UNSECURE] },
- {}
-};
-MODULE_DEVICE_TABLE(of, msm_smmu_dt_match);
-
-static struct device *msm_smmu_device_create(struct device *dev,
- enum msm_mmu_domain_type domain,
- struct msm_smmu *smmu)
-{
- struct device_node *child;
- struct platform_device *pdev;
- int i;
- const char *compat = NULL;
-
- for (i = 0; i < ARRAY_SIZE(msm_smmu_dt_match); i++) {
- if (msm_smmu_dt_match[i].data == &msm_smmu_domains[domain]) {
- compat = msm_smmu_dt_match[i].compatible;
- break;
- }
- }
-
- if (!compat) {
- DRM_ERROR("unable to find matching domain for %d\n", domain);
- return ERR_PTR(-ENOENT);
- }
- DRM_INFO("found domain %d compat: %s\n", domain, compat);
-
- if (domain == MSM_SMMU_DOMAIN_UNSECURE) {
- int rc;
-
- smmu->client.dev = dev;
- rc = _msm_smmu_create_mapping(msm_smmu_to_client(smmu),
- msm_smmu_dt_match[i].data);
- if (rc)
- return ERR_PTR(rc);
-
- return NULL;
- }
-
- child = of_find_compatible_node(dev->of_node, NULL, compat);
- if (!child) {
- DRM_ERROR("unable to find compatible node for %s\n", compat);
- return ERR_PTR(-ENODEV);
- }
-
- pdev = of_platform_device_create(child, NULL, dev);
- if (!pdev) {
- DRM_ERROR("unable to create smmu platform dev for domain %d\n",
- domain);
- return ERR_PTR(-ENODEV);
- }
-
- return &pdev->dev;
-}
-
-struct msm_mmu *msm_smmu_new(struct device *dev,
- enum msm_mmu_domain_type domain)
-{
- struct msm_smmu *smmu;
- struct device *client_dev;
-
- smmu = kzalloc(sizeof(*smmu), GFP_KERNEL);
- if (!smmu)
- return ERR_PTR(-ENOMEM);
-
- client_dev = msm_smmu_device_create(dev, domain, smmu);
- if (IS_ERR(client_dev))
- return (void *)client_dev ? : ERR_PTR(-ENODEV);
-
- smmu->client_dev = client_dev;
- msm_mmu_init(&smmu->base, dev, &funcs);
-
- return &smmu->base;
-}
-
-static int _msm_smmu_create_mapping(struct msm_smmu_client *client,
- const struct msm_smmu_domain *domain)
-{
- int disable_htw = 1;
- int rc;
-
- client->mmu_mapping = arm_iommu_create_mapping(&platform_bus_type,
- domain->va_start, domain->va_size);
- if (IS_ERR(client->mmu_mapping)) {
- dev_err(client->dev,
- "iommu create mapping failed for domain=%s\n",
- domain->label);
- return PTR_ERR(client->mmu_mapping);
- }
-
- if (domain->secure) {
- int secure_vmid = VMID_CP_PIXEL;
-
- rc = iommu_domain_set_attr(client->mmu_mapping->domain,
- DOMAIN_ATTR_SECURE_VMID, &secure_vmid);
- if (rc) {
- dev_err(client->dev, "couldn't set secure pix vmid\n");
- goto error;
- }
- }
-
- return 0;
-
-error:
- arm_iommu_release_mapping(client->mmu_mapping);
- return rc;
-}
-
-/**
- * msm_smmu_probe()
- * @pdev: platform device
- *
- * Each smmu context acts as a separate device and the context banks are
- * configured with a VA range.
- * Registers the clks as each context bank has its own clks, for which voting
- * has to be done everytime before using that context bank.
- */
-static int msm_smmu_probe(struct platform_device *pdev)
-{
- const struct of_device_id *match;
- struct msm_smmu_client *client;
- const struct msm_smmu_domain *domain;
- int rc;
-
- match = of_match_device(msm_smmu_dt_match, &pdev->dev);
- if (!match || !match->data) {
- dev_err(&pdev->dev, "probe failed as match data is invalid\n");
- return -EINVAL;
- }
-
- domain = match->data;
- if (!domain) {
- dev_err(&pdev->dev, "no matching device found\n");
- return -EINVAL;
- }
-
- DRM_INFO("probing device %s\n", match->compatible);
-
- client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
-
- client->dev = &pdev->dev;
-
- rc = _msm_smmu_create_mapping(client, domain);
- platform_set_drvdata(pdev, client);
-
- return rc;
-}
-
-static int msm_smmu_remove(struct platform_device *pdev)
-{
- struct msm_smmu_client *client;
-
- client = platform_get_drvdata(pdev);
- if (client->domain_attached) {
- arm_iommu_detach_device(client->dev);
- client->domain_attached = false;
- }
- arm_iommu_release_mapping(client->mmu_mapping);
-
- return 0;
-}
-
-static struct platform_driver msm_smmu_driver = {
- .probe = msm_smmu_probe,
- .remove = msm_smmu_remove,
- .driver = {
- .name = "msmdrm_smmu",
- .of_match_table = msm_smmu_dt_match,
- },
-};
-
-static int __init msm_smmu_driver_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&msm_smmu_driver);
- if (ret)
- pr_err("mdss_smmu_register_driver() failed!\n");
-
- return ret;
-}
-module_init(msm_smmu_driver_init);
-
-static void __exit msm_smmu_driver_cleanup(void)
-{
- platform_driver_unregister(&msm_smmu_driver);
-}
-module_exit(msm_smmu_driver_cleanup);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MSM SMMU driver");
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 5fc1664fd9a0..3ddad6f59180 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-#include <linux/sort.h>
#include <drm/drm_mode.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
@@ -18,498 +17,73 @@
#include "sde_kms.h"
#include "sde_hw_lm.h"
-#include "sde_hw_mdp_ctl.h"
-#include "sde_crtc.h"
+#include "sde_hw_mdss.h"
-#define CTL(i) (CTL_0 + (i))
-#define LM(i) (LM_0 + (i))
-#define INTF(i) (INTF_0 + (i))
-
-static struct sde_kms *get_kms(struct drm_crtc *crtc)
-{
- struct msm_drm_private *priv = crtc->dev->dev_private;
- return to_sde_kms(priv->kms);
-}
-
-static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc,
- struct drm_encoder *encoder)
-{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct sde_kms *sde_kms = get_kms(crtc);
- struct sde_encoder_hw_resources enc_hw_res;
- const struct sde_hw_res_map *plat_hw_res_map;
- enum sde_lm unused_lm_id[CRTC_DUAL_MIXERS] = {0};
- enum sde_lm lm_idx;
- int i, count = 0;
-
- if (!sde_kms) {
- DBG("[%s] invalid kms", __func__);
- return -EINVAL;
- }
-
- if (!sde_kms->mmio)
- return -EINVAL;
-
- /* Get unused LMs */
- for (i = 0; i < sde_kms->catalog->mixer_count; i++) {
- if (!sde_rm_get_mixer(sde_kms, LM(i))) {
- unused_lm_id[count++] = LM(i);
- if (count == CRTC_DUAL_MIXERS)
- break;
- }
- }
-
- /* query encoder resources */
- sde_encoder_get_hw_resources(sde_crtc->encoder, &enc_hw_res);
-
- /* parse encoder hw resources, find CTL paths */
- for (i = CTL_0; i <= sde_kms->catalog->ctl_count; i++) {
- WARN_ON(sde_crtc->num_ctls > CRTC_DUAL_MIXERS);
- if (enc_hw_res.ctls[i]) {
- struct sde_crtc_mixer *mixer =
- &sde_crtc->mixer[sde_crtc->num_ctls];
- mixer->hw_ctl = sde_rm_get_ctl_path(sde_kms, i);
- if (IS_ERR_OR_NULL(mixer->hw_ctl)) {
- DBG("[%s], Invalid ctl_path", __func__);
- return -EACCES;
- }
- sde_crtc->num_ctls++;
- }
- }
-
- /* shortcut this process if encoder has no ctl paths */
- if (!sde_crtc->num_ctls)
- return 0;
-
- /*
- * Get default LMs if specified in platform config
- * other wise acquire the free LMs
- */
- for (i = INTF_0; i <= sde_kms->catalog->intf_count; i++) {
- if (enc_hw_res.intfs[i]) {
- struct sde_crtc_mixer *mixer =
- &sde_crtc->mixer[sde_crtc->num_mixers];
- plat_hw_res_map = sde_rm_get_res_map(sde_kms, i);
-
- lm_idx = plat_hw_res_map->lm;
- if (!lm_idx)
- lm_idx = unused_lm_id[sde_crtc->num_mixers];
-
- DBG("Acquiring LM %d", lm_idx);
- mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx);
- if (IS_ERR_OR_NULL(mixer->hw_lm)) {
- DBG("[%s], Invalid mixer", __func__);
- return -EACCES;
- }
- /* interface info */
- mixer->intf_idx = i;
- mixer->mode = enc_hw_res.intfs[i];
- sde_crtc->num_mixers++;
- }
- }
+struct sde_crtc {
+ struct drm_crtc base;
+ char name[8];
+ struct drm_plane *plane;
+ struct drm_plane *planes[8];
+ int id;
+ bool enabled;
+ enum sde_lm mixer;
+ enum sde_ctl ctl_path;
+};
- DBG("control paths %d, num_mixers %d, lm[0] %d, ctl[0] %d ",
- sde_crtc->num_ctls, sde_crtc->num_mixers,
- sde_crtc->mixer[0].hw_lm->idx,
- sde_crtc->mixer[0].hw_ctl->idx);
- if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS)
- DBG("lm[1] %d, ctl[1], %d",
- sde_crtc->mixer[1].hw_lm->idx,
- sde_crtc->mixer[1].hw_ctl->idx);
- return 0;
-}
+#define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
static void sde_crtc_destroy(struct drm_crtc *crtc)
{
struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- DBG("");
drm_crtc_cleanup(crtc);
kfree(sde_crtc);
}
+static void sde_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+}
+
static bool sde_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- DBG("");
return true;
}
-static void sde_crtc_mode_set_nofb(struct drm_crtc *crtc)
-{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct sde_crtc_mixer *mixer = sde_crtc->mixer;
- struct drm_device *dev = crtc->dev;
- struct sde_hw_mixer *lm;
- unsigned long flags;
- struct drm_display_mode *mode;
- struct sde_hw_mixer_cfg cfg;
- u32 mixer_width;
- int i;
- int rc;
-
- DBG("");
- if (WARN_ON(!crtc->state))
- return;
-
- mode = &crtc->state->adjusted_mode;
-
- DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
- sde_crtc->name, mode->base.id, mode->name,
- mode->vrefresh, mode->clock,
- mode->hdisplay, mode->hsync_start,
- mode->hsync_end, mode->htotal,
- mode->vdisplay, mode->vsync_start,
- mode->vsync_end, mode->vtotal,
- mode->type, mode->flags);
-
- /*
- * reserve mixer(s) if not already avaialable
- * if dual mode, mixer_width = half mode width
- * program mode configuration on mixer(s)
- */
- if ((sde_crtc->num_ctls == 0) ||
- (sde_crtc->num_mixers == 0)) {
- rc = sde_crtc_reserve_hw_resources(crtc, sde_crtc->encoder);
- if (rc) {
- dev_err(dev->dev, " error reserving HW resource for this CRTC\n");
- return;
- }
- }
-
- if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS)
- mixer_width = mode->hdisplay >> 1;
- else
- mixer_width = mode->hdisplay;
-
- spin_lock_irqsave(&sde_crtc->lm_lock, flags);
-
- for (i = 0; i < sde_crtc->num_mixers; i++) {
- lm = mixer[i].hw_lm;
- cfg.out_width = mixer_width;
- cfg.out_height = mode->vdisplay;
- cfg.right_mixer = (i == 0) ? false : true;
- cfg.flags = 0;
- lm->ops.setup_mixer_out(lm, &cfg);
- }
-
- spin_unlock_irqrestore(&sde_crtc->lm_lock, flags);
-}
-
-static void sde_crtc_get_blend_cfg(struct sde_hw_blend_cfg *cfg,
- struct sde_plane_state *pstate)
-{
- const struct mdp_format *format;
- struct drm_plane *plane;
-
- format = to_mdp_format(
- msm_framebuffer_format(pstate->base.fb));
- plane = pstate->base.plane;
-
- cfg->fg.alpha_sel = ALPHA_FG_CONST;
- cfg->bg.alpha_sel = ALPHA_BG_CONST;
- cfg->fg.const_alpha = pstate->alpha;
- cfg->bg.const_alpha = 0xFF - pstate->alpha;
-
- if (format->alpha_enable && pstate->premultiplied) {
- cfg->fg.alpha_sel = ALPHA_FG_CONST;
- cfg->bg.alpha_sel = ALPHA_FG_PIXEL;
- if (pstate->alpha != 0xff) {
- cfg->bg.const_alpha = pstate->alpha;
- cfg->bg.inv_alpha_sel = 1;
- cfg->bg.mod_alpha = 1;
- } else {
- cfg->bg.inv_mode_alpha = 1;
- }
- } else if (format->alpha_enable) {
- cfg->fg.alpha_sel = ALPHA_FG_PIXEL;
- cfg->bg.alpha_sel = ALPHA_FG_PIXEL;
- if (pstate->alpha != 0xff) {
- cfg->bg.const_alpha = pstate->alpha;
- cfg->fg.mod_alpha = 1;
- cfg->bg.inv_alpha_sel = 1;
- cfg->bg.mod_alpha = 1;
- cfg->bg.inv_mode_alpha = 1;
- } else {
- cfg->bg.inv_mode_alpha = 1;
- }
- }
-}
-
-static void blend_setup(struct drm_crtc *crtc)
-{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct sde_crtc_mixer *mixer = sde_crtc->mixer;
- struct drm_plane *plane;
- struct sde_plane_state *pstate, *pstates[SDE_STAGE_MAX] = {0};
- struct sde_hw_stage_cfg stage_cfg;
- struct sde_hw_blend_cfg blend;
- struct sde_hw_ctl *ctl;
- struct sde_hw_mixer *lm;
- u32 flush_mask = 0;
- unsigned long flags;
- int i, j, plane_cnt = 0;
-
- DBG("");
- spin_lock_irqsave(&sde_crtc->lm_lock, flags);
-
- /* ctl could be reserved already */
- if (!sde_crtc->num_ctls)
- goto out;
-
- /* initialize stage cfg */
- memset(&stage_cfg, 0, sizeof(stage_cfg));
- memset(&blend, 0, sizeof(blend));
-
- /* Collect all plane information */
- drm_atomic_crtc_for_each_plane(plane, crtc) {
- pstate = to_sde_plane_state(plane->state);
- pstates[pstate->stage] = pstate;
- plane_cnt++;
- for (i = 0; i < sde_crtc->num_mixers; i++) {
- stage_cfg.stage[pstate->stage][i] =
- sde_plane_pipe(plane);
-
- /* Cache the flushmask for this layer
- * sourcesplit is always enabled, so this layer will
- * be staged on both the mixers
- */
- ctl = mixer[i].hw_ctl;
- ctl->ops.get_bitmask_sspp(ctl, &flush_mask,
- sde_plane_pipe(plane));
- }
- }
-
- /*
- * If there is no base layer, enable border color.
- * currently border color is always black
- */
- if ((stage_cfg.stage[SDE_STAGE_BASE][0] == SSPP_NONE) &&
- plane_cnt) {
- stage_cfg.border_enable = 1;
- DBG("Border Color is enabled\n");
- }
-
- /* Program hw */
- for (i = 0; i < sde_crtc->num_mixers; i++) {
- if (!mixer[i].hw_lm)
- continue;
-
- if (!mixer[i].hw_ctl)
- continue;
-
- ctl = mixer[i].hw_ctl;
- lm = mixer[i].hw_lm;
-
- /* stage config */
- ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
- &stage_cfg);
- /* stage config flush mask */
- mixer[i].flush_mask = flush_mask;
- /* get the flush mask for mixer */
- ctl->ops.get_bitmask_mixer(ctl, &mixer[i].flush_mask,
- mixer[i].hw_lm->idx);
-
- /* blend config */
- for (j = SDE_STAGE_0; j < SDE_STAGE_MAX; j++) {
- if (!pstates[j])
- continue;
- sde_crtc_get_blend_cfg(&blend, pstates[j]);
- blend.fg.alpha_sel = ALPHA_FG_CONST;
- blend.bg.alpha_sel = ALPHA_BG_CONST;
- blend.fg.const_alpha = pstate->alpha;
- blend.bg.const_alpha = 0xFF - pstate->alpha;
- lm->ops.setup_blend_config(lm, j, &blend);
- }
- }
-out:
- spin_unlock_irqrestore(&sde_crtc->lm_lock, flags);
-}
-
-/* if file!=NULL, this is preclose potential cancel-flip path */
-static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct drm_pending_vblank_event *event;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- event = sde_crtc->event;
- if (event) {
- /* if regular vblank case (!file) or if cancel-flip from
- * preclose on file that requested flip, then send the
- * event:
- */
- if (!file || (event->base.file_priv == file)) {
- sde_crtc->event = NULL;
- DBG("%s: send event: %pK", sde_crtc->name, event);
- drm_send_vblank_event(dev, sde_crtc->id, event);
- }
- }
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-static void sde_crtc_vblank_cb(void *data)
-{
- struct drm_crtc *crtc = (struct drm_crtc *)data;
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- unsigned pending;
-
- /* unregister callback */
- sde_encoder_register_vblank_callback(sde_crtc->encoder, NULL, NULL);
-
- pending = atomic_xchg(&sde_crtc->pending, 0);
-
- if (pending & PENDING_FLIP)
- complete_flip(crtc, NULL);
-}
-
-static int frame_flushed(struct sde_crtc *sde_crtc)
+static int sde_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
{
- struct vsync_info vsync;
-
- /* encoder get vsync_info */
- /* if frame_count does not match frame is flushed */
- sde_encoder_get_vsync_info(sde_crtc->encoder, &vsync);
-
- return (vsync.frame_count & sde_crtc->vsync_count);
-
+ return 0;
}
-void sde_crtc_wait_for_commit_done(struct drm_crtc *crtc)
+static void sde_crtc_prepare(struct drm_crtc *crtc)
{
- struct drm_device *dev = crtc->dev;
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- u32 pending;
- int i, ret;
-
- /* ref count the vblank event */
- ret = drm_crtc_vblank_get(crtc);
- if (ret)
- return;
-
- /* register callback */
- sde_encoder_register_vblank_callback(sde_crtc->encoder,
- sde_crtc_vblank_cb,
- (void *)crtc);
-
- /* wait */
- pending = atomic_read(&sde_crtc->pending);
- if (pending & PENDING_FLIP) {
- wait_event_timeout(dev->vblank[drm_crtc_index(crtc)].queue,
- (frame_flushed(sde_crtc) != 0),
- msecs_to_jiffies(CRTC_MAX_WAIT_ONE_FRAME));
- if (ret <= 0)
- dev_warn(dev->dev, "vblank time out, crtc=%d\n",
- sde_crtc->id);
- }
-
- for (i = 0; i < sde_crtc->num_ctls; i++)
- sde_crtc->mixer[i].flush_mask = 0;
-
- /* release */
- drm_crtc_vblank_put(crtc);
}
-static void request_pending(struct drm_crtc *crtc, u32 pending)
+static void sde_crtc_commit(struct drm_crtc *crtc)
{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct vsync_info vsync;
-
- /* request vsync info, cache the current frame count */
- sde_encoder_get_vsync_info(sde_crtc->encoder, &vsync);
- sde_crtc->vsync_count = vsync.frame_count;
-
- atomic_or(pending, &sde_crtc->pending);
}
-/**
- * Flush the CTL PATH
- */
-static u32 crtc_flush_all(struct drm_crtc *crtc)
+static int sde_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct sde_hw_ctl *ctl;
- int i;
-
- DBG("");
-
- for (i = 0; i < sde_crtc->num_ctls; i++) {
- ctl = sde_crtc->mixer[i].hw_ctl;
- ctl->ops.get_bitmask_intf(ctl,
- &(sde_crtc->mixer[i].flush_mask),
- sde_crtc->mixer[i].intf_idx);
- DBG("Flushing CTL_ID %d, flush_mask %x", ctl->idx,
- sde_crtc->mixer[i].flush_mask);
- ctl->ops.setup_flush(ctl,
- sde_crtc->mixer[i].flush_mask);
- }
-
return 0;
}
-static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
+static void sde_crtc_load_lut(struct drm_crtc *crtc)
{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- unsigned long flags;
-
- DBG("");
-
- WARN_ON(sde_crtc->event);
-
- spin_lock_irqsave(&dev->event_lock, flags);
- sde_crtc->event = crtc->state->event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- /*
- * If no CTL has been allocated in sde_crtc_atomic_check(),
- * it means we are trying to flush a CRTC whose state is disabled:
- * nothing else needs to be done.
- */
- if (unlikely(!sde_crtc->num_ctls))
- return;
-
- blend_setup(crtc);
-
- /*
- * PP_DONE irq is only used by command mode for now.
- * It is better to request pending before FLUSH and START trigger
- * to make sure no pp_done irq missed.
- * This is safe because no pp_done will happen before SW trigger
- * in command mode.
- */
}
-static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
+static int sde_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *new_fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t page_flip_flags)
{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- unsigned long flags;
-
- DBG("%s: event: %pK", sde_crtc->name, crtc->state->event);
-
- WARN_ON(sde_crtc->event);
-
- spin_lock_irqsave(&dev->event_lock, flags);
- sde_crtc->event = crtc->state->event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- /*
- * If no CTL has been allocated in sde_crtc_atomic_check(),
- * it means we are trying to flush a CRTC whose state is disabled:
- * nothing else needs to be done.
- */
- if (unlikely(!sde_crtc->num_ctls))
- return;
-
- crtc_flush_all(crtc);
-
- request_pending(crtc, PENDING_FLIP);
+ return 0;
}
static int sde_crtc_set_property(struct drm_crtc *crtc,
@@ -518,111 +92,21 @@ static int sde_crtc_set_property(struct drm_crtc *crtc,
return -EINVAL;
}
-static int sde_crtc_cursor_set(struct drm_crtc *crtc,
- struct drm_file *file, uint32_t handle,
- uint32_t width, uint32_t height)
-{
- return 0;
-}
-
-static int sde_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
- return 0;
-}
-
-static void sde_crtc_disable(struct drm_crtc *crtc)
-{
- DBG("");
-}
-
-static void sde_crtc_enable(struct drm_crtc *crtc)
-{
- DBG("");
-}
-
-struct plane_state {
- struct drm_plane *plane;
- struct sde_plane_state *state;
-};
-
-static int pstate_cmp(const void *a, const void *b)
-{
- struct plane_state *pa = (struct plane_state *)a;
- struct plane_state *pb = (struct plane_state *)b;
-
- return pa->state->zpos - pb->state->zpos;
-}
-
-static int sde_crtc_atomic_check(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- struct sde_kms *sde_kms = get_kms(crtc);
- struct drm_plane *plane;
- struct drm_device *dev = crtc->dev;
- struct plane_state pstates[SDE_STAGE_MAX];
- int max_stages = CRTC_HW_MIXER_MAXSTAGES(sde_kms->catalog, 0);
- int cnt = 0, i;
-
- DBG("%s: check", sde_crtc->name);
-
- /* verify that there are not too many planes attached to crtc
- * and that we don't have conflicting mixer stages:
- */
- drm_atomic_crtc_state_for_each_plane(plane, state) {
- struct drm_plane_state *pstate;
-
- if (cnt >= (max_stages)) {
- dev_err(dev->dev, "too many planes!\n");
- return -EINVAL;
- }
-
- pstate = state->state->plane_states[drm_plane_index(plane)];
-
- /* plane might not have changed, in which case take
- * current state:
- */
- if (!pstate)
- pstate = plane->state;
- pstates[cnt].plane = plane;
- pstates[cnt].state = to_sde_plane_state(pstate);
-
- cnt++;
- }
-
- /* assign a stage based on sorted zpos property */
- sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
-
- for (i = 0; i < cnt; i++) {
- pstates[i].state->stage = SDE_STAGE_0 + i;
- DBG("%s: assign pipe %d on stage=%d", sde_crtc->name,
- sde_plane_pipe(pstates[i].plane),
- pstates[i].state->stage);
- }
-
- return 0;
-}
-
static const struct drm_crtc_funcs sde_crtc_funcs = {
- .set_config = drm_atomic_helper_set_config,
+ .set_config = drm_crtc_helper_set_config,
.destroy = sde_crtc_destroy,
- .page_flip = drm_atomic_helper_page_flip,
+ .page_flip = sde_crtc_page_flip,
.set_property = sde_crtc_set_property,
- .reset = drm_atomic_helper_crtc_reset,
- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
- .cursor_set = sde_crtc_cursor_set,
- .cursor_move = sde_crtc_cursor_move,
};
static const struct drm_crtc_helper_funcs sde_crtc_helper_funcs = {
+ .dpms = sde_crtc_dpms,
.mode_fixup = sde_crtc_mode_fixup,
- .mode_set_nofb = sde_crtc_mode_set_nofb,
- .disable = sde_crtc_disable,
- .enable = sde_crtc_enable,
- .atomic_check = sde_crtc_atomic_check,
- .atomic_begin = sde_crtc_atomic_begin,
- .atomic_flush = sde_crtc_atomic_flush,
+ .mode_set = sde_crtc_mode_set,
+ .prepare = sde_crtc_prepare,
+ .commit = sde_crtc_commit,
+ .mode_set_base = sde_crtc_mode_set_base,
+ .load_lut = sde_crtc_load_lut,
};
uint32_t sde_crtc_vblank(struct drm_crtc *crtc)
@@ -634,20 +118,20 @@ void sde_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file)
{
}
-static void sde_crtc_install_properties(struct drm_crtc *crtc,
- struct drm_mode_object *obj)
+void sde_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane)
{
}
+void sde_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane)
+{
+}
-/* initialize crtc */
struct drm_crtc *sde_crtc_init(struct drm_device *dev,
struct drm_encoder *encoder,
struct drm_plane *plane, int id)
{
struct drm_crtc *crtc = NULL;
struct sde_crtc *sde_crtc;
- int rc;
sde_crtc = kzalloc(sizeof(*sde_crtc), GFP_KERNEL);
if (!sde_crtc)
@@ -656,21 +140,9 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev,
crtc = &sde_crtc->base;
sde_crtc->id = id;
- sde_crtc->encoder = encoder;
-
- sde_crtc_install_properties(crtc, &crtc->base);
- drm_crtc_init_with_planes(dev, crtc, plane, NULL, &sde_crtc_funcs);
+ /* find out if we need one or two lms */
drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs);
- plane->crtc = crtc;
-
- rc = sde_crtc_reserve_hw_resources(crtc, encoder);
- if (rc) {
- dev_err(dev->dev, " error reserving HW resource for this CRTC\n");
- return ERR_PTR(-EINVAL);
- }
-
- DBG("%s: Successfully initialized crtc", __func__);
return crtc;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
deleted file mode 100644
index 9f14f999913d..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (c) 2015-2016, 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 _SDE_CRTC_H_
-#define _SDE_CRTC_H_
-
-#include "drm_crtc.h"
-
-#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
-
-#define CRTC_DUAL_MIXERS 2
-#define PENDING_FLIP 2
-/* worst case one frame wait time based on 30 FPS : 33.33ms*/
-#define CRTC_MAX_WAIT_ONE_FRAME 34
-#define CRTC_HW_MIXER_MAXSTAGES(c, idx) ((c)->mixer[idx].sblk->maxblendstages)
-
-/**
- * struct sde_crtc_mixer - stores the map for each virtual pipeline in the CRTC
- * @hw_dspp : DSPP HW Driver context
- * @hw_lm : LM HW Driver context
- * @hw_ctl : CTL Path HW driver context
- * @intf_idx : Interface idx
- * @mode : Interface mode Active/CMD
- * @flush_mask : Flush mask value for this commit
- */
-struct sde_crtc_mixer {
- struct sde_hw_dspp *hw_dspp;
- struct sde_hw_mixer *hw_lm;
- struct sde_hw_ctl *hw_ctl;
- enum sde_intf intf_idx;
- enum sde_intf_mode mode;
- u32 flush_mask;
-};
-
-/**
- * struct sde_crtc - virtualized CRTC data structure
- * @base : Base drm crtc structure
- * @name : ASCII description of this crtc
- * @encoder : Associated drm encoder object
- * @id : Unique crtc identifier
- * @lm_lock : LM register access spinlock
- * @num_ctls : Number of ctl paths in use
- * @num_mixers : Number of mixers in use
- * @mixer : List of active mixers
- * @event : Pointer to last received drm vblank event
- * @pending : Whether or not an update is pending
- * @vsync_count : Running count of received vsync events
- */
-struct sde_crtc {
- struct drm_crtc base;
- char name[8];
- struct drm_encoder *encoder;
- int id;
-
- spinlock_t lm_lock; /* protect registers */
-
- /* HW Resources reserved for the crtc */
- u32 num_ctls;
- u32 num_mixers;
- struct sde_crtc_mixer mixer[CRTC_DUAL_MIXERS];
-
- /*if there is a pending flip, these will be non-null */
- struct drm_pending_vblank_event *event;
- atomic_t pending;
- u32 vsync_count;
-};
-
-#define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
-
-#endif /* _SDE_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index ad72bca11669..11e13849d295 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -10,560 +10,86 @@
* GNU General Public License for more details.
*/
-#include "msm_drv.h"
#include "sde_kms.h"
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
-#include "sde_hwio.h"
-#include "sde_hw_catalog.h"
-#include "sde_hw_intf.h"
-#include "sde_hw_mdp_ctl.h"
-#include "sde_mdp_formats.h"
-
-#include "sde_encoder_phys.h"
-#include "display_manager.h"
-
-#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
-
-#ifdef CONFIG_QCOM_BUS_SCALING
-#include <linux/msm-bus.h>
-#include <linux/msm-bus-board.h>
-#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
- { \
- .src = MSM_BUS_MASTER_MDP_PORT0, \
- .dst = MSM_BUS_SLAVE_EBI_CH0, \
- .ab = (ab_val), \
- .ib = (ib_val), \
- }
-
-static struct msm_bus_vectors mdp_bus_vectors[] = {
- MDP_BUS_VECTOR_ENTRY(0, 0),
- MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000),
+struct sde_encoder {
+ struct drm_encoder base;
+ int intf;
};
+#define to_sde_encoder(x) container_of(x, struct sde_encoder, base)
-static struct msm_bus_paths mdp_bus_usecases[] = { {
- .num_paths = 1,
- .vectors =
- &mdp_bus_vectors[0],
- }, {
- .num_paths = 1,
- .vectors =
- &mdp_bus_vectors[1],
- }
-};
-
-static struct msm_bus_scale_pdata mdp_bus_scale_table = {
- .usecase = mdp_bus_usecases,
- .num_usecases = ARRAY_SIZE(mdp_bus_usecases),
- .name = "mdss_mdp",
-};
-
-static void bs_init(struct sde_encoder_virt *sde_enc)
-{
- sde_enc->bus_scaling_client =
- msm_bus_scale_register_client(&mdp_bus_scale_table);
- DBG("bus scale client: %08x", sde_enc->bus_scaling_client);
-}
-
-static void bs_fini(struct sde_encoder_virt *sde_enc)
+static void sde_encoder_destroy(struct drm_encoder *encoder)
{
- if (sde_enc->bus_scaling_client) {
- msm_bus_scale_unregister_client(sde_enc->bus_scaling_client);
- sde_enc->bus_scaling_client = 0;
- }
-}
+ struct sde_encoder *sde_encoder = to_sde_encoder(encoder);
-static void bs_set(struct sde_encoder_virt *sde_enc, int idx)
-{
- if (sde_enc->bus_scaling_client) {
- DBG("set bus scaling: %d", idx);
- idx = 1;
- msm_bus_scale_client_update_request(sde_enc->bus_scaling_client,
- idx);
- }
-}
-#else
-static void bs_init(struct sde_encoder_virt *sde_enc)
-{
+ drm_encoder_cleanup(encoder);
+ kfree(sde_encoder);
}
-static void bs_fini(struct sde_encoder_virt *sde_enc)
-{
-}
+static const struct drm_encoder_funcs sde_encoder_funcs = {
+ .destroy = sde_encoder_destroy,
+};
-static void bs_set(struct sde_encoder_virt *sde_enc, int idx)
+static void sde_encoder_dpms(struct drm_encoder *encoder, int mode)
{
}
-#endif
-void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
- struct sde_encoder_hw_resources *hw_res)
+static bool sde_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
-
- DBG("");
-
- if (!hw_res || !drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- /* Query resources used by phys encs, expected to be without overlap */
- memset(hw_res, 0, sizeof(*hw_res));
- for (i = 0; i < sde_enc->num_phys_encs; i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
- if (phys && phys->phys_ops.get_hw_resources)
- phys->phys_ops.get_hw_resources(phys, hw_res);
- }
-}
-
-static void sde_encoder_destroy(struct drm_encoder *drm_enc)
-{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- for (i = 0; i < ARRAY_SIZE(sde_enc->phys_encs); i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
- if (phys && phys->phys_ops.destroy) {
- phys->phys_ops.destroy(phys);
- --sde_enc->num_phys_encs;
- sde_enc->phys_encs[i] = NULL;
- }
- }
-
- if (sde_enc->num_phys_encs) {
- DRM_ERROR("Expected num_phys_encs to be 0 not %d\n",
- sde_enc->num_phys_encs);
- }
-
- drm_encoder_cleanup(drm_enc);
- bs_fini(sde_enc);
- kfree(sde_enc);
+ return true;
}
-static bool sde_encoder_virt_mode_fixup(struct drm_encoder *drm_enc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void sde_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
- bool ret = true;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return false;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- for (i = 0; i < sde_enc->num_phys_encs; i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
- if (phys && phys->phys_ops.mode_fixup) {
- ret =
- phys->phys_ops.mode_fixup(phys, mode,
- adjusted_mode);
- if (!ret) {
- DBG("Mode unsupported by phys_enc %d", i);
- break;
- }
-
- if (sde_enc->num_phys_encs > 1) {
- DBG("ModeFix only checking 1 phys_enc");
- break;
- }
- }
- }
-
- return ret;
}
-static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void sde_encoder_prepare(struct drm_encoder *encoder)
{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
- bool splitmode = false;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- /*
- * Panel is driven by two interfaces ,each interface drives half of
- * the horizontal
- */
- if (sde_enc->num_phys_encs == 2)
- splitmode = true;
-
- for (i = 0; i < sde_enc->num_phys_encs; i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
- if (phys) {
- phys->phys_ops.mode_set(phys,
- mode,
- adjusted_mode,
- splitmode);
- if (memcmp(mode, adjusted_mode, sizeof(*mode)) != 0)
- DRM_ERROR("adjusted modes not supported\n");
- }
- }
}
-static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
+static void sde_encoder_commit(struct drm_encoder *encoder)
{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
- bool splitmode = false;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- bs_set(sde_enc, 1);
-
- if (sde_enc->num_phys_encs == 2)
- splitmode = true;
-
-
- for (i = 0; i < sde_enc->num_phys_encs; i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
- if (phys && phys->phys_ops.enable)
-
- /* enable/disable dual interface top config */
- if (phys->phys_ops.enable_split_config)
- phys->phys_ops.enable_split_config(phys,
- splitmode);
- phys->phys_ops.enable(phys);
- }
-}
-
-static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
-{
- struct sde_encoder_virt *sde_enc = NULL;
- int i = 0;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- for (i = 0; i < sde_enc->num_phys_encs; i++) {
- struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
- if (phys && phys->phys_ops.disable)
- phys->phys_ops.disable(phys);
- }
-
- bs_set(sde_enc, 0);
}
static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = {
- .mode_fixup = sde_encoder_virt_mode_fixup,
- .mode_set = sde_encoder_virt_mode_set,
- .disable = sde_encoder_virt_disable,
- .enable = sde_encoder_virt_enable,
-};
-
-static const struct drm_encoder_funcs sde_encoder_funcs = {
- .destroy = sde_encoder_destroy,
+ .dpms = sde_encoder_dpms,
+ .mode_fixup = sde_encoder_mode_fixup,
+ .mode_set = sde_encoder_mode_set,
+ .prepare = sde_encoder_prepare,
+ .commit = sde_encoder_commit,
};
-static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
- enum sde_intf_type type, u32 controller_id)
-{
- int i = 0;
-
- DBG("");
-
- for (i = 0; i < catalog->intf_count; i++) {
- if (catalog->intf[i].type == type
- && catalog->intf[i].controller_id == controller_id) {
- return catalog->intf[i].id;
- }
- }
-
- return INTF_MAX;
-}
-
-static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc)
-{
- struct sde_encoder_virt *sde_enc = NULL;
- unsigned long lock_flags;
-
- DBG("");
-
- if (!drm_enc) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- sde_enc = to_sde_encoder_virt(drm_enc);
-
- spin_lock_irqsave(&sde_enc->spin_lock, lock_flags);
- if (sde_enc->kms_vblank_callback)
- sde_enc->kms_vblank_callback(sde_enc->kms_vblank_callback_data);
- spin_unlock_irqrestore(&sde_enc->spin_lock, lock_flags);
-}
-
-static int sde_encoder_virt_add_phys_vid_enc(struct sde_encoder_virt *sde_enc,
- struct sde_kms *sde_kms,
- enum sde_intf intf_idx,
- enum sde_ctl ctl_idx)
+/* initialize encoder */
+struct drm_encoder *sde_encoder_init(struct drm_device *dev, int intf)
{
- int ret = 0;
-
- DBG("");
-
- if (sde_enc->num_phys_encs >= ARRAY_SIZE(sde_enc->phys_encs)) {
- DRM_ERROR("Too many video encoders %d, unable to add\n",
- sde_enc->num_phys_encs);
- ret = -EINVAL;
- } else {
- struct sde_encoder_virt_ops parent_ops = {
- sde_encoder_vblank_callback
- };
- struct sde_encoder_phys *enc =
- sde_encoder_phys_vid_init(sde_kms, intf_idx, ctl_idx,
- &sde_enc->base,
- parent_ops);
- if (IS_ERR(enc))
- ret = PTR_ERR(enc);
-
- if (!ret) {
- sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
- ++sde_enc->num_phys_encs;
- }
- }
-
- return ret;
-}
-
-static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
- struct sde_kms *sde_kms,
- struct display_info *disp_info,
- int *drm_enc_mode)
-{
- int ret = 0;
- int i = 0;
- enum sde_intf_type intf_type = INTF_NONE;
-
- DBG("");
-
- if (disp_info->intf == DISPLAY_INTF_DSI) {
- *drm_enc_mode = DRM_MODE_ENCODER_DSI;
- intf_type = INTF_DSI;
- } else if (disp_info->intf == DISPLAY_INTF_HDMI) {
- *drm_enc_mode = DRM_MODE_ENCODER_TMDS;
- intf_type = INTF_HDMI;
- } else {
- DRM_ERROR("Unsupported display interface type");
- return -EINVAL;
- }
-
- WARN_ON(disp_info->num_of_h_tiles < 1);
-
- DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles);
-
- for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
- /*
- * Left-most tile is at index 0, content is controller id
- * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right
- * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right
- */
- const struct sde_hw_res_map *hw_res_map = NULL;
- enum sde_intf intf_idx = INTF_MAX;
- enum sde_ctl ctl_idx = CTL_MAX;
- u32 controller_id = disp_info->h_tile_instance[i];
-
- DBG("h_tile_instance %d = %d", i, controller_id);
-
- intf_idx = sde_encoder_get_intf(sde_kms->catalog,
- intf_type, controller_id);
- if (intf_idx == INTF_MAX) {
- DBG("Error: could not get the interface id");
- ret = -EINVAL;
- }
-
- hw_res_map = sde_rm_get_res_map(sde_kms, intf_idx);
- if (IS_ERR_OR_NULL(hw_res_map))
- ret = -EINVAL;
- else
- ctl_idx = hw_res_map->ctl;
-
- /* Create both VID and CMD Phys Encoders here */
- if (!ret)
- ret = sde_encoder_virt_add_phys_vid_enc(
- sde_enc, sde_kms, intf_idx, ctl_idx);
- }
+ struct drm_encoder *encoder = NULL;
+ struct sde_encoder *sde_encoder;
+ int ret;
-
- return ret;
-}
-
-static struct drm_encoder *sde_encoder_virt_init(
- struct drm_device *dev, struct display_info *disp_info)
-{
- struct msm_drm_private *priv = dev->dev_private;
- struct sde_kms *sde_kms = to_sde_kms(priv->kms);
- struct drm_encoder *drm_enc = NULL;
- struct sde_encoder_virt *sde_enc = NULL;
- int drm_enc_mode = DRM_MODE_ENCODER_NONE;
- int ret = 0;
-
- DBG("");
-
- sde_enc = kzalloc(sizeof(*sde_enc), GFP_KERNEL);
- if (!sde_enc) {
+ sde_encoder = kzalloc(sizeof(*sde_encoder), GFP_KERNEL);
+ if (!sde_encoder) {
ret = -ENOMEM;
goto fail;
}
- ret = sde_encoder_setup_display(sde_enc, sde_kms, disp_info,
- &drm_enc_mode);
- if (ret)
- goto fail;
-
- spin_lock_init(&sde_enc->spin_lock);
- drm_enc = &sde_enc->base;
- drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode);
- drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
- bs_init(sde_enc);
+ sde_encoder->intf = intf;
+ encoder = &sde_encoder->base;
- DBG("Created encoder");
+ drm_encoder_init(dev, encoder, &sde_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+ drm_encoder_helper_add(encoder, &sde_encoder_helper_funcs);
- return drm_enc;
+ return encoder;
fail:
- DRM_ERROR("Failed to create encoder\n");
- if (drm_enc)
- sde_encoder_destroy(drm_enc);
+ if (encoder)
+ sde_encoder_destroy(encoder);
return ERR_PTR(ret);
}
-
-void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
- void (*cb)(void *), void *data)
-{
- struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
- unsigned long lock_flags;
-
- DBG("");
-
- spin_lock_irqsave(&sde_enc->spin_lock, lock_flags);
- sde_enc->kms_vblank_callback = cb;
- sde_enc->kms_vblank_callback_data = data;
- spin_unlock_irqrestore(&sde_enc->spin_lock, lock_flags);
-}
-
-void sde_encoder_get_vsync_info(struct drm_encoder *drm_enc,
- struct vsync_info *vsync)
-{
- struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
- struct sde_encoder_phys *phys;
-
- DBG("");
-
- if (!vsync) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- /* we get the vsync info from the intf at index 0: master index */
- phys = sde_enc->phys_encs[0];
- if (phys)
- phys->phys_ops.get_vsync_info(phys, vsync);
-}
-
-/* encoders init,
- * initialize encoder based on displays
- */
-void sde_encoders_init(struct drm_device *dev)
-{
- struct msm_drm_private *priv = NULL;
- struct display_manager *disp_man = NULL;
- u32 i = 0;
- u32 num_displays = 0;
-
- DBG("");
-
- if (!dev || !dev->dev_private) {
- DRM_ERROR("Invalid pointer");
- return;
- }
-
- priv = dev->dev_private;
- priv->num_encoders = 0;
- if (!priv->kms || !priv->dm) {
- DRM_ERROR("Invalid pointer");
- return;
- }
- disp_man = priv->dm;
-
- num_displays = display_manager_get_count(disp_man);
- DBG("num_displays %d", num_displays);
-
- if (num_displays > ARRAY_SIZE(priv->encoders)) {
- num_displays = ARRAY_SIZE(priv->encoders);
- DRM_ERROR("Too many displays found, capping to %d",
- num_displays);
- }
-
- for (i = 0; i < num_displays; i++) {
- struct display_info info = { 0 };
- struct drm_encoder *enc = NULL;
- u32 ret = 0;
-
- ret = display_manager_get_info_by_index(disp_man, i, &info);
- if (ret) {
- DRM_ERROR("Failed to get display info, %d", ret);
- return;
- }
-
- enc = sde_encoder_virt_init(dev, &info);
- if (IS_ERR_OR_NULL(enc)) {
- DRM_ERROR("Encoder initialization failed");
- return;
- }
-
- ret = display_manager_drm_init_by_index(disp_man, i, enc);
- if (ret) {
- DRM_ERROR("Display drm_init failed, %d", ret);
- return;
- }
-
- priv->encoders[priv->num_encoders++] = enc;
- }
-}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
deleted file mode 100644
index d35e084f9bef..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015-2016 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 __SDE_ENCODER_PHYS_H__
-#define __SDE_ENCODER_PHYS_H__
-
-#include "sde_kms.h"
-#include "sde_hw_intf.h"
-#include "sde_hw_mdp_ctl.h"
-
-#define MAX_PHYS_ENCODERS_PER_VIRTUAL 4
-
-struct sde_encoder_phys;
-
-struct sde_encoder_virt_ops {
- void (*handle_vblank_virt)(struct drm_encoder *);
-};
-
-struct sde_encoder_phys_ops {
- void (*mode_set)(struct sde_encoder_phys *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- bool splitmode);
- bool (*mode_fixup)(struct sde_encoder_phys *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
- void (*enable)(struct sde_encoder_phys *encoder);
- void (*disable)(struct sde_encoder_phys *encoder);
- void (*destroy)(struct sde_encoder_phys *encoder);
- void (*get_hw_resources)(struct sde_encoder_phys *encoder,
- struct sde_encoder_hw_resources *hw_res);
- void (*get_vsync_info)(struct sde_encoder_phys *enc,
- struct vsync_info *vsync);
- void (*enable_split_config)(struct sde_encoder_phys *enc,
- bool enable);
-};
-
-struct sde_encoder_phys {
- struct drm_encoder *parent;
- struct sde_encoder_virt_ops parent_ops;
- struct sde_encoder_phys_ops phys_ops;
- struct sde_hw_intf *hw_intf;
- struct sde_hw_ctl *hw_ctl;
- struct sde_kms *sde_kms;
- struct drm_display_mode cached_mode;
- bool enabled;
- spinlock_t spin_lock;
-};
-
-/**
- * struct sde_encoder_phys_vid - sub-class of sde_encoder_phys to handle video
- * mode specific operations
- * @base: Baseclass physical encoder structure
- * @irq_idx: IRQ interface lookup index
- * @vblank_complete: for vblank irq synchronization
- */
-struct sde_encoder_phys_vid {
- struct sde_encoder_phys base;
- int irq_idx;
- struct completion vblank_complete;
-};
-
-struct sde_encoder_virt {
- struct drm_encoder base;
- spinlock_t spin_lock;
- uint32_t bus_scaling_client;
-
- int num_phys_encs;
- struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
-
- void (*kms_vblank_callback)(void *);
- void *kms_vblank_callback_data;
-};
-
-struct sde_encoder_phys *sde_encoder_phys_vid_init(struct sde_kms *sde_kms,
- enum sde_intf intf_idx,
- enum sde_ctl ctl_idx,
- struct drm_encoder *parent,
- struct sde_encoder_virt_ops
- parent_ops);
-
-#endif /* __sde_encoder_phys_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
deleted file mode 100644
index 693e1f33e7d8..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2015 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.
- *
- */
-
-#include "msm_drv.h"
-#include "sde_kms.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-
-#include "sde_hwio.h"
-#include "sde_hw_catalog.h"
-#include "sde_hw_intf.h"
-#include "sde_mdp_formats.h"
-
-#include "sde_encoder_phys.h"
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
deleted file mode 100644
index aefa11d5cdde..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/* Copyright (c) 2015-2016, 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.
- */
-
-#include "msm_drv.h"
-#include "sde_kms.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-
-#include "sde_encoder_phys.h"
-#include "sde_mdp_formats.h"
-#include "sde_hw_mdp_top.h"
-
-#define VBLANK_TIMEOUT msecs_to_jiffies(100)
-
-#define to_sde_encoder_phys_vid(x) \
- container_of(x, struct sde_encoder_phys_vid, base)
-
-static bool sde_encoder_phys_vid_is_master(
- struct sde_encoder_phys *phys_enc)
-{
- bool ret = true;
-
- return ret;
-}
-
-static void sde_encoder_phys_vid_wait_for_vblank(
- struct sde_encoder_phys_vid *vid_enc)
-{
- int rc = 0;
-
- DBG("");
- rc = wait_for_completion_timeout(&vid_enc->vblank_complete,
- VBLANK_TIMEOUT);
- if (rc == 0)
- DRM_ERROR("Timed out waiting for vblank irq\n");
-}
-
-static void drm_mode_to_intf_timing_params(
- const struct sde_encoder_phys *phys_enc,
- const struct drm_display_mode *mode,
- struct intf_timing_params *timing)
-{
- memset(timing, 0, sizeof(*timing));
- /*
- * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html
- * Active Region Front Porch Sync Back Porch
- * <-----------------><------------><-----><----------->
- * <- [hv]display --->
- * <--------- [hv]sync_start ------>
- * <----------------- [hv]sync_end ------->
- * <---------------------------- [hv]total ------------->
- */
- timing->width = mode->hdisplay; /* active width */
- timing->height = mode->vdisplay; /* active height */
- timing->xres = timing->width;
- timing->yres = timing->height;
- timing->h_back_porch = mode->htotal - mode->hsync_end;
- timing->h_front_porch = mode->hsync_start - mode->hdisplay;
- timing->v_back_porch = mode->vtotal - mode->vsync_end;
- timing->v_front_porch = mode->vsync_start - mode->vdisplay;
- timing->hsync_pulse_width = mode->hsync_end - mode->hsync_start;
- timing->vsync_pulse_width = mode->vsync_end - mode->vsync_start;
- timing->hsync_polarity = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0;
- timing->vsync_polarity = (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
- timing->border_clr = 0;
- timing->underflow_clr = 0xff;
- timing->hsync_skew = mode->hskew;
-
- /* DSI controller cannot handle active-low sync signals. */
- if (phys_enc->hw_intf->cap->type == INTF_DSI) {
- timing->hsync_polarity = 0;
- timing->vsync_polarity = 0;
- }
-
- /*
- * For edp only:
- * DISPLAY_V_START = (VBP * HCYCLE) + HBP
- * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
- */
- /*
- * if (vid_enc->hw->cap->type == INTF_EDP) {
- * display_v_start += mode->htotal - mode->hsync_start;
- * display_v_end -= mode->hsync_start - mode->hdisplay;
- * }
- */
-}
-
-static inline u32 get_horizontal_total(const struct intf_timing_params *timing)
-{
- u32 active = timing->xres;
- u32 inactive =
- timing->h_back_porch + timing->h_front_porch +
- timing->hsync_pulse_width;
- return active + inactive;
-}
-
-static inline u32 get_vertical_total(const struct intf_timing_params *timing)
-{
- u32 active = timing->yres;
- u32 inactive =
- timing->v_back_porch + timing->v_front_porch +
- timing->vsync_pulse_width;
- return active + inactive;
-}
-
-/*
- * programmable_fetch_get_num_lines:
- * Number of fetch lines in vertical front porch
- * @timing: Pointer to the intf timing information for the requested mode
- *
- * Returns the number of fetch lines in vertical front porch at which mdp
- * can start fetching the next frame.
- *
- * Number of needed prefetch lines is anything that cannot be absorbed in the
- * start of frame time (back porch + vsync pulse width).
- *
- * Some panels have very large VFP, however we only need a total number of
- * lines based on the chip worst case latencies.
- */
-static u32 programmable_fetch_get_num_lines(
- struct sde_encoder_phys *phys_enc,
- const struct intf_timing_params *timing)
-{
- u32 worst_case_needed_lines =
- phys_enc->hw_intf->cap->prog_fetch_lines_worst_case;
- u32 start_of_frame_lines =
- timing->v_back_porch + timing->vsync_pulse_width;
- u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines;
- u32 actual_vfp_lines = 0;
-
- /* Fetch must be outside active lines, otherwise undefined. */
-
- if (start_of_frame_lines >= worst_case_needed_lines) {
- DBG("Programmable fetch is not needed due to large vbp+vsw");
- actual_vfp_lines = 0;
- } else if (timing->v_front_porch < needed_vfp_lines) {
- /* Warn fetch needed, but not enough porch in panel config */
- pr_warn_once
- ("low vbp+vfp may lead to perf issues in some cases\n");
- DBG("Less vfp than fetch requires, using entire vfp");
- actual_vfp_lines = timing->v_front_porch;
- } else {
- DBG("Room in vfp for needed prefetch");
- actual_vfp_lines = needed_vfp_lines;
- }
-
- DBG("v_front_porch %u v_back_porch %u vsync_pulse_width %u",
- timing->v_front_porch, timing->v_back_porch,
- timing->vsync_pulse_width);
- DBG("wc_lines %u needed_vfp_lines %u actual_vfp_lines %u",
- worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines);
-
- return actual_vfp_lines;
-}
-
-/*
- * programmable_fetch_config: Programs HW to prefetch lines by offsetting
- * the start of fetch into the vertical front porch for cases where the
- * vsync pulse width and vertical back porch time is insufficient
- *
- * Gets # of lines to pre-fetch, then calculate VSYNC counter value.
- * HW layer requires VSYNC counter of first pixel of tgt VFP line.
- *
- * @timing: Pointer to the intf timing information for the requested mode
- */
-static void programmable_fetch_config(struct sde_encoder_phys *phys_enc,
- const struct intf_timing_params *timing)
-{
- struct intf_prog_fetch f = { 0 };
- u32 vfp_fetch_lines = 0;
- u32 horiz_total = 0;
- u32 vert_total = 0;
- u32 vfp_fetch_start_vsync_counter = 0;
- unsigned long lock_flags;
-
- if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch))
- return;
-
- vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing);
- if (vfp_fetch_lines) {
- vert_total = get_vertical_total(timing);
- horiz_total = get_horizontal_total(timing);
- vfp_fetch_start_vsync_counter =
- (vert_total - vfp_fetch_lines) * horiz_total + 1;
- f.enable = 1;
- f.fetch_start = vfp_fetch_start_vsync_counter;
- }
-
- DBG("vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u",
- vfp_fetch_lines, vfp_fetch_start_vsync_counter);
-
- spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
- phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f);
- spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
-}
-
-static bool sde_encoder_phys_vid_mode_fixup(
- struct sde_encoder_phys *phys_enc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- DBG("");
-
- /*
- * Modifying mode has consequences when the mode comes back to us
- */
- return true;
-}
-
-static void sde_encoder_phys_vid_flush_intf(struct sde_encoder_phys *phys_enc)
-{
- struct sde_hw_intf *intf = phys_enc->hw_intf;
- struct sde_hw_ctl *ctl = phys_enc->hw_ctl;
- u32 flush_mask = 0;
-
- DBG("");
-
- ctl->ops.get_bitmask_intf(ctl, &flush_mask, intf->idx);
- ctl->ops.setup_flush(ctl, flush_mask);
-
- DBG("Flushing CTL_ID %d, flush_mask %x, INTF %d",
- ctl->idx, flush_mask, intf->idx);
-}
-
-static void sde_encoder_phys_vid_mode_set(struct sde_encoder_phys *phys_enc,
- struct drm_display_mode *mode,
- struct drm_display_mode
- *adjusted_mode,
- bool splitmode)
-{
- mode = adjusted_mode;
- phys_enc->cached_mode = *adjusted_mode;
- if (splitmode) {
- phys_enc->cached_mode.hdisplay >>= 1;
- phys_enc->cached_mode.htotal >>= 1;
- phys_enc->cached_mode.hsync_start >>= 1;
- phys_enc->cached_mode.hsync_end >>= 1;
- }
-
- DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
- mode->base.id, mode->name, mode->vrefresh, mode->clock,
- mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
- mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
- mode->type, mode->flags);
-}
-
-static void sde_encoder_phys_vid_setup_timing_engine(
- struct sde_encoder_phys *phys_enc)
-{
- struct drm_display_mode *mode = &phys_enc->cached_mode;
- struct intf_timing_params p = { 0 };
- struct sde_mdp_format_params *sde_fmt_params = NULL;
- u32 fmt_fourcc = DRM_FORMAT_RGB888;
- u32 fmt_mod = 0;
- unsigned long lock_flags;
- struct sde_hw_intf_cfg intf_cfg = { 0 };
-
- if (WARN_ON(!phys_enc->hw_intf->ops.setup_timing_gen))
- return;
-
- if (WARN_ON(!phys_enc->hw_ctl->ops.setup_intf_cfg))
- return;
-
- DBG("enable mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
- mode->base.id, mode->name, mode->vrefresh, mode->clock,
- mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
- mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
- mode->type, mode->flags);
-
- drm_mode_to_intf_timing_params(phys_enc, mode, &p);
-
- sde_fmt_params = sde_mdp_get_format_params(fmt_fourcc, fmt_mod);
-
- intf_cfg.intf = phys_enc->hw_intf->idx;
- intf_cfg.wb = SDE_NONE;
-
- spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
- phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf, &p,
- sde_fmt_params);
- phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
- spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
-
- programmable_fetch_config(phys_enc, &p);
-}
-
-static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
-{
- struct sde_encoder_phys_vid *vid_enc = arg;
- struct sde_encoder_phys *phys_enc = &vid_enc->base;
-
- phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent);
-
- /* signal VBLANK completion */
- complete_all(&vid_enc->vblank_complete);
-}
-
-static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc)
-{
- struct sde_encoder_phys_vid *vid_enc =
- to_sde_encoder_phys_vid(phys_enc);
- struct sde_irq_callback irq_cb;
- int ret = 0;
-
- vid_enc->irq_idx = sde_irq_idx_lookup(phys_enc->sde_kms,
- SDE_IRQ_TYPE_INTF_VSYNC, phys_enc->hw_intf->idx);
- if (vid_enc->irq_idx < 0) {
- DRM_ERROR(
- "Failed to lookup IRQ index for INTF_VSYNC with intf=%d\n",
- phys_enc->hw_intf->idx);
- return -EINVAL;
- }
-
- irq_cb.func = sde_encoder_phys_vid_vblank_irq;
- irq_cb.arg = vid_enc;
- ret = sde_register_irq_callback(phys_enc->sde_kms, vid_enc->irq_idx,
- &irq_cb);
- if (ret) {
- DRM_ERROR("Failed to register IRQ callback INTF_VSYNC\n");
- return ret;
- }
-
- ret = sde_enable_irq(phys_enc->sde_kms, &vid_enc->irq_idx, 1);
- if (ret) {
- DRM_ERROR(
- "Failed to enable IRQ for INTF_VSYNC, intf %d, irq_idx=%d\n",
- phys_enc->hw_intf->idx,
- vid_enc->irq_idx);
- vid_enc->irq_idx = -EINVAL;
-
- /* Unregister callback on IRQ enable failure */
- sde_register_irq_callback(phys_enc->sde_kms, vid_enc->irq_idx,
- NULL);
- return ret;
- }
-
- DBG("Registered IRQ for intf %d, irq_idx=%d\n",
- phys_enc->hw_intf->idx,
- vid_enc->irq_idx);
-
- return ret;
-}
-
-static int sde_encoder_phys_vid_unregister_irq(
- struct sde_encoder_phys *phys_enc)
-{
- struct sde_encoder_phys_vid *vid_enc =
- to_sde_encoder_phys_vid(phys_enc);
-
- sde_register_irq_callback(phys_enc->sde_kms, vid_enc->irq_idx, NULL);
- sde_disable_irq(phys_enc->sde_kms, &vid_enc->irq_idx, 1);
-
- DBG("Un-Register IRQ for intf %d, irq_idx=%d\n",
- phys_enc->hw_intf->idx,
- vid_enc->irq_idx);
-
- return 0;
-}
-
-static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
-{
- int ret = 0;
-
- DBG("");
-
- if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
- return;
-
- sde_encoder_phys_vid_setup_timing_engine(phys_enc);
-
- sde_encoder_phys_vid_flush_intf(phys_enc);
-
- /* Register for interrupt unless we're the slave encoder */
- if (sde_encoder_phys_vid_is_master(phys_enc))
- ret = sde_encoder_phys_vid_register_irq(phys_enc);
-
- if (!ret && !phys_enc->enabled) {
- unsigned long lock_flags = 0;
-
- /* Now enable timing engine */
- spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
- phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1);
- spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
-
- phys_enc->enabled = true;
- }
-}
-
-static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
-{
- unsigned long lock_flags;
- struct sde_encoder_phys_vid *vid_enc =
- to_sde_encoder_phys_vid(phys_enc);
-
- DBG("");
-
- if (WARN_ON(!phys_enc->enabled))
- return;
-
- if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
- return;
-
- spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
- phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
- reinit_completion(&vid_enc->vblank_complete);
- spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
-
- /*
- * Wait for a vsync so we know the ENABLE=0 latched before
- * the (connector) source of the vsync's gets disabled,
- * otherwise we end up in a funny state if we re-enable
- * before the disable latches, which results that some of
- * the settings changes for the new modeset (like new
- * scanout buffer) don't latch properly..
- */
- sde_encoder_phys_vid_wait_for_vblank(vid_enc);
- sde_encoder_phys_vid_unregister_irq(phys_enc);
- phys_enc->enabled = false;
-}
-
-static void sde_encoder_phys_vid_destroy(struct sde_encoder_phys *phys_enc)
-{
- struct sde_encoder_phys_vid *vid_enc =
- to_sde_encoder_phys_vid(phys_enc);
- DBG("");
- kfree(phys_enc->hw_intf);
- kfree(vid_enc);
-}
-
-static void sde_encoder_phys_vid_get_hw_resources(
- struct sde_encoder_phys *phys_enc,
- struct sde_encoder_hw_resources *hw_res)
-{
- struct msm_drm_private *priv = phys_enc->parent->dev->dev_private;
- struct sde_kms *sde_kms = to_sde_kms(priv->kms);
- const struct sde_hw_res_map *hw_res_map;
-
- DBG("Intf %d\n", phys_enc->hw_intf->idx);
-
- hw_res->intfs[phys_enc->hw_intf->idx] = INTF_MODE_VIDEO;
- /*
- * defaults should not be in use,
- * otherwise signal/return failure
- */
- hw_res_map = sde_rm_get_res_map(sde_kms, phys_enc->hw_intf->idx);
-
- /* This is video mode panel so PINGPONG will be in by-pass mode
- * only assign ctl path.For cmd panel check if pp_split is
- * enabled, override default map
- */
- hw_res->ctls[hw_res_map->ctl] = true;
-}
-
-/**
- * video mode will use the intf (get_status)
- * cmd mode will use the pingpong (get_vsync_info)
- * to get this information
- */
-static void sde_encoder_intf_get_vsync_info(struct sde_encoder_phys *phys_enc,
- struct vsync_info *vsync)
-{
- struct intf_status status;
-
- DBG("");
- phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &status);
- vsync->frame_count = status.frame_count;
- vsync->line_count = status.line_count;
- DBG(" sde_encoder_intf_get_vsync_info, count %d", vsync->frame_count);
-}
-
-static void sde_encoder_intf_split_config(struct sde_encoder_phys *phys_enc,
- bool enable)
-{
- struct msm_drm_private *priv = phys_enc->parent->dev->dev_private;
- struct sde_kms *sde_kms = to_sde_kms(priv->kms);
- struct sde_hw_mdp *mdp = sde_hw_mdptop_init(MDP_TOP, sde_kms->mmio,
- sde_kms->catalog);
- struct split_pipe_cfg cfg;
-
- DBG("%p", mdp);
- cfg.en = true;
- cfg.mode = INTF_MODE_VIDEO;
- if (!IS_ERR_OR_NULL(mdp))
- mdp->ops.setup_split_pipe(mdp, &cfg);
-}
-
-static void sde_encoder_phys_vid_init_cbs(struct sde_encoder_phys_ops *ops)
-{
- ops->mode_set = sde_encoder_phys_vid_mode_set;
- ops->mode_fixup = sde_encoder_phys_vid_mode_fixup;
- ops->enable = sde_encoder_phys_vid_enable;
- ops->disable = sde_encoder_phys_vid_disable;
- ops->destroy = sde_encoder_phys_vid_destroy;
- ops->get_hw_resources = sde_encoder_phys_vid_get_hw_resources;
- ops->get_vsync_info = sde_encoder_intf_get_vsync_info;
- ops->enable_split_config = sde_encoder_intf_split_config;
-}
-
-struct sde_encoder_phys *sde_encoder_phys_vid_init(
- struct sde_kms *sde_kms,
- enum sde_intf intf_idx,
- enum sde_ctl ctl_idx,
- struct drm_encoder *parent,
- struct sde_encoder_virt_ops parent_ops)
-{
- struct sde_encoder_phys *phys_enc = NULL;
- struct sde_encoder_phys_vid *vid_enc = NULL;
- int ret = 0;
-
- DBG("");
-
- vid_enc = kzalloc(sizeof(*vid_enc), GFP_KERNEL);
- if (!vid_enc) {
- ret = -ENOMEM;
- goto fail;
- }
- vid_enc->irq_idx = -EINVAL;
- init_completion(&vid_enc->vblank_complete);
-
- phys_enc = &vid_enc->base;
-
- phys_enc->hw_intf =
- sde_hw_intf_init(intf_idx, sde_kms->mmio, sde_kms->catalog);
- if (!phys_enc->hw_intf) {
- ret = -ENOMEM;
- goto fail;
- }
-
- phys_enc->hw_ctl = sde_rm_acquire_ctl_path(sde_kms, ctl_idx);
- if (!phys_enc->hw_ctl) {
- ret = -ENOMEM;
- goto fail;
- }
-
- sde_encoder_phys_vid_init_cbs(&phys_enc->phys_ops);
- phys_enc->parent = parent;
- phys_enc->parent_ops = parent_ops;
- phys_enc->sde_kms = sde_kms;
- spin_lock_init(&phys_enc->spin_lock);
-
- DBG("Created sde_encoder_phys_vid for intf %d", phys_enc->hw_intf->idx);
-
- return phys_enc;
-
-fail:
- DRM_ERROR("Failed to create encoder\n");
- if (vid_enc)
- sde_encoder_phys_vid_destroy(phys_enc);
-
- return ERR_PTR(ret);
-}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
index 46972f2d5dfd..64751fa4fddf 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
@@ -282,10 +282,6 @@ struct sde_wb_sub_blocks {
u32 maxlinewidth;
};
-struct sde_mdss_base_cfg {
- SDE_HW_BLK_INFO;
-};
-
/* struct sde_mdp_cfg : MDP TOP-BLK instance info
* @id: index identifying this block
* @base: register base offset to mdss
@@ -375,14 +371,10 @@ struct sde_cdm_cfg {
* @base register offset of this block
* @features bit mask identifying sub-blocks/features
* @type: Interface type(DSI, DP, HDMI)
- * @controller_id: Controller Instance ID in case of multiple of intf type
- * @prog_fetch_lines_worst_case Worst case latency num lines needed to prefetch
*/
struct sde_intf_cfg {
SDE_HW_BLK_INFO;
u32 type; /* interface type*/
- u32 controller_id;
- u32 prog_fetch_lines_worst_case;
};
/**
@@ -415,9 +407,6 @@ struct sde_ad_cfg {
struct sde_mdss_cfg {
u32 hwversion;
- u32 mdss_count;
- struct sde_mdss_base_cfg mdss[MAX_BLOCKS];
-
u32 mdp_count;
struct sde_mdp_cfg mdp[MAX_BLOCKS];
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c
index 7fb5a0616838..a9a1f05a00eb 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c
@@ -146,10 +146,6 @@ static inline int set_cfg_1xx_init(struct sde_mdss_cfg *cfg)
/* Setup Register maps and defaults */
*cfg = (struct sde_mdss_cfg){
- .mdss_count = 1,
- .mdss = {
- {.id = MDP_TOP, .base = 0x00000000, .features = 0}
- },
.mdp_count = 1,
.mdp = {
{.id = MDP_TOP, .base = 0x00001000, .features = 0,
@@ -175,13 +171,13 @@ static inline int set_cfg_1xx_init(struct sde_mdss_cfg *cfg)
{.id = SSPP_VIG3, .base = 0x0000b000,
.features = VIG_17X_MASK, .sblk = &layer},
- {.id = SSPP_RGB0, .base = 0x00015000,
+ {.id = SSPP_RGB0, .base = 0x00001500,
.features = RGB_17X_MASK, .sblk = &layer},
- {.id = SSPP_RGB1, .base = 0x00017000,
+ {.id = SSPP_RGB1, .base = 0x00001700,
.features = RGB_17X_MASK, .sblk = &layer},
- {.id = SSPP_RGB2, .base = 0x00019000,
+ {.id = SSPP_RGB2, .base = 0x00001900,
.features = RGB_17X_MASK, .sblk = &layer},
- {.id = SSPP_RGB3, .base = 0x0001B000,
+ {.id = SSPP_RGB3, .base = 0x00001B00,
.features = RGB_17X_MASK, .sblk = &layer},
{.id = SSPP_DMA0, .base = 0x00025000,
@@ -248,17 +244,13 @@ static inline int set_cfg_1xx_init(struct sde_mdss_cfg *cfg)
.intf_count = 4,
.intf = {
{.id = INTF_0, .base = 0x0006B000,
- .type = INTF_NONE, .controller_id = 0,
- .prog_fetch_lines_worst_case = 21},
+ .type = INTF_NONE},
{.id = INTF_1, .base = 0x0006B800,
- .type = INTF_DSI, .controller_id = 0,
- .prog_fetch_lines_worst_case = 21},
+ .type = INTF_DSI},
{.id = INTF_2, .base = 0x0006C000,
- .type = INTF_DSI, .controller_id = 1,
- .prog_fetch_lines_worst_case = 21},
+ .type = INTF_DSI},
{.id = INTF_3, .base = 0x0006C800,
- .type = INTF_HDMI, .controller_id = 0,
- .prog_fetch_lines_worst_case = 21},
+ .type = INTF_HDMI},
},
.wb_count = 3,
.wb = {
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
deleted file mode 100644
index 99aa2e59dd85..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/* Copyright (c) 2016, 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.
- */
-
-#include <linux/bitops.h>
-#include <linux/slab.h>
-
-#include "sde_kms.h"
-#include "sde_hw_interrupts.h"
-#include "sde_hw_mdp_util.h"
-#include "sde_hw_mdss.h"
-
-/**
- * Register offsets in MDSS register file for the interrupt registers
- * w.r.t. to the MDSS base
- */
-#define HW_INTR_STATUS 0x0010
-#define MDP_SSPP_TOP0_OFF 0x1000
-#define MDP_INTF_0_OFF 0x6B000
-#define MDP_INTF_1_OFF 0x6B800
-#define MDP_INTF_2_OFF 0x6C000
-#define MDP_INTF_3_OFF 0x6C800
-#define MDP_INTF_4_OFF 0x6D000
-
-/**
- * WB interrupt status bit definitions
- */
-#define SDE_INTR_WB_0_DONE BIT(0)
-#define SDE_INTR_WB_1_DONE BIT(1)
-#define SDE_INTR_WB_2_DONE BIT(4)
-
-/**
- * WDOG timer interrupt status bit definitions
- */
-#define SDE_INTR_WD_TIMER_0_DONE BIT(2)
-#define SDE_INTR_WD_TIMER_1_DONE BIT(3)
-#define SDE_INTR_WD_TIMER_2_DONE BIT(5)
-#define SDE_INTR_WD_TIMER_3_DONE BIT(6)
-#define SDE_INTR_WD_TIMER_4_DONE BIT(7)
-
-/**
- * Pingpong interrupt status bit definitions
- */
-#define SDE_INTR_PING_PONG_0_DONE BIT(8)
-#define SDE_INTR_PING_PONG_1_DONE BIT(9)
-#define SDE_INTR_PING_PONG_2_DONE BIT(10)
-#define SDE_INTR_PING_PONG_3_DONE BIT(11)
-#define SDE_INTR_PING_PONG_0_RD_PTR BIT(12)
-#define SDE_INTR_PING_PONG_1_RD_PTR BIT(13)
-#define SDE_INTR_PING_PONG_2_RD_PTR BIT(14)
-#define SDE_INTR_PING_PONG_3_RD_PTR BIT(15)
-#define SDE_INTR_PING_PONG_0_WR_PTR BIT(16)
-#define SDE_INTR_PING_PONG_1_WR_PTR BIT(17)
-#define SDE_INTR_PING_PONG_2_WR_PTR BIT(18)
-#define SDE_INTR_PING_PONG_3_WR_PTR BIT(19)
-#define SDE_INTR_PING_PONG_0_AUTOREFRESH_DONE BIT(20)
-#define SDE_INTR_PING_PONG_1_AUTOREFRESH_DONE BIT(21)
-#define SDE_INTR_PING_PONG_2_AUTOREFRESH_DONE BIT(22)
-#define SDE_INTR_PING_PONG_3_AUTOREFRESH_DONE BIT(23)
-
-/**
- * Interface interrupt status bit definitions
- */
-#define SDE_INTR_INTF_0_UNDERRUN BIT(24)
-#define SDE_INTR_INTF_1_UNDERRUN BIT(26)
-#define SDE_INTR_INTF_2_UNDERRUN BIT(28)
-#define SDE_INTR_INTF_3_UNDERRUN BIT(30)
-#define SDE_INTR_INTF_0_VSYNC BIT(25)
-#define SDE_INTR_INTF_1_VSYNC BIT(27)
-#define SDE_INTR_INTF_2_VSYNC BIT(29)
-#define SDE_INTR_INTF_3_VSYNC BIT(31)
-
-/**
- * Pingpong Secondary interrupt status bit definitions
- */
-#define SDE_INTR_PING_PONG_S0_AUTOREFRESH_DONE BIT(0)
-#define SDE_INTR_PING_PONG_S0_WR_PTR BIT(4)
-#define SDE_INTR_PING_PONG_S0_RD_PTR BIT(8)
-#define SDE_INTR_PING_PONG_S0_TEAR_DETECTED BIT(22)
-#define SDE_INTR_PING_PONG_S0_TE_DETECTED BIT(28)
-
-/**
- * Pingpong TEAR detection interrupt status bit definitions
- */
-#define SDE_INTR_PING_PONG_0_TEAR_DETECTED BIT(16)
-#define SDE_INTR_PING_PONG_1_TEAR_DETECTED BIT(17)
-#define SDE_INTR_PING_PONG_2_TEAR_DETECTED BIT(18)
-#define SDE_INTR_PING_PONG_3_TEAR_DETECTED BIT(19)
-
-/**
- * Pingpong TE detection interrupt status bit definitions
- */
-#define SDE_INTR_PING_PONG_0_TE_DETECTED BIT(24)
-#define SDE_INTR_PING_PONG_1_TE_DETECTED BIT(25)
-#define SDE_INTR_PING_PONG_2_TE_DETECTED BIT(26)
-#define SDE_INTR_PING_PONG_3_TE_DETECTED BIT(27)
-
-/**
- * Concurrent WB overflow interrupt status bit definitions
- */
-#define SDE_INTR_CWB_2_OVERFLOW BIT(14)
-#define SDE_INTR_CWB_3_OVERFLOW BIT(15)
-
-/**
- * Histogram VIG done interrupt status bit definitions
- */
-#define SDE_INTR_HIST_VIG_0_DONE BIT(0)
-#define SDE_INTR_HIST_VIG_1_DONE BIT(4)
-#define SDE_INTR_HIST_VIG_2_DONE BIT(8)
-#define SDE_INTR_HIST_VIG_3_DONE BIT(10)
-
-/**
- * Histogram VIG reset Sequence done interrupt status bit definitions
- */
-#define SDE_INTR_HIST_VIG_0_RSTSEQ_DONE BIT(1)
-#define SDE_INTR_HIST_VIG_1_RSTSEQ_DONE BIT(5)
-#define SDE_INTR_HIST_VIG_2_RSTSEQ_DONE BIT(9)
-#define SDE_INTR_HIST_VIG_3_RSTSEQ_DONE BIT(11)
-
-/**
- * Histogram DSPP done interrupt status bit definitions
- */
-#define SDE_INTR_HIST_DSPP_0_DONE BIT(12)
-#define SDE_INTR_HIST_DSPP_1_DONE BIT(16)
-#define SDE_INTR_HIST_DSPP_2_DONE BIT(20)
-#define SDE_INTR_HIST_DSPP_3_DONE BIT(22)
-
-/**
- * Histogram DSPP reset Sequence done interrupt status bit definitions
- */
-#define SDE_INTR_HIST_DSPP_0_RSTSEQ_DONE BIT(13)
-#define SDE_INTR_HIST_DSPP_1_RSTSEQ_DONE BIT(17)
-#define SDE_INTR_HIST_DSPP_2_RSTSEQ_DONE BIT(21)
-#define SDE_INTR_HIST_DSPP_3_RSTSEQ_DONE BIT(23)
-
-/**
- * INTF interrupt status bit definitions
- */
-#define SDE_INTR_VIDEO_INTO_STATIC BIT(0)
-#define SDE_INTR_VIDEO_OUTOF_STATIC BIT(1)
-#define SDE_INTR_DSICMD_0_INTO_STATIC BIT(2)
-#define SDE_INTR_DSICMD_0_OUTOF_STATIC BIT(3)
-#define SDE_INTR_DSICMD_1_INTO_STATIC BIT(4)
-#define SDE_INTR_DSICMD_1_OUTOF_STATIC BIT(5)
-#define SDE_INTR_DSICMD_2_INTO_STATIC BIT(6)
-#define SDE_INTR_DSICMD_2_OUTOF_STATIC BIT(7)
-#define SDE_INTR_PROG_LINE BIT(8)
-
-/**
- * struct sde_intr_reg - array of SDE register sets
- * @clr_off: offset to CLEAR reg
- * @en_off: offset to ENABLE reg
- * @status_off: offset to STATUS reg
- */
-struct sde_intr_reg {
- u32 clr_off;
- u32 en_off;
- u32 status_off;
-};
-
-/**
- * struct sde_irq_type - maps each irq with i/f
- * @intr_type: type of interrupt listed in sde_intr_type
- * @instance_idx: instance index of the associated HW block in SDE
- * @irq_mask: corresponding bit in the interrupt status reg
- * @reg_idx: which reg set to use
- */
-struct sde_irq_type {
- u32 intr_type;
- u32 instance_idx;
- u32 irq_mask;
- u32 reg_idx;
-};
-
-/**
- * List of SDE interrupt registers
- */
-static const struct sde_intr_reg sde_intr_set[] = {
- {
- MDP_SSPP_TOP0_OFF+INTR_CLEAR,
- MDP_SSPP_TOP0_OFF+INTR_EN,
- MDP_SSPP_TOP0_OFF+INTR_STATUS
- },
- {
- MDP_SSPP_TOP0_OFF+INTR2_CLEAR,
- MDP_SSPP_TOP0_OFF+INTR2_EN,
- MDP_SSPP_TOP0_OFF+INTR2_STATUS
- },
- {
- MDP_SSPP_TOP0_OFF+HIST_INTR_CLEAR,
- MDP_SSPP_TOP0_OFF+HIST_INTR_EN,
- MDP_SSPP_TOP0_OFF+HIST_INTR_STATUS
- },
- {
- MDP_INTF_0_OFF+INTF_INTR_CLEAR,
- MDP_INTF_0_OFF+INTF_INTR_EN,
- MDP_INTF_0_OFF+INTF_INTR_STATUS
- },
- {
- MDP_INTF_1_OFF+INTF_INTR_CLEAR,
- MDP_INTF_1_OFF+INTF_INTR_EN,
- MDP_INTF_1_OFF+INTF_INTR_STATUS
- },
- {
- MDP_INTF_2_OFF+INTF_INTR_CLEAR,
- MDP_INTF_2_OFF+INTF_INTR_EN,
- MDP_INTF_2_OFF+INTF_INTR_STATUS
- },
- {
- MDP_INTF_3_OFF+INTF_INTR_CLEAR,
- MDP_INTF_3_OFF+INTF_INTR_EN,
- MDP_INTF_3_OFF+INTF_INTR_STATUS
- },
- {
- MDP_INTF_4_OFF+INTF_INTR_CLEAR,
- MDP_INTF_4_OFF+INTF_INTR_EN,
- MDP_INTF_4_OFF+INTF_INTR_STATUS
- }
-};
-
-/**
- * IRQ mapping table - use for lookup an irq_idx in this table that have
- * a matching interface type and instance index.
- */
-static const struct sde_irq_type sde_irq_map[] = {
- /* BEGIN MAP_RANGE: 0-31, INTR */
- /* irq_idx: 0-3 */
- { SDE_IRQ_TYPE_WB_ROT_COMP, WB_0, SDE_INTR_WB_0_DONE, 0},
- { SDE_IRQ_TYPE_WB_ROT_COMP, WB_1, SDE_INTR_WB_1_DONE, 0},
- { SDE_IRQ_TYPE_WD_TIMER, WD_TIMER_0, SDE_INTR_WD_TIMER_0_DONE, 0},
- { SDE_IRQ_TYPE_WD_TIMER, WD_TIMER_1, SDE_INTR_WD_TIMER_1_DONE, 0},
- /* irq_idx: 4-7 */
- { SDE_IRQ_TYPE_WB_WFD_COMP, WB_2, SDE_INTR_WB_2_DONE, 0},
- { SDE_IRQ_TYPE_WD_TIMER, WD_TIMER_2, SDE_INTR_WD_TIMER_2_DONE, 0},
- { SDE_IRQ_TYPE_WD_TIMER, WD_TIMER_3, SDE_INTR_WD_TIMER_3_DONE, 0},
- { SDE_IRQ_TYPE_WD_TIMER, WD_TIMER_4, SDE_INTR_WD_TIMER_4_DONE, 0},
- /* irq_idx: 8-11 */
- { SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_0,
- SDE_INTR_PING_PONG_0_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_1,
- SDE_INTR_PING_PONG_1_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_2,
- SDE_INTR_PING_PONG_2_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_3,
- SDE_INTR_PING_PONG_3_DONE, 0},
- /* irq_idx: 12-15 */
- { SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_0,
- SDE_INTR_PING_PONG_0_RD_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_1,
- SDE_INTR_PING_PONG_1_RD_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_2,
- SDE_INTR_PING_PONG_2_RD_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_3,
- SDE_INTR_PING_PONG_3_RD_PTR, 0},
- /* irq_idx: 16-19 */
- { SDE_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_0,
- SDE_INTR_PING_PONG_0_WR_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_1,
- SDE_INTR_PING_PONG_1_WR_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_2,
- SDE_INTR_PING_PONG_2_WR_PTR, 0},
- { SDE_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_3,
- SDE_INTR_PING_PONG_3_WR_PTR, 0},
- /* irq_idx: 20-23 */
- { SDE_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_0,
- SDE_INTR_PING_PONG_0_AUTOREFRESH_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_1,
- SDE_INTR_PING_PONG_1_AUTOREFRESH_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_2,
- SDE_INTR_PING_PONG_2_AUTOREFRESH_DONE, 0},
- { SDE_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_3,
- SDE_INTR_PING_PONG_3_AUTOREFRESH_DONE, 0},
- /* irq_idx: 24-27 */
- { SDE_IRQ_TYPE_INTF_UNDER_RUN, INTF_0, SDE_INTR_INTF_0_UNDERRUN, 0},
- { SDE_IRQ_TYPE_INTF_VSYNC, INTF_0, SDE_INTR_INTF_0_VSYNC, 0},
- { SDE_IRQ_TYPE_INTF_UNDER_RUN, INTF_1, SDE_INTR_INTF_1_UNDERRUN, 0},
- { SDE_IRQ_TYPE_INTF_VSYNC, INTF_1, SDE_INTR_INTF_1_VSYNC, 0},
- /* irq_idx: 28-31 */
- { SDE_IRQ_TYPE_INTF_UNDER_RUN, INTF_2, SDE_INTR_INTF_2_UNDERRUN, 0},
- { SDE_IRQ_TYPE_INTF_VSYNC, INTF_2, SDE_INTR_INTF_2_VSYNC, 0},
- { SDE_IRQ_TYPE_INTF_UNDER_RUN, INTF_3, SDE_INTR_INTF_3_UNDERRUN, 0},
- { SDE_IRQ_TYPE_INTF_VSYNC, INTF_3, SDE_INTR_INTF_3_VSYNC, 0},
-
- /* BEGIN MAP_RANGE: 32-64, INTR2 */
- /* irq_idx: 32-35 */
- { SDE_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_S0,
- SDE_INTR_PING_PONG_S0_AUTOREFRESH_DONE, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 36-39 */
- { SDE_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_S0,
- SDE_INTR_PING_PONG_S0_WR_PTR, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 40-43 */
- { SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_S0,
- SDE_INTR_PING_PONG_S0_RD_PTR, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 44-47 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_CWB_OVERFLOW, CWB_2, SDE_INTR_CWB_2_OVERFLOW, 1},
- { SDE_IRQ_TYPE_CWB_OVERFLOW, CWB_3, SDE_INTR_CWB_3_OVERFLOW, 1},
- /* irq_idx: 48-51 */
- { SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_0,
- SDE_INTR_PING_PONG_0_TEAR_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_1,
- SDE_INTR_PING_PONG_1_TEAR_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_2,
- SDE_INTR_PING_PONG_2_TEAR_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_3,
- SDE_INTR_PING_PONG_3_TEAR_DETECTED, 1},
- /* irq_idx: 52-55 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_S0,
- SDE_INTR_PING_PONG_S0_TEAR_DETECTED, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 56-59 */
- { SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_0,
- SDE_INTR_PING_PONG_0_TE_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_1,
- SDE_INTR_PING_PONG_1_TE_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_2,
- SDE_INTR_PING_PONG_2_TE_DETECTED, 1},
- { SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_3,
- SDE_INTR_PING_PONG_3_TE_DETECTED, 1},
- /* irq_idx: 60-63 */
- { SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_S0,
- SDE_INTR_PING_PONG_S0_TE_DETECTED, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
-
- /* BEGIN MAP_RANGE: 64-95 HIST */
- /* irq_idx: 64-67 */
- { SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG0, SDE_INTR_HIST_VIG_0_DONE, 2},
- { SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG0,
- SDE_INTR_HIST_VIG_0_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 68-71 */
- { SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG1, SDE_INTR_HIST_VIG_1_DONE, 2},
- { SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG1,
- SDE_INTR_HIST_VIG_1_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 68-71 */
- { SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG2, SDE_INTR_HIST_VIG_2_DONE, 2},
- { SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG2,
- SDE_INTR_HIST_VIG_2_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG3, SDE_INTR_HIST_VIG_3_DONE, 2},
- { SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG3,
- SDE_INTR_HIST_VIG_3_RSTSEQ_DONE, 2},
- /* irq_idx: 72-75 */
- { SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_0, SDE_INTR_HIST_DSPP_0_DONE, 2},
- { SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_0,
- SDE_INTR_HIST_DSPP_0_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 76-79 */
- { SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_1, SDE_INTR_HIST_DSPP_1_DONE, 2},
- { SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_1,
- SDE_INTR_HIST_DSPP_1_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 80-83 */
- { SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_2, SDE_INTR_HIST_DSPP_2_DONE, 2},
- { SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_2,
- SDE_INTR_HIST_DSPP_2_RSTSEQ_DONE, 2},
- { SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_3, SDE_INTR_HIST_DSPP_3_DONE, 2},
- { SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_3,
- SDE_INTR_HIST_DSPP_3_RSTSEQ_DONE, 2},
- /* irq_idx: 84-87 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 88-91 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- /* irq_idx: 92-95 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-
- /* BEGIN MAP_RANGE: 96-127 INTF_0_INTR */
- /* irq_idx: 96-99 */
- { SDE_IRQ_TYPE_SFI_VIDEO_IN, INTF_0,
- SDE_INTR_VIDEO_INTO_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_VIDEO_OUT, INTF_0,
- SDE_INTR_VIDEO_OUTOF_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_CMD_0_IN, INTF_0,
- SDE_INTR_DSICMD_0_INTO_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_CMD_0_OUT, INTF_0,
- SDE_INTR_DSICMD_0_OUTOF_STATIC, 3},
- /* irq_idx: 100-103 */
- { SDE_IRQ_TYPE_SFI_CMD_1_IN, INTF_0,
- SDE_INTR_DSICMD_1_INTO_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_CMD_1_OUT, INTF_0,
- SDE_INTR_DSICMD_1_OUTOF_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_CMD_2_IN, INTF_0,
- SDE_INTR_DSICMD_2_INTO_STATIC, 3},
- { SDE_IRQ_TYPE_SFI_CMD_2_OUT, INTF_0,
- SDE_INTR_DSICMD_2_OUTOF_STATIC, 3},
- /* irq_idx: 104-107 */
- { SDE_IRQ_TYPE_PROG_LINE, INTF_0, SDE_INTR_PROG_LINE, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- /* irq_idx: 108-111 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- /* irq_idx: 112-115 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- /* irq_idx: 116-119 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- /* irq_idx: 120-123 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- /* irq_idx: 124-127 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 3},
-
- /* BEGIN MAP_RANGE: 128-159 INTF_1_INTR */
- /* irq_idx: 128-131 */
- { SDE_IRQ_TYPE_SFI_VIDEO_IN, INTF_1,
- SDE_INTR_VIDEO_INTO_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_VIDEO_OUT, INTF_1,
- SDE_INTR_VIDEO_OUTOF_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_CMD_0_IN, INTF_1,
- SDE_INTR_DSICMD_0_INTO_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_CMD_0_OUT, INTF_1,
- SDE_INTR_DSICMD_0_OUTOF_STATIC, 4},
- /* irq_idx: 132-135 */
- { SDE_IRQ_TYPE_SFI_CMD_1_IN, INTF_1,
- SDE_INTR_DSICMD_1_INTO_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_CMD_1_OUT, INTF_1,
- SDE_INTR_DSICMD_1_OUTOF_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_CMD_2_IN, INTF_1,
- SDE_INTR_DSICMD_2_INTO_STATIC, 4},
- { SDE_IRQ_TYPE_SFI_CMD_2_OUT, INTF_1,
- SDE_INTR_DSICMD_2_OUTOF_STATIC, 4},
- /* irq_idx: 136-139 */
- { SDE_IRQ_TYPE_PROG_LINE, INTF_1, SDE_INTR_PROG_LINE, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- /* irq_idx: 140-143 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- /* irq_idx: 144-147 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- /* irq_idx: 148-151 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- /* irq_idx: 152-155 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- /* irq_idx: 156-159 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 4},
-
- /* BEGIN MAP_RANGE: 160-191 INTF_2_INTR */
- /* irq_idx: 160-163 */
- { SDE_IRQ_TYPE_SFI_VIDEO_IN, INTF_2,
- SDE_INTR_VIDEO_INTO_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_VIDEO_OUT, INTF_2,
- SDE_INTR_VIDEO_OUTOF_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_CMD_0_IN, INTF_2,
- SDE_INTR_DSICMD_0_INTO_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_CMD_0_OUT, INTF_2,
- SDE_INTR_DSICMD_0_OUTOF_STATIC, 5},
- /* irq_idx: 164-167 */
- { SDE_IRQ_TYPE_SFI_CMD_1_IN, INTF_2,
- SDE_INTR_DSICMD_1_INTO_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_CMD_1_OUT, INTF_2,
- SDE_INTR_DSICMD_1_OUTOF_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_CMD_2_IN, INTF_2,
- SDE_INTR_DSICMD_2_INTO_STATIC, 5},
- { SDE_IRQ_TYPE_SFI_CMD_2_OUT, INTF_2,
- SDE_INTR_DSICMD_2_OUTOF_STATIC, 5},
- /* irq_idx: 168-171 */
- { SDE_IRQ_TYPE_PROG_LINE, INTF_2, SDE_INTR_PROG_LINE, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- /* irq_idx: 172-175 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- /* irq_idx: 176-179 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- /* irq_idx: 180-183 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- /* irq_idx: 184-187 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- /* irq_idx: 188-191 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 5},
-
- /* BEGIN MAP_RANGE: 192-223 INTF_3_INTR */
- /* irq_idx: 192-195 */
- { SDE_IRQ_TYPE_SFI_VIDEO_IN, INTF_3,
- SDE_INTR_VIDEO_INTO_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_VIDEO_OUT, INTF_3,
- SDE_INTR_VIDEO_OUTOF_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_CMD_0_IN, INTF_3,
- SDE_INTR_DSICMD_0_INTO_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_CMD_0_OUT, INTF_3,
- SDE_INTR_DSICMD_0_OUTOF_STATIC, 6},
- /* irq_idx: 196-199 */
- { SDE_IRQ_TYPE_SFI_CMD_1_IN, INTF_3,
- SDE_INTR_DSICMD_1_INTO_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_CMD_1_OUT, INTF_3,
- SDE_INTR_DSICMD_1_OUTOF_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_CMD_2_IN, INTF_3,
- SDE_INTR_DSICMD_2_INTO_STATIC, 6},
- { SDE_IRQ_TYPE_SFI_CMD_2_OUT, INTF_3,
- SDE_INTR_DSICMD_2_OUTOF_STATIC, 6},
- /* irq_idx: 200-203 */
- { SDE_IRQ_TYPE_PROG_LINE, INTF_3, SDE_INTR_PROG_LINE, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- /* irq_idx: 204-207 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- /* irq_idx: 208-211 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- /* irq_idx: 212-215 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- /* irq_idx: 216-219 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- /* irq_idx: 220-223 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 6},
-
- /* BEGIN MAP_RANGE: 224-255 INTF_4_INTR */
- /* irq_idx: 224-227 */
- { SDE_IRQ_TYPE_SFI_VIDEO_IN, INTF_4,
- SDE_INTR_VIDEO_INTO_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_VIDEO_OUT, INTF_4,
- SDE_INTR_VIDEO_OUTOF_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_CMD_0_IN, INTF_4,
- SDE_INTR_DSICMD_0_INTO_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_CMD_0_OUT, INTF_4,
- SDE_INTR_DSICMD_0_OUTOF_STATIC, 7},
- /* irq_idx: 228-231 */
- { SDE_IRQ_TYPE_SFI_CMD_1_IN, INTF_4,
- SDE_INTR_DSICMD_1_INTO_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_CMD_1_OUT, INTF_4,
- SDE_INTR_DSICMD_1_OUTOF_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_CMD_2_IN, INTF_4,
- SDE_INTR_DSICMD_2_INTO_STATIC, 7},
- { SDE_IRQ_TYPE_SFI_CMD_2_OUT, INTF_4,
- SDE_INTR_DSICMD_2_OUTOF_STATIC, 7},
- /* irq_idx: 232-235 */
- { SDE_IRQ_TYPE_PROG_LINE, INTF_4, SDE_INTR_PROG_LINE, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- /* irq_idx: 236-239 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- /* irq_idx: 240-243 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- /* irq_idx: 244-247 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- /* irq_idx: 248-251 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- /* irq_idx: 252-255 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 7},
-};
-
-static int sde_hw_intr_irqidx_lookup(enum sde_intr_type intr_type,
- u32 instance_idx)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sde_irq_map); i++) {
- if (intr_type == sde_irq_map[i].intr_type &&
- instance_idx == sde_irq_map[i].instance_idx)
- return i;
- }
-
- pr_debug("IRQ lookup fail!! intr_type=%d, instance_idx=%d\n",
- intr_type, instance_idx);
- return -EINVAL;
-}
-
-static void sde_hw_intr_set_mask(struct sde_hw_intr *intr, uint32_t reg_off,
- uint32_t mask)
-{
- SDE_REG_WRITE(&intr->hw, reg_off, mask);
-}
-
-static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
- void (*cbfunc)(void *, int),
- void *arg)
-{
- int reg_idx;
- int irq_idx;
- int start_idx;
- int end_idx;
- u32 irq_status;
- unsigned long irq_flags;
-
- /*
- * The dispatcher will save the IRQ status before calling here.
- * Now need to go through each IRQ status and find matching
- * irq lookup index.
- */
- spin_lock_irqsave(&intr->status_lock, irq_flags);
- for (reg_idx = 0; reg_idx < ARRAY_SIZE(sde_intr_set); reg_idx++) {
- irq_status = intr->save_irq_status[reg_idx];
-
- /*
- * Each Interrupt register has a range of 32 indexes, and
- * that is static for sde_irq_map.
- */
- start_idx = reg_idx * 32;
- end_idx = start_idx + 32;
-
- /*
- * Search through matching intr status from irq map.
- * start_idx and end_idx defined the search range in
- * the sde_irq_map.
- */
- for (irq_idx = start_idx;
- (irq_idx < end_idx) && irq_status;
- irq_idx++)
- if ((irq_status & sde_irq_map[irq_idx].irq_mask) &&
- (sde_irq_map[irq_idx].reg_idx == reg_idx)) {
- /*
- * Once a match on irq mask, perform a callback
- * to the given cbfunc. cbfunc will take care
- * the interrupt status clearing. If cbfunc is
- * not provided, then the interrupt clearing
- * is here.
- */
- if (cbfunc)
- cbfunc(arg, irq_idx);
- else
- intr->ops.clear_interrupt_status(
- intr, irq_idx);
-
- /*
- * When callback finish, clear the irq_status
- * with the matching mask. Once irq_status
- * is all cleared, the search can be stopped.
- */
- irq_status &= ~sde_irq_map[irq_idx].irq_mask;
- }
- }
- spin_unlock_irqrestore(&intr->status_lock, irq_flags);
-}
-
-static int sde_hw_intr_enable_irq(struct sde_hw_intr *intr, int irq_idx)
-{
- int reg_idx;
- unsigned long irq_flags;
- const struct sde_intr_reg *reg;
- const struct sde_irq_type *irq;
- const char *dbgstr = NULL;
- uint32_t cache_irq_mask;
-
- if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(sde_irq_map)) {
- pr_err("invalid IRQ index: [%d]\n", irq_idx);
- return -EINVAL;
- }
-
- irq = &sde_irq_map[irq_idx];
- reg_idx = irq->reg_idx;
- reg = &sde_intr_set[reg_idx];
-
- spin_lock_irqsave(&intr->mask_lock, irq_flags);
- cache_irq_mask = intr->cache_irq_mask[reg_idx];
- if (cache_irq_mask & irq->irq_mask) {
- dbgstr = "SDE IRQ already set:";
- } else {
- dbgstr = "SDE IRQ enabled:";
-
- cache_irq_mask |= irq->irq_mask;
- /* Cleaning any pending interrupt */
- SDE_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
- /* Enabling interrupts with the new mask */
- SDE_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
-
- intr->cache_irq_mask[reg_idx] = cache_irq_mask;
- }
- spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
-
- pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
- irq->irq_mask, cache_irq_mask);
-
- return 0;
-}
-
-static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx)
-{
- int reg_idx;
- unsigned long irq_flags;
- const struct sde_intr_reg *reg;
- const struct sde_irq_type *irq;
- const char *dbgstr = NULL;
- uint32_t cache_irq_mask;
-
- if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(sde_irq_map)) {
- pr_err("invalid IRQ index: [%d]\n", irq_idx);
- return -EINVAL;
- }
-
- irq = &sde_irq_map[irq_idx];
- reg_idx = irq->reg_idx;
- reg = &sde_intr_set[reg_idx];
-
- spin_lock_irqsave(&intr->mask_lock, irq_flags);
- cache_irq_mask = intr->cache_irq_mask[reg_idx];
- if ((cache_irq_mask & irq->irq_mask) == 0) {
- dbgstr = "SDE IRQ is already cleared:";
- } else {
- dbgstr = "SDE IRQ mask disable:";
-
- cache_irq_mask &= ~irq->irq_mask;
- /* Disable interrupts based on the new mask */
- SDE_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
- /* Cleaning any pending interrupt */
- SDE_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
-
- intr->cache_irq_mask[reg_idx] = cache_irq_mask;
- }
- spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
-
- pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
- irq->irq_mask, cache_irq_mask);
-
- return 0;
-}
-
-static int sde_hw_intr_clear_irqs(struct sde_hw_intr *intr)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sde_intr_set); i++)
- SDE_REG_WRITE(&intr->hw, sde_intr_set[i].clr_off, 0xffffffff);
-
- return 0;
-}
-
-static int sde_hw_intr_disable_irqs(struct sde_hw_intr *intr)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sde_intr_set); i++)
- SDE_REG_WRITE(&intr->hw, sde_intr_set[i].en_off, 0x00000000);
-
- return 0;
-}
-
-static int sde_hw_intr_get_valid_interrupts(struct sde_hw_intr *intr,
- uint32_t *mask)
-{
- *mask = IRQ_SOURCE_MDP | IRQ_SOURCE_DSI0 | IRQ_SOURCE_DSI1
- | IRQ_SOURCE_HDMI | IRQ_SOURCE_EDP;
- return 0;
-}
-
-static int sde_hw_intr_get_interrupt_sources(struct sde_hw_intr *intr,
- uint32_t *sources)
-{
- *sources = SDE_REG_READ(&intr->hw, HW_INTR_STATUS);
- return 0;
-}
-
-static void sde_hw_intr_get_interrupt_statuses(struct sde_hw_intr *intr)
-{
- int i;
- u32 enable_mask;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&intr->status_lock, irq_flags);
- for (i = 0; i < ARRAY_SIZE(sde_intr_set); i++) {
- /* Read interrupt status */
- intr->save_irq_status[i] = SDE_REG_READ(&intr->hw,
- sde_intr_set[i].status_off);
-
- /* Read enable mask */
- enable_mask = SDE_REG_READ(&intr->hw, sde_intr_set[i].en_off);
-
- /* and clear the interrupt */
- if (intr->save_irq_status[i])
- SDE_REG_WRITE(&intr->hw, sde_intr_set[i].clr_off,
- intr->save_irq_status[i]);
-
- /* Finally update IRQ status based on enable mask */
- intr->save_irq_status[i] &= enable_mask;
- }
- spin_unlock_irqrestore(&intr->status_lock, irq_flags);
-}
-
-static void sde_hw_intr_clear_interrupt_status(struct sde_hw_intr *intr,
- int irq_idx)
-{
- int reg_idx;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&intr->mask_lock, irq_flags);
-
- reg_idx = sde_irq_map[irq_idx].reg_idx;
- SDE_REG_WRITE(&intr->hw, sde_intr_set[reg_idx].clr_off,
- sde_irq_map[irq_idx].irq_mask);
-
- spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
-}
-
-
-static void __setup_intr_ops(struct sde_hw_intr_ops *ops)
-{
- ops->set_mask = sde_hw_intr_set_mask;
- ops->irq_idx_lookup = sde_hw_intr_irqidx_lookup;
- ops->enable_irq = sde_hw_intr_enable_irq;
- ops->disable_irq = sde_hw_intr_disable_irq;
- ops->dispatch_irqs = sde_hw_intr_dispatch_irq;
- ops->clear_all_irqs = sde_hw_intr_clear_irqs;
- ops->disable_all_irqs = sde_hw_intr_disable_irqs;
- ops->get_valid_interrupts = sde_hw_intr_get_valid_interrupts;
- ops->get_interrupt_sources = sde_hw_intr_get_interrupt_sources;
- ops->get_interrupt_statuses = sde_hw_intr_get_interrupt_statuses;
- ops->clear_interrupt_status = sde_hw_intr_clear_interrupt_status;
-}
-
-static struct sde_mdss_base_cfg *__intr_offset(struct sde_mdss_cfg *m,
- void __iomem *addr, struct sde_hw_blk_reg_map *hw)
-{
- if (m->mdp_count == 0)
- return NULL;
-
- hw->base_off = addr;
- hw->blk_off = m->mdss[0].base;
- hw->hwversion = m->hwversion;
- return &m->mdss[0];
-}
-
-struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr,
- struct sde_mdss_cfg *m)
-{
- struct sde_hw_intr *intr = kzalloc(sizeof(*intr), GFP_KERNEL);
- struct sde_mdss_base_cfg *cfg;
-
- if (!intr)
- return ERR_PTR(-ENOMEM);
-
- cfg = __intr_offset(m, addr, &intr->hw);
- if (!cfg) {
- kfree(intr);
- return ERR_PTR(-EINVAL);
- }
- __setup_intr_ops(&intr->ops);
-
- intr->irq_idx_tbl_size = ARRAY_SIZE(sde_irq_map);
-
- intr->cache_irq_mask = kcalloc(ARRAY_SIZE(sde_intr_set), sizeof(u32),
- GFP_KERNEL);
- if (intr->cache_irq_mask == NULL) {
- kfree(intr);
- return ERR_PTR(-ENOMEM);
- }
-
- intr->save_irq_status = kcalloc(ARRAY_SIZE(sde_intr_set), sizeof(u32),
- GFP_KERNEL);
- if (intr->save_irq_status == NULL) {
- kfree(intr->cache_irq_mask);
- kfree(intr);
- return ERR_PTR(-ENOMEM);
- }
-
- spin_lock_init(&intr->mask_lock);
- spin_lock_init(&intr->status_lock);
-
- return intr;
-}
-
-void sde_hw_intr_destroy(struct sde_hw_intr *intr)
-{
- if (intr) {
- kfree(intr->cache_irq_mask);
- kfree(intr->save_irq_status);
- kfree(intr);
- }
-}
-
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
deleted file mode 100644
index 0ddb1e78a953..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Copyright (c) 2016, 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 _SDE_HW_INTERRUPTS_H
-#define _SDE_HW_INTERRUPTS_H
-
-#include <linux/types.h>
-
-#include "sde_hwio.h"
-#include "sde_hw_catalog.h"
-#include "sde_hw_mdp_util.h"
-#include "sde_hw_mdss.h"
-
-#define IRQ_SOURCE_MDP BIT(0)
-#define IRQ_SOURCE_DSI0 BIT(4)
-#define IRQ_SOURCE_DSI1 BIT(5)
-#define IRQ_SOURCE_HDMI BIT(8)
-#define IRQ_SOURCE_EDP BIT(12)
-#define IRQ_SOURCE_MHL BIT(16)
-
-/**
- * sde_intr_type - HW Interrupt Type
- * @SDE_IRQ_TYPE_WB_ROT_COMP: WB rotator done
- * @SDE_IRQ_TYPE_WB_WFD_COMP: WB WFD done
- * @SDE_IRQ_TYPE_PING_PONG_COMP: PingPong done
- * @SDE_IRQ_TYPE_PING_PONG_RD_PTR: PingPong read pointer
- * @SDE_IRQ_TYPE_PING_PONG_WR_PTR: PingPong write pointer
- * @SDE_IRQ_TYPE_PING_PONG_AUTO_REF: PingPong auto refresh
- * @SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK: PingPong Tear check
- * @SDE_IRQ_TYPE_PING_PONG_TE_CHECK: PingPong TE detection
- * @SDE_IRQ_TYPE_INTF_UNDER_RUN: INTF underrun
- * @SDE_IRQ_TYPE_INTF_VSYNC: INTF VSYNC
- * @SDE_IRQ_TYPE_CWB_OVERFLOW: Concurrent WB overflow
- * @SDE_IRQ_TYPE_HIST_VIG_DONE: VIG Histogram done
- * @SDE_IRQ_TYPE_HIST_VIG_RSTSEQ: VIG Histogram reset
- * @SDE_IRQ_TYPE_HIST_DSPP_DONE: DSPP Histogram done
- * @SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ: DSPP Histogram reset
- * @SDE_IRQ_TYPE_WD_TIMER: Watchdog timer
- * @SDE_IRQ_TYPE_SFI_VIDEO_IN: Video static frame INTR into static
- * @SDE_IRQ_TYPE_SFI_VIDEO_OUT: Video static frame INTR out-of static
- * @SDE_IRQ_TYPE_SFI_CMD_0_IN: DSI CMD0 static frame INTR into static
- * @SDE_IRQ_TYPE_SFI_CMD_0_OUT: DSI CMD0 static frame INTR out-of static
- * @SDE_IRQ_TYPE_SFI_CMD_1_IN: DSI CMD1 static frame INTR into static
- * @SDE_IRQ_TYPE_SFI_CMD_1_OUT: DSI CMD1 static frame INTR out-of static
- * @SDE_IRQ_TYPE_SFI_CMD_2_IN: DSI CMD2 static frame INTR into static
- * @SDE_IRQ_TYPE_SFI_CMD_2_OUT: DSI CMD2 static frame INTR out-of static
- * @SDE_IRQ_TYPE_PROG_LINE: Programmable Line interrupt
- * @SDE_IRQ_TYPE_RESERVED: Reserved for expansion
- */
-enum sde_intr_type {
- SDE_IRQ_TYPE_WB_ROT_COMP,
- SDE_IRQ_TYPE_WB_WFD_COMP,
- SDE_IRQ_TYPE_PING_PONG_COMP,
- SDE_IRQ_TYPE_PING_PONG_RD_PTR,
- SDE_IRQ_TYPE_PING_PONG_WR_PTR,
- SDE_IRQ_TYPE_PING_PONG_AUTO_REF,
- SDE_IRQ_TYPE_PING_PONG_TEAR_CHECK,
- SDE_IRQ_TYPE_PING_PONG_TE_CHECK,
- SDE_IRQ_TYPE_INTF_UNDER_RUN,
- SDE_IRQ_TYPE_INTF_VSYNC,
- SDE_IRQ_TYPE_CWB_OVERFLOW,
- SDE_IRQ_TYPE_HIST_VIG_DONE,
- SDE_IRQ_TYPE_HIST_VIG_RSTSEQ,
- SDE_IRQ_TYPE_HIST_DSPP_DONE,
- SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ,
- SDE_IRQ_TYPE_WD_TIMER,
- SDE_IRQ_TYPE_SFI_VIDEO_IN,
- SDE_IRQ_TYPE_SFI_VIDEO_OUT,
- SDE_IRQ_TYPE_SFI_CMD_0_IN,
- SDE_IRQ_TYPE_SFI_CMD_0_OUT,
- SDE_IRQ_TYPE_SFI_CMD_1_IN,
- SDE_IRQ_TYPE_SFI_CMD_1_OUT,
- SDE_IRQ_TYPE_SFI_CMD_2_IN,
- SDE_IRQ_TYPE_SFI_CMD_2_OUT,
- SDE_IRQ_TYPE_PROG_LINE,
- SDE_IRQ_TYPE_RESERVED,
-};
-
-struct sde_hw_intr;
-
-/**
- * Interrupt operations.
- */
-struct sde_hw_intr_ops {
- /**
- * set_mask - Programs the given interrupt register with the
- * given interrupt mask. Register value will get overwritten.
- * @intr: HW interrupt handle
- * @reg_off: MDSS HW register offset
- * @irqmask: IRQ mask value
- */
- void (*set_mask)(
- struct sde_hw_intr *intr,
- uint32_t reg,
- uint32_t irqmask);
-
- /**
- * irq_idx_lookup - Lookup IRQ index on the HW interrupt type
- * Used for all irq related ops
- * @intr_type: Interrupt type defined in sde_intr_type
- * @instance_idx: HW interrupt block instance
- * @return: irq_idx or -EINVAL for lookup fail
- */
- int (*irq_idx_lookup)(
- enum sde_intr_type intr_type,
- u32 instance_idx);
-
- /**
- * enable_irq - Enable IRQ based on lookup IRQ index
- * @intr: HW interrupt handle
- * @irq_idx: Lookup irq index return from irq_idx_lookup
- * @return: 0 for success, otherwise failure
- */
- int (*enable_irq)(
- struct sde_hw_intr *intr,
- int irq_idx);
-
- /**
- * disable_irq - Disable IRQ based on lookup IRQ index
- * @intr: HW interrupt handle
- * @irq_idx: Lookup irq index return from irq_idx_lookup
- * @return: 0 for success, otherwise failure
- */
- int (*disable_irq)(
- struct sde_hw_intr *intr,
- int irq_idx);
-
- /**
- * clear_all_irqs - Clears all the interrupts (i.e. acknowledges
- * any asserted IRQs). Useful during reset.
- * @intr: HW interrupt handle
- * @return: 0 for success, otherwise failure
- */
- int (*clear_all_irqs)(
- struct sde_hw_intr *intr);
-
- /**
- * disable_all_irqs - Disables all the interrupts. Useful during reset.
- * @intr: HW interrupt handle
- * @return: 0 for success, otherwise failure
- */
- int (*disable_all_irqs)(
- struct sde_hw_intr *intr);
-
- /**
- * dispatch_irqs - IRQ dispatcher will call the given callback
- * function when a matching interrupt status bit is
- * found in the irq mapping table.
- * @intr: HW interrupt handle
- * @cbfunc: Callback function pointer
- * @arg: Argument to pass back during callback
- */
- void (*dispatch_irqs)(
- struct sde_hw_intr *intr,
- void (*cbfunc)(void *arg, int irq_idx),
- void *arg);
-
- /**
- * get_interrupt_statuses - Gets and store value from all interrupt
- * status registers that are currently fired.
- * @intr: HW interrupt handle
- */
- void (*get_interrupt_statuses)(
- struct sde_hw_intr *intr);
-
- /**
- * clear_interrupt_status - Clears HW interrupt status based on given
- * lookup IRQ index.
- * @intr: HW interrupt handle
- * @irq_idx: Lookup irq index return from irq_idx_lookup
- */
- void (*clear_interrupt_status)(
- struct sde_hw_intr *intr,
- int irq_idx);
-
- /**
- * get_valid_interrupts - Gets a mask of all valid interrupt sources
- * within SDE. These are actually status bits
- * within interrupt registers that specify the
- * source of the interrupt in IRQs. For example,
- * valid interrupt sources can be MDP, DSI,
- * HDMI etc.
- * @intr: HW interrupt handle
- * @mask: Returning the interrupt source MASK
- * @return: 0 for success, otherwise failure
- */
- int (*get_valid_interrupts)(
- struct sde_hw_intr *intr,
- uint32_t *mask);
-
- /**
- * get_interrupt_sources - Gets the bitmask of the SDE interrupt
- * source that are currently fired.
- * @intr: HW interrupt handle
- * @sources: Returning the SDE interrupt source status bit mask
- * @return: 0 for success, otherwise failure
- */
- int (*get_interrupt_sources)(
- struct sde_hw_intr *intr,
- uint32_t *sources);
-};
-
-/**
- * struct sde_hw_intr: hw interrupts handling data structure
- * @hw: virtual address mapping
- * @ops: function pointer mapping for IRQ handling
- * @cache_irq_mask: array of IRQ enable masks reg storage created during init
- * @save_irq_status: array of IRQ status reg storage created during init
- * @irq_idx_tbl_size: total number of irq_idx mapped in the hw_interrupts
- * @mask_lock: spinlock for accessing IRQ mask
- * @status_lock: spinlock for accessing IRQ status
- */
-struct sde_hw_intr {
- struct sde_hw_blk_reg_map hw;
- struct sde_hw_intr_ops ops;
- u32 *cache_irq_mask;
- u32 *save_irq_status;
- u32 irq_idx_tbl_size;
- spinlock_t mask_lock;
- spinlock_t status_lock;
-};
-
-/**
- * sde_hw_intr_init(): Initializes the interrupts hw object
- * @addr: mapped register io address of MDP
- * @m : pointer to mdss catalog data
- */
-struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr,
- struct sde_mdss_cfg *m);
-
-/**
- * sde_hw_intr_destroy(): Cleanup interrutps hw object
- * @intr: pointer to interrupts hw object
- */
-void sde_hw_intr_destroy(struct sde_hw_intr *intr);
-#endif
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.c b/drivers/gpu/drm/msm/sde/sde_hw_intf.c
index 8dd306720e90..b108e34de24f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_intf.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.c
@@ -13,7 +13,6 @@
#include "sde_hwio.h"
#include "sde_hw_catalog.h"
#include "sde_hw_intf.h"
-#include "sde_hw_mdp_top.h"
#define INTF_TIMING_ENGINE_EN 0x000
#define INTF_CONFIG 0x004
@@ -71,8 +70,7 @@ static struct sde_intf_cfg *_intf_offset(enum sde_intf intf,
int i;
for (i = 0; i < m->intf_count; i++) {
- if ((intf == m->intf[i].id) &&
- (m->intf[i].type != INTF_NONE)) {
+ if (intf == m->intf[i].id) {
b->base_off = addr;
b->blk_off = m->intf[i].base;
b->hwversion = m->hwversion;
@@ -160,13 +158,13 @@ static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx,
(hsync_polarity << 0); /* HSYNC Polarity */
if (!fmt->is_yuv)
- panel_format = (fmt->bits[C0_G_Y] |
- (fmt->bits[C1_B_Cb] << 2) |
- (fmt->bits[C2_R_Cr] << 4) |
+ panel_format = (fmt->bits[0] |
+ (fmt->bits[1] << 2) |
+ (fmt->bits[2] << 4) |
(0x21 << 8));
else
- /* Interface treats all the pixel data in RGB888 format */
- panel_format = (COLOR_8BIT |
+ /* Interface treats all the pixel data in RGB888 format */
+ panel_format |= (COLOR_8BIT |
(COLOR_8BIT << 2) |
(COLOR_8BIT << 4) |
(0x21 << 8));
@@ -206,16 +204,10 @@ static void sde_hw_intf_enable_timing_engine(
/* Display interface select */
if (enable) {
- /* top block */
- struct sde_hw_mdp *mdp = sde_hw_mdptop_init(MDP_TOP,
- c->base_off,
- intf->mdss);
- struct sde_hw_blk_reg_map *top = &mdp->hw;
+ intf_sel = SDE_REG_READ(c, DISP_INTF_SEL);
- intf_sel = SDE_REG_READ(top, DISP_INTF_SEL);
-
- intf_sel |= (intf->cap->type << ((intf->idx - INTF_0) * 8));
- SDE_REG_WRITE(top, DISP_INTF_SEL, intf_sel);
+ intf_sel |= (intf->cap->type << ((intf->idx) * 8));
+ SDE_REG_WRITE(c, DISP_INTF_SEL, intf_sel);
}
SDE_REG_WRITE(c, INTF_TIMING_ENGINE_EN,
@@ -362,9 +354,8 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx,
return ERR_PTR(-ENOMEM);
cfg = _intf_offset(idx, m, addr, &c->hw);
- if (IS_ERR_OR_NULL(cfg)) {
+ if (!cfg) {
kfree(c);
- pr_err("Error Panic\n");
return ERR_PTR(-EINVAL);
}
@@ -373,7 +364,6 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx,
*/
c->idx = idx;
c->cap = cfg;
- c->mdss = m;
_setup_intf_ops(&c->ops, c->cap->features);
/*
@@ -381,9 +371,3 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx,
*/
return c;
}
-
-void sde_hw_intf_deinit(struct sde_hw_intf *intf)
-{
- kfree(intf);
-}
-
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.h b/drivers/gpu/drm/msm/sde/sde_hw_intf.h
index 2de57868901a..f0d8a32dc802 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_intf.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.h
@@ -15,7 +15,6 @@
#include "sde_hw_catalog.h"
#include "sde_hw_mdss.h"
-#include "sde_hw_mdp_util.h"
struct sde_hw_intf;
@@ -85,7 +84,6 @@ struct sde_hw_intf {
/* intf */
enum sde_intf idx;
const struct sde_intf_cfg *cap;
- const struct sde_mdss_cfg *mdss;
/* ops */
struct sde_hw_intf_ops ops;
@@ -102,6 +100,4 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx,
void __iomem *addr,
struct sde_mdss_cfg *m);
-void sde_hw_intf_deinit(struct sde_hw_intf *intf);
-
#endif /*_SDE_HW_INTF_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.c b/drivers/gpu/drm/msm/sde/sde_hw_lm.c
index 56ebe8fa05b5..0a20821f3a32 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_lm.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.c
@@ -58,7 +58,7 @@ static inline int _stage_offset(struct sde_hw_mixer *ctx, enum sde_stage stage)
return -EINVAL;
if ((stage - SDE_STAGE_0) <= sblk->maxblendstages)
- return sblk->blendstage_base[stage - 1];
+ return sblk->blendstage_base[stage];
else
return -EINVAL;
}
@@ -76,7 +76,7 @@ static void sde_hw_lm_setup_out(struct sde_hw_mixer *ctx,
SDE_REG_WRITE(c, LM_OUT_SIZE, outsize);
/* SPLIT_LEFT_RIGHT */
- opmode = (opmode & ~(1 << 31)) | ((mixer->right_mixer) ? (1 << 31) : 0);
+ opmode = (opmode & ~(1 << 31)) | (mixer->right_mixer & 1 << 31);
SDE_REG_WRITE(c, LM_OP_MODE, opmode);
}
@@ -126,9 +126,9 @@ static void sde_hw_lm_setup_blendcfg(struct sde_hw_mixer *ctx,
SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off,
fg->const_alpha);
- SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off,
+ SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off,
bg->const_alpha);
- SDE_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
+ SDE_REG_WRITE(c, LM_OP_MODE, blend_op);
}
static void sde_hw_lm_setup_color3(struct sde_hw_mixer *ctx,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c
index f7181ab9ed3d..4886cdf87c9f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c
@@ -15,9 +15,9 @@
#include "sde_hw_mdp_ctl.h"
#define CTL_LAYER(lm) \
- (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004))
+ (((lm) == 5) ? (0x024) : ((lm) * 0x004))
#define CTL_LAYER_EXT(lm) \
- (0x40 + (((lm) - LM_0) * 0x004))
+ (0x40 + ((lm) * 0x004))
#define CTL_TOP 0x014
#define CTL_FLUSH 0x018
#define CTL_START 0x01C
@@ -61,14 +61,15 @@ static int _mixer_stages(const struct sde_lm_cfg *mixer, int count,
return stages;
}
-static inline void sde_hw_ctl_force_start(struct sde_hw_ctl *ctx)
+static inline void sde_hw_ctl_setup_flush(struct sde_hw_ctl *ctx, u32 flushbits,
+ u8 force_start)
{
- SDE_REG_WRITE(&ctx->hw, CTL_START, 0x1);
-}
+ struct sde_hw_blk_reg_map *c = &ctx->hw;
-static inline void sde_hw_ctl_setup_flush(struct sde_hw_ctl *ctx, u32 flushbits)
-{
- SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, flushbits);
+ SDE_REG_WRITE(c, CTL_FLUSH, flushbits);
+
+ if (force_start)
+ SDE_REG_WRITE(c, CTL_START, 0x1);
}
static inline int sde_hw_ctl_get_bitmask_sspp(struct sde_hw_ctl *ctx,
@@ -221,7 +222,7 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
struct sde_hw_stage_cfg *cfg)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
- u32 mixercfg, mixercfg_ext = 0;
+ u32 mixercfg, mixercfg_ext;
int i, j;
u8 stages;
int pipes_per_stage;
@@ -236,8 +237,8 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
else
pipes_per_stage = 1;
- mixercfg = cfg->border_enable << 24; /* BORDER_OUT */
-
+ mixercfg = cfg->border_enable >> 24; /* BORDER_OUT */
+;
for (i = 0; i <= stages; i++) {
for (j = 0; j < pipes_per_stage; j++) {
switch (cfg->stage[i][j]) {
@@ -297,38 +298,17 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext);
}
-static void sde_hw_ctl_intf_cfg(struct sde_hw_ctl *ctx,
- struct sde_hw_intf_cfg *cfg)
-{
- struct sde_hw_blk_reg_map *c = &ctx->hw;
- u32 intf_cfg = 0;
-
- intf_cfg |= (cfg->intf & 0xF) << 4;
-
- if (cfg->wb)
- intf_cfg |= (cfg->wb & 0x3) + 2;
-
- if (cfg->mode_3d) {
- intf_cfg |= BIT(19);
- intf_cfg |= (cfg->mode_3d - 1) << 20;
- }
-
- SDE_REG_WRITE(c, CTL_TOP, intf_cfg);
-}
-
static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
unsigned long cap)
{
ops->setup_flush = sde_hw_ctl_setup_flush;
- ops->setup_start = sde_hw_ctl_force_start;
- ops->setup_intf_cfg = sde_hw_ctl_intf_cfg;
ops->reset = sde_hw_ctl_reset_control;
- ops->setup_blendstage = sde_hw_ctl_setup_blendstage;
ops->get_bitmask_sspp = sde_hw_ctl_get_bitmask_sspp;
ops->get_bitmask_mixer = sde_hw_ctl_get_bitmask_mixer;
ops->get_bitmask_dspp = sde_hw_ctl_get_bitmask_dspp;
ops->get_bitmask_intf = sde_hw_ctl_get_bitmask_intf;
ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm;
+ ops->setup_blendstage = sde_hw_ctl_setup_blendstage;
};
struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx,
@@ -343,9 +323,8 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx,
return ERR_PTR(-ENOMEM);
cfg = _ctl_offset(idx, m, addr, &c->hw);
- if (IS_ERR_OR_NULL(cfg)) {
+ if (cfg) {
kfree(c);
- pr_err("Error Panic\n");
return ERR_PTR(-EINVAL);
}
@@ -357,8 +336,3 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx,
return c;
}
-
-void sde_hw_ctl_destroy(struct sde_hw_ctl *ctx)
-{
- kfree(ctx);
-}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h
index e914abd69906..5782b356bcf6 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h
@@ -14,7 +14,6 @@
#define _SDE_HW_MDP_CTL_H
#include "sde_hw_mdss.h"
-#include "sde_hw_mdp_util.h"
#include "sde_hw_catalog.h"
struct sde_hw_ctl;
@@ -29,45 +28,13 @@ struct sde_hw_stage_cfg {
};
/**
- * struct sde_hw_intf_cfg :Desbribes how the mdp writes data to
- * output interface
- * @intf : Interface id
- * @wb: writeback id
- * @mode_3d: 3d mux configuration
- */
-struct sde_hw_intf_cfg {
- enum sde_intf intf;
- enum sde_wb wb;
- enum sde_3d_blend_mode mode_3d;
-};
-
-/**
* struct sde_hw_ctl_ops - Interface to the wb Hw driver functions
* Assumption is these functions will be called after clocks are enabled
*/
struct sde_hw_ctl_ops {
- /**
- * kickoff hw operation for Sw controlled interfaces
- * DSI cmd mode and WB interface are SW controlled
- * @ctx : ctl path ctx pointer
- */
- void (*setup_start)(struct sde_hw_ctl *ctx);
-
- /**
- * FLUSH the modules for this control path
- * @ctx : ctl path ctx pointer
- * @flushbits : module flushmask
- */
void (*setup_flush)(struct sde_hw_ctl *ctx,
- u32 flushbits);
-
- /**
- * Setup ctl_path interface config
- * @ctx
- * @cfg : interface config structure pointer
- */
- void (*setup_intf_cfg)(struct sde_hw_ctl *ctx,
- struct sde_hw_intf_cfg *cfg);
+ u32 flushbits,
+ u8 force_start);
int (*reset)(struct sde_hw_ctl *c);
@@ -120,7 +87,7 @@ struct sde_hw_ctl {
/**
* sde_hw_ctl_init(): Initializes the ctl_path hw driver object.
- * should be called before accessing every ctl path registers.
+ * should be called before accessing every mixer.
* @idx: ctl_path index for which driver object is required
* @addr: mapped register io address of MDP
* @m : pointer to mdss catalog data
@@ -129,10 +96,4 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx,
void __iomem *addr,
struct sde_mdss_cfg *m);
-/**
- * sde_hw_ctl_destroy(): Destroys ctl driver context
- * should be called to free the context
- */
-void sde_hw_ctl_destroy(struct sde_hw_ctl *ctx);
-
#endif /*_SDE_HW_MDP_CTL_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c
deleted file mode 100644
index 92c08fff2031..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (c) 2015-2017, 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.
- */
-
-#include "sde_hwio.h"
-#include "sde_hw_catalog.h"
-#include "sde_hw_mdp_top.h"
-
-#define SPLIT_DISPLAY_ENABLE 0x2F4
-#define LOWER_PIPE_CTRL 0x2F8
-#define UPPER_PIPE_CTRL 0x3F0
-#define TE_LINE_INTERVAL 0x3F4
-
-static void sde_hw_setup_split_pipe_control(struct sde_hw_mdp *mdp,
- struct split_pipe_cfg *cfg)
-{
- struct sde_hw_blk_reg_map *c = &mdp->hw;
- u32 upper_pipe;
- u32 lower_pipe;
-
- if (cfg->en) {
- upper_pipe = BIT(8);
- lower_pipe = BIT(8);
-
- if (cfg->mode == INTF_MODE_CMD) {
- upper_pipe |= BIT(0);
- lower_pipe |= BIT(0);
- }
-
- SDE_REG_WRITE(c, LOWER_PIPE_CTRL, lower_pipe);
- SDE_REG_WRITE(c, UPPER_PIPE_CTRL, upper_pipe);
- }
-
- SDE_REG_WRITE(c, SPLIT_DISPLAY_ENABLE, cfg->en & 0x1);
-}
-
-static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,
- unsigned long cap)
-{
- ops->setup_split_pipe = sde_hw_setup_split_pipe_control;
-}
-
-static const struct sde_mdp_cfg *_top_offset(enum sde_mdp mdp,
- const struct sde_mdss_cfg *m,
- void __iomem *addr,
- struct sde_hw_blk_reg_map *b)
-{
- int i;
-
- for (i = 0; i < m->mdp_count; i++) {
- if (mdp == m->mdp[i].id) {
- b->base_off = addr;
- b->blk_off = m->mdp[i].base;
- b->hwversion = m->hwversion;
- return &m->mdp[i];
- }
- }
-
- return ERR_PTR(-EINVAL);
-}
-
-struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
- void __iomem *addr,
- const struct sde_mdss_cfg *m)
-{
- static struct sde_hw_mdp *c;
- const struct sde_mdp_cfg *cfg;
-
- /* mdp top is singleton */
- if (c) {
- pr_err(" %s returning %pK", __func__, c);
- return c;
- }
-
- c = kzalloc(sizeof(*c), GFP_KERNEL);
- pr_err(" %s returning %pK", __func__, c);
- if (!c)
- return ERR_PTR(-ENOMEM);
-
- cfg = _top_offset(idx, m, addr, &c->hw);
- if (IS_ERR_OR_NULL(cfg)) {
- kfree(c);
- return ERR_PTR(-EINVAL);
- }
-
- /*
- * Assign ops
- */
- c->idx = idx;
- c->cap = cfg;
- _setup_mdp_ops(&c->ops, c->cap->features);
-
- /*
- * Perform any default initialization for the intf
- */
- return c;
-}
-
-void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp)
-{
-}
-
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h
deleted file mode 100644
index 216a27e93d46..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright (c) 2015-2017, 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 _SDE_HW_MDP_TOP_H
-#define _SDE_HW_MDP_TOP_H
-
-#include "sde_hw_catalog.h"
-#include "sde_hw_mdss.h"
-#include "sde_hw_mdp_util.h"
-
-struct sde_hw_mdp;
-
-/**
- * struct split_pipe_cfg - pipe configuration for dual display panels
- * @en : Enable/disable dual pipe confguration
- * @mode : Panel interface mode
- */
-struct split_pipe_cfg {
- bool en;
- enum sde_intf_mode mode;
-};
-
-/**
- * struct sde_hw_mdp_ops - interface to the MDP TOP Hw driver functions
- * Assumption is these functions will be called after clocks are enabled.
- * @setup_split_pipe : Programs the pipe control registers
- */
-struct sde_hw_mdp_ops {
- void (*setup_split_pipe)(struct sde_hw_mdp *mdp,
- struct split_pipe_cfg *p);
-};
-
-struct sde_hw_mdp {
- /* base */
- struct sde_hw_blk_reg_map hw;
-
- /* intf */
- enum sde_mdp idx;
- const struct sde_mdp_cfg *cap;
-
- /* ops */
- struct sde_hw_mdp_ops ops;
-};
-
-/**
- * sde_hw_intf_init - initializes the intf driver for the passed interface idx
- * @idx: Interface index for which driver object is required
- * @addr: Mapped register io address of MDP
- * @m: Pointer to mdss catalog data
- */
-struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
- void __iomem *addr,
- const struct sde_mdss_cfg *m);
-
-void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp);
-
-#endif /*_SDE_HW_MDP_TOP_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
index 075e78042f17..ce7ecbf4c8c1 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
-#define SDE_NONE 0
#define SDE_CSC_MATRIX_COEFF_SIZE 9
#define SDE_CSC_CLAMP_SIZE 6
#define SDE_CSC_BIAS_SIZE 3
@@ -58,7 +57,7 @@ enum sde_sspp_type {
};
enum sde_lm {
- LM_0 = 1,
+ LM_0 = 0,
LM_1,
LM_2,
LM_3,
@@ -80,7 +79,7 @@ enum sde_stage {
SDE_STAGE_MAX
};
enum sde_dspp {
- DSPP_0 = 1,
+ DSPP_0 = 0,
DSPP_1,
DSPP_2,
DSPP_3,
@@ -88,7 +87,7 @@ enum sde_dspp {
};
enum sde_ctl {
- CTL_0 = 1,
+ CTL_0 = 0,
CTL_1,
CTL_2,
CTL_3,
@@ -97,23 +96,22 @@ enum sde_ctl {
};
enum sde_cdm {
- CDM_0 = 1,
+ CDM_0 = 0,
CDM_1,
CDM_MAX
};
enum sde_pingpong {
- PINGPONG_0 = 1,
+ PINGPONG_0 = 0,
PINGPONG_1,
PINGPONG_2,
PINGPONG_3,
PINGPONG_4,
- PINGPONG_S0,
PINGPONG_MAX
};
enum sde_intf {
- INTF_0 = 1,
+ INTF_0 = 0,
INTF_1,
INTF_2,
INTF_3,
@@ -155,24 +153,6 @@ enum sde_ad {
AD_MAX
};
-enum sde_cwb {
- CWB_0 = 0x1,
- CWB_1,
- CWB_2,
- CWB_3,
- CWB_MAX
-};
-
-enum sde_wd_timer {
- WD_TIMER_0 = 0x1,
- WD_TIMER_1,
- WD_TIMER_2,
- WD_TIMER_3,
- WD_TIMER_4,
- WD_TIMER_5,
- WD_TIMER_MAX
-};
-
/**
* MDP HW,Component order color map
*/
@@ -228,10 +208,12 @@ enum sde_mdp_fetch_type {
* expected by the HW programming.
*/
enum {
- COLOR_1BIT = 0,
- COLOR_5BIT = 1,
- COLOR_6BIT = 2,
- COLOR_8BIT = 3,
+ COLOR_4BIT,
+ COLOR_5BIT,
+ COLOR_6BIT,
+ COLOR_8BIT,
+ COLOR_ALPHA_1BIT = 0,
+ COLOR_ALPHA_4BIT = 1,
};
enum sde_alpha_blend_type {
@@ -242,26 +224,6 @@ enum sde_alpha_blend_type {
ALPHA_MAX
};
-
-/**
- * enum sde_3d_blend_mode
- * Desribes how the 3d data is blended
- * @BLEND_3D_NONE : 3d blending not enabled
- * @BLEND_3D_FRAME_INT : Frame interleaving
- * @BLEND_3D_H_ROW_INT : Horizontal row interleaving
- * @BLEND_3D_V_ROW_INT : vertical row interleaving
- * @BLEND_3D_COL_INT : column interleaving
- * @BLEND_3D_MAX :
- */
-enum sde_3d_blend_mode {
- BLEND_3D_NONE = 0,
- BLEND_3D_FRAME_INT,
- BLEND_3D_H_ROW_INT,
- BLEND_3D_V_ROW_INT,
- BLEND_3D_COL_INT,
- BLEND_3D_MAX
-};
-
struct addr_info {
u32 plane[SDE_MAX_PLANES];
};
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
index 8180078ac950..e179220daab9 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
@@ -182,7 +182,7 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
u32 opmode = 0;
u32 idx;
- if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
+ if (!_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
return;
opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
@@ -210,7 +210,7 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
(fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
- (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
+ (fmt->bits[C0_G_Y] << 0);
if (flags & SDE_SSPP_ROT_90)
src_format |= BIT(11); /* ROT90 */
@@ -235,9 +235,12 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
}
/* if this is YUV pixel format, enable CSC */
- if (fmt->is_yuv)
+ if (fmt->is_yuv) {
+ _sspp_setup_opmode(ctx, CSC, 0x0);
+ } else {
src_format |= BIT(15);
- _sspp_setup_opmode(ctx, CSC, fmt->is_yuv);
+ _sspp_setup_opmode(ctx, CSC, 0x1);
+ }
opmode |= MDSS_MDP_OP_PE_OVERRIDE;
@@ -257,8 +260,8 @@ static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
struct sde_hw_blk_reg_map *c = &ctx->hw;
u8 color;
u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
- const u32 bytemask = 0xff;
- const u32 shortmask = 0xffff;
+ const u32 bytemask = 0xffff;
+ const u8 shortmask = 0xff;
u32 idx;
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
@@ -280,7 +283,7 @@ static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
((pe_ext->top_ftch[color] & bytemask) << 8)|
(pe_ext->top_rpt[color] & bytemask);
- tot_req_pixels[color] = (((pe_ext->roi_h[color] +
+ tot_req_pixels[color] = (((cfg->src.height +
pe_ext->num_ext_pxls_top[color] +
pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
((pe_ext->roi_w[color] +
@@ -320,30 +323,30 @@ static void sde_hw_sspp_setup_scalar(struct sde_hw_pipe *ctx,
scale_config = BIT(0) | BIT(1);
/* RGB/YUV config */
- scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_LUMA] & mask) << 8;
- scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_LUMA] & mask) << 10;
+ scale_config |= (pe_ext->horz_filter[0] & mask) << 8;
+ scale_config |= (pe_ext->vert_filter[0] & mask) << 10;
/* Aplha config*/
- scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_ALPHA] & mask) << 16;
- scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_ALPHA] & mask) << 18;
+ scale_config |= (pe_ext->horz_filter[3] & mask) << 16;
+ scale_config |= (pe_ext->vert_filter[3] & mask) << 18;
SDE_REG_WRITE(c, SCALE_CONFIG + idx, scale_config);
SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
- pe_ext->init_phase_x[SDE_SSPP_COMP_LUMA]);
+ pe_ext->init_phase_x[0]);
SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
- pe_ext->init_phase_y[SDE_SSPP_COMP_LUMA]);
+ pe_ext->init_phase_y[0]);
SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
- pe_ext->phase_step_x[SDE_SSPP_COMP_LUMA]);
+ pe_ext->phase_step_x[0]);
SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
- pe_ext->phase_step_y[SDE_SSPP_COMP_LUMA]);
+ pe_ext->phase_step_y[0]);
SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
- pe_ext->init_phase_x[SDE_SSPP_COMP_CHROMA]);
+ pe_ext->init_phase_x[1]);
SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
- pe_ext->init_phase_y[SDE_SSPP_COMP_CHROMA]);
+ pe_ext->init_phase_y[1]);
SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
- pe_ext->phase_step_x[SDE_SSPP_COMP_CHROMA]);
+ pe_ext->phase_step_x[1]);
SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
- pe_ext->phase_step_y[SDE_SSPP_COMP_CHROMA]);
+ pe_ext->phase_step_y[0]);
}
/**
@@ -362,7 +365,7 @@ static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
return;
/* program pixel extension override */
- if (pe_ext)
+ if (!pe_ext)
sde_hw_sspp_setup_pe_config(ctx, cfg, pe_ext);
/* src and dest rect programming */
@@ -385,8 +388,10 @@ static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
if (test_bit(SDE_SSPP_SCALAR_RGB, &ctx->cap->features) ||
test_bit(SDE_SSPP_SCALAR_QSEED2, &ctx->cap->features)) {
/* program decimation */
- decimation = ((1 << cfg->horz_decimation) - 1) << 8;
- decimation |= ((1 << cfg->vert_decimation) - 1);
+ if (!cfg->horz_decimation)
+ decimation = (cfg->horz_decimation - 1) << 8;
+ if (!cfg->vert_decimation)
+ decimation |= (cfg->vert_decimation - 1);
sde_hw_sspp_setup_scalar(ctx, pe_ext);
}
@@ -414,8 +419,9 @@ static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
return;
for (i = 0; i < cfg->src.num_planes; i++)
- SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4,
+ SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4,
cfg->addr.plane[i]);
+
}
static void sde_hw_sspp_setup_csc_8bit(struct sde_hw_pipe *ctx,
@@ -470,6 +476,7 @@ static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx,
static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx,
void *cfg)
{
+
}
static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx,
@@ -582,8 +589,3 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
return c;
}
-void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
-{
- kfree(ctx);
-}
-
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
index 0e78c52cde56..733837286241 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
@@ -15,6 +15,7 @@
#include "sde_hw_catalog.h"
#include "sde_hw_mdss.h"
+#include "sde_mdp_formats.h"
#include "sde_hw_mdp_util.h"
struct sde_hw_pipe;
@@ -28,15 +29,6 @@ struct sde_hw_pipe;
#define SDE_SSPP_SOURCE_ROTATED_90 0x8
#define SDE_SSPP_ROT_90 0x10
-/**
- * Component indices
- */
-enum {
- SDE_SSPP_COMP_LUMA = 0,
- SDE_SSPP_COMP_CHROMA = 1,
- SDE_SSPP_COMP_ALPHA = 3
-};
-
enum {
SDE_MDP_FRAME_LINEAR,
SDE_MDP_FRAME_TILE_A4X,
@@ -96,7 +88,6 @@ struct sde_hw_pixel_ext {
int btm_rpt[SDE_MAX_PLANES];
uint32_t roi_w[SDE_MAX_PLANES];
- uint32_t roi_h[SDE_MAX_PLANES];
/*
* Filter type to be used for scaling in horizontal and vertical
@@ -271,12 +262,5 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
void __iomem *addr,
struct sde_mdss_cfg *m);
-/**
- * sde_hw_sspp_destroy(): Destroys SSPP driver context
- * should be called during Hw pipe cleanup.
- * @ctx: Pointer to SSPP driver context returned by sde_hw_sspp_init
- */
-void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx);
-
#endif /*_SDE_HW_SSPP_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_hwio.h b/drivers/gpu/drm/msm/sde/sde_hwio.h
index 2531463b654e..df0530ecfa34 100644
--- a/drivers/gpu/drm/msm/sde/sde_hwio.h
+++ b/drivers/gpu/drm/msm/sde/sde_hwio.h
@@ -28,9 +28,6 @@
#define HIST_INTR_EN 0x01c
#define HIST_INTR_STATUS 0x020
#define HIST_INTR_CLEAR 0x024
-#define INTF_INTR_EN 0x1C0
-#define INTF_INTR_STATUS 0x1C4
-#define INTF_INTR_CLEAR 0x1C8
#define SPLIT_DISPLAY_EN 0x2F4
#define SPLIT_DISPLAY_UPPER_PIPE_CTRL 0x2F8
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300
diff --git a/drivers/gpu/drm/msm/sde/sde_irq.c b/drivers/gpu/drm/msm/sde/sde_irq.c
index 722845df3d0b..7f87acb86c96 100644
--- a/drivers/gpu/drm/msm/sde/sde_irq.c
+++ b/drivers/gpu/drm/msm/sde/sde_irq.c
@@ -12,263 +12,36 @@
#include <linux/irqdomain.h>
#include <linux/irq.h>
-#include <linux/kthread.h>
#include "msm_drv.h"
#include "sde_kms.h"
-static void sde_irq_callback_handler(void *arg, int irq_idx)
+void sde_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+ uint32_t old_irqmask)
{
- struct sde_kms *sde_kms = arg;
- struct sde_irq *irq_obj = &sde_kms->irq_obj;
-
- /*
- * Perform registered function callback
- */
- if (irq_obj->irq_cb_tbl && irq_obj->irq_cb_tbl[irq_idx].func)
- irq_obj->irq_cb_tbl[irq_idx].func(
- irq_obj->irq_cb_tbl[irq_idx].arg,
- irq_idx);
-
- /*
- * Clear pending interrupt status in HW.
- * NOTE: sde_irq_callback_handler is protected by top-level
- * spinlock, so it is safe to clear any interrupt status here.
- */
- sde_kms->hw_intr->ops.clear_interrupt_status(
- sde_kms->hw_intr,
- irq_idx);
-}
-
-static void sde_irq_intf_error_handler(void *arg, int irq_idx)
-{
- DRM_ERROR("INTF underrun detected, irq_idx=%d\n", irq_idx);
-}
-
-void sde_set_irqmask(struct sde_kms *sde_kms, uint32_t reg, uint32_t irqmask)
-{
- if (!sde_kms || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.set_mask)
- return;
-
- sde_kms->hw_intr->ops.set_mask(sde_kms->hw_intr, reg, irqmask);
-}
-
-int sde_irq_idx_lookup(struct sde_kms *sde_kms, enum sde_intr_type intr_type,
- u32 instance_idx)
-{
- if (!sde_kms || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.irq_idx_lookup)
- return -EINVAL;
-
- return sde_kms->hw_intr->ops.irq_idx_lookup(intr_type,
- instance_idx);
-}
-
-int sde_enable_irq(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count)
-{
- int i;
- int ret = 0;
-
- if (!sde_kms || !irq_idxs || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.enable_irq)
- return -EINVAL;
-
- for (i = 0; i < irq_count; i++) {
- ret = sde_kms->hw_intr->ops.enable_irq(
- sde_kms->hw_intr,
- irq_idxs[i]);
- if (ret) {
- DRM_ERROR("Fail to enable IRQ for irq_idx:%d\n",
- irq_idxs[i]);
- return ret;
- }
- }
-
- return ret;
-}
-
-int sde_disable_irq(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count)
-{
- int i;
- int ret = 0;
-
- if (!sde_kms || !irq_idxs || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.disable_irq)
- return -EINVAL;
-
- for (i = 0; i < irq_count; i++) {
- ret = sde_kms->hw_intr->ops.disable_irq(
- sde_kms->hw_intr,
- irq_idxs[i]);
- if (ret) {
- DRM_ERROR("Fail to disable IRQ for irq_idx:%d\n",
- irq_idxs[i]);
- return ret;
- }
- }
-
- return ret;
-}
-
-int sde_register_irq_callback(struct sde_kms *sde_kms, int irq_idx,
- struct sde_irq_callback *register_irq_cb)
-{
- struct sde_irq_callback *irq_cb_tbl;
- unsigned long irq_flags;
-
- /*
- * We allow NULL register_irq_cb as input for callback registration
- */
- if (!sde_kms || !sde_kms->irq_obj.irq_cb_tbl)
- return -EINVAL;
-
- if (irq_idx < 0 || irq_idx >= sde_kms->hw_intr->irq_idx_tbl_size) {
- DRM_ERROR("invalid IRQ index: [%d]\n", irq_idx);
- return -EINVAL;
- }
-
- irq_cb_tbl = sde_kms->irq_obj.irq_cb_tbl;
- spin_lock_irqsave(&sde_kms->irq_obj.cb_lock, irq_flags);
- irq_cb_tbl[irq_idx].func = register_irq_cb ?
- register_irq_cb->func : NULL;
- irq_cb_tbl[irq_idx].arg = register_irq_cb ?
- register_irq_cb->arg : NULL;
- spin_unlock_irqrestore(&sde_kms->irq_obj.cb_lock, irq_flags);
-
- return 0;
-}
-
-void sde_clear_all_irqs(struct sde_kms *sde_kms)
-{
- if (!sde_kms || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.clear_all_irqs)
- return;
-
- sde_kms->hw_intr->ops.clear_all_irqs(sde_kms->hw_intr);
-}
-
-void sde_disable_all_irqs(struct sde_kms *sde_kms)
-{
- if (!sde_kms || !sde_kms->hw_intr ||
- !sde_kms->hw_intr->ops.disable_all_irqs)
- return;
-
- sde_kms->hw_intr->ops.disable_all_irqs(sde_kms->hw_intr);
}
void sde_irq_preinstall(struct msm_kms *kms)
{
- struct sde_kms *sde_kms = to_sde_kms(kms);
-
- sde_enable(sde_kms);
- sde_clear_all_irqs(sde_kms);
- sde_disable_all_irqs(sde_kms);
- sde_disable(sde_kms);
-
- spin_lock_init(&sde_kms->irq_obj.cb_lock);
-
- /* Create irq callbacks for all possible irq_idx */
- sde_kms->irq_obj.total_irqs = sde_kms->hw_intr->irq_idx_tbl_size;
- sde_kms->irq_obj.irq_cb_tbl = kcalloc(sde_kms->irq_obj.total_irqs,
- sizeof(struct sde_irq_callback), GFP_KERNEL);
- if (!sde_kms->irq_obj.irq_cb_tbl)
- DRM_ERROR("Fail to allocate memory of IRQ callback list\n");
}
int sde_irq_postinstall(struct msm_kms *kms)
{
- struct sde_kms *sde_kms = to_sde_kms(kms);
- struct sde_irq_callback irq_cb;
- int irq_idx;
- int i;
-
- irq_cb.func = sde_irq_intf_error_handler;
- irq_cb.arg = sde_kms;
-
- /* Register interface underrun callback */
- sde_enable(sde_kms);
- for (i = 0; i < sde_kms->catalog->intf_count; i++) {
- irq_idx = sde_irq_idx_lookup(sde_kms,
- SDE_IRQ_TYPE_INTF_UNDER_RUN, i+INTF_0);
- sde_register_irq_callback(sde_kms, irq_idx, &irq_cb);
- sde_enable_irq(sde_kms, &irq_idx, 1);
- }
- sde_disable(sde_kms);
-
return 0;
}
void sde_irq_uninstall(struct msm_kms *kms)
{
- struct sde_kms *sde_kms = to_sde_kms(kms);
-
- sde_enable(sde_kms);
- sde_clear_all_irqs(sde_kms);
- sde_disable_all_irqs(sde_kms);
- sde_disable(sde_kms);
-
- kfree(sde_kms->irq_obj.irq_cb_tbl);
-}
-
-static void _sde_irq_mdp_done(struct sde_kms *sde_kms)
-{
- /*
- * Read interrupt status from all sources. Interrupt status are
- * stored within hw_intr.
- * Function will also clear the interrupt status after reading.
- * Individual interrupt status bit will only get stored if it
- * is enabled.
- */
- sde_kms->hw_intr->ops.get_interrupt_statuses(sde_kms->hw_intr);
-
- /*
- * Dispatch to HW driver to handle interrupt lookup that is being
- * fired. When matching interrupt is located, HW driver will call to
- * sde_irq_callback_handler with the irq_idx from the lookup table.
- * sde_irq_callback_handler will perform the registered function
- * callback, and do the interrupt status clearing once the registered
- * callback is finished.
- */
- sde_kms->hw_intr->ops.dispatch_irqs(
- sde_kms->hw_intr,
- sde_irq_callback_handler,
- sde_kms);
}
irqreturn_t sde_irq(struct msm_kms *kms)
{
- struct sde_kms *sde_kms = to_sde_kms(kms);
- u32 interrupts;
-
- sde_kms->hw_intr->ops.get_interrupt_sources(sde_kms->hw_intr,
- &interrupts);
-
- /*
- * Taking care of MDP interrupt
- */
- if (interrupts & IRQ_SOURCE_MDP) {
- interrupts &= ~IRQ_SOURCE_MDP;
- _sde_irq_mdp_done(sde_kms);
- }
-
- /*
- * Routing all other interrupts to external drivers
- */
- while (interrupts) {
- irq_hw_number_t hwirq = fls(interrupts) - 1;
-
- generic_handle_irq(irq_find_mapping(
- sde_kms->irqcontroller.domain, hwirq));
- interrupts &= ~(1 << hwirq);
- }
-
return IRQ_HANDLED;
}
int sde_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
{
- return sde_crtc_vblank(crtc);
+ return 0;
}
void sde_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
@@ -303,13 +76,6 @@ static int sde_hw_irqdomain_map(struct irq_domain *d,
unsigned int irq, irq_hw_number_t hwirq)
{
struct sde_kms *sde_kms = d->host_data;
- uint32_t valid_irqs;
-
- sde_kms->hw_intr->ops.get_valid_interrupts(sde_kms->hw_intr,
- &valid_irqs);
-
- if (!(valid_irqs & (1 << hwirq)))
- return -EPERM;
irq_set_chip_and_handler(irq, &sde_hw_irq_chip, handle_level_irq);
irq_set_chip_data(irq, sde_kms);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 7fba38b9e60d..2cbff04e98cd 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -12,65 +12,31 @@
#include <drm/drm_crtc.h>
#include "msm_drv.h"
-#include "msm_mmu.h"
#include "sde_kms.h"
#include "sde_hw_mdss.h"
-#include "sde_hw_intf.h"
-static const char * const iommu_ports[] = {
- "mdp_0",
-};
-
-static const struct sde_hw_res_map res_table[INTF_MAX] = {
- { SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE},
- { INTF_0, SDE_NONE, SDE_NONE, SDE_NONE},
- { INTF_1, LM_0, PINGPONG_0, CTL_0},
- { INTF_2, LM_1, PINGPONG_1, CTL_1},
- { INTF_3, SDE_NONE, SDE_NONE, CTL_2},
-};
-
-
-#define DEFAULT_MDP_SRC_CLK 200000000
-
-int sde_disable(struct sde_kms *sde_kms)
-{
- DBG("");
-
- return 0;
-}
-
-int sde_enable(struct sde_kms *sde_kms)
+static int modeset_init_intf(struct sde_kms *sde_kms, int intf_num)
{
- DBG("");
-
- clk_prepare_enable(sde_kms->ahb_clk);
- clk_prepare_enable(sde_kms->axi_clk);
- clk_prepare_enable(sde_kms->core_clk);
- if (sde_kms->lut_clk)
- clk_prepare_enable(sde_kms->lut_clk);
+ struct sde_mdss_cfg *catalog = sde_kms->catalog;
+ u32 intf_type = catalog->intf[intf_num].type;
+
+ switch (intf_type) {
+ case INTF_NONE:
+ break;
+ case INTF_DSI:
+ break;
+ case INTF_LCDC:
+ break;
+ case INTF_HDMI:
+ break;
+ case INTF_EDP:
+ default:
+ break;
+ }
return 0;
}
-static void sde_prepare_commit(struct msm_kms *kms,
- struct drm_atomic_state *state)
-{
- struct sde_kms *sde_kms = to_sde_kms(kms);
- sde_enable(sde_kms);
-}
-
-static void sde_complete_commit(struct msm_kms *kms,
- struct drm_atomic_state *state)
-{
- struct sde_kms *sde_kms = to_sde_kms(kms);
- sde_disable(sde_kms);
-}
-
-static void sde_wait_for_crtc_commit_done(struct msm_kms *kms,
- struct drm_crtc *crtc)
-{
- sde_crtc_wait_for_commit_done(crtc);
-}
static int modeset_init(struct sde_kms *sde_kms)
{
struct msm_drm_private *priv = sde_kms->dev->dev_private;
@@ -96,9 +62,8 @@ static int modeset_init(struct sde_kms *sde_kms)
|| !num_private_planes)
primary = false;
- plane = sde_plane_init(dev, catalog->sspp[i].id, primary);
+ plane = sde_plane_init(dev, primary);
if (IS_ERR(plane)) {
- pr_err("%s: sde_plane_init failed", __func__);
ret = PTR_ERR(plane);
goto fail;
}
@@ -106,7 +71,7 @@ static int modeset_init(struct sde_kms *sde_kms)
if (primary)
primary_planes[primary_planes_idx++] = plane;
- if (primary && num_private_planes)
+ if (num_private_planes)
num_private_planes--;
}
@@ -116,21 +81,15 @@ static int modeset_init(struct sde_kms *sde_kms)
goto fail;
}
- /*
- * Enumerate displays supported
- */
- sde_encoders_init(dev);
-
- /* Create one CRTC per display */
- for (i = 0; i < priv->num_encoders; i++) {
+ /* Create one CRTC per mixer */
+ for (i = 0; i < catalog->mixer_count; i++) {
/*
- * Each CRTC receives a private plane. We start
+ * Each mixer receives a private plane. We start
* with first RGB, and then DMA and then VIG.
*/
struct drm_crtc *crtc;
- crtc = sde_crtc_init(dev, priv->encoders[i],
- primary_planes[i], i);
+ crtc = sde_crtc_init(dev, NULL, primary_planes[i], i);
if (IS_ERR(crtc)) {
ret = PTR_ERR(crtc);
goto fail;
@@ -138,13 +97,11 @@ static int modeset_init(struct sde_kms *sde_kms)
priv->crtcs[priv->num_crtcs++] = crtc;
}
- /*
- * Iterate through the list of encoders and
- * set the possible CRTCs
- */
- for (i = 0; i < priv->num_encoders; i++)
- priv->encoders[i]->possible_crtcs = (1 << priv->num_crtcs) - 1;
-
+ for (i = 0; i < catalog->intf_count; i++) {
+ ret = modeset_init_intf(sde_kms, i);
+ if (ret)
+ goto fail;
+ }
return 0;
fail:
return ret;
@@ -167,28 +124,27 @@ static void sde_preclose(struct msm_kms *kms, struct drm_file *file)
static void sde_destroy(struct msm_kms *kms)
{
- struct sde_kms *sde_kms = to_sde_kms(kms);
+ struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(kms));
sde_irq_domain_fini(sde_kms);
- sde_hw_intr_destroy(sde_kms->hw_intr);
kfree(sde_kms);
}
-static const struct msm_kms_funcs kms_funcs = {
- .hw_init = sde_hw_init,
- .irq_preinstall = sde_irq_preinstall,
- .irq_postinstall = sde_irq_postinstall,
- .irq_uninstall = sde_irq_uninstall,
- .irq = sde_irq,
- .prepare_commit = sde_prepare_commit,
- .complete_commit = sde_complete_commit,
- .wait_for_crtc_commit_done = sde_wait_for_crtc_commit_done,
- .enable_vblank = sde_enable_vblank,
- .disable_vblank = sde_disable_vblank,
- .get_format = mdp_get_format,
- .round_pixclk = sde_round_pixclk,
- .preclose = sde_preclose,
- .destroy = sde_destroy,
+static const struct mdp_kms_funcs kms_funcs = {
+ .base = {
+ .hw_init = sde_hw_init,
+ .irq_preinstall = sde_irq_preinstall,
+ .irq_postinstall = sde_irq_postinstall,
+ .irq_uninstall = sde_irq_uninstall,
+ .irq = sde_irq,
+ .enable_vblank = sde_enable_vblank,
+ .disable_vblank = sde_disable_vblank,
+ .get_format = mdp_get_format,
+ .round_pixclk = sde_round_pixclk,
+ .preclose = sde_preclose,
+ .destroy = sde_destroy,
+ },
+ .set_irqmask = sde_set_irqmask,
};
static int get_clk(struct platform_device *pdev, struct clk **clkp,
@@ -219,16 +175,15 @@ struct sde_kms *sde_hw_setup(struct platform_device *pdev)
if (!sde_kms)
return NULL;
- msm_kms_init(&sde_kms->base, &kms_funcs);
+ mdp_kms_init(&sde_kms->base, &kms_funcs);
- kms = &sde_kms->base;
+ kms = &sde_kms->base.base;
sde_kms->mmio = msm_ioremap(pdev, "mdp_phys", "SDE");
if (IS_ERR(sde_kms->mmio)) {
ret = PTR_ERR(sde_kms->mmio);
goto fail;
}
- pr_err("Mapped Mdp address space @%pK", sde_kms->mmio);
sde_kms->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
if (IS_ERR(sde_kms->vbif)) {
@@ -292,27 +247,8 @@ struct sde_kms *sde_hw_setup(struct platform_device *pdev)
get_clk(pdev, &sde_kms->mmagic_clk, "mmagic_clk", false);
get_clk(pdev, &sde_kms->iommu_clk, "iommu_clk", false);
- if (sde_kms->mmagic) {
- ret = regulator_enable(sde_kms->mmagic);
- if (ret) {
- dev_err(sde_kms->dev->dev,
- "failed to enable mmagic GDSC: %d\n", ret);
- goto fail;
- }
- }
- if (sde_kms->mmagic_clk) {
- clk_prepare_enable(sde_kms->mmagic_clk);
- if (ret) {
- dev_err(sde_kms->dev->dev, "failed to enable mmagic_clk\n");
- goto undo_gdsc;
- }
- }
-
return sde_kms;
-undo_gdsc:
- if (sde_kms->mmagic)
- regulator_disable(sde_kms->mmagic);
fail:
if (kms)
sde_destroy(kms);
@@ -320,111 +256,6 @@ fail:
return ERR_PTR(ret);
}
-static int sde_translation_ctrl_pwr(struct sde_kms *sde_kms, bool on)
-{
- struct device *dev = sde_kms->dev->dev;
- int ret;
-
- if (on) {
- if (sde_kms->iommu_clk) {
- ret = clk_prepare_enable(sde_kms->iommu_clk);
- if (ret) {
- dev_err(dev, "failed to enable iommu_clk\n");
- goto undo_mmagic_clk;
- }
- }
- } else {
- if (sde_kms->iommu_clk)
- clk_disable_unprepare(sde_kms->iommu_clk);
- if (sde_kms->mmagic_clk)
- clk_disable_unprepare(sde_kms->mmagic_clk);
- if (sde_kms->mmagic)
- regulator_disable(sde_kms->mmagic);
- }
-
- return 0;
-
-undo_mmagic_clk:
- if (sde_kms->mmagic_clk)
- clk_disable_unprepare(sde_kms->mmagic_clk);
-
- return ret;
-}
-int sde_mmu_init(struct sde_kms *sde_kms)
-{
- struct sde_mdss_cfg *catalog = sde_kms->catalog;
- struct sde_hw_intf *intf = NULL;
- struct iommu_domain *iommu;
- struct msm_mmu *mmu;
- int i, ret;
-
- /*
- * 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):
- */
- sde_enable(sde_kms);
- for (i = 0; i < catalog->intf_count; i++) {
- intf = sde_hw_intf_init(catalog->intf[i].id,
- sde_kms->mmio,
- catalog);
- if (!IS_ERR_OR_NULL(intf)) {
- intf->ops.enable_timing(intf, 0x0);
- sde_hw_intf_deinit(intf);
- }
- }
- sde_disable(sde_kms);
- msleep(20);
-
- iommu = iommu_domain_alloc(&platform_bus_type);
-
- if (!IS_ERR_OR_NULL(iommu)) {
- mmu = msm_smmu_new(sde_kms->dev->dev, MSM_SMMU_DOMAIN_UNSECURE);
- if (IS_ERR(mmu)) {
- ret = PTR_ERR(mmu);
- dev_err(sde_kms->dev->dev,
- "failed to init iommu: %d\n", ret);
- iommu_domain_free(iommu);
- goto fail;
- }
-
- ret = sde_translation_ctrl_pwr(sde_kms, true);
- if (ret) {
- dev_err(sde_kms->dev->dev,
- "failed to power iommu: %d\n", ret);
- mmu->funcs->destroy(mmu);
- goto fail;
- }
-
- ret = mmu->funcs->attach(mmu, (const char **)iommu_ports,
- ARRAY_SIZE(iommu_ports));
- if (ret) {
- dev_err(sde_kms->dev->dev,
- "failed to attach iommu: %d\n", ret);
- mmu->funcs->destroy(mmu);
- goto fail;
- }
- } else {
- dev_info(sde_kms->dev->dev,
- "no iommu, fallback to phys contig buffers for scanout\n");
- mmu = NULL;
- }
- sde_kms->mmu = mmu;
-
- sde_kms->mmu_id = msm_register_mmu(sde_kms->dev, mmu);
- if (sde_kms->mmu_id < 0) {
- ret = sde_kms->mmu_id;
- dev_err(sde_kms->dev->dev,
- "failed to register sde iommu: %d\n", ret);
- goto fail;
- }
-
- return 0;
-fail:
- return ret;
-
-}
-
struct msm_kms *sde_kms_init(struct drm_device *dev)
{
struct platform_device *pdev = dev->platformdev;
@@ -440,7 +271,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
}
sde_kms->dev = dev;
- msm_kms = &sde_kms->base;
+ msm_kms = &sde_kms->base.base;
/*
* Currently hardcoding to MDSS version 1.7.0 (8996)
@@ -451,21 +282,10 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
sde_kms->catalog = catalog;
- /* we need to set a default rate before enabling.
- * Set a safe rate first, before initializing catalog
- * later set more optimal rate based on bandwdith/clock
- * requirements
- */
-
- clk_set_rate(sde_kms->src_clk, DEFAULT_MDP_SRC_CLK);
- sde_enable(sde_kms);
- sde_kms->hw_res.res_table = res_table;
-
/*
* Now we need to read the HW catalog and initialize resources such as
* clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
*/
- sde_mmu_init(sde_kms);
/*
* modeset_init should create the DRM related objects i.e. CRTCs,
@@ -476,19 +296,6 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
- /*
- * we can assume the max crtc width is equal to the max supported
- * by LM_0
- * Also fixing the max height to 4k
- */
- dev->mode_config.max_width = catalog->mixer[0].sblk->maxwidth;
- dev->mode_config.max_height = 4096;
-
- sde_kms->hw_intr = sde_rm_acquire_intr(sde_kms);
-
- if (IS_ERR_OR_NULL(sde_kms->hw_intr))
- goto fail;
-
return msm_kms;
fail:
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 7ac1b6b827bc..24dabc93583f 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -17,72 +17,15 @@
#include "msm_kms.h"
#include "mdp/mdp_kms.h"
#include "sde_hw_catalog.h"
-#include "sde_hw_mdp_ctl.h"
-#include "sde_hw_lm.h"
-#include "sde_hw_interrupts.h"
-
-/*
- * struct sde_irq_callback - IRQ callback handlers
- * @func: intr handler
- * @arg: argument for the handler
- */
-struct sde_irq_callback {
- void (*func)(void *arg, int irq_idx);
- void *arg;
-};
-
-/**
- * struct sde_irq: IRQ structure contains callback registration info
- * @total_irq: total number of irq_idx obtained from HW interrupts mapping
- * @irq_cb_tbl: array of IRQ callbacks setting
- * @cb_lock: callback lock
- */
-struct sde_irq {
- u32 total_irqs;
- struct sde_irq_callback *irq_cb_tbl;
- spinlock_t cb_lock;
-};
-
-/**
- * struct sde_hw_res_map : Default resource table identifying default
- * hw resource map. Primarily used for forcing DSI to use CTL_0/1
- * and Pingpong 0/1, if the field is set to SDE_NONE means any HW
- * intstance for that tpye is allowed as long as it is unused.
- */
-struct sde_hw_res_map {
- enum sde_intf intf;
- enum sde_lm lm;
- enum sde_pingpong pp;
- enum sde_ctl ctl;
-};
-
-/* struct sde_hw_resource_manager : Resource mananger maintains the current
- * platform configuration and manages shared
- * hw resources ex:ctl_path hw driver context
- * is needed by CRTCs/PLANEs/ENCODERs
- * @ctl : table of control path hw driver contexts allocated
- * @mixer : list of mixer hw drivers contexts allocated
- * @intr : pointer to hw interrupt context
- * @res_table : pointer to default hw_res table for this platform
- * @feature_map :BIT map for default enabled features ex:specifies if PP_SPLIT
- * is enabled/disabled by defalt for this platform
- */
-struct sde_hw_resource_manager {
- struct sde_hw_ctl *ctl[CTL_MAX];
- struct sde_hw_mixer *mixer[LM_MAX];
- struct sde_hw_intr *intr;
- const struct sde_hw_res_map *res_table;
- bool feature_map;
-};
+#include "sde_hw_mdss.h"
struct sde_kms {
- struct msm_kms base;
+ struct mdp_kms base;
struct drm_device *dev;
int rev;
struct sde_mdss_cfg *catalog;
struct msm_mmu *mmu;
- int mmu_id;
/* io/register spaces: */
void __iomem *mmio, *vbif;
@@ -104,15 +47,6 @@ struct sde_kms {
unsigned long enabled_mask;
struct irq_domain *domain;
} irqcontroller;
-
- struct sde_hw_intr *hw_intr;
- struct sde_irq irq_obj;
- struct sde_hw_resource_manager hw_res;
-};
-
-struct vsync_info {
- u32 frame_count;
- u32 line_count;
};
#define to_sde_kms(x) container_of(x, struct sde_kms, base)
@@ -142,163 +76,41 @@ struct sde_plane_state {
int sde_disable(struct sde_kms *sde_kms);
int sde_enable(struct sde_kms *sde_kms);
-/**
- * HW resource manager functions
- * @sde_rm_acquire_ctl_path : Allocates control path
- * @sde_rm_get_ctl_path : returns control path driver context for already
- * acquired ctl path
- * @sde_rm_release_ctl_path : Frees control path driver context
- * @sde_rm_acquire_mixer : Allocates mixer hw driver context
- * @sde_rm_get_mixer : returns mixer context for already
- * acquired mixer
- * @sde_rm_release_mixer : Frees mixer hw driver context
- * @sde_rm_get_hw_res_map : Returns map for the passed INTF
- */
-struct sde_hw_ctl *sde_rm_acquire_ctl_path(struct sde_kms *sde_kms,
- enum sde_ctl idx);
-struct sde_hw_ctl *sde_rm_get_ctl_path(struct sde_kms *sde_kms,
- enum sde_ctl idx);
-void sde_rm_release_ctl_path(struct sde_kms *sde_kms,
- enum sde_ctl idx);
-struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms,
- enum sde_lm idx);
-struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms,
- enum sde_lm idx);
-void sde_rm_release_mixer(struct sde_kms *sde_kms,
- enum sde_lm idx);
-struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms);
-struct sde_hw_intr *sde_rm_get_intr(struct sde_kms *sde_kms);
-
-const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms,
- enum sde_intf idx);
-
-/**
- * IRQ functions
- */
-int sde_irq_domain_init(struct sde_kms *sde_kms);
-int sde_irq_domain_fini(struct sde_kms *sde_kms);
+void sde_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+ uint32_t old_irqmask);
void sde_irq_preinstall(struct msm_kms *kms);
int sde_irq_postinstall(struct msm_kms *kms);
void sde_irq_uninstall(struct msm_kms *kms);
irqreturn_t sde_irq(struct msm_kms *kms);
-
-/**
- * sde_set_irqmask - IRQ helper function for writing IRQ mask
- * to SDE HW interrupt register.
- * @sde_kms: SDE handle
- * @reg_off: SDE HW interrupt register offset
- * @irqmask: IRQ mask
- */
-void sde_set_irqmask(
- struct sde_kms *sde_kms,
- uint32_t reg_off,
- uint32_t irqmask);
-
-/**
- * sde_irq_idx_lookup - IRQ helper function for lookup irq_idx from HW
- * interrupt mapping table.
- * @sde_kms: SDE handle
- * @intr_type: SDE HW interrupt type for lookup
- * @instance_idx: SDE HW block instance defined in sde_hw_mdss.h
- * @return: irq_idx or -EINVAL when fail to lookup
- */
-int sde_irq_idx_lookup(
- struct sde_kms *sde_kms,
- enum sde_intr_type intr_type,
- uint32_t instance_idx);
-
-/**
- * sde_enable_irq - IRQ helper function for enabling one or more IRQs
- * @sde_kms: SDE handle
- * @irq_idxs: Array of irq index
- * @irq_count: Number of irq_idx provided in the array
- * @return: 0 for success enabling IRQ, otherwise failure
- */
-int sde_enable_irq(
- struct sde_kms *sde_kms,
- int *irq_idxs,
- uint32_t irq_count);
-
-/**
- * sde_disable_irq - IRQ helper function for diabling one of more IRQs
- * @sde_kms: SDE handle
- * @irq_idxs: Array of irq index
- * @irq_count: Number of irq_idx provided in the array
- * @return: 0 for success disabling IRQ, otherwise failure
- */
-int sde_disable_irq(
- struct sde_kms *sde_kms,
- int *irq_idxs,
- uint32_t irq_count);
-
-/**
- * sde_register_irq_callback - For registering callback function on IRQ
- * interrupt
- * @sde_kms: SDE handle
- * @irq_idx: irq index
- * @irq_cb: IRQ callback structure, containing callback function
- * and argument. Passing NULL for irq_cb will unregister
- * the callback for the given irq_idx
- * @return: 0 for success registering callback, otherwise failure
- */
-int sde_register_irq_callback(
- struct sde_kms *sde_kms,
- int irq_idx,
- struct sde_irq_callback *irq_cb);
-
-/**
- * sde_clear_all_irqs - Clearing all SDE IRQ interrupt status
- * @sde_kms: SDE handle
- */
-void sde_clear_all_irqs(struct sde_kms *sde_kms);
-
-/**
- * sde_disable_all_irqs - Diabling all SDE IRQ interrupt
- * @sde_kms: SDE handle
- */
-void sde_disable_all_irqs(struct sde_kms *sde_kms);
-
-/**
- * Vblank enable/disable functions
- */
int sde_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
void sde_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
-/**
- * Plane functions
- */
enum sde_sspp sde_plane_pipe(struct drm_plane *plane);
-struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe,
- bool private_plane);
+void sde_plane_install_properties(struct drm_plane *plane,
+ struct drm_mode_object *obj);
+void sde_plane_set_scanout(struct drm_plane *plane,
+ struct drm_framebuffer *fb);
+int sde_plane_mode_set(struct drm_plane *plane,
+ struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
+void sde_plane_complete_flip(struct drm_plane *plane);
+struct drm_plane *sde_plane_init(struct drm_device *dev, bool private_plane);
-/**
- * CRTC functions
- */
uint32_t sde_crtc_vblank(struct drm_crtc *crtc);
-void sde_crtc_wait_for_commit_done(struct drm_crtc *crtc);
+
void sde_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
+void sde_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
+void sde_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
struct drm_crtc *sde_crtc_init(struct drm_device *dev,
struct drm_encoder *encoder,
struct drm_plane *plane, int id);
-/**
- * Encoder functions and data types
- */
-struct sde_encoder_hw_resources {
- enum sde_intf_mode intfs[INTF_MAX];
- bool pingpongs[PINGPONG_MAX];
- bool ctls[CTL_MAX];
- bool pingpongsplit;
-};
-
-void sde_encoder_get_hw_resources(struct drm_encoder *encoder,
- struct sde_encoder_hw_resources *hw_res);
-void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
- void (*cb)(void *), void *data);
-void sde_encoders_init(struct drm_device *dev);
-void sde_encoder_get_vsync_info(struct drm_encoder *encoder,
- struct vsync_info *vsync);
-
+struct drm_encoder *sde_encoder_init(struct drm_device *dev, int intf);
+int sde_irq_domain_init(struct sde_kms *sde_kms);
+int sde_irq_domain_fini(struct sde_kms *sde_kms);
#endif /* __sde_kms_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_kms_utils.c b/drivers/gpu/drm/msm/sde/sde_kms_utils.c
deleted file mode 100644
index 9d6f28cfc06c..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_kms_utils.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2015-2016, 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.
- */
-
-#include "sde_kms.h"
-#include "sde_hw_lm.h"
-#include "sde_hw_mdp_ctl.h"
-
-struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms)
-{
- struct sde_hw_intr *hw_intr;
-
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
-
- if (sde_kms->hw_res.intr) {
- DRM_ERROR("intr already in use ");
- return ERR_PTR(-ENODEV);
- }
-
- sde_enable(sde_kms);
- hw_intr = sde_hw_intr_init(sde_kms->mmio,
- sde_kms->catalog);
- sde_disable(sde_kms);
-
- if (!IS_ERR_OR_NULL(hw_intr))
- sde_kms->hw_res.intr = hw_intr;
-
- return hw_intr;
-}
-
-struct sde_hw_intr *sde_rm_get_intr(struct sde_kms *sde_kms)
-{
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
-
- return sde_kms->hw_res.intr;
-}
-
-struct sde_hw_ctl *sde_rm_acquire_ctl_path(struct sde_kms *sde_kms,
- enum sde_ctl idx)
-{
- struct sde_hw_ctl *hw_ctl;
-
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS driver");
- return ERR_PTR(-EINVAL);
- }
-
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) {
- DRM_ERROR("Invalid Ctl Path Idx %d", idx);
- return ERR_PTR(-EINVAL);
- }
-
- if (sde_kms->hw_res.ctl[idx]) {
- DRM_ERROR("CTL path %d already in use ", idx);
- return ERR_PTR(-ENODEV);
- }
-
- sde_enable(sde_kms);
- hw_ctl = sde_hw_ctl_init(idx, sde_kms->mmio, sde_kms->catalog);
- sde_disable(sde_kms);
-
- if (!IS_ERR_OR_NULL(hw_ctl))
- sde_kms->hw_res.ctl[idx] = hw_ctl;
-
- return hw_ctl;
-}
-
-struct sde_hw_ctl *sde_rm_get_ctl_path(struct sde_kms *sde_kms,
- enum sde_ctl idx)
-{
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) {
- DRM_ERROR("Invalid Ctl path Idx %d", idx);
- return ERR_PTR(-EINVAL);
- }
-
- return sde_kms->hw_res.ctl[idx];
-}
-
-void sde_rm_release_ctl_path(struct sde_kms *sde_kms, enum sde_ctl idx)
-{
- if (!sde_kms) {
- DRM_ERROR("Invalid pointer\n");
- return;
- }
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) {
- DRM_ERROR("Invalid Ctl path Idx %d", idx);
- return;
- }
-}
-
-struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms,
- enum sde_lm idx)
-{
- struct sde_hw_mixer *mixer;
-
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
-
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->mixer_count)) {
- DBG("Invalid mixer id %d", idx);
- return ERR_PTR(-EINVAL);
- }
-
- if (sde_kms->hw_res.mixer[idx]) {
- DRM_ERROR("mixer %d already in use ", idx);
- return ERR_PTR(-ENODEV);
- }
-
- sde_enable(sde_kms);
- mixer = sde_hw_lm_init(idx, sde_kms->mmio, sde_kms->catalog);
- sde_disable(sde_kms);
-
- if (!IS_ERR_OR_NULL(mixer))
- sde_kms->hw_res.mixer[idx] = mixer;
-
- return mixer;
-}
-
-struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms,
- enum sde_lm idx)
-{
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
-
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->mixer_count)) {
- DRM_ERROR("Invalid mixer id %d", idx);
- return ERR_PTR(-EINVAL);
- }
-
- return sde_kms->hw_res.mixer[idx];
-}
-
-const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms,
- enum sde_intf idx)
-{
- if (!sde_kms) {
- DRM_ERROR("Invalid KMS Driver");
- return ERR_PTR(-EINVAL);
- }
- if ((idx == SDE_NONE) || (idx > sde_kms->catalog->intf_count)) {
- DRM_ERROR("Invalid intf id %d", idx);
- return ERR_PTR(-EINVAL);
- }
-
- DBG(" Platform Resource map for INTF %d -> lm %d, pp %d ctl %d",
- sde_kms->hw_res.res_table[idx].intf,
- sde_kms->hw_res.res_table[idx].lm,
- sde_kms->hw_res.res_table[idx].pp,
- sde_kms->hw_res.res_table[idx].ctl);
- return &(sde_kms->hw_res.res_table[idx]);
-}
diff --git a/drivers/gpu/drm/msm/sde/sde_mdp_formats.c b/drivers/gpu/drm/msm/sde/sde_mdp_formats.c
deleted file mode 100644
index 56b65d4bd45e..000000000000
--- a/drivers/gpu/drm/msm/sde/sde_mdp_formats.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2015-2016, 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.
- */
-
-#include <linux/kernel.h>
-#include "sde_mdp_formats.h"
-
-static struct sde_mdp_format_params sde_mdp_format_map[] = {
- INTERLEAVED_RGB_FMT(ARGB8888,
- COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA,
- true, 4, 0),
-
- INTERLEAVED_RGB_FMT(ABGR8888,
- COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA,
- true, 4, 0),
-
- INTERLEAVED_RGB_FMT(RGBA8888,
- COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr,
- true, 4, 0),
-
- INTERLEAVED_RGB_FMT(BGRA8888,
- COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb,
- true, 4, 0),
-
- INTERLEAVED_RGB_FMT(XRGB8888,
- COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA,
- true, 4, 0),
-
- INTERLEAVED_RGB_FMT(RGB888,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, 0,
- false, 3, 0),
-
- INTERLEAVED_RGB_FMT(BGR888,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, 0,
- false, 3, 0),
-
- INTERLEAVED_RGB_FMT(RGB565,
- 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, 0,
- false, 2, 0),
-
- INTERLEAVED_RGB_FMT(BGR565,
- 0, 5, 6, 5,
- C2_R_Cr, C0_G_Y, C1_B_Cb, 0,
- false, 2, 0),
-
- PSEDUO_YUV_FMT(NV12,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C2_R_Cr,
- SDE_MDP_CHROMA_420, 0),
-
- PSEDUO_YUV_FMT(NV21,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C1_B_Cb,
- SDE_MDP_CHROMA_420, 0),
-
- PSEDUO_YUV_FMT(NV16,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C2_R_Cr,
- SDE_MDP_CHROMA_H2V1, 0),
-
- PSEDUO_YUV_FMT(NV61,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C1_B_Cb,
- SDE_MDP_CHROMA_H2V1, 0),
-
- INTERLEAVED_YUV_FMT(VYUY,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
- false, SDE_MDP_CHROMA_H2V1, 4, 2,
- 0),
-
- INTERLEAVED_YUV_FMT(UYVY,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
- false, SDE_MDP_CHROMA_H2V1, 4, 2,
- 0),
-
- INTERLEAVED_YUV_FMT(YUYV,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
- false, SDE_MDP_CHROMA_H2V1, 4, 2,
- 0),
-
- INTERLEAVED_YUV_FMT(YVYU,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
- false, SDE_MDP_CHROMA_H2V1, 4, 2,
- 0),
-
- PLANAR_YUV_FMT(YUV420,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C2_R_Cr, C1_B_Cb, C0_G_Y,
- false, SDE_MDP_CHROMA_420, 2,
- 0),
-
- PLANAR_YUV_FMT(YVU420,
- 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
- C1_B_Cb, C2_R_Cr, C0_G_Y,
- false, SDE_MDP_CHROMA_420, 2,
- 0),
-};
-
-struct sde_mdp_format_params *sde_mdp_get_format_params(u32 format,
- u32 fmt_modifier)
-{
- u32 i = 0;
- struct sde_mdp_format_params *fmt = NULL;
-
- for (i = 0; i < sizeof(sde_mdp_format_map)/sizeof(*sde_mdp_format_map);
- i++)
- if (format == sde_mdp_format_map[i].format) {
- fmt = &sde_mdp_format_map[i];
- break;
- }
-
- return fmt;
-}
-
diff --git a/drivers/gpu/drm/msm/sde/sde_mdp_formats.h b/drivers/gpu/drm/msm/sde/sde_mdp_formats.h
index e6f1c60aad11..dfd5076bb9dc 100644
--- a/drivers/gpu/drm/msm/sde/sde_mdp_formats.h
+++ b/drivers/gpu/drm/msm/sde/sde_mdp_formats.h
@@ -58,7 +58,6 @@ alpha, chroma, count, bp, flg) \
.is_yuv = true, \
.flag = flg \
}
-
#define PSEDUO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg) \
{ \
.format = DRM_FORMAT_ ## fmt, \
@@ -93,12 +92,122 @@ alpha, chroma, count, bp, flg) \
.flag = flg \
}
-/**
- * sde_mdp_get_format_params(): Returns sde format structure pointer.
- * @format: DRM format
- * @fmt_modifier: DRM format modifier
- */
+static struct sde_mdp_format_params sde_mdp_format_map[] = {
+ INTERLEAVED_RGB_FMT(ARGB8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA,
+ true, 4, 0),
+
+ INTERLEAVED_RGB_FMT(ABGR8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA,
+ true, 4, 0),
+
+ INTERLEAVED_RGB_FMT(RGBA8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr,
+ true, 4, 0),
+
+ INTERLEAVED_RGB_FMT(BGRA8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb,
+ true, 4, 0),
+
+ INTERLEAVED_RGB_FMT(XRGB8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA,
+ true, 4, 0),
+
+ INTERLEAVED_RGB_FMT(RGB888,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, 0,
+ false, 3, 0),
+
+ INTERLEAVED_RGB_FMT(BGR888,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, 0,
+ false, 3, 0),
+
+ INTERLEAVED_RGB_FMT(RGB565,
+ 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, 0,
+ false, 2, 0),
+
+ INTERLEAVED_RGB_FMT(BGR565,
+ 0, 5, 6, 5,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, 0,
+ false, 2, 0),
+
+ PSEDUO_YUV_FMT(NV12,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C2_R_Cr,
+ SDE_MDP_CHROMA_420, 0),
+
+ PSEDUO_YUV_FMT(NV21,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C1_B_Cb,
+ SDE_MDP_CHROMA_420, 0),
+
+ PSEDUO_YUV_FMT(NV16,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C2_R_Cr,
+ SDE_MDP_CHROMA_H2V1, 0),
+
+ PSEDUO_YUV_FMT(NV61,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C1_B_Cb,
+ SDE_MDP_CHROMA_H2V1, 0),
+
+ INTERLEAVED_YUV_FMT(VYUY,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
+ false, SDE_MDP_CHROMA_H2V1, 4, 2,
+ 0),
+
+ INTERLEAVED_YUV_FMT(UYVY,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
+ false, SDE_MDP_CHROMA_H2V1, 4, 2,
+ 0),
+
+ INTERLEAVED_YUV_FMT(YUYV,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
+ false, SDE_MDP_CHROMA_H2V1, 4, 2,
+ 0),
+
+ INTERLEAVED_YUV_FMT(YVYU,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
+ false, SDE_MDP_CHROMA_H2V1, 4, 2,
+ 0),
+
+ PLANAR_YUV_FMT(YUV420,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C1_B_Cb, C0_G_Y,
+ false, SDE_MDP_CHROMA_420, 2,
+ 0),
+
+ PLANAR_YUV_FMT(YVU420,
+ 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C1_B_Cb, C2_R_Cr, C0_G_Y,
+ false, SDE_MDP_CHROMA_420, 2,
+ 0),
+};
+
struct sde_mdp_format_params *sde_mdp_get_format_params(u32 format,
- u32 fmt_modifier);
+ u32 fmt_modifier)
+{
+ u32 i = 0;
+ struct sde_mdp_format_params *fmt = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(sde_mdp_format_map); i++)
+ if (format == sde_mdp_format_map[i].format) {
+ fmt = &sde_mdp_format_map[i];
+ break;
+ }
+
+ return fmt;
+}
#endif /*_SDE_MDP_FORMATS_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index cf34de2f1e3d..6f2dd9dee668 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -11,757 +11,105 @@
*/
#include "sde_kms.h"
-#include "sde_hwio.h"
-#include "sde_hw_mdp_ctl.h"
-#include "sde_mdp_formats.h"
-#include "sde_hw_sspp.h"
-
-#define DECIMATED_DIMENSION(dim, deci) (((dim) + ((1 << (deci)) - 1)) >> (deci))
-#define PHASE_STEP_SHIFT 21
-#define PHASE_STEP_UNIT_SCALE ((int) (1 << PHASE_STEP_SHIFT))
-#define PHASE_RESIDUAL 15
-
-#define SDE_PLANE_FEATURE_SCALER \
- (BIT(SDE_SSPP_SCALAR_QSEED2)| \
- BIT(SDE_SSPP_SCALAR_QSEED3)| \
- BIT(SDE_SSPP_SCALAR_RGB))
-
-#ifndef SDE_PLANE_DEBUG_START
-#define SDE_PLANE_DEBUG_START()
-#endif
-
-#ifndef SDE_PLANE_DEBUG_END
-#define SDE_PLANE_DEBUG_END()
-#endif
struct sde_plane {
struct drm_plane base;
const char *name;
-
- int mmu_id;
-
- enum sde_sspp pipe;
- uint32_t features; /* capabilities from catalog */
- uint32_t flush_mask; /* used to commit pipe registers */
uint32_t nformats;
uint32_t formats[32];
-
- struct sde_hw_pipe *pipe_hw;
- struct sde_hw_pipe_cfg pipe_cfg;
- struct sde_hw_pixel_ext pixel_ext;
};
#define to_sde_plane(x) container_of(x, struct sde_plane, base)
-static bool sde_plane_enabled(struct drm_plane_state *state)
-{
- return state->fb && state->crtc;
-}
-
-static void sde_plane_set_scanout(struct drm_plane *plane,
- struct sde_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb)
-{
- struct sde_plane *psde = to_sde_plane(plane);
- int i;
-
- if (pipe_cfg && fb && psde->pipe_hw->ops.setup_sourceaddress) {
- /* stride */
- i = min_t(int, ARRAY_SIZE(fb->pitches), SDE_MAX_PLANES);
- while (i) {
- --i;
- pipe_cfg->src.ystride[i] = fb->pitches[i];
- }
-
- /* address */
- for (i = 0; i < ARRAY_SIZE(pipe_cfg->addr.plane); ++i)
- pipe_cfg->addr.plane[i] = msm_framebuffer_iova(fb,
- psde->mmu_id, i);
-
- /* hw driver */
- psde->pipe_hw->ops.setup_sourceaddress(psde->pipe_hw, pipe_cfg);
- }
-}
-
-static void sde_plane_scale_helper(struct drm_plane *plane,
- uint32_t src, uint32_t dst, uint32_t *phase_steps,
- enum sde_hw_filter *filter, struct sde_mdp_format_params *fmt,
- uint32_t chroma_subsampling)
-{
- /* calcualte phase steps, leave init phase as zero */
- phase_steps[SDE_SSPP_COMP_LUMA] =
- mult_frac(1 << PHASE_STEP_SHIFT, src, dst);
- phase_steps[SDE_SSPP_COMP_CHROMA] =
- phase_steps[SDE_SSPP_COMP_LUMA] / chroma_subsampling;
-
- /* calculate scaler config, if necessary */
- if (src != dst) {
- filter[SDE_SSPP_COMP_ALPHA] = (src < dst) ?
- SDE_MDP_SCALE_FILTER_BIL :
- SDE_MDP_SCALE_FILTER_PCMN;
-
- if (fmt->is_yuv)
- filter[SDE_SSPP_COMP_LUMA] = SDE_MDP_SCALE_FILTER_CA;
- else
- filter[SDE_SSPP_COMP_LUMA] =
- filter[SDE_SSPP_COMP_ALPHA];
- }
-}
-
-/* CIFIX: clean up fmt/subsampling params once we're using fourcc formats */
-static void _sde_plane_pixel_ext_helper(struct drm_plane *plane,
- uint32_t src, uint32_t dst, uint32_t decimated_src,
- uint32_t *phase_steps, uint32_t *out_src, int *out_edge1,
- int *out_edge2, struct sde_mdp_format_params *fmt,
- uint32_t chroma_subsampling, bool post_compare)
-{
- /* CIFIX: adapted from mdss_mdp_pipe_calc_pixel_extn() */
- int64_t edge1, edge2, caf;
- uint32_t src_work;
- int i, tmp;
-
- if (plane && phase_steps && out_src && out_edge1 && out_edge2 && fmt) {
- /* enable CAF for YUV formats */
- if (fmt->is_yuv)
- caf = PHASE_STEP_UNIT_SCALE;
- else
- caf = 0;
-
- for (i = 0; i < SDE_MAX_PLANES; i++) {
- src_work = decimated_src;
- if (i == 1 || i == 2)
- src_work /= chroma_subsampling;
- if (post_compare)
- src = src_work;
- if (!(fmt->is_yuv) && (src == dst)) {
- /* unity */
- edge1 = 0;
- edge2 = 0;
- } else if (dst >= src) {
- /* upscale */
- edge1 = (1 << PHASE_RESIDUAL);
- edge1 -= caf;
- edge2 = (1 << PHASE_RESIDUAL);
- edge2 += (dst - 1) * *(phase_steps + i);
- edge2 -= (src_work - 1) * PHASE_STEP_UNIT_SCALE;
- edge2 += caf;
- edge2 = -(edge2);
- } else {
- /* downscale */
- edge1 = 0;
- edge2 = (dst - 1) * *(phase_steps + i);
- edge2 -= (src_work - 1) * PHASE_STEP_UNIT_SCALE;
- edge2 += *(phase_steps + i);
- edge2 = -(edge2);
- }
-
- /* only enable CAF for luma plane */
- caf = 0;
-
- /* populate output arrays */
- *(out_src + i) = src_work;
-
- /* edge updates taken from __pxl_extn_helper */
- /* CIFIX: why are we casting first to uint32_t? */
- if (edge1 >= 0) {
- tmp = (uint32_t)edge1;
- tmp >>= PHASE_STEP_SHIFT;
- *(out_edge1 + i) = -tmp;
- } else {
- tmp = (uint32_t)(-edge1);
- *(out_edge1 + i) = (tmp + PHASE_STEP_UNIT_SCALE
- - 1) >> PHASE_STEP_SHIFT;
- }
- if (edge2 >= 0) {
- tmp = (uint32_t)edge2;
- tmp >>= PHASE_STEP_SHIFT;
- *(out_edge2 + i) = -tmp;
- } else {
- tmp = (uint32_t)(-edge2);
- *(out_edge2 + i) = (tmp + PHASE_STEP_UNIT_SCALE
- - 1) >> PHASE_STEP_SHIFT;
- }
- }
- }
-}
-
-static int sde_plane_mode_set(struct drm_plane *plane,
+static int sde_plane_update(struct drm_plane *plane,
struct drm_crtc *crtc, struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
- struct sde_plane *psde = to_sde_plane(plane);
- struct sde_plane_state *pstate;
- const struct mdp_format *format;
- uint32_t nplanes, pix_format, tmp;
- int i;
- struct sde_mdp_format_params *fmt;
- struct sde_hw_pixel_ext *pe;
- int ret = 0;
-
- SDE_PLANE_DEBUG_START();
- nplanes = drm_format_num_planes(fb->pixel_format);
-
- pstate = to_sde_plane_state(plane->state);
-
- format = to_mdp_format(msm_framebuffer_format(fb));
- pix_format = format->base.pixel_format;
-
- /* src values are in Q16 fixed point, convert to integer */
- src_x = src_x >> 16;
- src_y = src_y >> 16;
- src_w = src_w >> 16;
- src_h = src_h >> 16;
-
- DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", psde->name,
- fb->base.id, src_x, src_y, src_w, src_h,
- crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
-
- /* update format configuration */
- memset(&(psde->pipe_cfg), 0, sizeof(struct sde_hw_pipe_cfg));
-
- psde->pipe_cfg.src.format = sde_mdp_get_format_params(pix_format,
- 0/* CIFIX: fmt_modifier */);
- psde->pipe_cfg.src.width = fb->width;
- psde->pipe_cfg.src.height = fb->height;
- psde->pipe_cfg.src.num_planes = nplanes;
-
- sde_plane_set_scanout(plane, &psde->pipe_cfg, fb);
-
- psde->pipe_cfg.src_rect.x = src_x;
- psde->pipe_cfg.src_rect.y = src_y;
- psde->pipe_cfg.src_rect.w = src_w;
- psde->pipe_cfg.src_rect.h = src_h;
-
- psde->pipe_cfg.dst_rect.x = crtc_x;
- psde->pipe_cfg.dst_rect.y = crtc_y;
- psde->pipe_cfg.dst_rect.w = crtc_w;
- psde->pipe_cfg.dst_rect.h = crtc_h;
-
- psde->pipe_cfg.horz_decimation = 0;
- psde->pipe_cfg.vert_decimation = 0;
-
- /* get sde pixel format definition */
- fmt = psde->pipe_cfg.src.format;
-
- /* update pixel extensions */
- pe = &(psde->pixel_ext);
- if (!pe->enable_pxl_ext) {
- uint32_t chroma_subsample_h, chroma_subsample_v;
-
- chroma_subsample_h = psde->pipe_cfg.horz_decimation ? 1 :
- drm_format_horz_chroma_subsampling(pix_format);
- chroma_subsample_v = psde->pipe_cfg.vert_decimation ? 1 :
- drm_format_vert_chroma_subsampling(pix_format);
-
- memset(pe, 0, sizeof(struct sde_hw_pixel_ext));
-
- /* calculate phase steps */
- sde_plane_scale_helper(plane, src_w, crtc_w,
- pe->phase_step_x,
- pe->horz_filter, fmt, chroma_subsample_h);
- sde_plane_scale_helper(plane, src_h, crtc_h,
- pe->phase_step_y,
- pe->vert_filter, fmt, chroma_subsample_v);
-
- /* calculate left/right/top/bottom pixel extentions */
- tmp = DECIMATED_DIMENSION(src_w,
- psde->pipe_cfg.horz_decimation);
- if (fmt->is_yuv)
- tmp &= ~0x1;
- _sde_plane_pixel_ext_helper(plane, src_w, crtc_w, tmp,
- pe->phase_step_x,
- pe->roi_w,
- pe->num_ext_pxls_left,
- pe->num_ext_pxls_right, fmt,
- chroma_subsample_h, 0);
-
- tmp = DECIMATED_DIMENSION(src_h,
- psde->pipe_cfg.vert_decimation);
- _sde_plane_pixel_ext_helper(plane, src_h, crtc_h, tmp,
- pe->phase_step_y,
- pe->roi_h,
- pe->num_ext_pxls_top,
- pe->num_ext_pxls_btm, fmt,
- chroma_subsample_v, 1);
-
- /* CIFIX: port "Single pixel rgb scale adjustment"? */
-
- for (i = 0; i < SDE_MAX_PLANES; i++) {
- if (pe->num_ext_pxls_left[i] >= 0)
- pe->left_rpt[i] =
- pe->num_ext_pxls_left[i];
- else
- pe->left_ftch[i] =
- pe->num_ext_pxls_left[i];
-
- if (pe->num_ext_pxls_right[i] >= 0)
- pe->right_rpt[i] =
- pe->num_ext_pxls_right[i];
- else
- pe->right_ftch[i] =
- pe->num_ext_pxls_right[i];
-
- if (pe->num_ext_pxls_top[i] >= 0)
- pe->top_rpt[i] =
- pe->num_ext_pxls_top[i];
- else
- pe->top_ftch[i] =
- pe->num_ext_pxls_top[i];
-
- if (pe->num_ext_pxls_btm[i] >= 0)
- pe->btm_rpt[i] =
- pe->num_ext_pxls_btm[i];
- else
- pe->btm_ftch[i] =
- pe->num_ext_pxls_btm[i];
- }
- }
-
- if (psde->pipe_hw->ops.setup_sourceformat)
- psde->pipe_hw->ops.setup_sourceformat(psde->pipe_hw,
- &psde->pipe_cfg, 0 /* CIFIX: flags */);
- if (psde->pipe_hw->ops.setup_rects)
- psde->pipe_hw->ops.setup_rects(psde->pipe_hw,
- &psde->pipe_cfg, &psde->pixel_ext);
-
- /* update csc */
-
- SDE_PLANE_DEBUG_END();
- return ret;
-}
-
-static int sde_plane_prepare_fb(struct drm_plane *plane,
- const struct drm_plane_state *new_state)
-{
- struct drm_framebuffer *fb = new_state->fb;
- struct sde_plane *psde = to_sde_plane(plane);
-
- if (!new_state->fb)
- return 0;
-
- SDE_PLANE_DEBUG_START();
- SDE_PLANE_DEBUG_END();
- DBG("%s: prepare: FB[%u]", psde->name, fb->base.id);
- return msm_framebuffer_prepare(fb, psde->mmu_id);
-}
-
-static void sde_plane_cleanup_fb(struct drm_plane *plane,
- const struct drm_plane_state *old_state)
-{
- struct drm_framebuffer *fb = old_state->fb;
- struct sde_plane *psde = to_sde_plane(plane);
-
- if (!fb)
- return;
-
- SDE_PLANE_DEBUG_START();
- SDE_PLANE_DEBUG_END();
- DBG("%s: cleanup: FB[%u]", psde->name, fb->base.id);
- msm_framebuffer_cleanup(fb, psde->mmu_id);
+ return 0;
}
-static int sde_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+static int sde_plane_disable(struct drm_plane *plane)
{
- struct sde_plane *psde = to_sde_plane(plane);
- struct drm_plane_state *old_state = plane->state;
- const struct mdp_format *format;
-
- SDE_PLANE_DEBUG_START();
- SDE_PLANE_DEBUG_END();
- DBG("%s: check (%d -> %d)", psde->name,
- sde_plane_enabled(old_state), sde_plane_enabled(state));
-
- if (sde_plane_enabled(state)) {
- /* CIFIX: don't use mdp format? */
- format = to_mdp_format(msm_framebuffer_format(state->fb));
- if (MDP_FORMAT_IS_YUV(format) &&
- (!(psde->features & SDE_PLANE_FEATURE_SCALER) ||
- !(psde->features & BIT(SDE_SSPP_CSC)))) {
- dev_err(plane->dev->dev,
- "Pipe doesn't support YUV\n");
-
- return -EINVAL;
- }
-
- if (!(psde->features & SDE_PLANE_FEATURE_SCALER) &&
- (((state->src_w >> 16) != state->crtc_w) ||
- ((state->src_h >> 16) != state->crtc_h))) {
- dev_err(plane->dev->dev,
- "Pipe doesn't support scaling (%dx%d -> %dx%d)\n",
- state->src_w >> 16, state->src_h >> 16,
- state->crtc_w, state->crtc_h);
-
- return -EINVAL;
- }
- }
-
- if (sde_plane_enabled(state) && sde_plane_enabled(old_state)) {
- /* we cannot change SMP block configuration during scanout: */
- bool full_modeset = false;
-
- if (state->fb->pixel_format != old_state->fb->pixel_format) {
- DBG("%s: pixel_format change!", psde->name);
- full_modeset = true;
- }
- if (state->src_w != old_state->src_w) {
- DBG("%s: src_w change!", psde->name);
- full_modeset = true;
- }
- if (to_sde_plane_state(old_state)->pending) {
- DBG("%s: still pending!", psde->name);
- full_modeset = true;
- }
- if (full_modeset) {
- struct drm_crtc_state *crtc_state =
- drm_atomic_get_crtc_state(state->state,
- state->crtc);
- crtc_state->mode_changed = true;
- to_sde_plane_state(state)->mode_changed = true;
- }
- } else {
- to_sde_plane_state(state)->mode_changed = true;
- }
-
return 0;
}
-static void sde_plane_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void sde_plane_destroy(struct drm_plane *plane)
{
struct sde_plane *sde_plane = to_sde_plane(plane);
- struct drm_plane_state *state = plane->state;
+ struct msm_drm_private *priv = plane->dev->dev_private;
- DBG("%s: update", sde_plane->name);
+ if (priv->kms)
+ sde_plane_disable(plane);
- SDE_PLANE_DEBUG_START();
- if (!sde_plane_enabled(state)) {
- to_sde_plane_state(state)->pending = true;
- } else if (to_sde_plane_state(state)->mode_changed) {
- int ret;
+ drm_plane_cleanup(plane);
- to_sde_plane_state(state)->pending = true;
- ret = sde_plane_mode_set(plane,
- state->crtc, state->fb,
- state->crtc_x, state->crtc_y,
- state->crtc_w, state->crtc_h,
- state->src_x, state->src_y,
- state->src_w, state->src_h);
- /* atomic_check should have ensured that this doesn't fail */
- WARN_ON(ret < 0);
- } else {
- sde_plane_set_scanout(plane, &sde_plane->pipe_cfg, state->fb);
- }
- SDE_PLANE_DEBUG_END();
+ kfree(sde_plane);
}
/* helper to install properties which are common to planes and crtcs */
-static void sde_plane_install_properties(struct drm_plane *plane,
+void sde_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj)
{
- struct drm_device *dev = plane->dev;
- struct msm_drm_private *dev_priv = dev->dev_private;
- struct drm_property *prop;
-
- SDE_PLANE_DEBUG_START();
-#define INSTALL_PROPERTY(name, NAME, init_val, fnc, ...) do { \
- prop = dev_priv->plane_property[PLANE_PROP_##NAME]; \
- if (!prop) { \
- prop = drm_property_##fnc(dev, 0, #name, \
- ##__VA_ARGS__); \
- if (!prop) { \
- dev_warn(dev->dev, \
- "Create property %s failed\n", \
- #name); \
- return; \
- } \
- dev_priv->plane_property[PLANE_PROP_##NAME] = prop; \
- } \
- drm_object_attach_property(&plane->base, prop, init_val); \
- } while (0)
-
-#define INSTALL_RANGE_PROPERTY(name, NAME, min, max, init_val) \
- INSTALL_PROPERTY(name, NAME, init_val, \
- create_range, min, max)
-
-#define INSTALL_ENUM_PROPERTY(name, NAME, init_val) \
- INSTALL_PROPERTY(name, NAME, init_val, \
- create_enum, name##_prop_enum_list, \
- ARRAY_SIZE(name##_prop_enum_list))
-
- INSTALL_RANGE_PROPERTY(zpos, ZPOS, 1, 255, 1);
-
-#undef INSTALL_RANGE_PROPERTY
-#undef INSTALL_ENUM_PROPERTY
-#undef INSTALL_PROPERTY
- SDE_PLANE_DEBUG_END();
}
-static int sde_plane_atomic_set_property(struct drm_plane *plane,
- struct drm_plane_state *state, struct drm_property *property,
- uint64_t val)
-{
- struct drm_device *dev = plane->dev;
- struct sde_plane_state *pstate;
- struct msm_drm_private *dev_priv = dev->dev_private;
- int ret = 0;
-
- SDE_PLANE_DEBUG_START();
-
- pstate = to_sde_plane_state(state);
-
-#define SET_PROPERTY(name, NAME, type) do { \
- if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \
- pstate->name = (type)val; \
- DBG("Set property %s %d", #name, (type)val); \
- goto done; \
- } \
- } while (0)
-
- SET_PROPERTY(zpos, ZPOS, uint8_t);
-
- dev_err(dev->dev, "Invalid property\n");
- ret = -EINVAL;
-done:
- SDE_PLANE_DEBUG_END();
- return ret;
-#undef SET_PROPERTY
-}
-
-static int sde_plane_set_property(struct drm_plane *plane,
+int sde_plane_set_property(struct drm_plane *plane,
struct drm_property *property, uint64_t val)
{
- int rc;
-
- SDE_PLANE_DEBUG_START();
- rc = sde_plane_atomic_set_property(plane, plane->state, property,
- val);
- SDE_PLANE_DEBUG_END();
- return rc;
-}
-
-static int sde_plane_atomic_get_property(struct drm_plane *plane,
- const struct drm_plane_state *state,
- struct drm_property *property, uint64_t *val)
-{
- struct drm_device *dev = plane->dev;
- struct sde_plane_state *pstate;
- struct msm_drm_private *dev_priv = dev->dev_private;
- int ret = 0;
-
- SDE_PLANE_DEBUG_START();
- pstate = to_sde_plane_state(state);
-
-#define GET_PROPERTY(name, NAME, type) do { \
- if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \
- *val = pstate->name; \
- DBG("Get property %s %lld", #name, *val); \
- goto done; \
- } \
- } while (0)
-
- GET_PROPERTY(zpos, ZPOS, uint8_t);
-
- dev_err(dev->dev, "Invalid property\n");
- ret = -EINVAL;
-done:
- SDE_PLANE_DEBUG_END();
- return ret;
-#undef SET_PROPERTY
-}
-
-static void sde_plane_destroy(struct drm_plane *plane)
-{
- struct sde_plane *psde = to_sde_plane(plane);
-
- SDE_PLANE_DEBUG_START();
-
- if (psde->pipe_hw)
- sde_hw_sspp_destroy(psde->pipe_hw);
-
- drm_plane_helper_disable(plane);
- drm_plane_cleanup(plane);
-
- kfree(psde);
-
- SDE_PLANE_DEBUG_END();
-}
-
-static void sde_plane_destroy_state(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- SDE_PLANE_DEBUG_START();
- if (state->fb)
- drm_framebuffer_unreference(state->fb);
-
- kfree(to_sde_plane_state(state));
- SDE_PLANE_DEBUG_END();
-}
-
-static struct drm_plane_state *
-sde_plane_duplicate_state(struct drm_plane *plane)
-{
- struct sde_plane_state *pstate;
-
- if (WARN_ON(!plane->state))
- return NULL;
-
- SDE_PLANE_DEBUG_START();
- pstate = kmemdup(to_sde_plane_state(plane->state),
- sizeof(*pstate), GFP_KERNEL);
-
- if (pstate && pstate->base.fb)
- drm_framebuffer_reference(pstate->base.fb);
-
- pstate->mode_changed = false;
- pstate->pending = false;
- SDE_PLANE_DEBUG_END();
-
- return &pstate->base;
-}
-
-static void sde_plane_reset(struct drm_plane *plane)
-{
- struct sde_plane_state *pstate;
-
- SDE_PLANE_DEBUG_START();
- if (plane->state && plane->state->fb)
- drm_framebuffer_unreference(plane->state->fb);
-
- kfree(to_sde_plane_state(plane->state));
- pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
-
- memset(pstate, 0, sizeof(struct sde_plane_state));
-
- /* assign default blend parameters */
- pstate->alpha = 255;
- pstate->premultiplied = 0;
-
- if (plane->type == DRM_PLANE_TYPE_PRIMARY)
- pstate->zpos = STAGE_BASE;
- else
- pstate->zpos = STAGE0 + drm_plane_index(plane);
-
- pstate->base.plane = plane;
-
- plane->state = &pstate->base;
- SDE_PLANE_DEBUG_END();
+ return -EINVAL;
}
static const struct drm_plane_funcs sde_plane_funcs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
+ .update_plane = sde_plane_update,
+ .disable_plane = sde_plane_disable,
.destroy = sde_plane_destroy,
.set_property = sde_plane_set_property,
- .atomic_set_property = sde_plane_atomic_set_property,
- .atomic_get_property = sde_plane_atomic_get_property,
- .reset = sde_plane_reset,
- .atomic_duplicate_state = sde_plane_duplicate_state,
- .atomic_destroy_state = sde_plane_destroy_state,
};
-static const struct drm_plane_helper_funcs sde_plane_helper_funcs = {
- .prepare_fb = sde_plane_prepare_fb,
- .cleanup_fb = sde_plane_cleanup_fb,
- .atomic_check = sde_plane_atomic_check,
- .atomic_update = sde_plane_atomic_update,
-};
-
-enum sde_sspp sde_plane_pipe(struct drm_plane *plane)
+void sde_plane_set_scanout(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
{
- struct sde_plane *sde_plane = to_sde_plane(plane);
+}
- return sde_plane->pipe;
+int sde_plane_mode_set(struct drm_plane *plane,
+ struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ return 0;
}
/* initialize plane */
-struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe,
- bool private_plane)
+struct drm_plane *sde_plane_init(struct drm_device *dev, bool private_plane)
{
- static const char tmp_name[] = "---";
struct drm_plane *plane = NULL;
- struct sde_plane *psde;
- struct sde_hw_ctl *sde_ctl;
- struct msm_drm_private *priv;
- struct sde_kms *kms;
- struct sde_mdss_cfg *sde_cat;
+ struct sde_plane *sde_plane;
int ret;
enum drm_plane_type type;
- priv = dev->dev_private;
- if (!priv) {
- DRM_ERROR("[%u]Private data is NULL\n", pipe);
- goto exit;
- }
-
- if (!priv->kms) {
- DRM_ERROR("[%u]Invalid KMS reference\n", pipe);
- goto exit;
- }
- kms = to_sde_kms(priv->kms);
-
- psde = kzalloc(sizeof(*psde), GFP_KERNEL);
- if (!psde) {
+ sde_plane = kzalloc(sizeof(*sde_plane), GFP_KERNEL);
+ if (!sde_plane) {
ret = -ENOMEM;
goto fail;
}
- memset(psde, 0, sizeof(*psde));
-
- plane = &psde->base;
-
- psde->pipe = pipe;
- psde->name = tmp_name;
-
- if (kms) {
- /* mmu id for buffer mapping */
- psde->mmu_id = kms->mmu_id;
-
- /* check catalog for features mask */
- sde_cat = kms->catalog;
- if (sde_cat)
- psde->features = sde_cat->sspp[pipe].features;
- }
- psde->nformats = mdp_get_formats(psde->formats,
- ARRAY_SIZE(psde->formats),
- !(psde->features & BIT(SDE_SSPP_CSC)) ||
- !(psde->features & SDE_PLANE_FEATURE_SCALER));
+ plane = &sde_plane->base;
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
- ret = drm_universal_plane_init(dev, plane, 0xff, &sde_plane_funcs,
- psde->formats, psde->nformats,
- type);
- if (ret)
- goto fail;
-
- drm_plane_helper_add(plane, &sde_plane_helper_funcs);
+ drm_universal_plane_init(dev, plane, 0xff, &sde_plane_funcs,
+ sde_plane->formats, sde_plane->nformats,
+ type);
sde_plane_install_properties(plane, &plane->base);
- psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, sde_cat);
- if (IS_ERR(psde->pipe_hw)) {
- ret = PTR_ERR(psde->pipe_hw);
- psde->pipe_hw = NULL;
- goto fail;
- }
-
- /* cache flush mask for later */
- sde_ctl = sde_hw_ctl_init(CTL_0, kms->mmio, sde_cat);
- if (!IS_ERR(sde_ctl)) {
- if (sde_ctl->ops.get_bitmask_sspp)
- sde_ctl->ops.get_bitmask_sspp(sde_ctl,
- &psde->flush_mask, pipe);
- sde_hw_ctl_destroy(sde_ctl);
- }
-
- pr_err("%s: Successfully created plane\n", __func__);
return plane;
fail:
- pr_err("%s: Plane creation failed\n", __func__);
if (plane)
sde_plane_destroy(plane);
-exit:
+
return ERR_PTR(ret);
}