linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver
@ 2021-10-01  9:44 Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding Markus Schneider-Pargmann
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort driver to work.

For v3 I fixed/removed obsolete TODOs in the driver code and fixed one feedback
comment regarding a 'DRM_' prefix for the CEA_SAD defines.

The series is still based on v5.15-rc1 but also applies cleanly on linux-next
at the moment. There still is a functional dependency on many different patches
pulled in through the main two dependencies, vdosys0 and vdosys1, but I still
don't have a stable and clean base with these.

Note: This patch series is currently tested on v5.10 and I am still working on
testing it on v5.15.

Dependencies:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  https://lore.kernel.org/linux-mediatek/20210825144833.7757-1-jason-jh.lin@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  https://lore.kernel.org/linux-mediatek/20210825100531.5653-1-nancy.lin@mediatek.com/

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/

Thanks in advance for any feedback and comments.

Best,
Markus


Markus Schneider-Pargmann (6):
  dt-bindings: mediatek,dpintf: Add DP_INTF binding
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   89 +
 .../display/mediatek/mediatek,dpintf.yaml     |   78 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    7 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 2825 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  535 ++++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  248 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    6 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    1 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  218 ++
 drivers/video/hdmi.c                          |   83 +-
 include/drm/drm_dp_helper.h                   |    2 +
 include/drm/drm_edid.h                        |   18 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    2 +
 21 files changed, 4147 insertions(+), 74 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding
  2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
@ 2021-10-01  9:44 ` Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 2/6] dt-bindings: mediatek,dp: Add Display Port binding Markus Schneider-Pargmann
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

DP_INTF is a similar functional block to mediatek,dpi but is different
in that it serves the DisplayPort controller on mediatek SoCs and uses
different clocks. Therefore this patch creates a new binding file for
this functional block.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---

Notes:
    Changes v1 -> v2:
    - Move the devicetree binding from mediatek,dpi into its own binding file.

 .../display/mediatek/mediatek,dpintf.yaml     | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
new file mode 100644
index 000000000000..ac1fd93327e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dpintf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek DP_INTF Controller Device Tree Bindings
+
+maintainers:
+  - CK Hu <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+description: |
+  The Mediatek DP_INTF function block is a sink of the display subsystem
+  connected to the display port controller.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8195-dpintf
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: hf_fmm Clock
+      - description: hf_fdp Clock
+      - description: Pixel Clock
+      - description: DP_INTF PLL
+
+  clock-names:
+    items:
+      - const: hf_fmm
+      - const: hf_fdp
+      - const: pixel
+      - const: pll
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      Output port node. This port should be connected to the input port of an
+      attached display port controller.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+
+	dp_intf1: dp_intf1@1c113000 {
+		compatible = "mediatek,mt8195-dpintf";
+		reg = <0 0x1c113000 0 0x1000>;
+		interrupts = <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&vdosys1 CLK_VDO1_DP_INTF0_MM>,
+			 <&vdosys1 CLK_VDO1_DPINTF>,
+			 <&topckgen CLK_TOP_DP_SEL>,
+			 <&topckgen CLK_TOP_TVDPLL2>;
+		clock-names = "hf_fmm",
+			      "hf_fdp",
+			      "pixel",
+			      "pll";
+	};
+
+...
-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 2/6] dt-bindings: mediatek,dp: Add Display Port binding
  2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding Markus Schneider-Pargmann
@ 2021-10-01  9:44 ` Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 3/6] drm/edid: Add cea_sad helpers for freq/length Markus Schneider-Pargmann
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

This controller is present on several mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible field is added.

The controller can have two forms, as a normal display port and as an
embedded display port.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 89 +++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index 000000000000..f7a35962c23b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8195-edp_tx
+      - mediatek,mt8195-dp_tx
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: faxi clock
+
+  clock-names:
+    items:
+      - const: faxi
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input endpoint of the controller, usually dp_intf
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    dp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-edp_tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        status = "okay";
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 3/6] drm/edid: Add cea_sad helpers for freq/length
  2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 2/6] dt-bindings: mediatek,dp: Add Display Port binding Markus Schneider-Pargmann
@ 2021-10-01  9:44 ` Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 4/6] video/hdmi: Add audio_infoframe packing for DP Markus Schneider-Pargmann
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---

Notes:
    Changes v2 -> v3:
    - Add DRM_ prefix to the CEA_SAD defines.
    
    Changes v1 -> v2:
    - Use const struct pointers.
    - Add a check whether the format is actually uncompressed or not.

 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 18 ++++++++--
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..c134803e18db 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
+{
+	switch (sad->freq) {
+	case DRM_CEA_SAD_FREQ_32KHZ:
+		return 32000;
+	case DRM_CEA_SAD_FREQ_44KHZ:
+		return 44100;
+	case DRM_CEA_SAD_FREQ_48KHZ:
+		return 48000;
+	case DRM_CEA_SAD_FREQ_88KHZ:
+		return 88200;
+	case DRM_CEA_SAD_FREQ_96KHZ:
+		return 96000;
+	case DRM_CEA_SAD_FREQ_176KHZ:
+		return 176400;
+	case DRM_CEA_SAD_FREQ_192KHZ:
+		return 192000;
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
+{
+	switch (sad->format) {
+	case HDMI_AUDIO_CODING_TYPE_STREAM:
+	case HDMI_AUDIO_CODING_TYPE_PCM:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
+{
+	if (!drm_cea_sad_is_uncompressed(sad)) {
+		DRM_WARN("Unable to get the uncompressed word length for a compressed format: %u\n",
+			 sad->format);
+		return -EINVAL;
+	}
+
+	switch (sad->byte2) {
+	case DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+		return 16;
+	case DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+		return 20;
+	case DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+		return 24;
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..9d75df652b17 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-	u8 format;
+	u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
 	u8 channels; /* max number of channels - 1 */
-	u8 freq;
+	u8 freq; /* See CEA_SAD_FREQ_* */
 	u8 byte2; /* meaning depends on format */
 };
 
+#define DRM_CEA_SAD_FREQ_32KHZ  BIT(0)
+#define DRM_CEA_SAD_FREQ_44KHZ  BIT(1)
+#define DRM_CEA_SAD_FREQ_48KHZ  BIT(2)
+#define DRM_CEA_SAD_FREQ_88KHZ  BIT(3)
+#define DRM_CEA_SAD_FREQ_96KHZ  BIT(4)
+#define DRM_CEA_SAD_FREQ_176KHZ BIT(5)
+#define DRM_CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
 		      const struct drm_display_mode *mode);
 
-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 4/6] video/hdmi: Add audio_infoframe packing for DP
  2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
                   ` (2 preceding siblings ...)
  2021-10-01  9:44 ` [PATCH v3 3/6] drm/edid: Add cea_sad helpers for freq/length Markus Schneider-Pargmann
@ 2021-10-01  9:44 ` Markus Schneider-Pargmann
  2021-10-01  9:44 ` [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support Markus Schneider-Pargmann
       [not found] ` <20211001094443.2770169-7-msp@baylibre.com>
  5 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---

