The mutex serialises the components of a pipeline on the same frame: it
holds the list of the modules started together and the source of the
start and end of frame signals driving them.

Extend the driver, so far only used by the MT8188 HDMI pipeline, with the
DSI pipeline of the MT8365 and the MT8366: the overlay to the DSI,
through the colour pipeline on the MT8365 and straight out of the rdma on
the MT8366, which the per-compatible data selects.

Two compatibles are added, "mediatek,mt8365-disp-mutex" and
"mediatek,mt8366-disp-mutex". Neither node declares a generic fallback,
so both SoC specific strings have to be listed; they also differ in
the module indices, in the DSI0 module bit the MT8366 needs, and in the
shift of the end-of-frame selector (6 on the MT8365, 7 on the MT8366).

The MT8365 mutex has no clock of its own, as "no_clk" in the Linux
driver says, so the shared component probe now tolerates a node without
a "clocks" property instead of failing on it.

The driver includes <dm/device.h> and <dm/device_compat.h>, for the
dev_err() it now uses, instead of <dm.h>.

Signed-off-by: Julien Stephan <[email protected]>
---
 drivers/video/mediatek/mtk_disp_comp.c  |   3 +-
 drivers/video/mediatek/mtk_disp_mutex.c | 120 ++++++++++++++++++++++++++++++--
 drivers/video/mediatek/mtk_disp_mutex.h |   9 +++
 3 files changed, 125 insertions(+), 7 deletions(-)

diff --git a/drivers/video/mediatek/mtk_disp_comp.c 
b/drivers/video/mediatek/mtk_disp_comp.c
index 3846a46f698..5d0e69a75b3 100644
--- a/drivers/video/mediatek/mtk_disp_comp.c
+++ b/drivers/video/mediatek/mtk_disp_comp.c
@@ -114,8 +114,9 @@ int mtk_disp_comp_probe(struct udevice *dev)
        if (!priv->base)
                return -EINVAL;
 
+       /* some components, such as the MT8365 mutex, have no clock of their 
own */
        ret = clk_get_bulk(dev, &priv->clk_bulk);
