summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2021-02-05 09:25:20 +1000
committerDave Airlie <airlied@redhat.com>2021-02-05 09:25:26 +1000
commit54c820d05ee8156b1379ca0efd011b77e23cabb2 (patch)
treeece3ed5cca3a8ce152a2999fa470e49d5fba1dbf
parentce7c3bded64abbaabb1146803d0ce09694dc95e0 (diff)
parent738ed4156fbac6f6eb84c23b95cf25aa57707332 (diff)
Merge tag 'mediatek-drm-next-5.12' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next
Mediatek DRM Next for Linux 5.12 1. Decouple Mediatek DRM sub driver 2. Share mtk mutex driver for both DRM and MDP 3. Add support for SoC MT8183 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Chun-Kuang Hu <chunkuang.hu@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210204151750.7550-1-chunkuang.hu@kernel.org
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt12
-rw-r--r--drivers/gpu/drm/mediatek/Makefile5
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ccorr.c223
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_color.c89
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_drv.h92
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_gamma.c197
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ovl.c254
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_rdma.c194
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dpi.c57
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c107
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.h1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp.h28
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c503
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h100
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c88
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.h5
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c50
-rw-r--r--drivers/soc/mediatek/Makefile1
-rw-r--r--drivers/soc/mediatek/mtk-mutex.c (renamed from drivers/gpu/drm/mediatek/mtk_drm_ddp.c)328
-rw-r--r--include/linux/soc/mediatek/mtk-mutex.h26
20 files changed, 1446 insertions, 914 deletions
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 33977e15bebd..b47e1a0597c2 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -37,13 +37,14 @@ Required properties (all function blocks):
"mediatek,<chip>-disp-aal" - adaptive ambient light controller
"mediatek,<chip>-disp-gamma" - gamma correction
"mediatek,<chip>-disp-merge" - merge streams from two RDMA sources
+ "mediatek,<chip>-disp-postmask" - control round corner for display frame
"mediatek,<chip>-disp-split" - split stream to two encoders
"mediatek,<chip>-disp-ufoe" - data compression engine
"mediatek,<chip>-dsi" - DSI controller, see mediatek,dsi.txt
"mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt
"mediatek,<chip>-disp-mutex" - display mutex
"mediatek,<chip>-disp-od" - overdrive
- the supported chips are mt2701, mt7623, mt2712, mt8167 and mt8173.
+ the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
- reg: Physical base address and length of the function block register space
- interrupts: The interrupt signal from the function block (required, except for
merge and split function blocks).
@@ -66,6 +67,14 @@ Required properties (DMA function blocks):
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
+Optional properties (RDMA function blocks):
+- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
+ property to the corresponding rdma
+ the value is the Max value which defined in hardware data sheet.
+ mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+ mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+ mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+
Examples:
mmsys: clock-controller@14000000 {
@@ -103,6 +112,7 @@ rdma0: rdma@1400e000 {
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
mediatek,larb = <&larb0>;
+ mediatek,rdma-fifosize = <8192>;
};
rdma1: rdma@1400f000 {
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index a892edec5563..dc54a7a69005 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
-mediatek-drm-y := mtk_disp_color.o \
+mediatek-drm-y := mtk_disp_ccorr.o \
+ mtk_disp_color.o \
+ mtk_disp_gamma.o \
mtk_disp_ovl.o \
mtk_disp_rdma.o \
mtk_drm_crtc.o \
- mtk_drm_ddp.o \
mtk_drm_ddp_comp.o \
mtk_drm_drv.o \
mtk_drm_gem.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
new file mode 100644
index 000000000000..141cb36b9c07
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+
+#define DISP_CCORR_EN 0x0000
+#define CCORR_EN BIT(0)
+#define DISP_CCORR_CFG 0x0020
+#define CCORR_RELAY_MODE BIT(0)
+#define CCORR_ENGINE_EN BIT(1)
+#define CCORR_GAMMA_OFF BIT(2)
+#define CCORR_WGAMUT_SRC_CLIP BIT(3)
+#define DISP_CCORR_SIZE 0x0030
+#define DISP_CCORR_COEF_0 0x0080
+#define DISP_CCORR_COEF_1 0x0084
+#define DISP_CCORR_COEF_2 0x0088
+#define DISP_CCORR_COEF_3 0x008C
+#define DISP_CCORR_COEF_4 0x0090
+
+struct mtk_disp_ccorr_data {
+ u32 matrix_bits;
+};
+
+/**
+ * struct mtk_disp_ccorr - DISP_CCORR driver structure
+ * @ddp_comp - structure containing type enum and hardware resources
+ * @crtc - associated crtc to report irq events to
+ */
+struct mtk_disp_ccorr {
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
+ const struct mtk_disp_ccorr_data *data;
+};
+
+int mtk_ccorr_clk_enable(struct device *dev)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(ccorr->clk);
+}
+
+void mtk_ccorr_clk_disable(struct device *dev)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(ccorr->clk);
+}
+
+void mtk_ccorr_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, &ccorr->cmdq_reg, ccorr->regs,
+ DISP_CCORR_SIZE);
+ mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, &ccorr->cmdq_reg, ccorr->regs,
+ DISP_CCORR_CFG);
+}
+
+void mtk_ccorr_start(struct device *dev)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+
+ writel(CCORR_EN, ccorr->regs + DISP_CCORR_EN);
+}
+
+void mtk_ccorr_stop(struct device *dev)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+
+ writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN);
+}
+
+/* Converts a DRM S31.32 value to the HW S1.n format. */
+static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n)
+{
+ u16 r;
+
+ /* Sign bit. */
+ r = in & BIT_ULL(63) ? BIT(n + 1) : 0;
+
+ if ((in & GENMASK_ULL(62, 33)) > 0) {
+ /* identity value 0x100000000 -> 0x400(mt8183), */
+ /* identity value 0x100000000 -> 0x800(mt8192), */
+ /* if bigger this, set it to max 0x7ff. */
+ r |= GENMASK(n, 0);
+ } else {
+ /* take the n+1 most important bits. */
+ r |= (in >> (32 - n)) & GENMASK(n, 0);
+ }
+
+ return r;
+}
+
+void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+ struct drm_property_blob *blob = state->ctm;
+ struct drm_color_ctm *ctm;
+ const u64 *input;
+ uint16_t coeffs[9] = { 0 };
+ int i;
+ struct cmdq_pkt *cmdq_pkt = NULL;
+ u32 matrix_bits = ccorr->data->matrix_bits;
+
+ if (!blob)
+ return;
+
+ ctm = (struct drm_color_ctm *)blob->data;
+ input = ctm->matrix;
+
+ for (i = 0; i < ARRAY_SIZE(coeffs); i++)
+ coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits);
+
+ mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
+ &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0);
+ mtk_ddp_write(cmdq_pkt, coeffs[2] << 16 | coeffs[3],
+ &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_1);
+ mtk_ddp_write(cmdq_pkt, coeffs[4] << 16 | coeffs[5],
+ &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_2);
+ mtk_ddp_write(cmdq_pkt, coeffs[6] << 16 | coeffs[7],
+ &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_3);
+ mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,
+ &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_4);
+}
+
+static int mtk_disp_ccorr_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ return 0;
+}
+
+static void mtk_disp_ccorr_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+}
+
+static const struct component_ops mtk_disp_ccorr_component_ops = {
+ .bind = mtk_disp_ccorr_bind,
+ .unbind = mtk_disp_ccorr_unbind,
+};
+
+static int mtk_disp_ccorr_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_disp_ccorr *priv;
+ struct resource *res;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get ccorr clk\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "failed to ioremap ccorr\n");
+ return PTR_ERR(priv->regs);
+ }
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+ priv->data = of_device_get_match_data(dev);
+ platform_set_drvdata(pdev, priv);
+
+ ret = component_add(dev, &mtk_disp_ccorr_component_ops);
+ if (ret)
+ dev_err(dev, "Failed to add component: %d\n", ret);
+
+ return ret;
+}
+
+static int mtk_disp_ccorr_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &mtk_disp_ccorr_component_ops);
+
+ return 0;
+}
+
+static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = {
+ .matrix_bits = 10,
+};
+
+static const struct of_device_id mtk_disp_ccorr_driver_dt_match[] = {
+ { .compatible = "mediatek,mt8183-disp-ccorr",
+ .data = &mt8183_ccorr_driver_data},
+ {},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);
+
+struct platform_driver mtk_disp_ccorr_driver = {
+ .probe = mtk_disp_ccorr_probe,
+ .remove = mtk_disp_ccorr_remove,
+ .driver = {
+ .name = "mediatek-disp-ccorr",
+ .owner = THIS_MODULE,
+ .of_match_table = mtk_disp_ccorr_driver_dt_match,
+ },
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 6048cbc9f0ec..63f411ab393b 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
+#include "mtk_disp_drv.h"
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -36,64 +37,55 @@ struct mtk_disp_color_data {
* @data: platform colour driver data
*/
struct mtk_disp_color {
- struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
const struct mtk_disp_color_data *data;
};
-static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
+int mtk_color_clk_enable(struct device *dev)
{
- return container_of(comp, struct mtk_disp_color, ddp_comp);
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(color->clk);
}
-static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+void mtk_color_clk_disable(struct device *dev)
{
- struct mtk_disp_color *color = comp_to_color(comp);
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
- mtk_ddp_write(cmdq_pkt, w, comp, DISP_COLOR_WIDTH(color));
- mtk_ddp_write(cmdq_pkt, h, comp, DISP_COLOR_HEIGHT(color));
+ clk_disable_unprepare(color->clk);
}
-static void mtk_color_start(struct mtk_ddp_comp *comp)
+void mtk_color_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
- struct mtk_disp_color *color = comp_to_color(comp);
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
- writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
- comp->regs + DISP_COLOR_CFG_MAIN);
- writel(0x1, comp->regs + DISP_COLOR_START(color));
+ mtk_ddp_write(cmdq_pkt, w, &color->cmdq_reg, color->regs, DISP_COLOR_WIDTH(color));
+ mtk_ddp_write(cmdq_pkt, h, &color->cmdq_reg, color->regs, DISP_COLOR_HEIGHT(color));
}
-static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = {
- .config = mtk_color_config,
- .start = mtk_color_start,
-};
+void mtk_color_start(struct device *dev)
+{
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
+
+ writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
+ color->regs + DISP_COLOR_CFG_MAIN);
+ writel(0x1, color->regs + DISP_COLOR_START(color));
+}
static int mtk_disp_color_bind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_color *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
- int ret;
-
- ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
- if (ret < 0) {
- dev_err(dev, "Failed to register component %pOF: %d\n",
- dev->of_node, ret);
- return ret;
- }
-
return 0;
}
static void mtk_disp_color_unbind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_color *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
-
- mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
}
static const struct component_ops mtk_disp_color_component_ops = {
@@ -105,31 +97,32 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_color *priv;
- int comp_id;
+ struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR);
- if (comp_id < 0) {
- dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
- return comp_id;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get color clk\n");
+ return PTR_ERR(priv->clk);
}
- ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
- &mtk_disp_color_funcs);
- if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to initialize component: %d\n",
- ret);
-
- return ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "failed to ioremap color\n");
+ return PTR_ERR(priv->regs);
}
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
priv->data = of_device_get_match_data(dev);
-
platform_set_drvdata(pdev, priv);
ret = component_add(dev, &mtk_disp_color_component_ops);
@@ -141,8 +134,6 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
static int mtk_disp_color_remove(struct platform_device *pdev)
{
- component_del(&pdev->dev, &mtk_disp_color_component_ops);
-
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
new file mode 100644
index 000000000000..cafd9df2d63b
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#ifndef _MTK_DISP_DRV_H_
+#define _MTK_DISP_DRV_H_
+
+#include <linux/soc/mediatek/mtk-cmdq.h>
+#include "mtk_drm_plane.h"
+
+void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
+int mtk_ccorr_clk_enable(struct device *dev);
+void mtk_ccorr_clk_disable(struct device *dev);
+void mtk_ccorr_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ccorr_start(struct device *dev);
+void mtk_ccorr_stop(struct device *dev);
+
+void mtk_color_bypass_shadow(struct device *dev);
+int mtk_color_clk_enable(struct device *dev);
+void mtk_color_clk_disable(struct device *dev);
+void mtk_color_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_color_start(struct device *dev);
+
+void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
+ unsigned int bpc, unsigned int cfg,
+ unsigned int dither_en, struct cmdq_pkt *cmdq_pkt);
+
+void mtk_dpi_start(struct device *dev);
+void mtk_dpi_stop(struct device *dev);
+
+void mtk_dsi_ddp_start(struct device *dev);
+void mtk_dsi_ddp_stop(struct device *dev);
+
+int mtk_gamma_clk_enable(struct device *dev);
+void mtk_gamma_clk_disable(struct device *dev);
+void mtk_gamma_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state);
+void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
+void mtk_gamma_start(struct device *dev);
+void mtk_gamma_stop(struct device *dev);
+
+void mtk_ovl_bgclr_in_on(struct device *dev);
+void mtk_ovl_bgclr_in_off(struct device *dev);
+void mtk_ovl_bypass_shadow(struct device *dev);
+int mtk_ovl_clk_enable(struct device *dev);
+void mtk_ovl_clk_disable(struct device *dev);
+void mtk_ovl_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *mtk_state);
+void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt);
+unsigned int mtk_ovl_layer_nr(struct device *dev);
+void mtk_ovl_layer_on(struct device *dev, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_start(struct device *dev);
+void mtk_ovl_stop(struct device *dev);
+unsigned int mtk_ovl_supported_rotations(struct device *dev);
+void mtk_ovl_enable_vblank(struct device *dev,
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data);
+void mtk_ovl_disable_vblank(struct device *dev);
+
+void mtk_rdma_bypass_shadow(struct device *dev);
+int mtk_rdma_clk_enable(struct device *dev);
+void mtk_rdma_clk_disable(struct device *dev);
+void mtk_rdma_config(struct device *dev, unsigned int width,
+ unsigned int height, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+unsigned int mtk_rdma_layer_nr(struct device *dev);
+void mtk_rdma_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt);
+void mtk_rdma_start(struct device *dev);
+void mtk_rdma_stop(struct device *dev);
+void mtk_rdma_enable_vblank(struct device *dev,
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data);
+void mtk_rdma_disable_vblank(struct device *dev);
+
+#endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
new file mode 100644
index 000000000000..3ebf91e0ab41
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+
+#define DISP_GAMMA_EN 0x0000
+#define GAMMA_EN BIT(0)
+#define DISP_GAMMA_CFG 0x0020
+#define GAMMA_LUT_EN BIT(1)
+#define GAMMA_DITHERING BIT(2)
+#define DISP_GAMMA_SIZE 0x0030
+#define DISP_GAMMA_LUT 0x0700
+
+#define LUT_10BIT_MASK 0x03ff
+
+struct mtk_disp_gamma_data {
+ bool has_dither;
+};
+
+/**
+ * struct mtk_disp_gamma - DISP_GAMMA driver structure
+ * @ddp_comp - structure containing type enum and hardware resources
+ * @crtc - associated crtc to report irq events to
+ */
+struct mtk_disp_gamma {
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
+ const struct mtk_disp_gamma_data *data;
+};
+
+int mtk_gamma_clk_enable(struct device *dev)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(gamma->clk);
+}
+
+void mtk_gamma_clk_disable(struct device *dev)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(gamma->clk);
+}
+
+void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state)
+{
+ unsigned int i, reg;
+ struct drm_color_lut *lut;
+ void __iomem *lut_base;
+ u32 word;
+
+ if (state->gamma_lut) {
+ reg = readl(regs + DISP_GAMMA_CFG);
+ reg = reg | GAMMA_LUT_EN;
+ writel(reg, regs + DISP_GAMMA_CFG);
+ lut_base = regs + DISP_GAMMA_LUT;
+ lut = (struct drm_color_lut *)state->gamma_lut->data;
+ for (i = 0; i < MTK_LUT_SIZE; i++) {
+ word = (((lut[i].red >> 6) & LUT_10BIT_MASK) << 20) +
+ (((lut[i].green >> 6) & LUT_10BIT_MASK) << 10) +
+ ((lut[i].blue >> 6) & LUT_10BIT_MASK);
+ writel(word, (lut_base + i * 4));
+ }
+ }
+}
+
+void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ mtk_gamma_set_common(gamma->regs, state);
+}
+
+void mtk_gamma_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ mtk_ddp_write(cmdq_pkt, h << 16 | w, &gamma->cmdq_reg, gamma->regs,
+ DISP_GAMMA_SIZE);
+ if (gamma->data && gamma->data->has_dither)
+ mtk_dither_set_common(gamma->regs, &gamma->cmdq_reg, bpc,
+ DISP_GAMMA_CFG, GAMMA_DITHERING, cmdq_pkt);
+}
+
+void mtk_gamma_start(struct device *dev)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ writel(GAMMA_EN, gamma->regs + DISP_GAMMA_EN);
+}
+
+void mtk_gamma_stop(struct device *dev)
+{
+ struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+ writel_relaxed(0x0, gamma->regs + DISP_GAMMA_EN);
+}
+
+static int mtk_disp_gamma_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ return 0;
+}
+
+static void mtk_disp_gamma_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+}
+
+static const struct component_ops mtk_disp_gamma_component_ops = {
+ .bind = mtk_disp_gamma_bind,
+ .unbind = mtk_disp_gamma_unbind,
+};
+
+static int mtk_disp_gamma_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_disp_gamma *priv;
+ struct resource *res;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get gamma clk\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "failed to ioremap gamma\n");
+ return PTR_ERR(priv->regs);
+ }
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+ priv->data = of_device_get_match_data(dev);
+ platform_set_drvdata(pdev, priv);
+
+ ret = component_add(dev, &mtk_disp_gamma_component_ops);
+ if (ret)
+ dev_err(dev, "Failed to add component: %d\n", ret);
+
+ return ret;
+}
+
+static int mtk_disp_gamma_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &mtk_disp_gamma_component_ops);
+
+ return 0;
+}
+
+static const struct mtk_disp_gamma_data mt8173_gamma_driver_data = {
+ .has_dither = true,
+};
+
+static const struct of_device_id mtk_disp_gamma_driver_dt_match[] = {
+ { .compatible = "mediatek,mt8173-disp-gamma",
+ .data = &mt8173_gamma_driver_data},
+ { .compatible = "mediatek,mt8183-disp-gamma"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match);
+
+struct platform_driver mtk_disp_gamma_driver = {
+ .probe = mtk_disp_gamma_probe,
+ .remove = mtk_disp_gamma_remove,
+ .driver = {
+ .name = "mediatek-disp-gamma",
+ .owner = THIS_MODULE,
+ .of_match_table = mtk_disp_gamma_driver_dt_match,
+ },
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 74ef6fc0528b..961f87f8d4d1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
+#include "mtk_disp_drv.h"
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -23,6 +24,7 @@
#define DISP_REG_OVL_RST 0x0014
#define DISP_REG_OVL_ROI_SIZE 0x0020
#define DISP_REG_OVL_DATAPATH_CON 0x0024
+#define OVL_LAYER_SMI_ID_EN BIT(0)
#define OVL_BGCLR_SEL_IN BIT(2)
#define DISP_REG_OVL_ROI_BGCLR 0x0028
#define DISP_REG_OVL_SRC_CON 0x002c
@@ -61,6 +63,7 @@ struct mtk_disp_ovl_data {
unsigned int gmc_bits;
unsigned int layer_nr;
bool fmt_rgb565_is_0;
+ bool smi_id_en;
};
/**
@@ -70,88 +73,124 @@ struct mtk_disp_ovl_data {
* @data: platform data
*/
struct mtk_disp_ovl {
- struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
const struct mtk_disp_ovl_data *data;
+ void (*vblank_cb)(void *data);
+ void *vblank_cb_data;
};
-static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
-{
- return container_of(comp, struct mtk_disp_ovl, ddp_comp);
-}
-
static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
{
struct mtk_disp_ovl *priv = dev_id;
- struct mtk_ddp_comp *ovl = &priv->ddp_comp;
/* Clear frame completion interrupt */
- writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
+ writel(0x0, priv->regs + DISP_REG_OVL_INTSTA);
- if (!priv->crtc)
+ if (!priv->vblank_cb)
return IRQ_NONE;
- mtk_crtc_ddp_irq(priv->crtc, ovl);
+ priv->vblank_cb(priv->vblank_cb_data);
return IRQ_HANDLED;
}
-static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
- struct drm_crtc *crtc)
+void mtk_ovl_enable_vblank(struct device *dev,
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ ovl->vblank_cb = vblank_cb;
+ ovl->vblank_cb_data = vblank_cb_data;
+ writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
+ writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);
+}
+
+void mtk_ovl_disable_vblank(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ ovl->vblank_cb = NULL;
+ ovl->vblank_cb_data = NULL;
+ writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
+}
+
+int mtk_ovl_clk_enable(struct device *dev)
{
- struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
- ovl->crtc = crtc;
- writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
- writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
+ return clk_prepare_enable(ovl->clk);
}
-static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
+void mtk_ovl_clk_disable(struct device *dev)
{
- struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
- ovl->crtc = NULL;
- writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
+ clk_disable_unprepare(ovl->clk);
}
-static void mtk_ovl_start(struct mtk_ddp_comp *comp)
+void mtk_ovl_start(struct device *dev)
{
- writel_relaxed(0x1, comp->regs + DISP_REG_OVL_EN);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ if (ovl->data->smi_id_en) {
+ unsigned int reg;
+
+ reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+ reg = reg | OVL_LAYER_SMI_ID_EN;
+ writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+ }
+ writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
}
-static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
+void mtk_ovl_stop(struct device *dev)
{
- writel_relaxed(0x0, comp->regs + DISP_REG_OVL_EN);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
+ if (ovl->data->smi_id_en) {
+ unsigned int reg;
+
+ reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+ reg = reg & ~OVL_LAYER_SMI_ID_EN;
+ writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+ }
+
}
-static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+void mtk_ovl_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
if (w != 0 && h != 0)
- mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_ROI_SIZE);
- mtk_ddp_write_relaxed(cmdq_pkt, 0x0, comp, DISP_REG_OVL_ROI_BGCLR);
+ mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
- mtk_ddp_write(cmdq_pkt, 0x1, comp, DISP_REG_OVL_RST);
- mtk_ddp_write(cmdq_pkt, 0x0, comp, DISP_REG_OVL_RST);
+ mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
+ mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
}
-static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
+unsigned int mtk_ovl_layer_nr(struct device *dev)
{
- struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
return ovl->data->layer_nr;
}
-static unsigned int mtk_ovl_supported_rotations(struct mtk_ddp_comp *comp)
+unsigned int mtk_ovl_supported_rotations(struct device *dev)
{
return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
}
-static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx,
- struct mtk_plane_state *mtk_state)
+int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *mtk_state)
{
struct drm_plane_state *state = &mtk_state->base;
unsigned int rotation = 0;
@@ -178,15 +217,15 @@ static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx,
return 0;
}
-static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx,
- struct cmdq_pkt *cmdq_pkt)
+void mtk_ovl_layer_on(struct device *dev, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt)
{
unsigned int gmc_thrshd_l;
unsigned int gmc_thrshd_h;
unsigned int gmc_value;
- struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
- mtk_ddp_write(cmdq_pkt, 0x1, comp,
+ mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_RDMA_CTRL(idx));
gmc_thrshd_l = GMC_THRESHOLD_LOW >>
(GMC_THRESHOLD_BITS - ovl->data->gmc_bits);
@@ -198,17 +237,19 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx,
gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 |
gmc_thrshd_h << 16 | gmc_thrshd_h << 24;
mtk_ddp_write(cmdq_pkt, gmc_value,
- comp, DISP_REG_OVL_RDMA_GMC(idx));
- mtk_ddp_write_mask(cmdq_pkt, BIT(idx), comp,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RDMA_GMC(idx));
+ mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_SRC_CON, BIT(idx));
}
-static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx,
- struct cmdq_pkt *cmdq_pkt)
+void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt)
{
- mtk_ddp_write_mask(cmdq_pkt, 0, comp,
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_SRC_CON, BIT(idx));
- mtk_ddp_write(cmdq_pkt, 0, comp,
+ mtk_ddp_write(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_RDMA_CTRL(idx));
}
@@ -248,11 +289,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
}
}
-static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
- struct mtk_plane_state *state,
- struct cmdq_pkt *cmdq_pkt)
+void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt)
{
- struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
struct mtk_plane_pending_state *pending = &state->pending;
unsigned int addr = pending->addr;
unsigned int pitch = pending->pitch & 0xffff;
@@ -262,12 +303,12 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
unsigned int con;
if (!pending->enable) {
- mtk_ovl_layer_off(comp, idx, cmdq_pkt);
+ mtk_ovl_layer_off(dev, idx, cmdq_pkt);
return;
}
con = ovl_fmt_convert(ovl, fmt);
- if (state->base.fb->format->has_alpha)
+ if (state->base.fb && state->base.fb->format->has_alpha)
con |= OVL_CON_AEN | OVL_CON_ALPHA;
if (pending->rotation & DRM_MODE_REFLECT_Y) {
@@ -280,76 +321,49 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
addr += pending->pitch - 1;
}
- mtk_ddp_write_relaxed(cmdq_pkt, con, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_CON(idx));
- mtk_ddp_write_relaxed(cmdq_pkt, pitch, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, pitch, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_PITCH(idx));
- mtk_ddp_write_relaxed(cmdq_pkt, src_size, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_SRC_SIZE(idx));
- mtk_ddp_write_relaxed(cmdq_pkt, offset, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_OFFSET(idx));
- mtk_ddp_write_relaxed(cmdq_pkt, addr, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_ADDR(ovl, idx));
- mtk_ovl_layer_on(comp, idx, cmdq_pkt);
+ mtk_ovl_layer_on(dev, idx, cmdq_pkt);
}
-static void mtk_ovl_bgclr_in_on(struct mtk_ddp_comp *comp)
+void mtk_ovl_bgclr_in_on(struct device *dev)
{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
unsigned int reg;
- reg = readl(comp->regs + DISP_REG_OVL_DATAPATH_CON);
+ reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
reg = reg | OVL_BGCLR_SEL_IN;
- writel(reg, comp->regs + DISP_REG_OVL_DATAPATH_CON);
+ writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
-static void mtk_ovl_bgclr_in_off(struct mtk_ddp_comp *comp)
+void mtk_ovl_bgclr_in_off(struct device *dev)
{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
unsigned int reg;
- reg = readl(comp->regs + DISP_REG_OVL_DATAPATH_CON);
+ reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
reg = reg & ~OVL_BGCLR_SEL_IN;
- writel(reg, comp->regs + DISP_REG_OVL_DATAPATH_CON);
+ writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
-static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
- .config = mtk_ovl_config,
- .start = mtk_ovl_start,
- .stop = mtk_ovl_stop,
- .enable_vblank = mtk_ovl_enable_vblank,
- .disable_vblank = mtk_ovl_disable_vblank,
- .supported_rotations = mtk_ovl_supported_rotations,
- .layer_nr = mtk_ovl_layer_nr,
- .layer_check = mtk_ovl_layer_check,
- .layer_config = mtk_ovl_layer_config,
- .bgclr_in_on = mtk_ovl_bgclr_in_on,
- .bgclr_in_off = mtk_ovl_bgclr_in_off,
-};
-
static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
- int ret;
-
- ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
- if (ret < 0) {
- dev_err(dev, "Failed to register component %pOF: %d\n",
- dev->of_node, ret);
- return ret;
- }
-
return 0;
}
static void mtk_disp_ovl_unbind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
-
- mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
}
static const struct component_ops mtk_disp_ovl_component_ops = {
@@ -361,7 +375,7 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_ovl *priv;
- int comp_id;
+ struct resource *res;
int irq;
int ret;
@@ -373,27 +387,25 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- priv->data = of_device_get_match_data(dev);
-
- comp_id = mtk_ddp_comp_get_id(dev->of_node,
- priv->data->layer_nr == 4 ?
- MTK_DISP_OVL :
- MTK_DISP_OVL_2L);
- if (comp_id < 0) {
- dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
- return comp_id;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get ovl clk\n");
+ return PTR_ERR(priv->clk);
}
- ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
- &mtk_disp_ovl_funcs);
- if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to initialize component: %d\n",
- ret);
-
- return ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "failed to ioremap ovl\n");
+ return PTR_ERR(priv->regs);
}
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+ priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
@@ -412,8 +424,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
static int mtk_disp_ovl_remove(struct platform_device *pdev)
{
- component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
-
return 0;
}
@@ -431,11 +441,29 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
};
+static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
+ .addr = DISP_REG_OVL_ADDR_MT8173,
+ .gmc_bits = 10,
+ .layer_nr = 4,
+ .fmt_rgb565_is_0 = true,
+};
+
+static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
+ .addr = DISP_REG_OVL_ADDR_MT8173,
+ .gmc_bits = 10,
+ .layer_nr = 2,
+ .fmt_rgb565_is_0 = true,
+};
+
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-ovl",
.data = &mt2701_ovl_driver_data},
{ .compatible = "mediatek,mt8173-disp-ovl",
.data = &mt8173_ovl_driver_data},
+ { .compatible = "mediatek,mt8183-disp-ovl",
+ .data = &mt8183_ovl_driver_data},
+ { .compatible = "mediatek,mt8183-disp-ovl-2l",
+ .data = &mt8183_ovl_2l_driver_data},
{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index d46b8ae1d080..728aaadfea8c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
+#include "mtk_disp_drv.h"
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -61,83 +62,105 @@ struct mtk_disp_rdma_data {
* @data: local driver data
*/
struct mtk_disp_rdma {
- struct mtk_ddp_comp ddp_comp;
- struct drm_crtc *crtc;
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
const struct mtk_disp_rdma_data *data;
+ void (*vblank_cb)(void *data);
+ void *vblank_cb_data;
+ u32 fifo_size;
};
-static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
-{
- return container_of(comp, struct mtk_disp_rdma, ddp_comp);
-}
-
static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
{
struct mtk_disp_rdma *priv = dev_id;
- struct mtk_ddp_comp *rdma = &priv->ddp_comp;
/* Clear frame completion interrupt */
- writel(0x0, rdma->regs + DISP_REG_RDMA_INT_STATUS);
+ writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
- if (!priv->crtc)
+ if (!priv->vblank_cb)
return IRQ_NONE;
- mtk_crtc_ddp_irq(priv->crtc, rdma);
+ priv->vblank_cb(priv->vblank_cb_data);
return IRQ_HANDLED;
}
-static void rdma_update_bits(struct mtk_ddp_comp *comp, unsigned int reg,
+static void rdma_update_bits(struct device *dev, unsigned int reg,
unsigned int mask, unsigned int val)
{
- unsigned int tmp = readl(comp->regs + reg);
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+ unsigned int tmp = readl(rdma->regs + reg);
tmp = (tmp & ~mask) | (val & mask);
- writel(tmp, comp->regs + reg);
+ writel(tmp, rdma->regs + reg);
}
-static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
- struct drm_crtc *crtc)
+void mtk_rdma_enable_vblank(struct device *dev,
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data)
{
- struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
- rdma->crtc = crtc;
- rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
+ rdma->vblank_cb = vblank_cb;
+ rdma->vblank_cb_data = vblank_cb_data;
+ rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
RDMA_FRAME_END_INT);
}
-static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
+void mtk_rdma_disable_vblank(struct device *dev)
+{
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+ rdma->vblank_cb = NULL;
+ rdma->vblank_cb_data = NULL;
+ rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
+}
+
+int mtk_rdma_clk_enable(struct device *dev)
{
- struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
- rdma->crtc = NULL;
- rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
+ return clk_prepare_enable(rdma->clk);
}
-static void mtk_rdma_start(struct mtk_ddp_comp *comp)
+void mtk_rdma_clk_disable(struct device *dev)
{
- rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON, RDMA_ENGINE_EN,
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(rdma->clk);
+}
+
+void mtk_rdma_start(struct device *dev)
+{
+ rdma_update_bits(dev, DISP_REG_RDMA_GLOBAL_CON, RDMA_ENGINE_EN,
RDMA_ENGINE_EN);
}
-static void mtk_rdma_stop(struct mtk_ddp_comp *comp)
+void mtk_rdma_stop(struct device *dev)
{
- rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON, RDMA_ENGINE_EN, 0);
+ rdma_update_bits(dev, DISP_REG_RDMA_GLOBAL_CON, RDMA_ENGINE_EN, 0);
}
-static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
- unsigned int height, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+void mtk_rdma_config(struct device *dev, unsigned int width,
+ unsigned int height, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
unsigned int threshold;
unsigned int reg;
- struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+ u32 rdma_fifo_size;
- mtk_ddp_write_mask(cmdq_pkt, width, comp,
+ mtk_ddp_write_mask(cmdq_pkt, width, &rdma->cmdq_reg, rdma->regs,
DISP_REG_RDMA_SIZE_CON_0, 0xfff);
- mtk_ddp_write_mask(cmdq_pkt, height, comp,
+ mtk_ddp_write_mask(cmdq_pkt, height, &rdma->cmdq_reg, rdma->regs,
DISP_REG_RDMA_SIZE_CON_1, 0xfffff);
+ if (rdma->fifo_size)
+ rdma_fifo_size = rdma->fifo_size;
+ else
+ rdma_fifo_size = RDMA_FIFO_SIZE(rdma);
+
/*
* Enable FIFO underflow since DSI and DPI can't be blocked.
* Keep the FIFO pseudo size reset default of 8 KiB. Set the
@@ -146,9 +169,9 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
*/
threshold = width * height * vrefresh * 4 * 7 / 1000000;
reg = RDMA_FIFO_UNDERFLOW_EN |
- RDMA_FIFO_PSEUDO_SIZE(RDMA_FIFO_SIZE(rdma)) |
+ RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size) |
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
- mtk_ddp_write(cmdq_pkt, reg, comp, DISP_REG_RDMA_FIFO_CON);
+ mtk_ddp_write(cmdq_pkt, reg, &rdma->cmdq_reg, rdma->regs, DISP_REG_RDMA_FIFO_CON);
}
static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
@@ -188,16 +211,16 @@ static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
}
}
-static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp)
+unsigned int mtk_rdma_layer_nr(struct device *dev)
{
return 1;
}
-static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
- struct mtk_plane_state *state,
- struct cmdq_pkt *cmdq_pkt)
+void mtk_rdma_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt)
{
- struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
struct mtk_plane_pending_state *pending = &state->pending;
unsigned int addr = pending->addr;
unsigned int pitch = pending->pitch & 0xffff;
@@ -205,53 +228,34 @@ static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
unsigned int con;
con = rdma_fmt_convert(rdma, fmt);
- mtk_ddp_write_relaxed(cmdq_pkt, con, comp, DISP_RDMA_MEM_CON);
+ mtk_ddp_write_relaxed(cmdq_pkt, con, &rdma->cmdq_reg, rdma->regs, DISP_RDMA_MEM_CON);
if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) {
- mtk_ddp_write_mask(cmdq_pkt, RDMA_MATRIX_ENABLE, comp,
+ mtk_ddp_write_mask(cmdq_pkt, RDMA_MATRIX_ENABLE, &rdma->cmdq_reg, rdma->regs,
DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE);
mtk_ddp_write_mask(cmdq_pkt, RDMA_MATRIX_INT_MTX_BT601_to_RGB,
- comp, DISP_REG_RDMA_SIZE_CON_0,
+ &rdma->cmdq_reg, rdma->regs, DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_INT_MTX_SEL);
} else {
- mtk_ddp_write_mask(cmdq_pkt, 0, comp,
+ mtk_ddp_write_mask(cmdq_pkt, 0, &rdma->cmdq_reg, rdma->regs,
DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE);
}
- mtk_ddp_write_relaxed(cmdq_pkt, addr, comp, DISP_RDMA_MEM_START_ADDR);
- mtk_ddp_write_relaxed(cmdq_pkt, pitch, comp, DISP_RDMA_MEM_SRC_PITCH);
- mtk_ddp_write(cmdq_pkt, RDMA_MEM_GMC, comp,
+ mtk_ddp_write_relaxed(cmdq_pkt, addr, &rdma->cmdq_reg, rdma->regs,
+ DISP_RDMA_MEM_START_ADDR);
+ mtk_ddp_write_relaxed(cmdq_pkt, pitch, &rdma->cmdq_reg, rdma->regs,
+ DISP_RDMA_MEM_SRC_PITCH);
+ mtk_ddp_write(cmdq_pkt, RDMA_MEM_GMC, &rdma->cmdq_reg, rdma->regs,
DISP_RDMA_MEM_GMC_SETTING_0);
- mtk_ddp_write_mask(cmdq_pkt, RDMA_MODE_MEMORY, comp,
+ mtk_ddp_write_mask(cmdq_pkt, RDMA_MODE_MEMORY, &rdma->cmdq_reg, rdma->regs,
DISP_REG_RDMA_GLOBAL_CON, RDMA_MODE_MEMORY);
}
-static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
- .config = mtk_rdma_config,
- .start = mtk_rdma_start,
- .stop = mtk_rdma_stop,
- .enable_vblank = mtk_rdma_enable_vblank,
- .disable_vblank = mtk_rdma_disable_vblank,
- .layer_nr = mtk_rdma_layer_nr,
- .layer_config = mtk_rdma_layer_config,
-};
-
static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
- int ret;
-
- ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
- if (ret < 0) {
- dev_err(dev, "Failed to register component %pOF: %d\n",
- dev->of_node, ret);
- return ret;
- }
-
return 0;
}
@@ -259,10 +263,6 @@ static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
static void mtk_disp_rdma_unbind(struct device *dev, struct device *master,
void *data)
{
- struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
-
- mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
}
static const struct component_ops mtk_disp_rdma_component_ops = {
@@ -274,7 +274,7 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_rdma *priv;
- int comp_id;
+ struct resource *res;
int irq;
int ret;
@@ -286,25 +286,37 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_RDMA);
- if (comp_id < 0) {
- dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
- return comp_id;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get rdma clk\n");
+ return PTR_ERR(priv->clk);
}
- ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
- &mtk_disp_rdma_funcs);
- if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to initialize component: %d\n",
- ret);
-
- return ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "failed to ioremap rdma\n");
+ return PTR_ERR(priv->regs);
+ }
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+ if (of_find_property(dev->of_node, "mediatek,rdma-fifo-size", &ret)) {
+ ret = of_property_read_u32(dev->of_node,
+ "mediatek,rdma-fifo-size",
+ &priv->fifo_size);
+ if (ret) {
+ dev_err(dev, "Failed to get rdma fifo size\n");
+ return ret;
+ }
}
/* Disable and clear pending interrupts */
- writel(0x0, priv->ddp_comp.regs + DISP_REG_RDMA_INT_ENABLE);
- writel(0x0, priv->ddp_comp.regs + DISP_REG_RDMA_INT_STATUS);
+ writel(0x0, priv->regs + DISP_REG_RDMA_INT_ENABLE);
+ writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
ret = devm_request_irq(dev, irq, mtk_disp_rdma_irq_handler,
IRQF_TRIGGER_NONE, dev_name(dev), priv);
@@ -339,11 +351,17 @@ static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
.fifo_size = SZ_8K,
};
+static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
+ .fifo_size = 5 * SZ_1K,
+};
+
static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-rdma",
.data = &mt2701_rdma_driver_data},
{ .compatible = "mediatek,mt8173-disp-rdma",
.data = &mt8173_rdma_driver_data},
+ { .compatible = "mediatek,mt8183-disp-rdma",
+ .data = &mt8183_rdma_driver_data},
{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 52f11a63a330..b05f900d9322 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -20,10 +20,12 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_of.h>
#include <drm/drm_simple_kms_helper.h>
+#include "mtk_disp_drv.h"
#include "mtk_dpi_regs.h"
#include "mtk_drm_ddp_comp.h"
@@ -62,10 +64,10 @@ enum mtk_dpi_out_color_format {
};
struct mtk_dpi {
- struct mtk_ddp_comp ddp_comp;
struct drm_encoder encoder;
struct drm_bridge bridge;
struct drm_bridge *next_bridge;
+ struct drm_connector *connector;
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
@@ -562,53 +564,50 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
.enable = mtk_dpi_bridge_enable,
};
-static void mtk_dpi_start(struct mtk_ddp_comp *comp)
+void mtk_dpi_start(struct device *dev)
{
- struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
+ struct mtk_dpi *dpi = dev_get_drvdata(dev);
mtk_dpi_power_on(dpi);
}
-static void mtk_dpi_stop(struct mtk_ddp_comp *comp)
+void mtk_dpi_stop(struct device *dev)
{
- struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
+ struct mtk_dpi *dpi = dev_get_drvdata(dev);
mtk_dpi_power_off(dpi);
}
-static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = {
- .start = mtk_dpi_start,
- .stop = mtk_dpi_stop,
-};
-
static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
{
struct mtk_dpi *dpi = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
int ret;
- ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp);
- if (ret < 0) {
- dev_err(dev, "Failed to register component %pOF: %d\n",
- dev->of_node, ret);
- return ret;
- }
-
ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
DRM_MODE_ENCODER_TMDS);
if (ret) {
dev_err(dev, "Failed to initialize decoder: %d\n", ret);
- goto err_unregister;
+ return ret;
}
- dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp);
+ dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->dev);
- ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, 0);
+ ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret) {
dev_err(dev, "Failed to attach bridge: %d\n", ret);
goto err_cleanup;
}
+ dpi->connector = drm_bridge_connector_init(drm_dev, &dpi->encoder);
+ if (IS_ERR(dpi->connector)) {
+ dev_err(dev, "Unable to create bridge connector\n");
+ ret = PTR_ERR(dpi->connector);
+ goto err_cleanup;
+ }
+ drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
+
dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
@@ -618,8 +617,6 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
err_cleanup:
drm_encoder_cleanup(&dpi->encoder);
-err_unregister:
- mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
return ret;
}
@@ -627,10 +624,8 @@ static void mtk_dpi_unbind(struct device *dev, struct device *master,
void *data)
{
struct mtk_dpi *dpi = dev_get_drvdata(dev);
- struct drm_device *drm_dev = data;
drm_encoder_cleanup(&dpi->encoder);
- mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
}
static const struct component_ops mtk_dpi_component_ops = {
@@ -691,7 +686,6 @@ static int mtk_dpi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mtk_dpi *dpi;
struct resource *mem;
- int comp_id;
int ret;
dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
@@ -769,19 +763,6 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
- comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
- if (comp_id < 0) {
- dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
- return comp_id;
- }
-
- ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id,
- &mtk_dpi_funcs);
- if (ret) {
- dev_err(dev, "Failed to initialize component: %d\n", ret);
- return ret;
- }
-
platform_set_drvdata(pdev, dpi);
dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 584dc26affc1..8b0de90156c6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -7,6 +7,7 @@
#include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-mutex.h>
#include <asm/barrier.h>
#include <soc/mediatek/smi.h>
@@ -19,7 +20,6 @@
#include "mtk_drm_drv.h"
#include "mtk_drm_crtc.h"
-#include "mtk_drm_ddp.h"
#include "mtk_drm_ddp_comp.h"
#include "mtk_drm_gem.h"
#include "mtk_drm_plane.h"
@@ -55,7 +55,7 @@ struct mtk_drm_crtc {
#endif
struct device *mmsys_dev;
- struct mtk_disp_mutex *mutex;
+ struct mtk_mutex *mutex;
unsigned int ddp_comp_nr;
struct mtk_ddp_comp **ddp_comp;
@@ -107,7 +107,7 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- mtk_disp_mutex_put(mtk_crtc->mutex);
+ mtk_mutex_put(mtk_crtc->mutex);
drm_crtc_cleanup(crtc);
}
@@ -169,31 +169,13 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
state->pending_config = true;
}
-static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
-{
- struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
-
- mtk_ddp_comp_enable_vblank(comp, &mtk_crtc->base);
-
- return 0;
-}
-
-static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
-{
- struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
-
- mtk_ddp_comp_disable_vblank(comp);
-}
-
static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
{
int ret;
int i;
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
- ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk);
+ ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);
if (ret) {
DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
goto err;
@@ -203,7 +185,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
return 0;
err:
while (--i >= 0)
- clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
+ mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
return ret;
}
@@ -212,7 +194,7 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
int i;
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
- clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
+ mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
}
static
@@ -283,7 +265,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
return ret;
}
- ret = mtk_disp_mutex_prepare(mtk_crtc->mutex);
+ ret = mtk_mutex_prepare(mtk_crtc->mutex);
if (ret < 0) {
DRM_ERROR("Failed to enable mutex clock: %d\n", ret);
goto err_pm_runtime_put;
@@ -299,11 +281,11 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
- mtk_disp_mutex_add_comp(mtk_crtc->mutex,
+ mtk_mutex_add_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
}
- mtk_disp_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
- mtk_disp_mutex_enable(mtk_crtc->mutex);
+ mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
+ mtk_mutex_enable(mtk_crtc->mutex);
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
@@ -332,7 +314,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
return 0;
err_mutex_unprepare:
- mtk_disp_mutex_unprepare(mtk_crtc->mutex);
+ mtk_mutex_unprepare(mtk_crtc->mutex);
err_pm_runtime_put:
pm_runtime_put(crtc->dev->dev);
return ret;
@@ -351,19 +333,19 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
}
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
- mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
+ mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
- mtk_disp_mutex_disable(mtk_crtc->mutex);
+ mtk_mutex_disable(mtk_crtc->mutex);
for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
- mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
+ mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
}
- mtk_disp_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
+ mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
mtk_crtc_ddp_clk_disable(mtk_crtc);
- mtk_disp_mutex_unprepare(mtk_crtc->mutex);
+ mtk_mutex_unprepare(mtk_crtc->mutex);
pm_runtime_put(drm->dev);
@@ -475,9 +457,9 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
mtk_crtc->pending_async_planes = true;
if (priv->data->shadow_register) {
- mtk_disp_mutex_acquire(mtk_crtc->mutex);
+ mtk_mutex_acquire(mtk_crtc->mutex);
mtk_crtc_ddp_config(crtc, NULL);
- mtk_disp_mutex_release(mtk_crtc->mutex);
+ mtk_mutex_release(mtk_crtc->mutex);
}
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (mtk_crtc->cmdq_client) {
@@ -493,6 +475,40 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
mutex_unlock(&mtk_crtc->hw_lock);
}
+static void mtk_crtc_ddp_irq(void *data)
+{
+ struct drm_crtc *crtc = data;
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_drm_private *priv = crtc->dev->dev_private;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
+#else
+ if (!priv->data->shadow_register)
+#endif
+ mtk_crtc_ddp_config(crtc, NULL);
+
+ mtk_drm_finish_page_flip(mtk_crtc);
+}
+
+static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
+
+ mtk_ddp_comp_enable_vblank(comp, mtk_crtc_ddp_irq, &mtk_crtc->base);
+
+ return 0;
+}
+
+static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
+
+ mtk_ddp_comp_disable_vblank(comp);
+}
+
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state)
{
@@ -661,21 +677,6 @@ err_cleanup_crtc:
return ret;
}
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
-{
- struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_drm_private *priv = crtc->dev->dev_private;
-
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
-#else
- if (!priv->data->shadow_register)
-#endif
- mtk_crtc_ddp_config(crtc, NULL);
-
- mtk_drm_finish_page_flip(mtk_crtc);
-}
-
static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
int comp_idx)
{
@@ -771,7 +772,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (!mtk_crtc->ddp_comp)
return -ENOMEM;
- mtk_crtc->mutex = mtk_disp_mutex_get(priv->mutex_dev, pipe);
+ mtk_crtc->mutex = mtk_mutex_get(priv->mutex_dev);
if (IS_ERR(mtk_crtc->mutex)) {
ret = PTR_ERR(mtk_crtc->mutex);
dev_err(dev, "Failed to get mutex: %d\n", ret);
@@ -784,7 +785,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
struct device_node *node;
node = priv->comp_node[comp_id];
- comp = priv->ddp_comp[comp_id];
+ comp = &priv->ddp_comp[comp_id];
if (!comp) {
dev_err(dev, "Component %pOF not initialized\n", node);
ret = -ENODEV;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index a2b4677a451c..45cfd0a032de 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -15,7 +15,6 @@
#define MTK_MIN_BPC 3
void mtk_drm_crtc_commit(struct drm_crtc *crtc);
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);
int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path,
unsigned int path_len);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
deleted file mode 100644
index 6b691a57be4a..000000000000
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2015 MediaTek Inc.
- */
-
-#ifndef MTK_DRM_DDP_H
-#define MTK_DRM_DDP_H
-
-#include "mtk_drm_ddp_comp.h"
-
-struct regmap;
-struct device;
-struct mtk_disp_mutex;
-
-struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id);
-int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
- enum mtk_ddp_comp_id id);
-void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
- enum mtk_ddp_comp_id id);
-void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex);
-void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex);
-
-#endif /* MTK_DRM_DDP_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 3064eac1a750..75bc00e17fc4 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -9,12 +9,12 @@
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <drm/drm_print.h>
+#include "mtk_disp_drv.h"
#include "mtk_drm_drv.h"
#include "mtk_drm_plane.h"
#include "mtk_drm_ddp_comp.h"
@@ -35,31 +35,13 @@
#define DISP_AAL_EN 0x0000
#define DISP_AAL_SIZE 0x0030
-#define DISP_CCORR_EN 0x0000
-#define CCORR_EN BIT(0)
-#define DISP_CCORR_CFG 0x0020
-#define CCORR_RELAY_MODE BIT(0)
-#define CCORR_ENGINE_EN BIT(1)
-#define CCORR_GAMMA_OFF BIT(2)
-#define CCORR_WGAMUT_SRC_CLIP BIT(3)
-#define DISP_CCORR_SIZE 0x0030
-#define DISP_CCORR_COEF_0 0x0080
-#define DISP_CCORR_COEF_1 0x0084
-#define DISP_CCORR_COEF_2 0x0088
-#define DISP_CCORR_COEF_3 0x008C
-#define DISP_CCORR_COEF_4 0x0090
-
#define DISP_DITHER_EN 0x0000
#define DITHER_EN BIT(0)
#define DISP_DITHER_CFG 0x0020
#define DITHER_RELAY_MODE BIT(0)
+#define DITHER_ENGINE_EN BIT(1)
#define DISP_DITHER_SIZE 0x0030
-#define DISP_GAMMA_EN 0x0000
-#define DISP_GAMMA_CFG 0x0020
-#define DISP_GAMMA_SIZE 0x0030
-#define DISP_GAMMA_LUT 0x0700
-
#define LUT_10BIT_MASK 0x03ff
#define OD_RELAYMODE BIT(0)
@@ -68,9 +50,6 @@
#define AAL_EN BIT(0)
-#define GAMMA_EN BIT(0)
-#define GAMMA_LUT_EN BIT(1)
-
#define DISP_DITHERING BIT(2)
#define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28)
#define DITHER_OVFLW_BIT_R(x) (((x) & 0x7) << 24)
@@ -86,262 +65,233 @@
#define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4)
#define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0)
+struct mtk_ddp_comp_dev {
+ struct clk *clk;
+ void __iomem *regs;
+ struct cmdq_client_reg cmdq_reg;
+};
+
void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
- struct mtk_ddp_comp *comp, unsigned int offset)
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
+ unsigned int offset)
{
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (cmdq_pkt)
- cmdq_pkt_write(cmdq_pkt, comp->subsys,
- comp->regs_pa + offset, value);
+ cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
+ cmdq_reg->offset + offset, value);
else
#endif
- writel(value, comp->regs + offset);
+ writel(value, regs + offset);
}
void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
- struct mtk_ddp_comp *comp,
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
unsigned int offset)
{
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (cmdq_pkt)
- cmdq_pkt_write(cmdq_pkt, comp->subsys,
- comp->regs_pa + offset, value);
+ cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
+ cmdq_reg->offset + offset, value);
else
#endif
- writel_relaxed(value, comp->regs + offset);
+ writel_relaxed(value, regs + offset);
}
-void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt,
- unsigned int value,
- struct mtk_ddp_comp *comp,
- unsigned int offset,
- unsigned int mask)
+void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
+ unsigned int offset, unsigned int mask)
{
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (cmdq_pkt) {
- cmdq_pkt_write_mask(cmdq_pkt, comp->subsys,
- comp->regs_pa + offset, value, mask);
+ cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
+ cmdq_reg->offset + offset, value, mask);
} else {
#endif
- u32 tmp = readl(comp->regs + offset);
+ u32 tmp = readl(regs + offset);
tmp = (tmp & ~mask) | (value & mask);
- writel(tmp, comp->regs + offset);
+ writel(tmp, regs + offset);
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
}
#endif
}
-void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
- unsigned int CFG, struct cmdq_pkt *cmdq_pkt)
+static int mtk_ddp_clk_enable(struct device *dev)
+{
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(priv->clk);
+}
+
+static void mtk_ddp_clk_disable(struct device *dev)
+{
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(priv->clk);
+}
+
+void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
+ unsigned int bpc, unsigned int cfg,
+ unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
{
/* If bpc equal to 0, the dithering function didn't be enabled */
if (bpc == 0)
return;
if (bpc >= MTK_MIN_BPC) {
- mtk_ddp_write(cmdq_pkt, 0, comp, DISP_DITHER_5);
- mtk_ddp_write(cmdq_pkt, 0, comp, DISP_DITHER_7);
+ mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
+ mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
mtk_ddp_write(cmdq_pkt,
DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
DITHER_NEW_BIT_MODE,
- comp, DISP_DITHER_15);
+ cmdq_reg, regs, DISP_DITHER_15);
mtk_ddp_write(cmdq_pkt,
DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
- comp, DISP_DITHER_16);
- mtk_ddp_write(cmdq_pkt, DISP_DITHERING, comp, CFG);
+ cmdq_reg, regs, DISP_DITHER_16);
+ mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
}
}
-static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+static void mtk_dither_set(struct device *dev, unsigned int bpc,
+ unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
{
- mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_OD_SIZE);
- mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, comp, DISP_OD_CFG);
- mtk_dither_set(comp, bpc, DISP_OD_CFG, cmdq_pkt);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_od_start(struct mtk_ddp_comp *comp)
-{
- writel(1, comp->regs + DISP_OD_EN);
+ mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
+ DISP_DITHERING, cmdq_pkt);
}
-static void mtk_ufoe_start(struct mtk_ddp_comp *comp)
+static void mtk_od_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
- writel(UFO_BYPASS, comp->regs + DISP_REG_UFO_START);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
-{
- mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_AAL_SIZE);
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
+ mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
+ mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
}
-static void mtk_aal_start(struct mtk_ddp_comp *comp)
+static void mtk_od_start(struct device *dev)
{
- writel(AAL_EN, comp->regs + DISP_AAL_EN);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_aal_stop(struct mtk_ddp_comp *comp)
-{
- writel_relaxed(0x0, comp->regs + DISP_AAL_EN);
+ writel(1, priv->regs + DISP_OD_EN);
}
-static void mtk_ccorr_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+static void mtk_ufoe_start(struct device *dev)
{
- mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_CCORR_SIZE);
- mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, comp, DISP_CCORR_CFG);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_ccorr_start(struct mtk_ddp_comp *comp)
-{
- writel(CCORR_EN, comp->regs + DISP_CCORR_EN);
+ writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
}
-static void mtk_ccorr_stop(struct mtk_ddp_comp *comp)
+static void mtk_aal_config(struct device *dev, unsigned int w,
+ unsigned int h, unsigned int vrefresh,
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
- writel_relaxed(0x0, comp->regs + DISP_CCORR_EN);
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
}
-/* Converts a DRM S31.32 value to the HW S1.10 format. */
-static u16 mtk_ctm_s31_32_to_s1_10(u64 in)
+static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
{
- u16 r;
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
- /* Sign bit. */
- r = in & BIT_ULL(63) ? BIT(11) : 0;
+ mtk_gamma_set_common(priv->regs, state);
+}
- if ((in & GENMASK_ULL(62, 33)) > 0) {
- /* identity value 0x100000000 -> 0x400, */
- /* if bigger this, set it to max 0x7ff. */
- r |= GENMASK(10, 0);
- } else {
- /* take the 11 most important bits. */
- r |= (in >> 22) & GENMASK(10, 0);
- }
+static void mtk_aal_start(struct device *dev)
+{
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
- return r;
+ writel(AAL_EN, priv->regs + DISP_AAL_EN);
}
-static void mtk_ccorr_ctm_set(struct mtk_ddp_comp *comp,
- struct drm_crtc_state *state)
+static void mtk_aal_stop(struct device *dev)
{
- struct drm_property_blob *blob = state->ctm;
- struct drm_color_ctm *ctm;
- const u64 *input;
- uint16_t coeffs[9] = { 0 };
- int i;
- struct cmdq_pkt *cmdq_pkt = NULL;
-
- if (!blob)
- return;
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
- ctm = (struct drm_color_ctm *)blob->data;
- input = ctm->matrix;
-
- for (i = 0; i < ARRAY_SIZE(coeffs); i++)
- coeffs[i] = mtk_ctm_s31_32_to_s1_10(input[i]);
-
- mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
- comp, DISP_CCORR_COEF_0);
- mtk_ddp_write(cmdq_pkt, coeffs[2] << 16 | coeffs[3],
- comp, DISP_CCORR_COEF_1);
- mtk_ddp_write(cmdq_pkt, coeffs[4] << 16 | coeffs[5],
- comp, DISP_CCORR_COEF_2);
- mtk_ddp_write(cmdq_pkt, coeffs[6] << 16 | coeffs[7],
- comp, DISP_CCORR_COEF_3);
- mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,
- comp, DISP_CCORR_COEF_4);
+ writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
}
-static void mtk_dither_config(struct mtk_ddp_comp *comp, unsigned int w,
+static void mtk_dither_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
- mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_DITHER_SIZE);
- mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, comp, DISP_DITHER_CFG);
-}
-
-static void mtk_dither_start(struct mtk_ddp_comp *comp)
-{
- writel(DITHER_EN, comp->regs + DISP_DITHER_EN);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_dither_stop(struct mtk_ddp_comp *comp)
-{
- writel_relaxed(0x0, comp->regs + DISP_DITHER_EN);
+ mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
+ mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
+ mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
+ DITHER_ENGINE_EN, cmdq_pkt);
}
-static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
- unsigned int h, unsigned int vrefresh,
- unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+static void mtk_dither_start(struct device *dev)
{
- mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_GAMMA_SIZE);
- mtk_dither_set(comp, bpc, DISP_GAMMA_CFG, cmdq_pkt);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_gamma_start(struct mtk_ddp_comp *comp)
-{
- writel(GAMMA_EN, comp->regs + DISP_GAMMA_EN);
+ writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
}
-static void mtk_gamma_stop(struct mtk_ddp_comp *comp)
+static void mtk_dither_stop(struct device *dev)
{
- writel_relaxed(0x0, comp->regs + DISP_GAMMA_EN);
-}
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-static void mtk_gamma_set(struct mtk_ddp_comp *comp,
- struct drm_crtc_state *state)
-{
- unsigned int i, reg;
- struct drm_color_lut *lut;
- void __iomem *lut_base;
- u32 word;
-
- if (state->gamma_lut) {
- reg = readl(comp->regs + DISP_GAMMA_CFG);
- reg = reg | GAMMA_LUT_EN;
- writel(reg, comp->regs + DISP_GAMMA_CFG);
- lut_base = comp->regs + DISP_GAMMA_LUT;
- lut = (struct drm_color_lut *)state->gamma_lut->data;
- for (i = 0; i < MTK_LUT_SIZE; i++) {
- word = (((lut[i].red >> 6) & LUT_10BIT_MASK) << 20) +
- (((lut[i].green >> 6) & LUT_10BIT_MASK) << 10) +
- ((lut[i].blue >> 6) & LUT_10BIT_MASK);
- writel(word, (lut_base + i * 4));
- }
- }
+ writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
}
static const struct mtk_ddp_comp_funcs ddp_aal = {
- .gamma_set = mtk_gamma_set,
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
+ .gamma_set = mtk_aal_gamma_set,
.config = mtk_aal_config,
.start = mtk_aal_start,
.stop = mtk_aal_stop,
};
static const struct mtk_ddp_comp_funcs ddp_ccorr = {
+ .clk_enable = mtk_ccorr_clk_enable,
+ .clk_disable = mtk_ccorr_clk_disable,
.config = mtk_ccorr_config,
.start = mtk_ccorr_start,
.stop = mtk_ccorr_stop,
.ctm_set = mtk_ccorr_ctm_set,
};
+static const struct mtk_ddp_comp_funcs ddp_color = {
+ .clk_enable = mtk_color_clk_enable,
+ .clk_disable = mtk_color_clk_disable,
+ .config = mtk_color_config,
+ .start = mtk_color_start,
+};
+
static const struct mtk_ddp_comp_funcs ddp_dither = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.config = mtk_dither_config,
.start = mtk_dither_start,
.stop = mtk_dither_stop,
};
+static const struct mtk_ddp_comp_funcs ddp_dpi = {
+ .start = mtk_dpi_start,
+ .stop = mtk_dpi_stop,
+};
+
+static const struct mtk_ddp_comp_funcs ddp_dsi = {
+ .start = mtk_dsi_ddp_start,
+ .stop = mtk_dsi_ddp_stop,
+};
+
static const struct mtk_ddp_comp_funcs ddp_gamma = {
+ .clk_enable = mtk_gamma_clk_enable,
+ .clk_disable = mtk_gamma_clk_disable,
.gamma_set = mtk_gamma_set,
.config = mtk_gamma_config,
.start = mtk_gamma_start,
@@ -349,11 +299,43 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
};
static const struct mtk_ddp_comp_funcs ddp_od = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.config = mtk_od_config,
.start = mtk_od_start,
};
+static const struct mtk_ddp_comp_funcs ddp_ovl = {
+ .clk_enable = mtk_ovl_clk_enable,
+ .clk_disable = mtk_ovl_clk_disable,
+ .config = mtk_ovl_config,
+ .start = mtk_ovl_start,
+ .stop = mtk_ovl_stop,
+ .enable_vblank = mtk_ovl_enable_vblank,
+ .disable_vblank = mtk_ovl_disable_vblank,
+ .supported_rotations = mtk_ovl_supported_rotations,
+ .layer_nr = mtk_ovl_layer_nr,
+ .layer_check = mtk_ovl_layer_check,
+ .layer_config = mtk_ovl_layer_config,
+ .bgclr_in_on = mtk_ovl_bgclr_in_on,
+ .bgclr_in_off = mtk_ovl_bgclr_in_off,
+};
+
+static const struct mtk_ddp_comp_funcs ddp_rdma = {
+ .clk_enable = mtk_rdma_clk_enable,
+ .clk_disable = mtk_rdma_clk_disable,
+ .config = mtk_rdma_config,
+ .start = mtk_rdma_start,
+ .stop = mtk_rdma_stop,
+ .enable_vblank = mtk_rdma_enable_vblank,
+ .disable_vblank = mtk_rdma_disable_vblank,
+ .layer_nr = mtk_rdma_layer_nr,
+ .layer_config = mtk_rdma_layer_config,
+};
+
static const struct mtk_ddp_comp_funcs ddp_ufoe = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.start = mtk_ufoe_start,
};
@@ -387,36 +369,37 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL1] = { MTK_DISP_AAL, 1, &ddp_aal },
[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_CCORR] = { MTK_DISP_CCORR, 0, &ddp_ccorr },
- [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, NULL },
- [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, NULL },
+ [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color },
+ [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color },
[DDP_COMPONENT_DITHER] = { MTK_DISP_DITHER, 0, &ddp_dither },
- [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL },
- [DDP_COMPONENT_DPI1] = { MTK_DPI, 1, NULL },
- [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, NULL },
- [DDP_COMPONENT_DSI1] = { MTK_DSI, 1, NULL },
- [DDP_COMPONENT_DSI2] = { MTK_DSI, 2, NULL },
- [DDP_COMPONENT_DSI3] = { MTK_DSI, 3, NULL },
+ [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, &ddp_dpi },
+ [DDP_COMPONENT_DPI1] = { MTK_DPI, 1, &ddp_dpi },
+ [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, &ddp_dsi },
+ [DDP_COMPONENT_DSI1] = { MTK_DSI, 1, &ddp_dsi },
+ [DDP_COMPONENT_DSI2] = { MTK_DSI, 2, &ddp_dsi },
+ [DDP_COMPONENT_DSI3] = { MTK_DSI, 3, &ddp_dsi },
[DDP_COMPONENT_GAMMA] = { MTK_DISP_GAMMA, 0, &ddp_gamma },
[DDP_COMPONENT_OD0] = { MTK_DISP_OD, 0, &ddp_od },
[DDP_COMPONENT_OD1] = { MTK_DISP_OD, 1, &ddp_od },
- [DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, NULL },
- [DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, NULL },
- [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, NULL },
- [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, NULL },
+ [DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, &ddp_ovl },
+ [DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, &ddp_ovl },
+ [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, &ddp_ovl },
+ [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, &ddp_ovl },
[DDP_COMPONENT_PWM0] = { MTK_DISP_PWM, 0, NULL },
[DDP_COMPONENT_PWM1] = { MTK_DISP_PWM, 1, NULL },
[DDP_COMPONENT_PWM2] = { MTK_DISP_PWM, 2, NULL },
- [DDP_COMPONENT_RDMA0] = { MTK_DISP_RDMA, 0, NULL },
- [DDP_COMPONENT_RDMA1] = { MTK_DISP_RDMA, 1, NULL },
- [DDP_COMPONENT_RDMA2] = { MTK_DISP_RDMA, 2, NULL },
+ [DDP_COMPONENT_RDMA0] = { MTK_DISP_RDMA, 0, &ddp_rdma },
+ [DDP_COMPONENT_RDMA1] = { MTK_DISP_RDMA, 1, &ddp_rdma },
+ [DDP_COMPONENT_RDMA2] = { MTK_DISP_RDMA, 2, &ddp_rdma },
[DDP_COMPONENT_UFOE] = { MTK_DISP_UFOE, 0, &ddp_ufoe },
[DDP_COMPONENT_WDMA0] = { MTK_DISP_WDMA, 0, NULL },
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
};
-static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp,
+static bool mtk_drm_find_comp_in_ddp(struct device *dev,
const enum mtk_ddp_comp_id *path,
- unsigned int path_len)
+ unsigned int path_len,
+ struct mtk_ddp_comp *ddp_comp)
{
unsigned int i;
@@ -424,7 +407,7 @@ static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp,
return false;
for (i = 0U; i < path_len; i++)
- if (ddp_comp.id == path[i])
+ if (dev == ddp_comp[path[i]].dev)
return true;
return false;
@@ -446,18 +429,19 @@ int mtk_ddp_comp_get_id(struct device_node *node,
}
unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
- struct mtk_ddp_comp ddp_comp)
+ struct device *dev)
{
struct mtk_drm_private *private = drm->dev_private;
unsigned int ret = 0;
- if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path, private->data->main_len))
+ if (mtk_drm_find_comp_in_ddp(dev, private->data->main_path, private->data->main_len,
+ private->ddp_comp))
ret = BIT(0);
- else if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->ext_path,
- private->data->ext_len))
+ else if (mtk_drm_find_comp_in_ddp(dev, private->data->ext_path,
+ private->data->ext_len, private->ddp_comp))
ret = BIT(1);
- else if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->third_path,
- private->data->third_len))
+ else if (mtk_drm_find_comp_in_ddp(dev, private->data->third_path,
+ private->data->third_len, private->ddp_comp))
ret = BIT(2);
else
DRM_INFO("Failed to find comp in ddp table\n");
@@ -465,59 +449,15 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
return ret;
}
-int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
- struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
- const struct mtk_ddp_comp_funcs *funcs)
+static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp *comp,
+ struct device *dev)
{
- enum mtk_ddp_comp_type type;
struct device_node *larb_node;
struct platform_device *larb_pdev;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- struct resource res;
- struct cmdq_client_reg cmdq_reg;
- int ret;
-#endif
-
- if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
- return -EINVAL;
-
- type = mtk_ddp_matches[comp_id].type;
-
- comp->id = comp_id;
- comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
-
- if (comp_id == DDP_COMPONENT_BLS ||
- comp_id == DDP_COMPONENT_DPI0 ||
- comp_id == DDP_COMPONENT_DPI1 ||
- comp_id == DDP_COMPONENT_DSI0 ||
- comp_id == DDP_COMPONENT_DSI1 ||
- comp_id == DDP_COMPONENT_DSI2 ||
- comp_id == DDP_COMPONENT_DSI3 ||
- comp_id == DDP_COMPONENT_PWM0) {
- comp->regs = NULL;
- comp->clk = NULL;
- comp->irq = 0;
- return 0;
- }
-
- comp->regs = of_iomap(node, 0);
- comp->irq = of_irq_get(node, 0);
- comp->clk = of_clk_get(node, 0);
- if (IS_ERR(comp->clk))
- return PTR_ERR(comp->clk);
-
- /* Only DMA capable components need the LARB property */
- comp->larb_dev = NULL;
- if (type != MTK_DISP_OVL &&
- type != MTK_DISP_OVL_2L &&
- type != MTK_DISP_RDMA &&
- type != MTK_DISP_WDMA)
- return 0;
larb_node = of_parse_phandle(node, "mediatek,larb", 0);
if (!larb_node) {
- dev_err(dev,
- "Missing mediadek,larb phandle in %pOF node\n", node);
+ dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", node);
return -EINVAL;
}
@@ -528,40 +468,71 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
return -EPROBE_DEFER;
}
of_node_put(larb_node);
-
comp->larb_dev = &larb_pdev->dev;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- if (of_address_to_resource(node, 0, &res) != 0) {
- dev_err(dev, "Missing reg in %s node\n", node->full_name);
- put_device(&larb_pdev->dev);
- return -EINVAL;
- }
- comp->regs_pa = res.start;
-
- ret = cmdq_dev_get_client_reg(dev, &cmdq_reg, 0);
- if (ret)
- dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
- else
- comp->subsys = cmdq_reg.subsys;
-#endif
return 0;
}
-int mtk_ddp_comp_register(struct drm_device *drm, struct mtk_ddp_comp *comp)
+int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
+ enum mtk_ddp_comp_id comp_id)
{
- struct mtk_drm_private *private = drm->dev_private;
+ struct platform_device *comp_pdev;
+ enum mtk_ddp_comp_type type;
+ struct mtk_ddp_comp_dev *priv;
+ int ret;
- if (private->ddp_comp[comp->id])
- return -EBUSY;
+ if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
+ return -EINVAL;
- private->ddp_comp[comp->id] = comp;
- return 0;
-}
+ type = mtk_ddp_matches[comp_id].type;
-void mtk_ddp_comp_unregister(struct drm_device *drm, struct mtk_ddp_comp *comp)
-{
- struct mtk_drm_private *private = drm->dev_private;
+ comp->id = comp_id;
+ comp->funcs = mtk_ddp_matches[comp_id].funcs;
+ comp_pdev = of_find_device_by_node(node);
+ if (!comp_pdev) {
+ DRM_INFO("Waiting for device %s\n", node->full_name);
+ return -EPROBE_DEFER;
+ }
+ comp->dev = &comp_pdev->dev;
- private->ddp_comp[comp->id] = NULL;
+ /* Only DMA capable components need the LARB property */
+ if (type == MTK_DISP_OVL ||
+ type == MTK_DISP_OVL_2L ||
+ type == MTK_DISP_RDMA ||
+ type == MTK_DISP_WDMA) {
+ ret = mtk_ddp_get_larb_dev(node, comp, comp->dev);
+ if (ret)
+ return ret;
+ }
+
+ if (type == MTK_DISP_BLS ||
+ type == MTK_DISP_CCORR ||
+ type == MTK_DISP_COLOR ||
+ type == MTK_DISP_GAMMA ||
+ type == MTK_DPI ||
+ type == MTK_DSI ||
+ type == MTK_DISP_OVL ||
+ type == MTK_DISP_OVL_2L ||
+ type == MTK_DISP_PWM ||
+ type == MTK_DISP_RDMA)
+ return 0;
+
+ priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->regs = of_iomap(node, 0);
+ priv->clk = of_clk_get(node, 0);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0);
+ if (ret)
+ dev_dbg(comp->dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+ platform_set_drvdata(comp_pdev, priv);
+
+ return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 5aa52b7afeec..bb914d976cf5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -7,6 +7,7 @@
#define MTK_DRM_DDP_COMP_H
#include <linux/io.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
struct device;
@@ -39,79 +40,95 @@ enum mtk_ddp_comp_type {
struct mtk_ddp_comp;
struct cmdq_pkt;
struct mtk_ddp_comp_funcs {
- void (*config)(struct mtk_ddp_comp *comp, unsigned int w,
+ int (*clk_enable)(struct device *dev);
+ void (*clk_disable)(struct device *dev);
+ void (*config)(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
- void (*start)(struct mtk_ddp_comp *comp);
- void (*stop)(struct mtk_ddp_comp *comp);
- void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
- void (*disable_vblank)(struct mtk_ddp_comp *comp);
- unsigned int (*supported_rotations)(struct mtk_ddp_comp *comp);
- unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
- int (*layer_check)(struct mtk_ddp_comp *comp,
+ void (*start)(struct device *dev);
+ void (*stop)(struct device *dev);
+ void (*enable_vblank)(struct device *dev,
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data);
+ void (*disable_vblank)(struct device *dev);
+ unsigned int (*supported_rotations)(struct device *dev);
+ unsigned int (*layer_nr)(struct device *dev);
+ int (*layer_check)(struct device *dev,
unsigned int idx,
struct mtk_plane_state *state);
- void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
+ void (*layer_config)(struct device *dev, unsigned int idx,
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt);
- void (*gamma_set)(struct mtk_ddp_comp *comp,
+ void (*gamma_set)(struct device *dev,
struct drm_crtc_state *state);
- void (*bgclr_in_on)(struct mtk_ddp_comp *comp);
- void (*bgclr_in_off)(struct mtk_ddp_comp *comp);
- void (*ctm_set)(struct mtk_ddp_comp *comp,
+ void (*bgclr_in_on)(struct device *dev);
+ void (*bgclr_in_off)(struct device *dev);
+ void (*ctm_set)(struct device *dev,
struct drm_crtc_state *state);
};
struct mtk_ddp_comp {
- struct clk *clk;
- void __iomem *regs;
+ struct device *dev;
int irq;
struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
- resource_size_t regs_pa;
- u8 subsys;
};
+static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->clk_enable)
+ return comp->funcs->clk_enable(comp->dev);
+
+ return 0;
+}
+
+static inline void mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->clk_disable)
+ comp->funcs->clk_disable(comp->dev);
+}
+
static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
unsigned int w, unsigned int h,
unsigned int vrefresh, unsigned int bpc,
struct cmdq_pkt *cmdq_pkt)
{
if (comp->funcs && comp->funcs->config)
- comp->funcs->config(comp, w, h, vrefresh, bpc, cmdq_pkt);
+ comp->funcs->config(comp->dev, w, h, vrefresh, bpc, cmdq_pkt);
}
static inline void mtk_ddp_comp_start(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->start)
- comp->funcs->start(comp);
+ comp->funcs->start(comp->dev);
}
static inline void mtk_ddp_comp_stop(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->stop)
- comp->funcs->stop(comp);
+ comp->funcs->stop(comp->dev);
}
static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp,
- struct drm_crtc *crtc)
+ void (*vblank_cb)(void *),
+ void *vblank_cb_data)
{
if (comp->funcs && comp->funcs->enable_vblank)
- comp->funcs->enable_vblank(comp, crtc);
+ comp->funcs->enable_vblank(comp->dev, vblank_cb, vblank_cb_data);
}
static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->disable_vblank)
- comp->funcs->disable_vblank(comp);
+ comp->funcs->disable_vblank(comp->dev);
}
static inline
unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->supported_rotations)
- return comp->funcs->supported_rotations(comp);
+ return comp->funcs->supported_rotations(comp->dev);
return 0;
}
@@ -119,7 +136,7 @@ unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->layer_nr)
- return comp->funcs->layer_nr(comp);
+ return comp->funcs->layer_nr(comp->dev);
return 0;
}
@@ -129,7 +146,7 @@ static inline int mtk_ddp_comp_layer_check(struct mtk_ddp_comp *comp,
struct mtk_plane_state *state)
{
if (comp->funcs && comp->funcs->layer_check)
- return comp->funcs->layer_check(comp, idx, state);
+ return comp->funcs->layer_check(comp->dev, idx, state);
return 0;
}
@@ -139,52 +156,49 @@ static inline void mtk_ddp_comp_layer_config(struct mtk_ddp_comp *comp,
struct cmdq_pkt *cmdq_pkt)
{
if (comp->funcs && comp->funcs->layer_config)
- comp->funcs->layer_config(comp, idx, state, cmdq_pkt);
+ comp->funcs->layer_config(comp->dev, idx, state, cmdq_pkt);
}
static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp,
struct drm_crtc_state *state)
{
if (comp->funcs && comp->funcs->gamma_set)
- comp->funcs->gamma_set(comp, state);
+ comp->funcs->gamma_set(comp->dev, state);
}
static inline void mtk_ddp_comp_bgclr_in_on(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->bgclr_in_on)
- comp->funcs->bgclr_in_on(comp);
+ comp->funcs->bgclr_in_on(comp->dev);
}
static inline void mtk_ddp_comp_bgclr_in_off(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->bgclr_in_off)
- comp->funcs->bgclr_in_off(comp);
+ comp->funcs->bgclr_in_off(comp->dev);
}
static inline void mtk_ddp_ctm_set(struct mtk_ddp_comp *comp,
struct drm_crtc_state *state)
{
if (comp->funcs && comp->funcs->ctm_set)
- comp->funcs->ctm_set(comp, state);
+ comp->funcs->ctm_set(comp->dev, state);
}
int mtk_ddp_comp_get_id(struct device_node *node,
enum mtk_ddp_comp_type comp_type);
unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
- struct mtk_ddp_comp ddp_comp);
-int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node,
- struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
- const struct mtk_ddp_comp_funcs *funcs);
-int mtk_ddp_comp_register(struct drm_device *drm, struct mtk_ddp_comp *comp);
-void mtk_ddp_comp_unregister(struct drm_device *drm, struct mtk_ddp_comp *comp);
-void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
- unsigned int CFG, struct cmdq_pkt *cmdq_pkt);
+ struct device *dev);
+int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
+ enum mtk_ddp_comp_id comp_id);
enum mtk_ddp_comp_type mtk_ddp_comp_get_type(enum mtk_ddp_comp_id comp_id);
void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
- struct mtk_ddp_comp *comp, unsigned int offset);
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
+ unsigned int offset);
void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
- struct mtk_ddp_comp *comp, unsigned int offset);
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
+ unsigned int offset);
void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
- struct mtk_ddp_comp *comp, unsigned int offset,
- unsigned int mask);
+ struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
+ unsigned int offset, unsigned int mask);
#endif /* MTK_DRM_DDP_COMP_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 2f717df28a77..b013d56d2777 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -10,7 +10,6 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
-#include <linux/soc/mediatek/mtk-mmsys.h>
#include <linux/dma-mapping.h>
#include <drm/drm_atomic.h>
@@ -26,7 +25,6 @@
#include <drm/drm_vblank.h>
#include "mtk_drm_crtc.h"
-#include "mtk_drm_ddp.h"
#include "mtk_drm_ddp_comp.h"
#include "mtk_drm_drv.h"
#include "mtk_drm_gem.h"
@@ -131,6 +129,24 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
DDP_COMPONENT_DPI0,
};
+static const enum mtk_ddp_comp_id mt8183_mtk_ddp_main[] = {
+ DDP_COMPONENT_OVL0,
+ DDP_COMPONENT_OVL_2L0,
+ DDP_COMPONENT_RDMA0,
+ DDP_COMPONENT_COLOR0,
+ DDP_COMPONENT_CCORR,
+ DDP_COMPONENT_AAL0,
+ DDP_COMPONENT_GAMMA,
+ DDP_COMPONENT_DITHER,
+ DDP_COMPONENT_DSI0,
+};
+
+static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
+ DDP_COMPONENT_OVL_2L1,
+ DDP_COMPONENT_RDMA1,
+ DDP_COMPONENT_DPI0,
+};
+
static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.main_path = mt2701_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -163,6 +179,13 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
};
+static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
+ .main_path = mt8183_mtk_ddp_main,
+ .main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
+ .ext_path = mt8183_mtk_ddp_ext,
+ .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
+};
+
static int mtk_drm_kms_init(struct drm_device *drm)
{
struct mtk_drm_private *private = drm->dev_private;
@@ -377,12 +400,20 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
.data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8173-disp-ovl",
.data = (void *)MTK_DISP_OVL },
+ { .compatible = "mediatek,mt8183-disp-ovl",
+ .data = (void *)MTK_DISP_OVL },
+ { .compatible = "mediatek,mt8183-disp-ovl-2l",
+ .data = (void *)MTK_DISP_OVL_2L },
{ .compatible = "mediatek,mt2701-disp-rdma",
.data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-rdma",
.data = (void *)MTK_DISP_RDMA },
+ { .compatible = "mediatek,mt8183-disp-rdma",
+ .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-wdma",
.data = (void *)MTK_DISP_WDMA },
+ { .compatible = "mediatek,mt8183-disp-ccorr",
+ .data = (void *)MTK_DISP_CCORR },
{ .compatible = "mediatek,mt2701-disp-color",
.data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-color",
@@ -391,22 +422,32 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
.data = (void *)MTK_DISP_AAL},
{ .compatible = "mediatek,mt8173-disp-gamma",
.data = (void *)MTK_DISP_GAMMA, },
+ { .compatible = "mediatek,mt8183-disp-gamma",
+ .data = (void *)MTK_DISP_GAMMA, },
+ { .compatible = "mediatek,mt8183-disp-dither",
+ .data = (void *)MTK_DISP_DITHER },
{ .compatible = "mediatek,mt8173-disp-ufoe",
.data = (void *)MTK_DISP_UFOE },
{ .compatible = "mediatek,mt2701-dsi",
.data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dsi",
.data = (void *)MTK_DSI },
+ { .compatible = "mediatek,mt8183-dsi",
+ .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt2701-dpi",
.data = (void *)MTK_DPI },
{ .compatible = "mediatek,mt8173-dpi",
.data = (void *)MTK_DPI },
+ { .compatible = "mediatek,mt8183-dpi",
+ .data = (void *)MTK_DPI },
{ .compatible = "mediatek,mt2701-disp-mutex",
.data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2712-disp-mutex",
.data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8173-disp-mutex",
.data = (void *)MTK_DISP_MUTEX },
+ { .compatible = "mediatek,mt8183-disp-mutex",
+ .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2701-disp-pwm",
.data = (void *)MTK_DISP_BLS },
{ .compatible = "mediatek,mt8173-disp-pwm",
@@ -425,6 +466,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
.data = &mt2712_mmsys_driver_data},
{ .compatible = "mediatek,mt8173-mmsys",
.data = &mt8173_mmsys_driver_data},
+ { .compatible = "mediatek,mt8183-mmsys",
+ .data = &mt8183_mmsys_driver_data},
{ }
};
@@ -488,11 +531,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
private->comp_node[comp_id] = of_node_get(node);
/*
- * Currently only the COLOR, OVL, RDMA, DSI, and DPI blocks have
- * separate component platform drivers and initialize their own
+ * Currently only the CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+ * blocks have separate component platform drivers and initialize their own
* DDP component structure. The others are initialized here.
*/
- if (comp_type == MTK_DISP_COLOR ||
+ if (comp_type == MTK_DISP_CCORR ||
+ comp_type == MTK_DISP_COLOR ||
+ comp_type == MTK_DISP_GAMMA ||
comp_type == MTK_DISP_OVL ||
comp_type == MTK_DISP_OVL_2L ||
comp_type == MTK_DISP_RDMA ||
@@ -502,24 +547,12 @@ static int mtk_drm_probe(struct platform_device *pdev)
node);
drm_of_component_match_add(dev, &match, compare_of,
node);
- } else {
- struct mtk_ddp_comp *comp;
-
- comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
- if (!comp) {
- ret = -ENOMEM;
- of_node_put(node);
- goto err_node;
- }
-
- ret = mtk_ddp_comp_init(dev->parent, node, comp,
- comp_id, NULL);
- if (ret) {
- of_node_put(node);
- goto err_node;
- }
-
- private->ddp_comp[comp_id] = comp;
+ }
+
+ ret = mtk_ddp_comp_init(node, &private->ddp_comp[comp_id], comp_id);
+ if (ret) {
+ of_node_put(node);
+ goto err_node;
}
}
@@ -545,10 +578,8 @@ err_node:
of_node_put(private->mutex_node);
for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) {
of_node_put(private->comp_node[i]);
- if (private->ddp_comp[i]) {
- put_device(private->ddp_comp[i]->larb_dev);
- private->ddp_comp[i] = NULL;
- }
+ if (private->ddp_comp[i].larb_dev)
+ put_device(private->ddp_comp[i].larb_dev);
}
return ret;
}
@@ -604,8 +635,9 @@ static struct platform_driver mtk_drm_platform_driver = {
};
static struct platform_driver * const mtk_drm_drivers[] = {
- &mtk_ddp_driver,
+ &mtk_disp_ccorr_driver,
&mtk_disp_color_driver,
+ &mtk_disp_gamma_driver,
&mtk_disp_ovl_driver,
&mtk_disp_rdma_driver,
&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 5d771cf0bf25..637f5669e895 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -41,13 +41,14 @@ struct mtk_drm_private {
struct device *mutex_dev;
struct device *mmsys_dev;
struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
- struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
+ struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
const struct mtk_mmsys_driver_data *data;
struct drm_atomic_state *suspend_state;
};
-extern struct platform_driver mtk_ddp_driver;
+extern struct platform_driver mtk_disp_ccorr_driver;
extern struct platform_driver mtk_disp_color_driver;
+extern struct platform_driver mtk_disp_gamma_driver;
extern struct platform_driver mtk_disp_ovl_driver;
extern struct platform_driver mtk_disp_rdma_driver;
extern struct platform_driver mtk_dpi_driver;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 65fd99c528af..a1ff152ef468 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -25,6 +25,7 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
+#include "mtk_disp_drv.h"
#include "mtk_drm_ddp_comp.h"
#define DSI_START 0x00
@@ -178,7 +179,6 @@ struct mtk_dsi_driver_data {
};
struct mtk_dsi {
- struct mtk_ddp_comp ddp_comp;
struct device *dev;
struct mipi_dsi_host host;
struct drm_encoder encoder;
@@ -767,25 +767,20 @@ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
.mode_set = mtk_dsi_bridge_mode_set,
};
-static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
+void mtk_dsi_ddp_start(struct device *dev)
{
- struct mtk_dsi *dsi = container_of(comp, struct mtk_dsi, ddp_comp);
+ struct mtk_dsi *dsi = dev_get_drvdata(dev);
mtk_dsi_poweron(dsi);
}
-static void mtk_dsi_ddp_stop(struct mtk_ddp_comp *comp)
+void mtk_dsi_ddp_stop(struct device *dev)
{
- struct mtk_dsi *dsi = container_of(comp, struct mtk_dsi, ddp_comp);
+ struct mtk_dsi *dsi = dev_get_drvdata(dev);
mtk_dsi_poweroff(dsi);
}
-static const struct mtk_ddp_comp_funcs mtk_dsi_funcs = {
- .start = mtk_dsi_ddp_start,
- .stop = mtk_dsi_ddp_stop,
-};
-
static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device)
{
@@ -952,7 +947,7 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
return ret;
}
- dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->ddp_comp);
+ dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
@@ -980,32 +975,17 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
struct drm_device *drm = data;
struct mtk_dsi *dsi = dev_get_drvdata(dev);
- ret = mtk_ddp_comp_register(drm, &dsi->ddp_comp);
- if (ret < 0) {
- dev_err(dev, "Failed to register component %pOF: %d\n",
- dev->of_node, ret);
- return ret;
- }
-
ret = mtk_dsi_encoder_init(drm, dsi);
- if (ret)
- goto err_unregister;
- return 0;
-
-err_unregister:
- mtk_ddp_comp_unregister(drm, &dsi->ddp_comp);
return ret;
}
static void mtk_dsi_unbind(struct device *dev, struct device *master,
void *data)
{
- struct drm_device *drm = data;
struct mtk_dsi *dsi = dev_get_drvdata(dev);
drm_encoder_cleanup(&dsi->encoder);
- mtk_ddp_comp_unregister(drm, &dsi->ddp_comp);
}
static const struct component_ops mtk_dsi_component_ops = {
@@ -1020,7 +1000,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
struct drm_panel *panel;
struct resource *regs;
int irq_num;
- int comp_id;
int ret;
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -1090,20 +1069,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
goto err_unregister_host;
}
- comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DSI);
- if (comp_id < 0) {
- dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
- ret = comp_id;
- goto err_unregister_host;
- }
-
- ret = mtk_ddp_comp_init(dev, dev->of_node, &dsi->ddp_comp, comp_id,
- &mtk_dsi_funcs);
- if (ret) {
- dev_err(dev, "Failed to initialize component: %d\n", ret);
- goto err_unregister_host;
- }
-
irq_num = platform_get_irq(pdev, 0);
if (irq_num < 0) {
dev_err(&pdev->dev, "failed to get dsi irq_num: %d\n", irq_num);
@@ -1111,9 +1076,8 @@ static int mtk_dsi_probe(struct platform_device *pdev)
goto err_unregister_host;
}
- irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
- IRQF_TRIGGER_LOW, dev_name(&pdev->dev), dsi);
+ IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi);
if (ret) {
dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
goto err_unregister_host;
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index b6908db534c2..90270f8114ed 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
+obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/soc/mediatek/mtk-mutex.c
index 1f99db6b1a42..f531b119da7a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -9,12 +9,11 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-mutex.h>
-#include "mtk_drm_ddp.h"
-#include "mtk_drm_ddp_comp.h"
-
-#define MT2701_DISP_MUTEX0_MOD0 0x2c
-#define MT2701_DISP_MUTEX0_SOF0 0x30
+#define MT2701_MUTEX0_MOD0 0x2c
+#define MT2701_MUTEX0_SOF0 0x30
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
@@ -79,33 +78,32 @@
#define MT2701_MUTEX_MOD_DISP_RDMA0 10
#define MT2701_MUTEX_MOD_DISP_RDMA1 12
-#define MUTEX_SOF_SINGLE_MODE 0
-#define MUTEX_SOF_DSI0 1
-#define MUTEX_SOF_DSI1 2
-#define MUTEX_SOF_DPI0 3
-#define MUTEX_SOF_DPI1 4
-#define MUTEX_SOF_DSI2 5
-#define MUTEX_SOF_DSI3 6
-#define MT8167_MUTEX_SOF_DPI0 2
-#define MT8167_MUTEX_SOF_DPI1 3
-
-
-struct mtk_disp_mutex {
+#define MT2712_MUTEX_SOF_SINGLE_MODE 0
+#define MT2712_MUTEX_SOF_DSI0 1
+#define MT2712_MUTEX_SOF_DSI1 2
+#define MT2712_MUTEX_SOF_DPI0 3
+#define MT2712_MUTEX_SOF_DPI1 4
+#define MT2712_MUTEX_SOF_DSI2 5
+#define MT2712_MUTEX_SOF_DSI3 6
+#define MT8167_MUTEX_SOF_DPI0 2
+#define MT8167_MUTEX_SOF_DPI1 3
+
+struct mtk_mutex {
int id;
bool claimed;
};
-enum mtk_ddp_mutex_sof_id {
- DDP_MUTEX_SOF_SINGLE_MODE,
- DDP_MUTEX_SOF_DSI0,
- DDP_MUTEX_SOF_DSI1,
- DDP_MUTEX_SOF_DPI0,
- DDP_MUTEX_SOF_DPI1,
- DDP_MUTEX_SOF_DSI2,
- DDP_MUTEX_SOF_DSI3,
+enum mtk_mutex_sof_id {
+ MUTEX_SOF_SINGLE_MODE,
+ MUTEX_SOF_DSI0,
+ MUTEX_SOF_DSI1,
+ MUTEX_SOF_DPI0,
+ MUTEX_SOF_DPI1,
+ MUTEX_SOF_DSI2,
+ MUTEX_SOF_DSI3,
};
-struct mtk_ddp_data {
+struct mtk_mutex_data {
const unsigned int *mutex_mod;
const unsigned int *mutex_sof;
const unsigned int mutex_mod_reg;
@@ -113,12 +111,12 @@ struct mtk_ddp_data {
const bool no_clk;
};
-struct mtk_ddp {
+struct mtk_mutex_ctx {
struct device *dev;
struct clk *clk;
void __iomem *regs;
- struct mtk_disp_mutex mutex[10];
- const struct mtk_ddp_data *data;
+ struct mtk_mutex mutex[10];
+ const struct mtk_mutex_data *data;
};
static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
@@ -183,150 +181,155 @@ static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
};
-static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = {
- [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
- [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
- [DDP_MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
- [DDP_MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
- [DDP_MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
- [DDP_MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
- [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
+static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+ [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+ [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
+ [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
+ [MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
+ [MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
+ [MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
+ [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
};
-static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = {
- [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
- [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
- [DDP_MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
- [DDP_MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1,
+static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+ [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+ [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
+ [MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
+ [MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1,
};
-static const struct mtk_ddp_data mt2701_ddp_driver_data = {
+static const struct mtk_mutex_data mt2701_mutex_driver_data = {
.mutex_mod = mt2701_mutex_mod,
.mutex_sof = mt2712_mutex_sof,
- .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
- .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
+ .mutex_mod_reg = MT2701_MUTEX0_MOD0,
+ .mutex_sof_reg = MT2701_MUTEX0_SOF0,
};
-static const struct mtk_ddp_data mt2712_ddp_driver_data = {
+static const struct mtk_mutex_data mt2712_mutex_driver_data = {
.mutex_mod = mt2712_mutex_mod,
.mutex_sof = mt2712_mutex_sof,
- .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
- .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
+ .mutex_mod_reg = MT2701_MUTEX0_MOD0,
+ .mutex_sof_reg = MT2701_MUTEX0_SOF0,
};
-static const struct mtk_ddp_data mt8167_ddp_driver_data = {
+static const struct mtk_mutex_data mt8167_mutex_driver_data = {
.mutex_mod = mt8167_mutex_mod,
.mutex_sof = mt8167_mutex_sof,
- .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
- .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
+ .mutex_mod_reg = MT2701_MUTEX0_MOD0,
+ .mutex_sof_reg = MT2701_MUTEX0_SOF0,
.no_clk = true,
};
-static const struct mtk_ddp_data mt8173_ddp_driver_data = {
+static const struct mtk_mutex_data mt8173_mutex_driver_data = {
.mutex_mod = mt8173_mutex_mod,
.mutex_sof = mt2712_mutex_sof,
- .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
- .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
+ .mutex_mod_reg = MT2701_MUTEX0_MOD0,
+ .mutex_sof_reg = MT2701_MUTEX0_SOF0,
};
-struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id)
+struct mtk_mutex *mtk_mutex_get(struct device *dev)
{
- struct mtk_ddp *ddp = dev_get_drvdata(dev);
-
- if (id >= 10)
- return ERR_PTR(-EINVAL);
- if (ddp->mutex[id].claimed)
- return ERR_PTR(-EBUSY);
+ struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
+ int i;
- ddp->mutex[id].claimed = true;
+ for (i = 0; i < 10; i++)
+ if (!mtx->mutex[i].claimed) {
+ mtx->mutex[i].claimed = true;
+ return &mtx->mutex[i];
+ }
- return &ddp->mutex[id];
+ return ERR_PTR(-EBUSY);
}
+EXPORT_SYMBOL_GPL(mtk_mutex_get);
-void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex)
+void mtk_mutex_put(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
- WARN_ON(&ddp->mutex[mutex->id] != mutex);
+ WARN_ON(&mtx->mutex[mutex->id] != mutex);
mutex->claimed = false;
}
+EXPORT_SYMBOL_GPL(mtk_mutex_put);
-int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex)
+int mtk_mutex_prepare(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
- return clk_prepare_enable(ddp->clk);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
+ return clk_prepare_enable(mtx->clk);
}
+EXPORT_SYMBOL_GPL(mtk_mutex_prepare);
-void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex)
+void mtk_mutex_unprepare(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
- clk_disable_unprepare(ddp->clk);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
+ clk_disable_unprepare(mtx->clk);
}
+EXPORT_SYMBOL_GPL(mtk_mutex_unprepare);
-void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
- enum mtk_ddp_comp_id id)
+void mtk_mutex_add_comp(struct mtk_mutex *mutex,
+ enum mtk_ddp_comp_id id)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
unsigned int reg;
unsigned int sof_id;
unsigned int offset;
- WARN_ON(&ddp->mutex[mutex->id] != mutex);
+ WARN_ON(&mtx->mutex[mutex->id] != mutex);
switch (id) {
case DDP_COMPONENT_DSI0:
- sof_id = DDP_MUTEX_SOF_DSI0;
+ sof_id = MUTEX_SOF_DSI0;
break;
case DDP_COMPONENT_DSI1:
- sof_id = DDP_MUTEX_SOF_DSI0;
+ sof_id = MUTEX_SOF_DSI0;
break;
case DDP_COMPONENT_DSI2:
- sof_id = DDP_MUTEX_SOF_DSI2;
+ sof_id = MUTEX_SOF_DSI2;
break;
case DDP_COMPONENT_DSI3:
- sof_id = DDP_MUTEX_SOF_DSI3;
+ sof_id = MUTEX_SOF_DSI3;
break;
case DDP_COMPONENT_DPI0:
- sof_id = DDP_MUTEX_SOF_DPI0;
+ sof_id = MUTEX_SOF_DPI0;
break;
case DDP_COMPONENT_DPI1:
- sof_id = DDP_MUTEX_SOF_DPI1;
+ sof_id = MUTEX_SOF_DPI1;
break;
default:
- if (ddp->data->mutex_mod[id] < 32) {
- offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg,
+ if (mtx->data->mutex_mod[id] < 32) {
+ offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
mutex->id);
- reg = readl_relaxed(ddp->regs + offset);
- reg |= 1 << ddp->data->mutex_mod[id];
- writel_relaxed(reg, ddp->regs + offset);
+ reg = readl_relaxed(mtx->regs + offset);
+ reg |= 1 << mtx->data->mutex_mod[id];
+ writel_relaxed(reg, mtx->regs + offset);
} else {
offset = DISP_REG_MUTEX_MOD2(mutex->id);
- reg = readl_relaxed(ddp->regs + offset);
- reg |= 1 << (ddp->data->mutex_mod[id] - 32);
- writel_relaxed(reg, ddp->regs + offset);
+ reg = readl_relaxed(mtx->regs + offset);
+ reg |= 1 << (mtx->data->mutex_mod[id] - 32);
+ writel_relaxed(reg, mtx->regs + offset);
}
return;
}
- writel_relaxed(ddp->data->mutex_sof[sof_id],
- ddp->regs +
- DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, mutex->id));
+ writel_relaxed(mtx->data->mutex_sof[sof_id],
+ mtx->regs +
+ DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id));
}
+EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
-void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
- enum mtk_ddp_comp_id id)
+void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
+ enum mtk_ddp_comp_id id)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
unsigned int reg;
unsigned int offset;
- WARN_ON(&ddp->mutex[mutex->id] != mutex);
+ WARN_ON(&mtx->mutex[mutex->id] != mutex);
switch (id) {
case DDP_COMPONENT_DSI0:
@@ -336,129 +339,136 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
case DDP_COMPONENT_DPI0:
case DDP_COMPONENT_DPI1:
writel_relaxed(MUTEX_SOF_SINGLE_MODE,
- ddp->regs +
- DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg,
+ mtx->regs +
+ DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
mutex->id));
break;
default:
- if (ddp->data->mutex_mod[id] < 32) {
- offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg,
+ if (mtx->data->mutex_mod[id] < 32) {
+ offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
mutex->id);
- reg = readl_relaxed(ddp->regs + offset);
- reg &= ~(1 << ddp->data->mutex_mod[id]);
- writel_relaxed(reg, ddp->regs + offset);
+ reg = readl_relaxed(mtx->regs + offset);
+ reg &= ~(1 << mtx->data->mutex_mod[id]);
+ writel_relaxed(reg, mtx->regs + offset);
} else {
offset = DISP_REG_MUTEX_MOD2(mutex->id);
- reg = readl_relaxed(ddp->regs + offset);
- reg &= ~(1 << (ddp->data->mutex_mod[id] - 32));
- writel_relaxed(reg, ddp->regs + offset);
+ reg = readl_relaxed(mtx->regs + offset);
+ reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
+ writel_relaxed(reg, mtx->regs + offset);
}
break;
}
}
+EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp);
-void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex)
+void mtk_mutex_enable(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
- WARN_ON(&ddp->mutex[mutex->id] != mutex);
+ WARN_ON(&mtx->mutex[mutex->id] != mutex);
- writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
+ writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
}
+EXPORT_SYMBOL_GPL(mtk_mutex_enable);
-void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex)
+void mtk_mutex_disable(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
- WARN_ON(&ddp->mutex[mutex->id] != mutex);
+ WARN_ON(&mtx->mutex[mutex->id] != mutex);
- writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
+ writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
}
+EXPORT_SYMBOL_GPL(mtk_mutex_disable);
-void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex)
+void mtk_mutex_acquire(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
u32 tmp;
- writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
- writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id));
- if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id),
+ writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
+ writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id));
+ if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id),
tmp, tmp & INT_MUTEX, 1, 10000))
pr_err("could not acquire mutex %d\n", mutex->id);
}
+EXPORT_SYMBOL_GPL(mtk_mutex_acquire);
-void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex)
+void mtk_mutex_release(struct mtk_mutex *mutex)
{
- struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
- mutex[mutex->id]);
+ struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+ mutex[mutex->id]);
- writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id));
+ writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id));
}
+EXPORT_SYMBOL_GPL(mtk_mutex_release);
-static int mtk_ddp_probe(struct platform_device *pdev)
+static int mtk_mutex_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct mtk_ddp *ddp;
+ struct mtk_mutex_ctx *mtx;
struct resource *regs;
int i;
- ddp = devm_kzalloc(dev, sizeof(*ddp), GFP_KERNEL);
- if (!ddp)
+ mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
+ if (!mtx)
return -ENOMEM;
for (i = 0; i < 10; i++)
- ddp->mutex[i].id = i;
+ mtx->mutex[i].id = i;
- ddp->data = of_device_get_match_data(dev);
+ mtx->data = of_device_get_match_data(dev);
- if (!ddp->data->no_clk) {
- ddp->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(ddp->clk)) {
- if (PTR_ERR(ddp->clk) != -EPROBE_DEFER)
+ if (!mtx->data->no_clk) {
+ mtx->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(mtx->clk)) {
+ if (PTR_ERR(mtx->clk) != -EPROBE_DEFER)
dev_err(dev, "Failed to get clock\n");
- return PTR_ERR(ddp->clk);
+ return PTR_ERR(mtx->clk);
}
}
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ddp->regs = devm_ioremap_resource(dev, regs);
- if (IS_ERR(ddp->regs)) {
+ mtx->regs = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(mtx->regs)) {
dev_err(dev, "Failed to map mutex registers\n");
- return PTR_ERR(ddp->regs);
+ return PTR_ERR(mtx->regs);
}
- platform_set_drvdata(pdev, ddp);
+ platform_set_drvdata(pdev, mtx);
return 0;
}
-static int mtk_ddp_remove(struct platform_device *pdev)
+static int mtk_mutex_remove(struct platform_device *pdev)
{
return 0;
}
-static const struct of_device_id ddp_driver_dt_match[] = {
+static const struct of_device_id mutex_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-mutex",
- .data = &mt2701_ddp_driver_data},
+ .data = &mt2701_mutex_driver_data},
{ .compatible = "mediatek,mt2712-disp-mutex",
- .data = &mt2712_ddp_driver_data},
+ .data = &mt2712_mutex_driver_data},
{ .compatible = "mediatek,mt8167-disp-mutex",
- .data = &mt8167_ddp_driver_data},
+ .data = &mt8167_mutex_driver_data},
{ .compatible = "mediatek,mt8173-disp-mutex",
- .data = &mt8173_ddp_driver_data},
+ .data = &mt8173_mutex_driver_data},
{},
};
-MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
+MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-struct platform_driver mtk_ddp_driver = {
- .probe = mtk_ddp_probe,
- .remove = mtk_ddp_remove,
+struct platform_driver mtk_mutex_driver = {
+ .probe = mtk_mutex_probe,
+ .remove = mtk_mutex_remove,
.driver = {
- .name = "mediatek-ddp",
+ .name = "mediatek-mutex",
.owner = THIS_MODULE,
- .of_match_table = ddp_driver_dt_match,
+ .of_match_table = mutex_driver_dt_match,
},
};
+
+builtin_platform_driver(mtk_mutex_driver);
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
new file mode 100644
index 000000000000..6fe4ffbde290
--- /dev/null
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ */
+
+#ifndef MTK_MUTEX_H
+#define MTK_MUTEX_H
+
+struct regmap;
+struct device;
+struct mtk_mutex;
+
+struct mtk_mutex *mtk_mutex_get(struct device *dev);
+int mtk_mutex_prepare(struct mtk_mutex *mutex);
+void mtk_mutex_add_comp(struct mtk_mutex *mutex,
+ enum mtk_ddp_comp_id id);
+void mtk_mutex_enable(struct mtk_mutex *mutex);
+void mtk_mutex_disable(struct mtk_mutex *mutex);
+void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
+ enum mtk_ddp_comp_id id);
+void mtk_mutex_unprepare(struct mtk_mutex *mutex);
+void mtk_mutex_put(struct mtk_mutex *mutex);
+void mtk_mutex_acquire(struct mtk_mutex *mutex);
+void mtk_mutex_release(struct mtk_mutex *mutex);
+
+#endif /* MTK_MUTEX_H */