Notes:
    Changes v1 -> v2:
    - Create a define for HB2.
    - Use struct dp_sdp to pass data in a better way.

 drivers/video/hdmi.c        | 83 ++++++++++++++++++++++++++++---------
 include/drm/drm_dp_helper.h |  2 +
 include/linux/hdmi.h        |  7 +++-
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..63e74d9fd210 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *fr
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
 {
 	return hdmi_audio_infoframe_check_only(frame);
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+				  u8 *buffer)
+{
+	u8 channels;
+
+	if (frame->channels >= 2)
+		channels = frame->channels - 1;
+	else
+		channels = 0;
+
+	buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+	buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+		 (frame->sample_size & 0x3);
+	buffer[2] = frame->coding_type_ext & 0x1f;
+	buffer[3] = frame->channel_allocation;
+	buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+	if (frame->downmix_inhibit)
+		buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size)
 {
-	unsigned char channels;
 	u8 *ptr = buffer;
 	size_t length;
 	int ret;
@@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 
 	memset(buffer, 0, size);
 
-	if (frame->channels >= 2)
-		channels = frame->channels - 1;
-	else
-		channels = 0;
-
 	ptr[0] = frame->type;
 	ptr[1] = frame->version;
 	ptr[2] = frame->length;
 	ptr[3] = 0; /* checksum */
 
-	/* start infoframe payload */
-	ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-	ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-	ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-		 (frame->sample_size & 0x3);
-	ptr[2] = frame->coding_type_ext & 0x1f;
-	ptr[3] = frame->channel_allocation;
-	ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-	if (frame->downmix_inhibit)
-		ptr[4] |= BIT(7);
+	hdmi_audio_infoframe_pack_payload(frame,
+					  ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
 	hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *                                    displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @sdp secondary data packet for display port. This is filled with the
+ * appropriate data
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills the secondary data packet to be used for Display Port.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version)
+{
+	int ret;
+
+	ret = hdmi_audio_infoframe_check(frame);
+	if (ret)
+		return ret;
+
+	memset(sdp->db, 0, sizeof(sdp->db));
+
+	// Secondary-data packet header
+	sdp->sdp_header.HB0 = 0;
+	sdp->sdp_header.HB1 = frame->type;
+	sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
+	sdp->sdp_header.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 1d5b3dbb6e56..9debbcc34b14 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1524,6 +1524,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support
  2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
                   ` (3 preceding siblings ...)
  2021-10-01  9:44 ` [PATCH v3 4/6] video/hdmi: Add audio_infoframe packing for DP Markus Schneider-Pargmann
@ 2021-10-01  9:44 ` Markus Schneider-Pargmann
  2021-10-14 16:04   ` Chun-Kuang Hu
       [not found] ` <20211001094443.2770169-7-msp@baylibre.com>
  5 siblings, 1 reply; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-01  9:44 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel
  Cc: Sam Ravnborg, dri-devel, linux-mediatek, linux-arm-kernel,
	Markus Schneider-Pargmann

dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---

Notes:
    Changes RFC -> v1:
    - Remove setting parents and fully rely on the clock tree instead which already
      models a mux at the important place.
    - Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c          | 248 ++++++++++++++++----
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   5 +-
 5 files changed, 218 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..87961ebf5d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,8 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *hf_fmm_clk;
+	struct clk *hf_fdp_clk;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -125,6 +127,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 				 struct mtk_dpi_sync_param *sync)
 {
-	mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-		     sync->sync_width << HPW, HPW_MASK);
-	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-		     sync->back_porch << HBP, HBP_MASK);
-	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-		     HFP_MASK);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+			     sync->sync_width << HPW, DPINTF_HPW_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+			     sync->back_porch << HBP, DPINTF_HBP_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+			     DPINTF_HFP_MASK);
+	} else {
+		mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+			     sync->sync_width << HPW, HPW_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+			     sync->back_porch << HBP, HBP_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+			     HFP_MASK);
+	}
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 				 struct mtk_dpi_sync_param *sync,
 				 u32 width_addr, u32 porch_addr)
 {
-	mtk_dpi_mask(dpi, width_addr,
-		     sync->sync_width << VSYNC_WIDTH_SHIFT,
-		     VSYNC_WIDTH_MASK);
 	mtk_dpi_mask(dpi, width_addr,
 		     sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 		     VSYNC_HALF_LINE_MASK);
-	mtk_dpi_mask(dpi, porch_addr,
-		     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-		     VSYNC_BACK_PORCH_MASK);
-	mtk_dpi_mask(dpi, porch_addr,
-		     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-		     VSYNC_FRONT_PORCH_MASK);
+
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, width_addr,
+			     sync->sync_width << VSYNC_WIDTH_SHIFT,
+			     DPINTF_VSYNC_WIDTH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+			     DPINTF_VSYNC_BACK_PORCH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+			     DPINTF_VSYNC_FRONT_PORCH_MASK);
+	} else {
+		mtk_dpi_mask(dpi, width_addr,
+			     sync->sync_width << VSYNC_WIDTH_SHIFT,
+			     VSYNC_WIDTH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+			     VSYNC_BACK_PORCH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+			     VSYNC_FRONT_PORCH_MASK);
+	}
 }
 
 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -210,13 +235,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (!dpi->conf->is_dpintf) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -231,8 +263,13 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, DPINTF_HSIZE_MASK);
+		mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, DPINTF_VSIZE_MASK);
+	} else {
+		mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
+		mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	}
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
@@ -332,12 +369,21 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	if (dpi->conf->is_dpintf)
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << DPINTF_CH_SWAP,
+			     DPINTF_CH_SWAP_MASK);
+	else
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
+			     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	if (dpi->conf->is_dpintf)
+		mtk_dpi_mask(dpi, DPI_CON, enable ? DPINTF_YUV422_EN : 0,
+			     DPINTF_YUV422_EN);
+	else
+		mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -367,19 +413,25 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
-		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, true);
+			mtk_dpi_config_swap_input(dpi, false);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
-		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, true);
+			mtk_dpi_config_swap_input(dpi, true);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
-		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, false);
+			mtk_dpi_config_swap_input(dpi, false);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -410,6 +462,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
 
 	mtk_dpi_disable(dpi);
+	clk_disable_unprepare(dpi->hf_fdp_clk);
+	clk_disable_unprepare(dpi->hf_fmm_clk);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
 }
@@ -433,12 +487,28 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_pixel;
 	}
 
+	ret = clk_prepare_enable(dpi->hf_fmm_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hf_fmm clock: %d\n", ret);
+		goto err_hf_fmm;
+	}
+
+	ret = clk_prepare_enable(dpi->hf_fdp_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hf_fdp clock: %d\n", ret);
+		goto err_hf_fdp;
+	}
+
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
 	mtk_dpi_enable(dpi);
 	return 0;
 
+err_hf_fdp:
+	clk_disable_unprepare(dpi->hf_fmm_clk);
+err_hf_fmm:
+	clk_disable_unprepare(dpi->pixel_clk);
 err_pixel:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
@@ -472,22 +542,30 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	pll_rate = clk_get_rate(dpi->tvd_clk);
 
 	vm.pixelclock = pll_rate / factor;
-	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+	if (dpi->conf->is_dpintf)
+		clk_set_rate(dpi->pixel_clk, vm.pixelclock / 4);
+	else if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
 	else
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
 
-
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
+	if (dpi->conf->is_dpintf) {
+		limit.c_bottom = 0x0000;
+		limit.c_top = 0xFFF;
+		limit.y_bottom = 0x0000;
+		limit.y_top = 0xFFF;
+	} else {
+		limit.c_bottom = 0x0010;
+		limit.c_top = 0x0FE0;
+		limit.y_bottom = 0x0010;
+		limit.y_top = 0x0FE0;
+	}
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
@@ -495,9 +573,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -539,11 +623,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi, &limit);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
 	return 0;
@@ -687,6 +776,17 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 };
 
+static const struct drm_bridge_funcs mtk_dpintf_bridge_funcs = {
+	.attach = mtk_dpi_bridge_attach,
+	.mode_set = mtk_dpi_bridge_mode_set,
+	.disable = mtk_dpi_bridge_disable,
+	.enable = mtk_dpi_bridge_enable,
+	.atomic_check = mtk_dpi_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
 void mtk_dpi_start(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
@@ -781,6 +881,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -796,6 +906,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +916,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +925,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +934,12 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
+};
+
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.is_dpintf = true,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
@@ -866,13 +985,16 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dpi->engine_clk = devm_clk_get(dev, "engine");
-	if (IS_ERR(dpi->engine_clk)) {
-		ret = PTR_ERR(dpi->engine_clk);
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+	if (!dpi->conf->is_dpintf) {
+		dpi->engine_clk = devm_clk_get(dev, "engine");
+		if (IS_ERR(dpi->engine_clk)) {
+			ret = PTR_ERR(dpi->engine_clk);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to get engine clock: %d\n",
+					ret);
 
-		return ret;
+			return ret;
+		}
 	}
 
 	dpi->pixel_clk = devm_clk_get(dev, "pixel");
@@ -893,6 +1015,24 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dpi->hf_fmm_clk = devm_clk_get_optional(dev, "hf_fmm");
+	if (IS_ERR(dpi->hf_fmm_clk)) {
+		ret = PTR_ERR(dpi->hf_fmm_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get hf_fmm clock: %d\n", ret);
+
+		return ret;
+	}
+
+	dpi->hf_fdp_clk = devm_clk_get_optional(dev, "hf_fdp");
+	if (IS_ERR(dpi->hf_fdp_clk)) {
+		ret = PTR_ERR(dpi->hf_fdp_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get hf_fdp clock: %d\n", ret);
+
+		return ret;
+	}
+
 	dpi->irq = platform_get_irq(pdev, 0);
 	if (dpi->irq <= 0)
 		return -EINVAL;
@@ -906,7 +1046,10 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, dpi);
 
-	dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
+	if (dpi->conf->is_dpintf)
+		dpi->bridge.funcs = &mtk_dpintf_bridge_funcs;
+	else
+		dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
 	dpi->bridge.of_node = dev->of_node;
 	dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
 
@@ -945,6 +1088,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..72efe6ee2584 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,14 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +84,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +99,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 99cbf44463e4..da9e059312a5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -317,6 +317,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_UFOE] = "ufoe",
 	[MTK_DSI] = "dsi",
 	[MTK_DPI] = "dpi",
+	[MTK_DP_INTF] = "dp-intf",
 	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -339,6 +340,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF0]= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]= { MTK_DP_INTF,	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 },
@@ -476,6 +479,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..ee9d853cfa1c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DSI,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index aec39724ebeb..1ff4e31c8634 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -459,6 +459,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -569,7 +571,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DSI ||
-		    comp_type == MTK_DPI) {
+		    comp_type == MTK_DPI ||
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, compare_of,
-- 
2.33.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver
       [not found] ` <20211001094443.2770169-7-msp@baylibre.com>
@ 2021-10-01 16:16   ` Chun-Kuang Hu
  2021-10-05  7:16     ` Markus Schneider-Pargmann
  0 siblings, 1 reply; 10+ messages in thread
From: Chun-Kuang Hu @ 2021-10-01 16:16 UTC (permalink / raw)
  To: Markus Schneider-Pargmann
  Cc: Chun-Kuang Hu, Philipp Zabel, Sam Ravnborg, DRI Development,
	moderated list:ARM/Mediatek SoC support, Linux ARM

Hi, Markus:

Markus Schneider-Pargmann <msp@baylibre.com> 於 2021年10月1日 週五 下午5:44寫道:
>
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
> according phy driver mediatek-dp-phy.
>
> It supports both functional units on the mt8195, the embedded
> DisplayPort as well as the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> to 4 lanes.
>
> The driver creates a child device for the phy. The child device will
> never exist without the parent being active. As they are sharing a
> register range, the parent passes a regmap pointer to the child so that
> both can work with the same register range. The phy driver sets device
> data that is read by the parent to get the phy device that can be used
> to control the phy properties.
>
> This driver is based on an initial version by
> Jason-JH.Lin <jason-jh.lin@mediatek.com>.
>
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> ---
>
> Notes:
>     Changes v2 -> v3:
>     - Solve TODOs and add defines for undescribed registers
>     - Remove TODOs that were irrelevant
>
>     Changes v1 -> v2:
>     - Fix checkpatch --strict suggestions
>     - General cleanups of the code.
>     - Remove all remaining non-atomic functions.
>     - Remove unused includes and sort them.
>     - Remove unused select GENERIC_PHY
>     - Rename phy registers DP_PHY -> MTK_DP_PHY
>     - Replace usage of delays with usleep_range.
>     - Split the phy register accesses into a separate phy driver.
>     - Use a lock to guard access to mtk_dp->edid as it can be allocated/used/freed
>       in different threads
>     - use struct dp_sdp for sdp packets.
>
>     Changes RFC -> v1:
>     - Removed unused register definitions.
>     - Replaced workqueue with threaded irq.
>     - Removed connector code.
>     - Move to atomic_* drm functions.
>     - General cleanups of the code.
>     - Remove unused select GENERIC_PHY.
>
>  drivers/gpu/drm/mediatek/Kconfig       |    7 +
>  drivers/gpu/drm/mediatek/Makefile      |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c      | 2825 ++++++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h |    1 +
>  drivers/phy/mediatek/Kconfig           |    8 +
>  drivers/phy/mediatek/Makefile          |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c      |  218 ++

Separate the phy driver to another patch because phy driver would go
into different maintainer's tree.

Regards,
Chun-Kuang.

>  include/linux/soc/mediatek/mtk-mmsys.h |    2 +
>  10 files changed, 3600 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver
  2021-10-01 16:16   ` [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver Chun-Kuang Hu
@ 2021-10-05  7:16     ` Markus Schneider-Pargmann
  0 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-05  7:16 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Philipp Zabel, Sam Ravnborg, DRI Development,
	moderated list:ARM/Mediatek SoC support, Linux ARM

Hi Chun-Kuang,

On Sat, Oct 02, 2021 at 12:16:26AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> [...]
> >
> >  drivers/gpu/drm/mediatek/Kconfig       |    7 +
> >  drivers/gpu/drm/mediatek/Makefile      |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c      | 2825 ++++++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +++++
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h |    1 +
> >  drivers/phy/mediatek/Kconfig           |    8 +
> >  drivers/phy/mediatek/Makefile          |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c      |  218 ++
> 
> Separate the phy driver to another patch because phy driver would go
> into different maintainer's tree.

Oh of course. Thank you. I fixed it for the next version.

Best,
Markus

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support
  2021-10-01  9:44 ` [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support Markus Schneider-Pargmann
@ 2021-10-14 16:04   ` Chun-Kuang Hu
  2021-10-20 19:08     ` Markus Schneider-Pargmann
  0 siblings, 1 reply; 10+ messages in thread
From: Chun-Kuang Hu @ 2021-10-14 16:04 UTC (permalink / raw)
  To: Markus Schneider-Pargmann
  Cc: Chun-Kuang Hu, Philipp Zabel, Sam Ravnborg, DRI Development,
	moderated list:ARM/Mediatek SoC support, Linux ARM

Hi, Markus:

Markus Schneider-Pargmann <msp@baylibre.com> 於 2021年10月1日 週五 下午5:44寫道:
>
> dpintf is the displayport interface hardware unit. This unit is similar
> to dpi and can reuse most of the code.
>
> This patch adds support for mt8195-dpintf to this dpi driver. Main
> differences are:
>  - Some features/functional components are not available for dpintf
>    which are now excluded from code execution once is_dpintf is set
>  - dpintf can and needs to choose between different clockdividers based
>    on the clockspeed. This is done by choosing a different clock parent.
>  - There are two additional clocks that need to be managed. These are
>    only set for dpintf and will be set to NULL if not supplied. The
>    clk_* calls handle these as normal clocks then.
>  - Some register contents differ slightly between the two components. To
>    work around this I added register bits/masks with a DPINTF_ prefix
>    and use them where different.
>
> Based on a separate driver for dpintf created by
> Jason-JH.Lin <jason-jh.lin@mediatek.com>.
>
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> ---
>
> Notes:
>     Changes RFC -> v1:
>     - Remove setting parents and fully rely on the clock tree instead which already
>       models a mux at the important place.
>     - Integrated mtk_dpi dpintf changes into the mediatek drm driver.
>
>  drivers/gpu/drm/mediatek/mtk_dpi.c          | 248 ++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  12 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   5 +-
>  5 files changed, 218 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4554e2de1430..87961ebf5d35 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,8 @@ struct mtk_dpi {
>         void __iomem *regs;
>         struct device *dev;
>         struct clk *engine_clk;
> +       struct clk *hf_fmm_clk;
> +       struct clk *hf_fdp_clk;
>         struct clk *pixel_clk;
>         struct clk *tvd_clk;
>         int irq;
> @@ -125,6 +127,7 @@ struct mtk_dpi_conf {
>         bool edge_sel_en;
>         const u32 *output_fmts;
>         u32 num_output_fmts;
> +       bool is_dpintf;
>  };
>
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> @@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
>  static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
>                                  struct mtk_dpi_sync_param *sync)
>  {
> -       mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> -                    sync->sync_width << HPW, HPW_MASK);
> -       mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> -                    sync->back_porch << HBP, HBP_MASK);
> -       mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> -                    HFP_MASK);
> +       if (dpi->conf->is_dpintf) {
> +               mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> +                            sync->sync_width << HPW, DPINTF_HPW_MASK);
> +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> +                            sync->back_porch << HBP, DPINTF_HBP_MASK);
> +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> +                            DPINTF_HFP_MASK);

define dpi->conf->hpw_mask
define dpi->conf->hbp_mask
define dpi->conf->hfp_mask

> +       } else {
> +               mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> +                            sync->sync_width << HPW, HPW_MASK);
> +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> +                            sync->back_porch << HBP, HBP_MASK);
> +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> +                            HFP_MASK);
> +       }
>  }
>
>  static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
>                                  struct mtk_dpi_sync_param *sync,
>                                  u32 width_addr, u32 porch_addr)
>  {
> -       mtk_dpi_mask(dpi, width_addr,
> -                    sync->sync_width << VSYNC_WIDTH_SHIFT,
> -                    VSYNC_WIDTH_MASK);
>         mtk_dpi_mask(dpi, width_addr,
>                      sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
>                      VSYNC_HALF_LINE_MASK);
> -       mtk_dpi_mask(dpi, porch_addr,
> -                    sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> -                    VSYNC_BACK_PORCH_MASK);
> -       mtk_dpi_mask(dpi, porch_addr,
> -                    sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> -                    VSYNC_FRONT_PORCH_MASK);
> +
> +       if (dpi->conf->is_dpintf) {
> +               mtk_dpi_mask(dpi, width_addr,
> +                            sync->sync_width << VSYNC_WIDTH_SHIFT,
> +                            DPINTF_VSYNC_WIDTH_MASK);
> +               mtk_dpi_mask(dpi, porch_addr,
> +                            sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> +                            DPINTF_VSYNC_BACK_PORCH_MASK);
> +               mtk_dpi_mask(dpi, porch_addr,
> +                            sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> +                            DPINTF_VSYNC_FRONT_PORCH_MASK);
> +       } else {
> +               mtk_dpi_mask(dpi, width_addr,
> +                            sync->sync_width << VSYNC_WIDTH_SHIFT,
> +                            VSYNC_WIDTH_MASK);
> +               mtk_dpi_mask(dpi, porch_addr,
> +                            sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> +                            VSYNC_BACK_PORCH_MASK);
> +               mtk_dpi_mask(dpi, porch_addr,
> +                            sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> +                            VSYNC_FRONT_PORCH_MASK);
> +       }
>  }
>
>  static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -210,13 +235,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
>                                struct mtk_dpi_polarities *dpi_pol)
>  {
>         unsigned int pol;
> +       unsigned int mask;
>
> -       pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
> -             (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
> -             (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
> +       mask = HSYNC_POL | VSYNC_POL;
> +       pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
>               (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
> -       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -                    CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +       if (!dpi->conf->is_dpintf) {

define dpi->conf->is_ck_de_pol

> +               mask |= CK_POL | DE_POL;
> +               pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +                       0 : CK_POL) |
> +                      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +                       0 : DE_POL);
> +       }
> +
> +       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -231,8 +263,13 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
>
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
>  {
> -       mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -       mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +       if (dpi->conf->is_dpintf) {
> +               mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, DPINTF_HSIZE_MASK);
> +               mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, DPINTF_VSIZE_MASK);
> +       } else {
> +               mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> +               mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +       }
>  }
>
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
> @@ -332,12 +369,21 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
>                 break;
>         }
>
> -       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
> +       if (dpi->conf->is_dpintf)
> +               mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << DPINTF_CH_SWAP,
> +                            DPINTF_CH_SWAP_MASK);
> +       else
> +               mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> +                            CH_SWAP_MASK);
>  }
>
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
>  {
> -       mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +       if (dpi->conf->is_dpintf)
> +               mtk_dpi_mask(dpi, DPI_CON, enable ? DPINTF_YUV422_EN : 0,
> +                            DPINTF_YUV422_EN);
> +       else
> +               mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
>  }
>
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
> @@ -367,19 +413,25 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
>         if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
>             (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>                 mtk_dpi_config_yuv422_enable(dpi, false);
> -               mtk_dpi_config_csc_enable(dpi, true);
> -               mtk_dpi_config_swap_input(dpi, false);
> +               if (!dpi->conf->is_dpintf) {
> +                       mtk_dpi_config_csc_enable(dpi, true);

define dpi->conf->csc_support

> +                       mtk_dpi_config_swap_input(dpi, false);

define dpi->conf->swap_input_support

> +               }
>                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>         } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>                    (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>                 mtk_dpi_config_yuv422_enable(dpi, true);
> -               mtk_dpi_config_csc_enable(dpi, true);
> -               mtk_dpi_config_swap_input(dpi, true);
> +               if (!dpi->conf->is_dpintf) {
> +                       mtk_dpi_config_csc_enable(dpi, true);
> +                       mtk_dpi_config_swap_input(dpi, true);
> +               }
>                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>         } else {
>                 mtk_dpi_config_yuv422_enable(dpi, false);
> -               mtk_dpi_config_csc_enable(dpi, false);
> -               mtk_dpi_config_swap_input(dpi, false);
> +               if (!dpi->conf->is_dpintf) {
> +                       mtk_dpi_config_csc_enable(dpi, false);
> +                       mtk_dpi_config_swap_input(dpi, false);
> +               }
>                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>         }
>  }
> @@ -410,6 +462,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>                 pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
>
>         mtk_dpi_disable(dpi);
> +       clk_disable_unprepare(dpi->hf_fdp_clk);
> +       clk_disable_unprepare(dpi->hf_fmm_clk);
>         clk_disable_unprepare(dpi->pixel_clk);
>         clk_disable_unprepare(dpi->engine_clk);
>  }
> @@ -433,12 +487,28 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>                 goto err_pixel;
>         }
>
> +       ret = clk_prepare_enable(dpi->hf_fmm_clk);
> +       if (ret) {
> +               dev_err(dpi->dev, "Failed to enable hf_fmm clock: %d\n", ret);
> +               goto err_hf_fmm;
> +       }
> +
> +       ret = clk_prepare_enable(dpi->hf_fdp_clk);
> +       if (ret) {
> +               dev_err(dpi->dev, "Failed to enable hf_fdp clock: %d\n", ret);
> +               goto err_hf_fdp;
> +       }
> +
>         if (dpi->pinctrl && dpi->pins_dpi)
>                 pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
>
>         mtk_dpi_enable(dpi);
>         return 0;
>
> +err_hf_fdp:
> +       clk_disable_unprepare(dpi->hf_fmm_clk);
> +err_hf_fmm:
> +       clk_disable_unprepare(dpi->pixel_clk);
>  err_pixel:
>         clk_disable_unprepare(dpi->engine_clk);
>  err_refcount:
> @@ -472,22 +542,30 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         pll_rate = clk_get_rate(dpi->tvd_clk);
>
>         vm.pixelclock = pll_rate / factor;
> -       if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -           (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +       if (dpi->conf->is_dpintf)
> +               clk_set_rate(dpi->pixel_clk, vm.pixelclock / 4);
> +       else if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> +                (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
>                 clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
>         else
>                 clk_set_rate(dpi->pixel_clk, vm.pixelclock);
>
> -
>         vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>
>         dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
>                 pll_rate, vm.pixelclock);
>
> -       limit.c_bottom = 0x0010;
> -       limit.c_top = 0x0FE0;
> -       limit.y_bottom = 0x0010;
> -       limit.y_top = 0x0FE0;
> +       if (dpi->conf->is_dpintf) {
> +               limit.c_bottom = 0x0000;
> +               limit.c_top = 0xFFF;
> +               limit.y_bottom = 0x0000;
> +               limit.y_top = 0xFFF;
> +       } else {
> +               limit.c_bottom = 0x0010;
> +               limit.c_top = 0x0FE0;
> +               limit.y_bottom = 0x0010;
> +               limit.y_top = 0x0FE0;
> +       }
>
>         dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
>         dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
> @@ -495,9 +573,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>         dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -       hsync.sync_width = vm.hsync_len;
> -       hsync.back_porch = vm.hback_porch;
> -       hsync.front_porch = vm.hfront_porch;
> +       if (dpi->conf->is_dpintf) {
> +               hsync.sync_width = vm.hsync_len / 4;
> +               hsync.back_porch = vm.hback_porch / 4;
> +               hsync.front_porch = vm.hfront_porch / 4;
> +       } else {
> +               hsync.sync_width = vm.hsync_len;
> +               hsync.back_porch = vm.hback_porch;
> +               hsync.front_porch = vm.hfront_porch;
> +       }
>         hsync.shift_half_line = false;
>         vsync_lodd.sync_width = vm.vsync_len;
>         vsync_lodd.back_porch = vm.vback_porch;
> @@ -539,11 +623,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         mtk_dpi_config_channel_limit(dpi, &limit);
>         mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>         mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -       mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>         mtk_dpi_config_color_format(dpi, dpi->color_format);
> -       mtk_dpi_config_2n_h_fre(dpi);
> -       mtk_dpi_dual_edge(dpi);
> -       mtk_dpi_config_disable_edge(dpi);
> +       if (dpi->conf->is_dpintf) {
> +               mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +                            DPINTF_INPUT_2P_EN);
> +       } else {
> +               mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +               mtk_dpi_config_2n_h_fre(dpi);
> +               mtk_dpi_dual_edge(dpi);
> +               mtk_dpi_config_disable_edge(dpi);
> +       }
>         mtk_dpi_sw_reset(dpi, false);
>
>         return 0;
> @@ -687,6 +776,17 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
>         .atomic_reset = drm_atomic_helper_bridge_reset,
>  };
>
> +static const struct drm_bridge_funcs mtk_dpintf_bridge_funcs = {
> +       .attach = mtk_dpi_bridge_attach,
> +       .mode_set = mtk_dpi_bridge_mode_set,
> +       .disable = mtk_dpi_bridge_disable,
> +       .enable = mtk_dpi_bridge_enable,
> +       .atomic_check = mtk_dpi_bridge_atomic_check,
> +       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> +       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> +       .atomic_reset = drm_atomic_helper_bridge_reset,
> +};

I think mtk_dpintf_bridge_funcs is the same as mtk_dpi_bridge_func, so
remove this and use mtk_dpi_bridge_func.

> +
>  void mtk_dpi_start(struct device *dev)
>  {
>         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> @@ -781,6 +881,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>                 return 2;
>  }
>
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +       if (clock < 70000)
> +               return 4;
> +       else if (clock < 200000)
> +               return 2;
> +       else
> +               return 1;
> +}
> +
>  static const u32 mt8173_output_fmts[] = {
>         MEDIA_BUS_FMT_RGB888_1X24,
>  };
> @@ -796,6 +906,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>         .max_clock_khz = 300000,
>         .output_fmts = mt8173_output_fmts,
>         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +       .is_dpintf = false,

Global variable is defualt zero, so remove this.

>  };
>
>  static const struct mtk_dpi_conf mt2701_conf = {
> @@ -805,6 +916,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>         .max_clock_khz = 150000,
>         .output_fmts = mt8173_output_fmts,
>         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +       .is_dpintf = false,
>  };
>
>  static const struct mtk_dpi_conf mt8183_conf = {
> @@ -813,6 +925,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>         .max_clock_khz = 100000,
>         .output_fmts = mt8183_output_fmts,
>         .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +       .is_dpintf = false,
>  };
>
>  static const struct mtk_dpi_conf mt8192_conf = {
> @@ -821,6 +934,12 @@ static const struct mtk_dpi_conf mt8192_conf = {
>         .max_clock_khz = 150000,
>         .output_fmts = mt8173_output_fmts,
>         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +       .is_dpintf = false,
> +};
> +
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +       .cal_factor = mt8195_dpintf_calculate_factor,
> +       .is_dpintf = true,
>  };
>
>  static int mtk_dpi_probe(struct platform_device *pdev)
> @@ -866,13 +985,16 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       dpi->engine_clk = devm_clk_get(dev, "engine");
> -       if (IS_ERR(dpi->engine_clk)) {
> -               ret = PTR_ERR(dpi->engine_clk);
> -               if (ret != -EPROBE_DEFER)
> -                       dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +       if (!dpi->conf->is_dpintf) {
> +               dpi->engine_clk = devm_clk_get(dev, "engine");
> +               if (IS_ERR(dpi->engine_clk)) {
> +                       ret = PTR_ERR(dpi->engine_clk);
> +                       if (ret != -EPROBE_DEFER)
> +                               dev_err(dev, "Failed to get engine clock: %d\n",
> +                                       ret);
>
> -               return ret;
> +                       return ret;
> +               }
>         }
>
>         dpi->pixel_clk = devm_clk_get(dev, "pixel");
> @@ -893,6 +1015,24 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> +       dpi->hf_fmm_clk = devm_clk_get_optional(dev, "hf_fmm");
> +       if (IS_ERR(dpi->hf_fmm_clk)) {
> +               ret = PTR_ERR(dpi->hf_fmm_clk);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(dev, "Failed to get hf_fmm clock: %d\n", ret);
> +
> +               return ret;
> +       }
> +
> +       dpi->hf_fdp_clk = devm_clk_get_optional(dev, "hf_fdp");
> +       if (IS_ERR(dpi->hf_fdp_clk)) {
> +               ret = PTR_ERR(dpi->hf_fdp_clk);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(dev, "Failed to get hf_fdp clock: %d\n", ret);
> +
> +               return ret;
> +       }

You does not send the device tree patch, so I found one in chromium
gerrit [1]. Compare the clock of disp_dpi1 with dp_intf1, I think
hf_fdp is likely the pixel clock and hf_fmm is likely the engine
clock. Could you provide the information of the function of each
clock?

[1] https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/changes/99/2781499/219/arch/arm64/boot/dts/mediatek/mt8195.dtsi#3499

Regards,
Chun-Kuang.

> +
>         dpi->irq = platform_get_irq(pdev, 0);
>         if (dpi->irq <= 0)
>                 return -EINVAL;
> @@ -906,7 +1046,10 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>
>         platform_set_drvdata(pdev, dpi);
>
> -       dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
> +       if (dpi->conf->is_dpintf)
> +               dpi->bridge.funcs = &mtk_dpintf_bridge_funcs;
> +       else
> +               dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
>         dpi->bridge.of_node = dev->of_node;
>         dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
>
> @@ -945,6 +1088,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>         { .compatible = "mediatek,mt8192-dpi",
>           .data = &mt8192_conf,
>         },
> +       { .compatible = "mediatek,mt8195-dpintf",
> +         .data = &mt8195_dpintf_conf,
> +       },
>         { },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..72efe6ee2584 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,14 @@
>  #define FAKE_DE_LEVEN                  BIT(21)
>  #define FAKE_DE_RODD                   BIT(22)
>  #define FAKE_DE_REVEN                  BIT(23)
> +#define DPINTF_YUV422_EN               BIT(24)
> +#define DPINTF_INPUT_2P_EN             BIT(29)
>
>  #define DPI_OUTPUT_SETTING     0x14
>  #define CH_SWAP                                0
> +#define DPINTF_CH_SWAP                 BIT(1)
>  #define CH_SWAP_MASK                   (0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK            (0x7 << 1)
>  #define SWAP_RGB                       0x00
>  #define SWAP_GBR                       0x01
>  #define SWAP_BRG                       0x02
> @@ -80,8 +84,10 @@
>  #define DPI_SIZE               0x18
>  #define HSIZE                          0
>  #define HSIZE_MASK                     (0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK              (0xFFFF << 0)
>  #define VSIZE                          16
>  #define VSIZE_MASK                     (0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK              (0xFFFF << 16)
>
>  #define DPI_DDR_SETTING                0x1C
>  #define DDR_EN                         BIT(0)
> @@ -93,24 +99,30 @@
>  #define DPI_TGEN_HWIDTH                0x20
>  #define HPW                            0
>  #define HPW_MASK                       (0xFFF << 0)
> +#define DPINTF_HPW_MASK                        (0xFFFF << 0)
>
>  #define DPI_TGEN_HPORCH                0x24
>  #define HBP                            0
>  #define HBP_MASK                       (0xFFF << 0)
> +#define DPINTF_HBP_MASK                        (0xFFFF << 0)
>  #define HFP                            16
>  #define HFP_MASK                       (0xFFF << 16)
> +#define DPINTF_HFP_MASK                        (0xFFFF << 16)
>
>  #define DPI_TGEN_VWIDTH                0x28
>  #define DPI_TGEN_VPORCH                0x2C
>
>  #define VSYNC_WIDTH_SHIFT              0
>  #define VSYNC_WIDTH_MASK               (0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK                (0xFFFF << 0)
>  #define VSYNC_HALF_LINE_SHIFT          16
>  #define VSYNC_HALF_LINE_MASK           BIT(16)
>  #define VSYNC_BACK_PORCH_SHIFT         0
>  #define VSYNC_BACK_PORCH_MASK          (0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK   (0xFFFF << 0)
>  #define VSYNC_FRONT_PORCH_SHIFT                16
>  #define VSYNC_FRONT_PORCH_MASK         (0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK  (0xFFFF << 16)
>
>  #define DPI_BG_HCNTL           0x30
>  #define BG_RIGHT                       (0x1FFF << 0)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 99cbf44463e4..da9e059312a5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -317,6 +317,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>         [MTK_DISP_UFOE] = "ufoe",
>         [MTK_DSI] = "dsi",
>         [MTK_DPI] = "dpi",
> +       [MTK_DP_INTF] = "dp-intf",
>         [MTK_DISP_PWM] = "pwm",
>         [MTK_DISP_MUTEX] = "mutex",
>         [MTK_DISP_OD] = "od",
> @@ -339,6 +340,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0, &ddp_dither },
>         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi },
>         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi },
> +       [DDP_COMPONENT_DP_INTF0]= { MTK_DP_INTF,        0, &ddp_dpi },
> +       [DDP_COMPONENT_DP_INTF1]= { MTK_DP_INTF,        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 },
> @@ -476,6 +479,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>             type == MTK_DISP_COLOR ||
>             type == MTK_DISP_GAMMA ||
>             type == MTK_DPI ||
> +           type == MTK_DP_INTF ||
>             type == MTK_DSI ||
>             type == MTK_DISP_OVL ||
>             type == MTK_DISP_OVL_2L ||
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index bb914d976cf5..ee9d853cfa1c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
>         MTK_DISP_UFOE,
>         MTK_DSI,
>         MTK_DPI,
> +       MTK_DP_INTF,
>         MTK_DISP_PWM,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index aec39724ebeb..1ff4e31c8634 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -459,6 +459,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt8183-dpi",
>           .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8195-dpintf",
> +         .data = (void *)MTK_DP_INTF },
>         { .compatible = "mediatek,mt2701-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2712-disp-mutex",
> @@ -569,7 +571,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
>                     comp_type == MTK_DISP_OVL_2L ||
>                     comp_type == MTK_DISP_RDMA ||
>                     comp_type == MTK_DSI ||
> -                   comp_type == MTK_DPI) {
> +                   comp_type == MTK_DPI ||
> +                   comp_type == MTK_DP_INTF) {
>                         dev_info(dev, "Adding component match for %pOF\n",
>                                  node);
>                         drm_of_component_match_add(dev, &match, compare_of,
> --
> 2.33.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support
  2021-10-14 16:04   ` Chun-Kuang Hu
@ 2021-10-20 19:08     ` Markus Schneider-Pargmann
  0 siblings, 0 replies; 10+ messages in thread
From: Markus Schneider-Pargmann @ 2021-10-20 19:08 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Philipp Zabel, Sam Ravnborg, DRI Development,
	moderated list:ARM/Mediatek SoC support, Linux ARM

Hi Chun-Kuang,

On Fri, Oct 15, 2021 at 12:04:10AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> 
> Markus Schneider-Pargmann <msp@baylibre.com> 於 2021年10月1日 週五 下午5:44寫道:
> >
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> >
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >    which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >    on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >    only set for dpintf and will be set to NULL if not supplied. The
> >    clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >    work around this I added register bits/masks with a DPINTF_ prefix
> >    and use them where different.
> >
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin <jason-jh.lin@mediatek.com>.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > ---
> >
> > Notes:
> >     Changes RFC -> v1:
> >     - Remove setting parents and fully rely on the clock tree instead which already
> >       models a mux at the important place.
> >     - Integrated mtk_dpi dpintf changes into the mediatek drm driver.
> >
> >  drivers/gpu/drm/mediatek/mtk_dpi.c          | 248 ++++++++++++++++----
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  12 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   5 +-
> >  5 files changed, 218 insertions(+), 52 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4554e2de1430..87961ebf5d35 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,8 @@ struct mtk_dpi {
> >         void __iomem *regs;
> >         struct device *dev;
> >         struct clk *engine_clk;
> > +       struct clk *hf_fmm_clk;
> > +       struct clk *hf_fdp_clk;
> >         struct clk *pixel_clk;
> >         struct clk *tvd_clk;
> >         int irq;
> > @@ -125,6 +127,7 @@ struct mtk_dpi_conf {
> >         bool edge_sel_en;
> >         const u32 *output_fmts;
> >         u32 num_output_fmts;
> > +       bool is_dpintf;
> >  };
> >
> >  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> > @@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
> >  static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
> >                                  struct mtk_dpi_sync_param *sync)
> >  {
> > -       mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > -                    sync->sync_width << HPW, HPW_MASK);
> > -       mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > -                    sync->back_porch << HBP, HBP_MASK);
> > -       mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > -                    HFP_MASK);
> > +       if (dpi->conf->is_dpintf) {
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > +                            sync->sync_width << HPW, DPINTF_HPW_MASK);
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > +                            sync->back_porch << HBP, DPINTF_HBP_MASK);
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > +                            DPINTF_HFP_MASK);
> 
> define dpi->conf->hpw_mask
> define dpi->conf->hbp_mask
> define dpi->conf->hfp_mask

Thanks, I defined a dpi->conf->dimension_mask instead which I now use
for HWIDTH/HPORCH as well as VSYNC_WIDTH and VSYNC_PORCH as the only
difference is the width of the masks, not their positions. Hope that's
fine.

> 
> > +       } else {
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > +                            sync->sync_width << HPW, HPW_MASK);
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > +                            sync->back_porch << HBP, HBP_MASK);
> > +               mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > +                            HFP_MASK);
> > +       }
> >  }
> >
> >  static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
> >                                  struct mtk_dpi_sync_param *sync,
> >                                  u32 width_addr, u32 porch_addr)
> >  {
> > -       mtk_dpi_mask(dpi, width_addr,
> > -                    sync->sync_width << VSYNC_WIDTH_SHIFT,
> > -                    VSYNC_WIDTH_MASK);
> >         mtk_dpi_mask(dpi, width_addr,
> >                      sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
> >                      VSYNC_HALF_LINE_MASK);
> > -       mtk_dpi_mask(dpi, porch_addr,
> > -                    sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> > -                    VSYNC_BACK_PORCH_MASK);
> > -       mtk_dpi_mask(dpi, porch_addr,
> > -                    sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> > -                    VSYNC_FRONT_PORCH_MASK);
> > +
> > +       if (dpi->conf->is_dpintf) {
> > +               mtk_dpi_mask(dpi, width_addr,
> > +                            sync->sync_width << VSYNC_WIDTH_SHIFT,
> > +                            DPINTF_VSYNC_WIDTH_MASK);
> > +               mtk_dpi_mask(dpi, porch_addr,
> > +                            sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> > +                            DPINTF_VSYNC_BACK_PORCH_MASK);
> > +               mtk_dpi_mask(dpi, porch_addr,
> > +                            sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> > +                            DPINTF_VSYNC_FRONT_PORCH_MASK);
> > +       } else {
> > +               mtk_dpi_mask(dpi, width_addr,
> > +                            sync->sync_width << VSYNC_WIDTH_SHIFT,
> > +                            VSYNC_WIDTH_MASK);
> > +               mtk_dpi_mask(dpi, porch_addr,
> > +                            sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
> > +                            VSYNC_BACK_PORCH_MASK);
> > +               mtk_dpi_mask(dpi, porch_addr,
> > +                            sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
> > +                            VSYNC_FRONT_PORCH_MASK);
> > +       }
> >  }
> >
> >  static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
> > @@ -210,13 +235,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
> >                                struct mtk_dpi_polarities *dpi_pol)
> >  {
> >         unsigned int pol;
> > +       unsigned int mask;
> >
> > -       pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
> > -             (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
> > -             (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
> > +       mask = HSYNC_POL | VSYNC_POL;
> > +       pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
> >               (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
> > -       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -                    CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +       if (!dpi->conf->is_dpintf) {
> 
> define dpi->conf->is_ck_de_pol

done

> 
> > +               mask |= CK_POL | DE_POL;
> > +               pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +                       0 : CK_POL) |
> > +                      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +                       0 : DE_POL);
> > +       }
> > +
> > +       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -231,8 +263,13 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
> >
> >  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
> >  {
> > -       mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> > -       mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> > +       if (dpi->conf->is_dpintf) {
> > +               mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, DPINTF_HSIZE_MASK);
> > +               mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, DPINTF_VSIZE_MASK);
> > +       } else {
> > +               mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> > +               mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> > +       }
> >  }
> >
> >  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
> > @@ -332,12 +369,21 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
> >                 break;
> >         }
> >
> > -       mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
> > +       if (dpi->conf->is_dpintf)
> > +               mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << DPINTF_CH_SWAP,
> > +                            DPINTF_CH_SWAP_MASK);
> > +       else
> > +               mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > +                            CH_SWAP_MASK);
> >  }
> >
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
> >  {
> > -       mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> > +       if (dpi->conf->is_dpintf)
> > +               mtk_dpi_mask(dpi, DPI_CON, enable ? DPINTF_YUV422_EN : 0,
> > +                            DPINTF_YUV422_EN);
> > +       else
> > +               mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> >  }
> >
> >  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
> > @@ -367,19 +413,25 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
> >         if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
> >             (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >                 mtk_dpi_config_yuv422_enable(dpi, false);
> > -               mtk_dpi_config_csc_enable(dpi, true);
> > -               mtk_dpi_config_swap_input(dpi, false);
> > +               if (!dpi->conf->is_dpintf) {
> > +                       mtk_dpi_config_csc_enable(dpi, true);
> 
> define dpi->conf->csc_support
> 
> > +                       mtk_dpi_config_swap_input(dpi, false);
> 
> define dpi->conf->swap_input_support

these two done as well.

> 
> > +               }
> >                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >         } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >                    (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >                 mtk_dpi_config_yuv422_enable(dpi, true);
> > -               mtk_dpi_config_csc_enable(dpi, true);
> > -               mtk_dpi_config_swap_input(dpi, true);
> > +               if (!dpi->conf->is_dpintf) {
> > +                       mtk_dpi_config_csc_enable(dpi, true);
> > +                       mtk_dpi_config_swap_input(dpi, true);
> > +               }
> >                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >         } else {
> >                 mtk_dpi_config_yuv422_enable(dpi, false);
> > -               mtk_dpi_config_csc_enable(dpi, false);
> > -               mtk_dpi_config_swap_input(dpi, false);
> > +               if (!dpi->conf->is_dpintf) {
> > +                       mtk_dpi_config_csc_enable(dpi, false);
> > +                       mtk_dpi_config_swap_input(dpi, false);
> > +               }
> >                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >         }
> >  }
> > @@ -410,6 +462,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
> >                 pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
> >
> >         mtk_dpi_disable(dpi);
> > +       clk_disable_unprepare(dpi->hf_fdp_clk);
> > +       clk_disable_unprepare(dpi->hf_fmm_clk);
> >         clk_disable_unprepare(dpi->pixel_clk);
> >         clk_disable_unprepare(dpi->engine_clk);
> >  }
> > @@ -433,12 +487,28 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> >                 goto err_pixel;
> >         }
> >
> > +       ret = clk_prepare_enable(dpi->hf_fmm_clk);
> > +       if (ret) {
> > +               dev_err(dpi->dev, "Failed to enable hf_fmm clock: %d\n", ret);
> > +               goto err_hf_fmm;
> > +       }
> > +
> > +       ret = clk_prepare_enable(dpi->hf_fdp_clk);
> > +       if (ret) {
> > +               dev_err(dpi->dev, "Failed to enable hf_fdp clock: %d\n", ret);
> > +               goto err_hf_fdp;
> > +       }
> > +
> >         if (dpi->pinctrl && dpi->pins_dpi)
> >                 pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
> >
> >         mtk_dpi_enable(dpi);
> >         return 0;
> >
> > +err_hf_fdp:
> > +       clk_disable_unprepare(dpi->hf_fmm_clk);
> > +err_hf_fmm:
> > +       clk_disable_unprepare(dpi->pixel_clk);
> >  err_pixel:
> >         clk_disable_unprepare(dpi->engine_clk);
> >  err_refcount:
> > @@ -472,22 +542,30 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> >         pll_rate = clk_get_rate(dpi->tvd_clk);
> >
> >         vm.pixelclock = pll_rate / factor;
> > -       if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -           (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +       if (dpi->conf->is_dpintf)
> > +               clk_set_rate(dpi->pixel_clk, vm.pixelclock / 4);
> > +       else if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > +                (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> >                 clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> >         else
> >                 clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> >
> > -
> >         vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >
> >         dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
> >                 pll_rate, vm.pixelclock);
> >
> > -       limit.c_bottom = 0x0010;
> > -       limit.c_top = 0x0FE0;
> > -       limit.y_bottom = 0x0010;
> > -       limit.y_top = 0x0FE0;
> > +       if (dpi->conf->is_dpintf) {
> > +               limit.c_bottom = 0x0000;
> > +               limit.c_top = 0xFFF;
> > +               limit.y_bottom = 0x0000;
> > +               limit.y_top = 0xFFF;
> > +       } else {
> > +               limit.c_bottom = 0x0010;
> > +               limit.c_top = 0x0FE0;
> > +               limit.y_bottom = 0x0010;
> > +               limit.y_top = 0x0FE0;
> > +       }
> >
> >         dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
> >         dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
> > @@ -495,9 +573,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> >                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> >         dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> > -       hsync.sync_width = vm.hsync_len;
> > -       hsync.back_porch = vm.hback_porch;
> > -       hsync.front_porch = vm.hfront_porch;
> > +       if (dpi->conf->is_dpintf) {
> > +               hsync.sync_width = vm.hsync_len / 4;
> > +               hsync.back_porch = vm.hback_porch / 4;
> > +               hsync.front_porch = vm.hfront_porch / 4;
> > +       } else {
> > +               hsync.sync_width = vm.hsync_len;
> > +               hsync.back_porch = vm.hback_porch;
> > +               hsync.front_porch = vm.hfront_porch;
> > +       }
> >         hsync.shift_half_line = false;
> >         vsync_lodd.sync_width = vm.vsync_len;
> >         vsync_lodd.back_porch = vm.vback_porch;
> > @@ -539,11 +623,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> >         mtk_dpi_config_channel_limit(dpi, &limit);
> >         mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >         mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -       mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >         mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -       mtk_dpi_config_2n_h_fre(dpi);
> > -       mtk_dpi_dual_edge(dpi);
> > -       mtk_dpi_config_disable_edge(dpi);
> > +       if (dpi->conf->is_dpintf) {
> > +               mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +                            DPINTF_INPUT_2P_EN);
> > +       } else {
> > +               mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +               mtk_dpi_config_2n_h_fre(dpi);
> > +               mtk_dpi_dual_edge(dpi);
> > +               mtk_dpi_config_disable_edge(dpi);
> > +       }
> >         mtk_dpi_sw_reset(dpi, false);
> >
> >         return 0;
> > @@ -687,6 +776,17 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
> >         .atomic_reset = drm_atomic_helper_bridge_reset,
> >  };
> >
> > +static const struct drm_bridge_funcs mtk_dpintf_bridge_funcs = {
> > +       .attach = mtk_dpi_bridge_attach,
> > +       .mode_set = mtk_dpi_bridge_mode_set,
> > +       .disable = mtk_dpi_bridge_disable,
> > +       .enable = mtk_dpi_bridge_enable,
> > +       .atomic_check = mtk_dpi_bridge_atomic_check,
> > +       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> > +       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +       .atomic_reset = drm_atomic_helper_bridge_reset,
> > +};
> 
> I think mtk_dpintf_bridge_funcs is the same as mtk_dpi_bridge_func, so
> remove this and use mtk_dpi_bridge_func.

They weren't 100% identical as the output formats were missing. I looked
these up in the datasheet and recombined them.

> 
> > +
> >  void mtk_dpi_start(struct device *dev)
> >  {
> >         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> > @@ -781,6 +881,16 @@ static unsigned int mt8183_calculate_factor(int clock)
> >                 return 2;
> >  }
> >
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +       if (clock < 70000)
> > +               return 4;
> > +       else if (clock < 200000)
> > +               return 2;
> > +       else
> > +               return 1;
> > +}
> > +
> >  static const u32 mt8173_output_fmts[] = {
> >         MEDIA_BUS_FMT_RGB888_1X24,
> >  };
> > @@ -796,6 +906,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
> >         .max_clock_khz = 300000,
> >         .output_fmts = mt8173_output_fmts,
> >         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +       .is_dpintf = false,
> 
> Global variable is defualt zero, so remove this.

Done.

> 
> >  };
> >
> >  static const struct mtk_dpi_conf mt2701_conf = {
> > @@ -805,6 +916,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
> >         .max_clock_khz = 150000,
> >         .output_fmts = mt8173_output_fmts,
> >         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +       .is_dpintf = false,
> >  };
> >
> >  static const struct mtk_dpi_conf mt8183_conf = {
> > @@ -813,6 +925,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
> >         .max_clock_khz = 100000,
> >         .output_fmts = mt8183_output_fmts,
> >         .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +       .is_dpintf = false,
> >  };
> >
> >  static const struct mtk_dpi_conf mt8192_conf = {
> > @@ -821,6 +934,12 @@ static const struct mtk_dpi_conf mt8192_conf = {
> >         .max_clock_khz = 150000,
> >         .output_fmts = mt8173_output_fmts,
> >         .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +       .is_dpintf = false,
> > +};
> > +
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +       .cal_factor = mt8195_dpintf_calculate_factor,
> > +       .is_dpintf = true,
> >  };
> >
> >  static int mtk_dpi_probe(struct platform_device *pdev)
> > @@ -866,13 +985,16 @@ static int mtk_dpi_probe(struct platform_device *pdev)
> >                 return ret;
> >         }
> >
> > -       dpi->engine_clk = devm_clk_get(dev, "engine");
> > -       if (IS_ERR(dpi->engine_clk)) {
> > -               ret = PTR_ERR(dpi->engine_clk);
> > -               if (ret != -EPROBE_DEFER)
> > -                       dev_err(dev, "Failed to get engine clock: %d\n", ret);
> > +       if (!dpi->conf->is_dpintf) {
> > +               dpi->engine_clk = devm_clk_get(dev, "engine");
> > +               if (IS_ERR(dpi->engine_clk)) {
> > +                       ret = PTR_ERR(dpi->engine_clk);
> > +                       if (ret != -EPROBE_DEFER)
> > +                               dev_err(dev, "Failed to get engine clock: %d\n",
> > +                                       ret);
> >
> > -               return ret;
> > +                       return ret;
> > +               }
> >         }
> >
> >         dpi->pixel_clk = devm_clk_get(dev, "pixel");
> > @@ -893,6 +1015,24 @@ static int mtk_dpi_probe(struct platform_device *pdev)
> >                 return ret;
> >         }
> >
> > +       dpi->hf_fmm_clk = devm_clk_get_optional(dev, "hf_fmm");
> > +       if (IS_ERR(dpi->hf_fmm_clk)) {
> > +               ret = PTR_ERR(dpi->hf_fmm_clk);
> > +               if (ret != -EPROBE_DEFER)
> > +                       dev_err(dev, "Failed to get hf_fmm clock: %d\n", ret);
> > +
> > +               return ret;
> > +       }
> > +
> > +       dpi->hf_fdp_clk = devm_clk_get_optional(dev, "hf_fdp");
> > +       if (IS_ERR(dpi->hf_fdp_clk)) {
> > +               ret = PTR_ERR(dpi->hf_fdp_clk);
> > +               if (ret != -EPROBE_DEFER)
> > +                       dev_err(dev, "Failed to get hf_fdp clock: %d\n", ret);
> > +
> > +               return ret;
> > +       }
> 
> You does not send the device tree patch, so I found one in chromium
> gerrit [1]. Compare the clock of disp_dpi1 with dp_intf1, I think
> hf_fdp is likely the pixel clock and hf_fmm is likely the engine
> clock. Could you provide the information of the function of each
> clock?

Thank you. I checked with the original author and can now confirm that
they can be mapped to engine and pixel clock. I fixed that. Also the now
fdp_clk is the direct parent of the current pixel clock, so there was no
need for it. So basically it is now reduced to the clocks of the
original dpi driver again. That also means that I am removing the
separate binding document as there is no difference other than the name
of the block.

Thank you for your feedback Chun-Kuang.

Best,
Markus

> 
> [1] https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/changes/99/2781499/219/arch/arm64/boot/dts/mediatek/mt8195.dtsi#3499
> 
> Regards,
> Chun-Kuang.
> 
> > +
> >         dpi->irq = platform_get_irq(pdev, 0);
> >         if (dpi->irq <= 0)
> >                 return -EINVAL;
> > @@ -906,7 +1046,10 @@ static int mtk_dpi_probe(struct platform_device *pdev)
> >
> >         platform_set_drvdata(pdev, dpi);
> >
> > -       dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
> > +       if (dpi->conf->is_dpintf)
> > +               dpi->bridge.funcs = &mtk_dpintf_bridge_funcs;
> > +       else
> > +               dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
> >         dpi->bridge.of_node = dev->of_node;
> >         dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
> >
> > @@ -945,6 +1088,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
> >         { .compatible = "mediatek,mt8192-dpi",
> >           .data = &mt8192_conf,
> >         },
> > +       { .compatible = "mediatek,mt8195-dpintf",
> > +         .data = &mt8195_dpintf_conf,
> > +       },
> >         { },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..72efe6ee2584 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,14 @@
> >  #define FAKE_DE_LEVEN                  BIT(21)
> >  #define FAKE_DE_RODD                   BIT(22)
> >  #define FAKE_DE_REVEN                  BIT(23)
> > +#define DPINTF_YUV422_EN               BIT(24)
> > +#define DPINTF_INPUT_2P_EN             BIT(29)
> >
> >  #define DPI_OUTPUT_SETTING     0x14
> >  #define CH_SWAP                                0
> > +#define DPINTF_CH_SWAP                 BIT(1)
> >  #define CH_SWAP_MASK                   (0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK            (0x7 << 1)
> >  #define SWAP_RGB                       0x00
> >  #define SWAP_GBR                       0x01
> >  #define SWAP_BRG                       0x02
> > @@ -80,8 +84,10 @@
> >  #define DPI_SIZE               0x18
> >  #define HSIZE                          0
> >  #define HSIZE_MASK                     (0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK              (0xFFFF << 0)
> >  #define VSIZE                          16
> >  #define VSIZE_MASK                     (0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK              (0xFFFF << 16)
> >
> >  #define DPI_DDR_SETTING                0x1C
> >  #define DDR_EN                         BIT(0)
> > @@ -93,24 +99,30 @@
> >  #define DPI_TGEN_HWIDTH                0x20
> >  #define HPW                            0
> >  #define HPW_MASK                       (0xFFF << 0)
> > +#define DPINTF_HPW_MASK                        (0xFFFF << 0)
> >
> >  #define DPI_TGEN_HPORCH                0x24
> >  #define HBP                            0
> >  #define HBP_MASK                       (0xFFF << 0)
> > +#define DPINTF_HBP_MASK                        (0xFFFF << 0)
> >  #define HFP                            16
> >  #define HFP_MASK                       (0xFFF << 16)
> > +#define DPINTF_HFP_MASK                        (0xFFFF << 16)
> >
> >  #define DPI_TGEN_VWIDTH                0x28
> >  #define DPI_TGEN_VPORCH                0x2C
> >
> >  #define VSYNC_WIDTH_SHIFT              0
> >  #define VSYNC_WIDTH_MASK               (0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK                (0xFFFF << 0)
> >  #define VSYNC_HALF_LINE_SHIFT          16
> >  #define VSYNC_HALF_LINE_MASK           BIT(16)
> >  #define VSYNC_BACK_PORCH_SHIFT         0
> >  #define VSYNC_BACK_PORCH_MASK          (0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK   (0xFFFF << 0)
> >  #define VSYNC_FRONT_PORCH_SHIFT                16
> >  #define VSYNC_FRONT_PORCH_MASK         (0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK  (0xFFFF << 16)
> >
> >  #define DPI_BG_HCNTL           0x30
> >  #define BG_RIGHT                       (0x1FFF << 0)
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 99cbf44463e4..da9e059312a5 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -317,6 +317,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >         [MTK_DISP_UFOE] = "ufoe",
> >         [MTK_DSI] = "dsi",
> >         [MTK_DPI] = "dpi",
> > +       [MTK_DP_INTF] = "dp-intf",
> >         [MTK_DISP_PWM] = "pwm",
> >         [MTK_DISP_MUTEX] = "mutex",
> >         [MTK_DISP_OD] = "od",
> > @@ -339,6 +340,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0, &ddp_dither },
> >         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi },
> >         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi },
> > +       [DDP_COMPONENT_DP_INTF0]= { MTK_DP_INTF,        0, &ddp_dpi },
> > +       [DDP_COMPONENT_DP_INTF1]= { MTK_DP_INTF,        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 },
> > @@ -476,6 +479,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
> >             type == MTK_DISP_COLOR ||
> >             type == MTK_DISP_GAMMA ||
> >             type == MTK_DPI ||
> > +           type == MTK_DP_INTF ||
> >             type == MTK_DSI ||
> >             type == MTK_DISP_OVL ||
> >             type == MTK_DISP_OVL_2L ||
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index bb914d976cf5..ee9d853cfa1c 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
> >         MTK_DISP_UFOE,
> >         MTK_DSI,
> >         MTK_DPI,
> > +       MTK_DP_INTF,
> >         MTK_DISP_PWM,
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index aec39724ebeb..1ff4e31c8634 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -459,6 +459,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> >           .data = (void *)MTK_DPI },
> >         { .compatible = "mediatek,mt8183-dpi",
> >           .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt8195-dpintf",
> > +         .data = (void *)MTK_DP_INTF },
> >         { .compatible = "mediatek,mt2701-disp-mutex",
> >           .data = (void *)MTK_DISP_MUTEX },
> >         { .compatible = "mediatek,mt2712-disp-mutex",
> > @@ -569,7 +571,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
> >                     comp_type == MTK_DISP_OVL_2L ||
> >                     comp_type == MTK_DISP_RDMA ||
> >                     comp_type == MTK_DSI ||
> > -                   comp_type == MTK_DPI) {
> > +                   comp_type == MTK_DPI ||
> > +                   comp_type == MTK_DP_INTF) {
> >                         dev_info(dev, "Adding component match for %pOF\n",
> >                                  node);
> >                         drm_of_component_match_add(dev, &match, compare_of,
> > --
> > 2.33.0
> >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-10-20 19:10 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-01  9:44 [PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver Markus Schneider-Pargmann
2021-10-01  9:44 ` [PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding Markus Schneider-Pargmann
2021-10-01  9:44 ` [PATCH v3 2/6] dt-bindings: mediatek,dp: Add Display Port binding Markus Schneider-Pargmann
2021-10-01  9:44 ` [PATCH v3 3/6] drm/edid: Add cea_sad helpers for freq/length Markus Schneider-Pargmann
2021-10-01  9:44 ` [PATCH v3 4/6] video/hdmi: Add audio_infoframe packing for DP Markus Schneider-Pargmann
2021-10-01  9:44 ` [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support Markus Schneider-Pargmann
2021-10-14 16:04   ` Chun-Kuang Hu
2021-10-20 19:08     ` Markus Schneider-Pargmann
     [not found] ` <20211001094443.2770169-7-msp@baylibre.com>
2021-10-01 16:16   ` [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver Chun-Kuang Hu
2021-10-05  7:16     ` Markus Schneider-Pargmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).