From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:20:52 +0000
Subject: [PATCH] add new system file
---
kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 104 ++++++++++++++++++++++++++++++++++------------------
1 files changed, 68 insertions(+), 36 deletions(-)
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
index 9e533b8..96f3908 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -3,25 +3,43 @@
* Copyright (c) 2018, The Linux Foundation
*/
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdesc.h>
+#include <linux/irqchip/chained_irq.h>
#include "dpu_kms.h"
#define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base)
+#define HW_REV 0x0
#define HW_INTR_STATUS 0x0010
+
+#define UBWC_STATIC 0x144
+#define UBWC_CTRL_2 0x150
+#define UBWC_PREDICTION_MODE 0x154
+
+/* Max BW defined in KBps */
+#define MAX_BW 6800000
+
+struct dpu_irq_controller {
+ unsigned long enabled_mask;
+ struct irq_domain *domain;
+};
struct dpu_mdss {
struct msm_mdss base;
void __iomem *mmio;
- unsigned long mmio_len;
- u32 hwversion;
struct dss_module_power mp;
struct dpu_irq_controller irq_controller;
};
-static irqreturn_t dpu_mdss_irq(int irq, void *arg)
+static void dpu_mdss_irq(struct irq_desc *desc)
{
- struct dpu_mdss *dpu_mdss = arg;
+ struct dpu_mdss *dpu_mdss = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
u32 interrupts;
+
+ chained_irq_enter(chip, desc);
interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
@@ -34,20 +52,20 @@
hwirq);
if (mapping == 0) {
DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq);
- return IRQ_NONE;
+ break;
}
rc = generic_handle_irq(mapping);
if (rc < 0) {
DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n",
hwirq, mapping, rc);
- return IRQ_NONE;
+ break;
}
interrupts &= ~(1 << hwirq);
}
- return IRQ_HANDLED;
+ chained_irq_exit(chip, desc);
}
static void dpu_mdss_irq_mask(struct irq_data *irqd)
@@ -78,16 +96,16 @@
.irq_unmask = dpu_mdss_irq_unmask,
};
+static struct lock_class_key dpu_mdss_lock_key, dpu_mdss_request_key;
+
static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
unsigned int irq, irq_hw_number_t hwirq)
{
struct dpu_mdss *dpu_mdss = domain->host_data;
- int ret;
+ irq_set_lockdep_class(irq, &dpu_mdss_lock_key, &dpu_mdss_request_key);
irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
- ret = irq_set_chip_data(irq, dpu_mdss);
-
- return ret;
+ return irq_set_chip_data(irq, dpu_mdss);
}
static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
@@ -115,13 +133,12 @@
return 0;
}
-static int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
+static void _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
{
if (dpu_mdss->irq_controller.domain) {
irq_domain_remove(dpu_mdss->irq_controller.domain);
dpu_mdss->irq_controller.domain = NULL;
}
- return 0;
}
static int dpu_mdss_enable(struct msm_mdss *mdss)
{
@@ -130,8 +147,30 @@
int ret;
ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
- if (ret)
+ if (ret) {
DPU_ERROR("clock enable failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ /*
+ * ubwc config is part of the "mdss" region which is not accessible
+ * from the rest of the driver. hardcode known configurations here
+ */
+ switch (readl_relaxed(dpu_mdss->mmio + HW_REV)) {
+ case DPU_HW_VER_500:
+ case DPU_HW_VER_501:
+ writel_relaxed(0x420, dpu_mdss->mmio + UBWC_STATIC);
+ break;
+ case DPU_HW_VER_600:
+ /* TODO: 0x102e for LP_DDR4 */
+ writel_relaxed(0x103e, dpu_mdss->mmio + UBWC_STATIC);
+ writel_relaxed(2, dpu_mdss->mmio + UBWC_CTRL_2);
+ writel_relaxed(1, dpu_mdss->mmio + UBWC_PREDICTION_MODE);
+ break;
+ case DPU_HW_VER_620:
+ writel_relaxed(0x1e, dpu_mdss->mmio + UBWC_STATIC);
+ break;
+ }
return ret;
}
@@ -155,17 +194,19 @@
struct msm_drm_private *priv = dev->dev_private;
struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
struct dss_module_power *mp = &dpu_mdss->mp;
+ int irq;
+ pm_runtime_suspend(dev->dev);
+ pm_runtime_disable(dev->dev);
_dpu_mdss_irq_domain_fini(dpu_mdss);
-
+ irq = platform_get_irq(pdev, 0);
+ irq_set_chained_handler_and_data(irq, NULL, NULL);
msm_dss_put_clk(mp->clk_config, mp->num_clk);
devm_kfree(&pdev->dev, mp->clk_config);
if (dpu_mdss->mmio)
devm_iounmap(&pdev->dev, dpu_mdss->mmio);
dpu_mdss->mmio = NULL;
-
- pm_runtime_disable(dev->dev);
priv->mdss = NULL;
}
@@ -179,10 +220,10 @@
{
struct platform_device *pdev = to_platform_device(dev->dev);
struct msm_drm_private *priv = dev->dev_private;
- struct resource *res;
struct dpu_mdss *dpu_mdss;
struct dss_module_power *mp;
- int ret = 0;
+ int ret;
+ int irq;
dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
if (!dpu_mdss)
@@ -193,13 +234,6 @@
return PTR_ERR(dpu_mdss->mmio);
DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdss");
- if (!res) {
- DRM_ERROR("failed to get memory resource for mdss\n");
- return -ENOMEM;
- }
- dpu_mdss->mmio_len = resource_size(res);
mp = &dpu_mdss->mp;
ret = msm_dss_parse_clock(pdev, mp);
@@ -215,22 +249,20 @@
if (ret)
goto irq_domain_error;
- ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
- dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
- if (ret) {
- DPU_ERROR("failed to init irq: %d\n", ret);
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = irq;
goto irq_error;
}
- pm_runtime_enable(dev->dev);
-
- pm_runtime_get_sync(dev->dev);
- dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
- pm_runtime_put_sync(dev->dev);
+ irq_set_chained_handler_and_data(irq, dpu_mdss_irq,
+ dpu_mdss);
priv->mdss = &dpu_mdss->base;
- return ret;
+ pm_runtime_enable(dev->dev);
+
+ return 0;
irq_error:
_dpu_mdss_irq_domain_fini(dpu_mdss);
--
Gitblit v1.6.2