-       if (ret) {
+       if (ret && ret != -ENOENT) {
                dev_err(dev, "failed to get clocks: %d\n", ret);
                return ret;
        }
diff --git a/drivers/video/mediatek/mtk_disp_mutex.c 
b/drivers/video/mediatek/mtk_disp_mutex.c
index 0e1d2e3ead2..36a1fca26b1 100644
--- a/drivers/video/mediatek/mtk_disp_mutex.c
+++ b/drivers/video/mediatek/mtk_disp_mutex.c
@@ -6,7 +6,8 @@
  * Author: Julien Stephan <[email protected]>
  */
 
-#include <dm.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
 #include <linux/bitops.h>
 
 #include "mtk_disp_comp.h"
@@ -16,8 +17,8 @@
  * Register layout of one mutex instance @id (as in the Linux mtk-mutex
  * driver): the block packs the per-mutex registers 0x20 apart. SOF holds
  * the start/end-of-frame source, MOD0/MOD1 the attached modules 0-31 and
- * 32-63. The offsets are index-based so a future DSI helper can drive a
- * different instance/controller.
+ * 32-63. The offsets are index-based so the HDMI and DSI helpers below can
+ * drive a different instance/controller each.
  */
 #define DISP_MUTEX_EN(id)      (0x20 + 0x20 * (id))
 #define MUTEX_EN                       BIT(0)
@@ -48,6 +49,47 @@
 #define MT8188_MUTEX_MOD_DISP1_DISP_MIXER      30
 #define MT8188_MUTEX_MOD_DISP1_DPI1            38
 
+/* The MT8365 and MT8366 DSI pipelines use instance 0 of the mmsys mutex */
+#define MUTEX_DSI_ID           0
+
+/* the MT8365 shifts the end-of-frame selector by 6 instead of 7 */
+#define MT8365_MUTEX_SOF_DSI0          1
+#define MT8365_MUTEX_EOF_DSI0          (MT8365_MUTEX_SOF_DSI0 << 6)
+
+#define MT8365_MUTEX_MOD_DISP_OVL0     7
+#define MT8365_MUTEX_MOD_DISP_RDMA0    9
+#define MT8365_MUTEX_MOD_DISP_COLOR0   12
+#define MT8365_MUTEX_MOD_DISP_CCORR    13
+#define MT8365_MUTEX_MOD_DISP_AAL      14
+#define MT8365_MUTEX_MOD_DISP_GAMMA    15
+#define MT8365_MUTEX_MOD_DISP_DITHER   16
+
+/* the MT8366 drives the DSI straight out of the rdma, without the PQ blocks */
+#define MT8366_MUTEX_SOF_DSI0          1
+#define MT8366_MUTEX_EOF_DSI0          (MT8366_MUTEX_SOF_DSI0 << 7)
+
+#define MT8366_MUTEX_MOD_DISP_OVL0     0
+#define MT8366_MUTEX_MOD_DISP_RDMA0    4
+#define MT8366_MUTEX_MOD_DISP_DSI0     13
+
+/**
+ * struct mtk_disp_mutex_data - per-SoC mutex data
+ * @ovl_dsi_enable: set up the mutex of the OVL -> DSI pipeline
+ */
+struct mtk_disp_mutex_data {
+       void (*ovl_dsi_enable)(struct udevice *dev);
+};
+
+/**
+ * struct mtk_disp_mutex_priv - private data of a mutex
+ * @comp: common component state, must be the first member
+ * @data: per-SoC data, NULL on the SoCs without a DSI pipeline
+ */
+struct mtk_disp_mutex_priv {
+       struct mtk_disp_comp_priv comp;
+       const struct mtk_disp_mutex_data *data;
+};
+
 void mtk_disp_mutex_config_hdmi(struct udevice *dev)
 {
        mtk_disp_comp_write(dev, DISP_MUTEX_SOF(MUTEX_HDMI_ID),
@@ -65,8 +107,74 @@ void mtk_disp_mutex_config_hdmi(struct udevice *dev)
        mtk_disp_comp_write(dev, DISP_MUTEX_EN(MUTEX_HDMI_ID), MUTEX_EN);
 }
 
+static void mtk_disp_mutex_ovl_dsi_enable_color_pipeline(struct udevice *dev)
+{
+       mtk_disp_comp_write(dev, DISP_MUTEX_MOD0(MUTEX_DSI_ID),
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_OVL0) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_RDMA0) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_COLOR0) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_CCORR) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_AAL) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_GAMMA) |
+                           MUTEX_MOD_BIT(MT8365_MUTEX_MOD_DISP_DITHER));
+       mtk_disp_comp_write(dev, DISP_MUTEX_SOF(MUTEX_DSI_ID),
+                           MT8365_MUTEX_EOF_DSI0 | MT8365_MUTEX_SOF_DSI0);
+       mtk_disp_comp_write(dev, DISP_MUTEX_EN(MUTEX_DSI_ID), MUTEX_EN);
+}
+
+static void mtk_disp_mutex_ovl_dsi_enable_no_color_pipeline(struct udevice 
*dev)
+{
+       mtk_disp_comp_write(dev, DISP_MUTEX_MOD0(MUTEX_DSI_ID),
+                           MUTEX_MOD_BIT(MT8366_MUTEX_MOD_DISP_OVL0) |
+                           MUTEX_MOD_BIT(MT8366_MUTEX_MOD_DISP_RDMA0) |
+                           MUTEX_MOD_BIT(MT8366_MUTEX_MOD_DISP_DSI0));
+       mtk_disp_comp_write(dev, DISP_MUTEX_SOF(MUTEX_DSI_ID),
+                           MT8366_MUTEX_EOF_DSI0 | MT8366_MUTEX_SOF_DSI0);
+       mtk_disp_comp_write(dev, DISP_MUTEX_EN(MUTEX_DSI_ID), MUTEX_EN);
+}
+
+static const struct mtk_disp_mutex_data mt8365_mutex_data = {
+       .ovl_dsi_enable = mtk_disp_mutex_ovl_dsi_enable_color_pipeline,
+};
+
+static const struct mtk_disp_mutex_data mt8366_mutex_data = {
+       .ovl_dsi_enable = mtk_disp_mutex_ovl_dsi_enable_no_color_pipeline,
+};
+
+void mtk_disp_mutex_ovl_dsi_enable(struct udevice *dev)
+{
+       struct mtk_disp_mutex_priv *mutex = dev_get_priv(dev);
+
+       if (!mutex->data) {
+               dev_err(dev, "no DSI pipeline on this mutex\n");
+               return;
+       }
+
+       mutex->data->ovl_dsi_enable(dev);
+}
+
+static int mtk_disp_mutex_probe(struct udevice *dev)
+{
+       struct mtk_disp_mutex_priv *mutex = dev_get_priv(dev);
+
+       /* the HDMI pipeline needs no per-SoC data */
+       mutex->data = (const struct mtk_disp_mutex_data 
*)dev_get_driver_data(dev);
+
+       return mtk_disp_comp_probe(dev);
+}
+
 static const struct udevice_id mtk_disp_mutex_ids[] = {
-       { .compatible = "mediatek,mt8188-disp-mutex" },
+       {
+               .compatible = "mediatek,mt8188-disp-mutex",
+       },
+       {
+               .compatible = "mediatek,mt8365-disp-mutex",
+               .data = (ulong)&mt8365_mutex_data,
+       },
+       {
+               .compatible = "mediatek,mt8366-disp-mutex",
+               .data = (ulong)&mt8366_mutex_data,
+       },
        { }
 };
 
@@ -74,6 +182,6 @@ U_BOOT_DRIVER(mtk_disp_mutex) = {
        .name      = "mtk_disp_mutex",
        .id        = UCLASS_MISC,
        .of_match  = mtk_disp_mutex_ids,
-       .probe     = mtk_disp_comp_probe,
-       .priv_auto = sizeof(struct mtk_disp_comp_priv),
+       .probe     = mtk_disp_mutex_probe,
+       .priv_auto = sizeof(struct mtk_disp_mutex_priv),
 };
diff --git a/drivers/video/mediatek/mtk_disp_mutex.h 
b/drivers/video/mediatek/mtk_disp_mutex.h
index 76630e6291f..34fecaaaa1b 100644
--- a/drivers/video/mediatek/mtk_disp_mutex.h
+++ b/drivers/video/mediatek/mtk_disp_mutex.h
@@ -18,4 +18,13 @@ struct udevice;
  */
 void mtk_disp_mutex_config_hdmi(struct udevice *dev);
 
+/**
+ * mtk_disp_mutex_ovl_dsi_enable() - set up the mutex of the DSI pipeline
+ * @dev: mmsys mutex device
+ *
+ * Put all the components of the OVL -> DSI pipeline under one mutex
+ * instance, and start and end their frames on the DSI ones.
+ */
+void mtk_disp_mutex_ovl_dsi_enable(struct udevice *dev);
+
 #endif /* _MTK_DISP_MUTEX_H */

-- 
2.55.0

Reply via email to