Skip to contentSkip to conversation

Add StarFive JH7110 SoC DSI support

PATCH Superseded Shengyang Chen 3 participants 6 messages Feb 6, 2024 – Feb 22, 2024

Subsystems (4)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover Add StarFive JH7110 SoC DSI support

This series is the series that attempts to support the CDNS DSI driver used to converts DPI to DSI. CDNS DSI is embedded in StarFive JH7110 SoC. The series has been tested on the VisionFive 2 board.

change since v2:
- Rebased on tag v6.8-rc3.

patch 1:
- Modify commit message and patch subject
- Change 'starfve,jh7110-dsi' to 'starfive,jh7110-dsi'
- Add constraints for reset-names and clock names
- Add resets, reset-names attribute
- Correct reset and clock names

patch 2:
- Modify commit message and patch subject
- Drop useless MAINTAINERS modification
- Change callback name from 'update' to 'mode_fixup'
- Optimize the mode_fixup function.
- Change devm_reset_control_get() to devm_reset_control_get_exclusive()
- Correct reset and clock names

v2: https://patchwork.kernel.org/project/dri-devel/cover/[email protected]/

changes since v1:
- Rebased on tag v6.7.

patch 1:
- Changed the 'starfive,cdns-dsi' to 'starfve,jh7110-dsi'.
- Changed the compatible enum alphabetical order.
- Restrict other variants.
- Drop 'dsi_' prefix.

patch 2:
- Optimize the calculation process.
- Drop useless definition.

v1: https://patchwork.kernel.org/project/dri-devel/cover/[email protected]/

Keith Zhao (2):
dt-bindings: display: bridge: cdns: Add display bridge support for dsi
on StarFive JH7110 SoC
drm/bridge: cdns-dsi: Add support for StarFive JH7110 SoC

 .../bindings/display/bridge/cdns,dsi.yaml     |  56 ++++-
 drivers/gpu/drm/bridge/cadence/Kconfig        |   7 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-dsi-core.c    |  29 ++-
 .../gpu/drm/bridge/cadence/cdns-dsi-core.h    |  21 ++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.c  | 193 ++++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.h  |  16 ++
 7 files changed, 320 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h
Signature · 1 line
2.17.1
#1 lore raw

PATCH v3 1/2 dt-bindings: display: bridge: cdns: Add display bridge support for dsi on StarFive JH7110 SoC

From: Keith Zhao <[email protected]>

Add compatible to support dsi bridge on StarFive JH7110 SoC

---
 .../bindings/display/bridge/cdns,dsi.yaml     | 56 ++++++++++++++++++-
 1 file changed, 54 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml +54 -2
index 23060324d16e..4ad0ecaacaae 100644
@@ -16,6 +16,7 @@ properties:
   compatible:
     enum:
       - cdns,dsi
+      - starfive,jh7110-dsi
       - ti,j721e-dsi
 
   reg:
@@ -27,14 +28,20 @@ properties:
           Register block for wrapper settings registers in case of TI J7 SoCs.
 
   clocks:
+    minItems: 2
     items:
       - description: PSM clock, used by the IP
       - description: sys clock, used by the IP
+      - description: dpi clock, used by the IP
+      - description: txesc clock, used by the IP
 
   clock-names:
+    minItems: 2
     items:
       - const: dsi_p_clk
       - const: dsi_sys_clk
+      - const: dpi
+      - const: txesc
 
   phys:
     maxItems: 1
@@ -46,10 +53,22 @@ properties:
     maxItems: 1
 
   resets:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: apb reset, associated to dsi_p_clk
+      - description: sys reset, associated to sys clock
+      - description: dpi reset, associated to dpi clock
+      - description: txesc reset, associated to txesc clock
+      - description: txbytehs reset, associated to txbytehs clock
 
   reset-names:
-    const: dsi_p_rst
+    minItems: 1
+    items:
+      - const: dsi_p_rst
+      - const: sys
+      - const: dpi
+      - const: txesc
+      - const: txbytehs
 
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
@@ -90,6 +109,39 @@ allOf:
         reg:
           maxItems: 1
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: starfive,jh7110-dsi
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          minItems: 4
+          maxItems: 4
+        resets:
+          minItems: 5
+          maxItems: 5
+        reset-names:
+          minItems: 5
+          maxItems: 5
+      required:
+        - resets
+        - reset-names
+    else:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          maxItems: 2
+        resets:
+          maxItems: 1
+        reset-names:
+          maxItems: 1
+
 required:
   - compatible
   - reg
Signature · 1 line
2.17.1
#3 lore raw

PATCH v3 2/2 drm/bridge: cdns-dsi: Add support for StarFive JH7110 SoC

In reply to Shengyang Chen

From: Keith Zhao <[email protected]>

Add display bridge support for dsi on StarFive JH7110 SoC.

The mainly modification is followed:
1.Add extra clock and reset operation for JH7110. 2.Add callback for JH7110.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   7 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-dsi-core.c    |  29 ++-
 .../gpu/drm/bridge/cadence/cdns-dsi-core.h    |  21 ++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.c  | 193 ++++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.h  |  16 ++
 6 files changed, 266 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h
drivers/gpu/drm/bridge/cadence/Kconfig +7 -0
index cced81633ddc..ad9f572f4720 100644
@@ -19,6 +19,13 @@ config DRM_CDNS_DSI_J721E
 	help
 	  Support J721E Cadence DSI wrapper. The wrapper manages
 	  the routing of the DSS DPI signal to the Cadence DSI.
+
+config DRM_CDNS_DSI_JH7110
+	bool "JH7110 SOC Cadence DSI support"
+	default n
+	help
+	  Cadence DPI to DSI bridge which is embedded in the
+	  StarFive JH7110 SoC.
 endif
 
 config DRM_CDNS_MHDP8546
drivers/gpu/drm/bridge/cadence/Makefile +1 -0
index c95fd5b81d13..87f603a9f4ad 100644
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 cdns-dsi-y := cdns-dsi-core.o
 cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+cdns-dsi-$(CONFIG_DRM_CDNS_DSI_JH7110) += cdns-dsi-jh7110.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +28 -1
index 7457d38622b0..c0c81745e765 100644
@@ -27,6 +27,10 @@
 #include "cdns-dsi-j721e.h"
 #endif
 
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+#include "cdns-dsi-jh7110.h"
+#endif
+
 #define IP_CONF				0x0
 #define SP_HS_FIFO_DEPTH(x)		(((x) & GENMASK(30, 26)) >> 26)
 #define SP_LP_FIFO_DEPTH(x)		(((x) & GENMASK(25, 21)) >> 21)
@@ -552,6 +556,10 @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi,
 	/* data rate was in bytes/sec, convert to bits/sec. */
 	phy_cfg->hs_clk_rate = dlane_bps * 8;
 
+	if (dsi->platform_ops && dsi->platform_ops->mode_fixup)
+		adj_dsi_htotal = dsi->platform_ops->mode_fixup(dsi, dsi_cfg, phy_cfg,
+							   dpi_hz, dpi_htotal, dsi_htotal);
+
 	dsi_hfp_ext = adj_dsi_htotal - dsi_htotal;
 	dsi_cfg->hfp += dsi_hfp_ext;
 	dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext;
@@ -683,7 +691,7 @@ static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge)
 	pm_runtime_put(dsi->base.dev);
 }
 
-static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
+void cdns_dsi_hs_init(struct cdns_dsi *dsi)
 {
 	struct cdns_dsi_output *output = &dsi->output;
 	u32 status;
@@ -1026,6 +1034,14 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
 
 	cdns_dsi_init_link(dsi);
 
+	/*
+	 * on JH7110 SoC , when transfer dsi command ,
+	 * cdns_dsi_hs_init is needed.
+	 * or the final ret will be error value.
+	 */
+	if (dsi->platform_ops && dsi->platform_ops->transfer)
+		dsi->platform_ops->transfer(dsi);
+
 	ret = mipi_dsi_create_packet(&packet, msg);
 	if (ret)
 		goto out;
@@ -1142,6 +1158,9 @@ static int __maybe_unused cdns_dsi_resume(struct device *dev)
 	clk_prepare_enable(dsi->dsi_p_clk);
 	clk_prepare_enable(dsi->dsi_sys_clk);
 
+	if (dsi->platform_ops && dsi->platform_ops->resume)
+		dsi->platform_ops->resume(dsi);
+
 	return 0;
 }
 
@@ -1152,6 +1171,10 @@ static int __maybe_unused cdns_dsi_suspend(struct device *dev)
 	clk_disable_unprepare(dsi->dsi_sys_clk);
 	clk_disable_unprepare(dsi->dsi_p_clk);
 	reset_control_assert(dsi->dsi_p_rst);
+
+	if (dsi->platform_ops && dsi->platform_ops->suspend)
+		dsi->platform_ops->suspend(dsi);
+
 	dsi->link_initialized = false;
 	return 0;
 }
@@ -1294,6 +1317,10 @@ static const struct of_device_id cdns_dsi_of_match[] = {
 #ifdef CONFIG_DRM_CDNS_DSI_J721E
 	{ .compatible = "ti,j721e-dsi", .data = &dsi_ti_j721e_ops, },
 #endif
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+	{ .compatible = "starfive,jh7110-dsi", .data = &dsi_ti_jh7110_ops, },
+#endif
+
 	{ },
 };
 MODULE_DEVICE_TABLE(of, cdns_dsi_of_match);
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +21 -0
index ca7ea2da635c..0a86495ead7b 100644
@@ -53,12 +53,22 @@ struct cdns_dsi;
  * @deinit: Called in the CDNS DSI remove
  * @enable: Called at the beginning of CDNS DSI bridge enable
  * @disable: Called at the end of CDNS DSI bridge disable
+ * @resume: Called at the resume of CDNS DSI
+ * @suspend: Called at the suspend of CDNS DSI
+ * @update: Called at the middle of CDNS DSI bridge enable
  */
 struct cdns_dsi_platform_ops {
 	int (*init)(struct cdns_dsi *dsi);
 	void (*deinit)(struct cdns_dsi *dsi);
 	void (*enable)(struct cdns_dsi *dsi);
 	void (*disable)(struct cdns_dsi *dsi);
+	void (*resume)(struct cdns_dsi *dsi);
+	void (*suspend)(struct cdns_dsi *dsi);
+	int (*mode_fixup)(struct cdns_dsi *dsi, struct cdns_dsi_cfg *dsi_cfg,
+			  struct phy_configure_opts_mipi_dphy *phy_cfg,
+			  unsigned long dpi_hz, unsigned long dpi_htotal,
+			  unsigned long dsi_htotal);
+	void (*transfer)(struct cdns_dsi *dsi);
 };
 
 struct cdns_dsi {
@@ -79,6 +89,17 @@ struct cdns_dsi {
 	bool link_initialized;
 	bool phy_initialized;
 	struct phy *dphy;
+
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+	struct clk *dpi_clk;
+	struct clk *txesc_clk;
+	struct reset_control *dpi_rst;
+	struct reset_control *sys_rst;
+	struct reset_control *txesc_rst;
+	struct reset_control *txbytehs_rst;
+#endif
 };
 
+void cdns_dsi_hs_init(struct cdns_dsi *dsi);
+
 #endif /* !__CDNS_DSI_H__ */
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +193 -0

193 lines not on this page · raw message

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h new file +16 -0
new file mode 100644
index 000000000000..15d6a766b502
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * JH7110 Cadence DSI
+ *
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ * Author: keith.zhao <[email protected]>
+ */
+
+#ifndef __CDNS_DSI_JH7110_H__
+#define __CDNS_DSI_JH7110_H__
+
+#include "cdns-dsi-core.h"
+
+extern const struct cdns_dsi_platform_ops dsi_ti_jh7110_ops;
+
+#endif /* !__CDNS_DSI_JH7110_H__ */
Signature · 1 line
2.17.1
#4 lore raw

Re: [PATCH v3 2/2] drm/bridge: cdns-dsi: Add support for StarFive JH7110 SoC

Quoted 212 lines · Shengyang Chen

From: Keith Zhao <[email protected]>

Add display bridge support for dsi on StarFive JH7110 SoC.

The mainly modification is followed:
1.Add extra clock and reset operation for JH7110. 2.Add callback for JH7110.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   7 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-dsi-core.c    |  29 ++-
 .../gpu/drm/bridge/cadence/cdns-dsi-core.h    |  21 ++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.c  | 193 ++++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.h  |  16 ++
 6 files changed, 266 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h
drivers/gpu/drm/bridge/cadence/Kconfig +7 -0
index cced81633ddc..ad9f572f4720 100644
@@ -19,6 +19,13 @@ config DRM_CDNS_DSI_J721E
        help
          Support J721E Cadence DSI wrapper. The wrapper manages
          the routing of the DSS DPI signal to the Cadence DSI.
+
+config DRM_CDNS_DSI_JH7110
+       bool "JH7110 SOC Cadence DSI support"
+       default n
+       help
+         Cadence DPI to DSI bridge which is embedded in the
+         StarFive JH7110 SoC.
 endif
 
 config DRM_CDNS_MHDP8546
drivers/gpu/drm/bridge/cadence/Makefile +1 -0
index c95fd5b81d13..87f603a9f4ad 100644
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 cdns-dsi-y := cdns-dsi-core.o
 cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+cdns-dsi-$(CONFIG_DRM_CDNS_DSI_JH7110) += cdns-dsi-jh7110.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +28 -1
index 7457d38622b0..c0c81745e765 100644
@@ -27,6 +27,10 @@
 #include "cdns-dsi-j721e.h"
 #endif
 
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+#include "cdns-dsi-jh7110.h"
+#endif
+
 #define IP_CONF                                0x0
 #define SP_HS_FIFO_DEPTH(x)            (((x) & GENMASK(30, 26)) >> 26)
 #define SP_LP_FIFO_DEPTH(x)            (((x) & GENMASK(25, 21)) >> 21)
@@ -552,6 +556,10 @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi,
        /* data rate was in bytes/sec, convert to bits/sec. */
        phy_cfg->hs_clk_rate = dlane_bps * 8;
 
+       if (dsi->platform_ops && dsi->platform_ops->mode_fixup)
+               adj_dsi_htotal = dsi->platform_ops->mode_fixup(dsi, dsi_cfg, phy_cfg,
+                                                          dpi_hz, dpi_htotal, dsi_htotal);
+
        dsi_hfp_ext = adj_dsi_htotal - dsi_htotal;
        dsi_cfg->hfp += dsi_hfp_ext;
        dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext;
@@ -683,7 +691,7 @@ static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge)
        pm_runtime_put(dsi->base.dev);
 }
 
-static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
+void cdns_dsi_hs_init(struct cdns_dsi *dsi)
 {
        struct cdns_dsi_output *output = &dsi->output;
        u32 status;
@@ -1026,6 +1034,14 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
 
        cdns_dsi_init_link(dsi);
 
+       /*
+        * on JH7110 SoC , when transfer dsi command ,
+        * cdns_dsi_hs_init is needed.
+        * or the final ret will be error value.
+        */
+       if (dsi->platform_ops && dsi->platform_ops->transfer)
+               dsi->platform_ops->transfer(dsi);
+
        ret = mipi_dsi_create_packet(&packet, msg);
        if (ret)
                goto out;
@@ -1142,6 +1158,9 @@ static int __maybe_unused cdns_dsi_resume(struct device *dev)
        clk_prepare_enable(dsi->dsi_p_clk);
        clk_prepare_enable(dsi->dsi_sys_clk);
 
+       if (dsi->platform_ops && dsi->platform_ops->resume)
+               dsi->platform_ops->resume(dsi);
+
        return 0;
 }
 
@@ -1152,6 +1171,10 @@ static int __maybe_unused cdns_dsi_suspend(struct device *dev)
        clk_disable_unprepare(dsi->dsi_sys_clk);
        clk_disable_unprepare(dsi->dsi_p_clk);
        reset_control_assert(dsi->dsi_p_rst);
+
+       if (dsi->platform_ops && dsi->platform_ops->suspend)
+               dsi->platform_ops->suspend(dsi);
+
        dsi->link_initialized = false;
        return 0;
 }
@@ -1294,6 +1317,10 @@ static const struct of_device_id cdns_dsi_of_match[] = {
 #ifdef CONFIG_DRM_CDNS_DSI_J721E
        { .compatible = "ti,j721e-dsi", .data = &dsi_ti_j721e_ops, },
 #endif
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+       { .compatible = "starfive,jh7110-dsi", .data = &dsi_ti_jh7110_ops, },
+#endif
+
        { },
 };
 MODULE_DEVICE_TABLE(of, cdns_dsi_of_match);
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +21 -0
index ca7ea2da635c..0a86495ead7b 100644
@@ -53,12 +53,22 @@ struct cdns_dsi;
  * @deinit: Called in the CDNS DSI remove
  * @enable: Called at the beginning of CDNS DSI bridge enable
  * @disable: Called at the end of CDNS DSI bridge disable
+ * @resume: Called at the resume of CDNS DSI
+ * @suspend: Called at the suspend of CDNS DSI
+ * @update: Called at the middle of CDNS DSI bridge enable
  */
 struct cdns_dsi_platform_ops {
        int (*init)(struct cdns_dsi *dsi);
        void (*deinit)(struct cdns_dsi *dsi);
        void (*enable)(struct cdns_dsi *dsi);
        void (*disable)(struct cdns_dsi *dsi);
+       void (*resume)(struct cdns_dsi *dsi);
+       void (*suspend)(struct cdns_dsi *dsi);
+       int (*mode_fixup)(struct cdns_dsi *dsi, struct cdns_dsi_cfg *dsi_cfg,
+                         struct phy_configure_opts_mipi_dphy *phy_cfg,
+                         unsigned long dpi_hz, unsigned long dpi_htotal,
+                         unsigned long dsi_htotal);
+       void (*transfer)(struct cdns_dsi *dsi);
 };
 
 struct cdns_dsi {
@@ -79,6 +89,17 @@ struct cdns_dsi {
        bool link_initialized;
        bool phy_initialized;
        struct phy *dphy;
+
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+       struct clk *dpi_clk;
+       struct clk *txesc_clk;
+       struct reset_control *dpi_rst;
+       struct reset_control *sys_rst;
+       struct reset_control *txesc_rst;
+       struct reset_control *txbytehs_rst;
+#endif
 };
 
+void cdns_dsi_hs_init(struct cdns_dsi *dsi);
+
 #endif /* !__CDNS_DSI_H__ */
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +27 -0
new file mode 100644
index 000000000000..c6b9296a9275
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * JH7110 SoC Cadence DSI wrapper
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/reset.h>
+
+#include "cdns-dsi-jh7110.h"
+
+static int cdns_dsi_clock_enable(struct cdns_dsi *dsi, struct device *dev)
+{
+       int ret;
+
+       ret = clk_prepare_enable(dsi->dpi_clk);
+       if (ret) {
+               dev_err(dev, "Failed to prepare/enable dpi_clk\n");
+               return ret;
+       }
+
+       ret = clk_prepare_enable(dsi->txesc_clk);
+       if (ret) {
+               dev_err(dev, "Failed to prepare/enable txesc_clk\n");

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 37

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+               return ret;
+       }
+
+       return ret;
+}
+
+static void cdns_dsi_clock_disable(struct cdns_dsi *dsi)
+{
+       clk_disable_unprepare(dsi->dpi_clk);
+       clk_disable_unprepare(dsi->txesc_clk);

Please use clk_bulk_ API and inline these two functions.

Quoted 13 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +13 -0
+}
+
+static int cdns_dsi_resets_deassert(struct cdns_dsi *dsi, struct device *dev)
+{
+       int ret;
+
+       ret = reset_control_deassert(dsi->dpi_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert dpi_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(dsi->txesc_rst);

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 60

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert txesc_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(dsi->sys_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert sys_rst\n");
+               return ret;
+       }

Same, please use reset_control_bulk API.

Quoted 104 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +104 -0
+
+       return ret;
+}
+
+static int cdns_dsi_resets_assert(struct cdns_dsi *dsi, struct device *dev)
+{
+       int ret;
+
+       ret = reset_control_assert(dsi->dpi_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert dpi_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_assert(dsi->txesc_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert txesc_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_assert(dsi->sys_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert sys_rst\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int cdns_dsi_get_clock(struct device *dev, struct cdns_dsi *dsi)
+{
+       dsi->dpi_clk = devm_clk_get(dev, "dpi");
+       if (IS_ERR(dsi->dpi_clk))
+               return PTR_ERR(dsi->dpi_clk);
+
+       dsi->txesc_clk = devm_clk_get(dev, "txesc");
+       if (IS_ERR(dsi->txesc_clk))
+               return PTR_ERR(dsi->txesc_clk);
+
+       return 0;
+}
+
+static int cdns_dsi_get_reset(struct device *dev, struct cdns_dsi *dsi)
+{
+       dsi->sys_rst = devm_reset_control_get_exclusive(dev, "sys");
+       if (IS_ERR(dsi->sys_rst))
+               return PTR_ERR(dsi->sys_rst);
+
+       dsi->dpi_rst = devm_reset_control_get_exclusive(dev, "dpi");
+       if (IS_ERR(dsi->dpi_rst))
+               return PTR_ERR(dsi->dpi_rst);
+
+       dsi->txesc_rst = devm_reset_control_get_exclusive(dev, "txesc");
+       if (IS_ERR(dsi->txesc_rst))
+               return PTR_ERR(dsi->txesc_rst);
+
+       dsi->txbytehs_rst = devm_reset_control_get_exclusive(dev, "txbytehs");
+       if (IS_ERR(dsi->txbytehs_rst))
+               return PTR_ERR(dsi->txbytehs_rst);
+
+       return 0;
+}
+
+static int cdns_dsi_jh7110_init(struct cdns_dsi *dsi)
+{
+       int ret;
+
+       ret = cdns_dsi_get_clock(dsi->base.dev, dsi);
+       if (ret)
+               return ret;
+
+       return cdns_dsi_get_reset(dsi->base.dev, dsi);
+}
+
+static void cdns_dsi_jh7110_resume(struct cdns_dsi *dsi)
+{
+       int ret;
+
+       ret = cdns_dsi_clock_enable(dsi, dsi->base.dev);
+       if (ret) {
+               dev_err(dsi->base.dev, "failed to enable clock\n");
+               return;
+       }
+       ret = cdns_dsi_resets_deassert(dsi, dsi->base.dev);
+       if (ret < 0) {
+               dev_err(dsi->base.dev, "failed to deassert reset\n");
+               return;
+       }
+}
+
+static void cdns_dsi_jh7110_suspend(struct cdns_dsi *dsi)
+{
+       int ret;
+
+       ret = cdns_dsi_resets_assert(dsi, dsi->base.dev);
+       if (ret < 0) {
+               dev_err(dsi->base.dev, "failed to deassert reset\n");
+               return;
+       }
+
+       cdns_dsi_clock_disable(dsi);
+}
+
+static int cdns_dsi_jh7110_mode_fixup(struct cdns_dsi *dsi, struct cdns_dsi_cfg *dsi_cfg,

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 174

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+                                     struct phy_configure_opts_mipi_dphy *phy_cfg,
+                                     unsigned long dpi_hz, unsigned long dpi_htotal,
+                                     unsigned long dsi_htotal)
+{
+       unsigned long long dlane_bps;
+       unsigned long adj_dsi_htotal;
+       unsigned int lanes = dsi->output.dev->lanes;
+
+       phy_cfg->hs_clk_rate = phy_cfg->hs_clk_rate - (phy_cfg->hs_clk_rate % 10000000);
+       phy_cfg->hs_clk_rate += 100000000;

phy_cfg->hs_clk_rate = roundup(phy_cfg->hs_clk_rate, 100000000);

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 184

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+       dlane_bps = phy_cfg->hs_clk_rate * lanes * dpi_htotal / 8;
+       adj_dsi_htotal = dlane_bps / dpi_hz;
+
+       return adj_dsi_htotal;
+}
+
+static void jh7110_cdns_dsi_hs_init(struct cdns_dsi *dsi)
+{
+       cdns_dsi_hs_init(dsi);
+       reset_control_deassert(dsi->txbytehs_rst);

Is a single deassert enough here? Which funciion asserts the reset?

Quoted 34 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +9 -0
+}
+
+const struct cdns_dsi_platform_ops dsi_ti_jh7110_ops = {
+       .init = cdns_dsi_jh7110_init,
+       .resume = cdns_dsi_jh7110_resume,
+       .suspend = cdns_dsi_jh7110_suspend,
+       .mode_fixup = cdns_dsi_jh7110_mode_fixup,
+       .transfer = jh7110_cdns_dsi_hs_init,
+};
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h new file +16 -1
new file mode 100644
index 000000000000..15d6a766b502
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * JH7110 Cadence DSI
+ *
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ * Author: keith.zhao <[email protected]>
+ */
+
+#ifndef __CDNS_DSI_JH7110_H__
+#define __CDNS_DSI_JH7110_H__
+
+#include "cdns-dsi-core.h"
+
+extern const struct cdns_dsi_platform_ops dsi_ti_jh7110_ops;
+
+#endif /* !__CDNS_DSI_JH7110_H__ */
--

2.17.1

Signature · 2 lines
With best wishes
Dmitry
#5 lore raw

RE: [PATCH v3 2/2] drm/bridge: cdns-dsi: Add support for StarFive JH7110 SoC

Hi, Dmitry

Thanks for review and comment.

Quoted 254 lines

-----Original Message-----
From: Dmitry Baryshkov <[email protected]>
Sent: 2024年2月7日 18:58
To: Shengyang Chen <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Changhuang Liang <[email protected]>; Keith Zhao <[email protected]>; Jack Zhu <[email protected]>; [email protected]
Subject: Re: [PATCH v3 2/2] drm/bridge: cdns-dsi: Add support for StarFive JH7110 SoC

Quoted 49 lines · Shengyang Chen

From: Keith Zhao <[email protected]>

Add display bridge support for dsi on StarFive JH7110 SoC.

The mainly modification is followed:
1.Add extra clock and reset operation for JH7110. 2.Add callback for JH7110.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   7 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-dsi-core.c    |  29 ++-
 .../gpu/drm/bridge/cadence/cdns-dsi-core.h    |  21 ++
 .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.c  | 193
++++++++++++++++++  .../gpu/drm/bridge/cadence/cdns-dsi-jh7110.h  |
16 ++
 6 files changed, 266 insertions(+), 1 deletion(-)  create mode 100644
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h
drivers/gpu/drm/bridge/cadence/Kconfig +7 -0
index cced81633ddc..ad9f572f4720 100644
@@ -19,6 +19,13 @@ config DRM_CDNS_DSI_J721E
        help
          Support J721E Cadence DSI wrapper. The wrapper manages
          the routing of the DSS DPI signal to the Cadence DSI.
+
+config DRM_CDNS_DSI_JH7110
+       bool "JH7110 SOC Cadence DSI support"
+       default n
+       help
+         Cadence DPI to DSI bridge which is embedded in the
+         StarFive JH7110 SoC.
 endif
 
 config DRM_CDNS_MHDP8546
drivers/gpu/drm/bridge/cadence/Makefile +0 -0
index c95fd5b81d13..87f603a9f4ad 100644
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o  cdns-dsi-y :=
Quoted 4 lines

cdns-dsi-core.o
cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+cdns-dsi-$(CONFIG_DRM_CDNS_DSI_JH7110) += cdns-dsi-jh7110.o
obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o

cdns-mhdp8546-y

Quoted 9 lines

:= cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) +=
cdns-mhdp8546-j721e.o diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 7457d38622b0..c0c81745e765 100644

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c line 35

Quoted 9 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +4 -0
@@ -27,6 +27,10 @@
 #include "cdns-dsi-j721e.h"
 #endif
 
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+#include "cdns-dsi-jh7110.h"
+#endif
+
 #define IP_CONF                                0x0
 #define SP_HS_FIFO_DEPTH(x)            (((x) & GENMASK(30, 26)) >>

26)

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c line 36

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +0 -0
 #define SP_LP_FIFO_DEPTH(x)            (((x) & GENMASK(25, 21)) >>

21)

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c static int cdns_dsi_adjust_phy_config(struct cdns_dsi

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +0 -0
@@ -552,6 +556,10 @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi

*dsi,

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi,

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +2 -0
        /* data rate was in bytes/sec, convert to bits/sec. */
        phy_cfg->hs_clk_rate = dlane_bps * 8;
 
+       if (dsi->platform_ops && dsi->platform_ops->mode_fixup)
+               adj_dsi_htotal = dsi->platform_ops->mode_fixup(dsi,

dsi_cfg, phy_cfg,

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c static int cdns_dsi_adjust_phy_config(struct cdns_dsi · line 561

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +1 -0
+

dpi_hz,

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c static int __maybe_unused cdns_dsi_resume(struct

Quoted 30 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +2 -0
+ dpi_htotal, dsi_htotal);
+
        dsi_hfp_ext = adj_dsi_htotal - dsi_htotal;
        dsi_cfg->hfp += dsi_hfp_ext;
        dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext; @@ -683,7 +691,7

@@ static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge)

        pm_runtime_put(dsi->base.dev);  }
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +9 -1
-static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
+void cdns_dsi_hs_init(struct cdns_dsi *dsi)
 {
        struct cdns_dsi_output *output = &dsi->output;
        u32 status;
@@ -1026,6 +1034,14 @@ static ssize_t cdns_dsi_transfer(struct
 mipi_dsi_host *host,
 
        cdns_dsi_init_link(dsi);
 
+       /*
+        * on JH7110 SoC , when transfer dsi command ,
+        * cdns_dsi_hs_init is needed.
+        * or the final ret will be error value.
+        */
+       if (dsi->platform_ops && dsi->platform_ops->transfer)
+               dsi->platform_ops->transfer(dsi);
+
        ret = mipi_dsi_create_packet(&packet, msg);
        if (ret)
                goto out;
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +0 -0
@@ -1142,6 +1158,9 @@ static int __maybe_unused cdns_dsi_resume(struct

device *dev)

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c static int __maybe_unused

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +3 -0
        clk_prepare_enable(dsi->dsi_p_clk);
        clk_prepare_enable(dsi->dsi_sys_clk);
 
+       if (dsi->platform_ops && dsi->platform_ops->resume)
+               dsi->platform_ops->resume(dsi);
+
        return 0;
 }
 
@@ -1152,6 +1171,10 @@ static int __maybe_unused

cdns_dsi_suspend(struct device *dev)

Quoted 33 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +4 -0
        clk_disable_unprepare(dsi->dsi_sys_clk);
        clk_disable_unprepare(dsi->dsi_p_clk);
        reset_control_assert(dsi->dsi_p_rst);
+
+       if (dsi->platform_ops && dsi->platform_ops->suspend)
+               dsi->platform_ops->suspend(dsi);
+
        dsi->link_initialized = false;
        return 0;
 }
@@ -1294,6 +1317,10 @@ static const struct of_device_id

cdns_dsi_of_match[] = { #ifdef CONFIG_DRM_CDNS_DSI_J721E

        { .compatible = "ti,j721e-dsi", .data = &dsi_ti_j721e_ops, },

#endif

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +4 -0
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+       { .compatible = "starfive,jh7110-dsi", .data =
+&dsi_ti_jh7110_ops, }, #endif
+
        { },
 };
 MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); diff --git

a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h
b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h
index ca7ea2da635c..0a86495ead7b 100644

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +3 -0
@@ -53,12 +53,22 @@ struct cdns_dsi;
  * @deinit: Called in the CDNS DSI remove
  * @enable: Called at the beginning of CDNS DSI bridge enable
  * @disable: Called at the end of CDNS DSI bridge disable
+ * @resume: Called at the resume of CDNS DSI
+ * @suspend: Called at the suspend of CDNS DSI
+ * @update: Called at the middle of CDNS DSI bridge enable

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h struct cdns_dsi; · line 68

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +4 -0
  */
 struct cdns_dsi_platform_ops {
        int (*init)(struct cdns_dsi *dsi);
        void (*deinit)(struct cdns_dsi *dsi);
        void (*enable)(struct cdns_dsi *dsi);
        void (*disable)(struct cdns_dsi *dsi);
+       void (*resume)(struct cdns_dsi *dsi);
+       void (*suspend)(struct cdns_dsi *dsi);
+       int (*mode_fixup)(struct cdns_dsi *dsi, struct cdns_dsi_cfg *dsi_cfg,
+                         struct phy_configure_opts_mipi_dphy

*phy_cfg,

drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h struct cdns_dsi; · line 69

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +1 -0
+                         unsigned long dpi_hz, unsigned long

dpi_htotal,

Quoted 59 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +12 -0
+                         unsigned long dsi_htotal);
+       void (*transfer)(struct cdns_dsi *dsi);
 };
 
 struct cdns_dsi {
@@ -79,6 +89,17 @@ struct cdns_dsi {
        bool link_initialized;
        bool phy_initialized;
        struct phy *dphy;
+
+#ifdef CONFIG_DRM_CDNS_DSI_JH7110
+       struct clk *dpi_clk;
+       struct clk *txesc_clk;
+       struct reset_control *dpi_rst;
+       struct reset_control *sys_rst;
+       struct reset_control *txesc_rst;
+       struct reset_control *txbytehs_rst; #endif
 };
 
+void cdns_dsi_hs_init(struct cdns_dsi *dsi);
+
 #endif /* !__CDNS_DSI_H__ */
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +30 -0
new file mode 100644
index 000000000000..c6b9296a9275
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * JH7110 SoC Cadence DSI wrapper
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/reset.h>
+
+#include "cdns-dsi-jh7110.h"
+
+static int cdns_dsi_clock_enable(struct cdns_dsi *dsi, struct device
+*dev) {
+       int ret;
+
+       ret = clk_prepare_enable(dsi->dpi_clk);
+       if (ret) {
+               dev_err(dev, "Failed to prepare/enable dpi_clk\n");
+               return ret;
+       }
+
+       ret = clk_prepare_enable(dsi->txesc_clk);
+       if (ret) {
+               dev_err(dev, "Failed to prepare/enable txesc_clk\n");
+               return ret;
+       }
+
Quoted 9 lines

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 37

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +6 -0
+       return ret;
+}
+
+static void cdns_dsi_clock_disable(struct cdns_dsi *dsi) {
+       clk_disable_unprepare(dsi->dpi_clk);
+       clk_disable_unprepare(dsi->txesc_clk);

Please use clk_bulk_ API and inline these two functions.

ok, will follow up this issue.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +17 -0
+}
+
+static int cdns_dsi_resets_deassert(struct cdns_dsi *dsi, struct
+device *dev) {
+       int ret;
+
+       ret = reset_control_deassert(dsi->dpi_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert dpi_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(dsi->txesc_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert txesc_rst\n");
+               return ret;
+       }
Quoted 9 lines

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 60

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +6 -0
+
+       ret = reset_control_deassert(dsi->sys_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to deassert sys_rst\n");
+               return ret;
+       }

Same, please use reset_control_bulk API.

ok, will follow up this issue.

Quoted 112 lines
Quoted 47 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +47 -0
+
+       return ret;
+}
+
+static int cdns_dsi_resets_assert(struct cdns_dsi *dsi, struct device
+*dev) {
+       int ret;
+
+       ret = reset_control_assert(dsi->dpi_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert dpi_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_assert(dsi->txesc_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert txesc_rst\n");
+               return ret;
+       }
+
+       ret = reset_control_assert(dsi->sys_rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to assert sys_rst\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int cdns_dsi_get_clock(struct device *dev, struct cdns_dsi
+*dsi) {
+       dsi->dpi_clk = devm_clk_get(dev, "dpi");
+       if (IS_ERR(dsi->dpi_clk))
+               return PTR_ERR(dsi->dpi_clk);
+
+       dsi->txesc_clk = devm_clk_get(dev, "txesc");
+       if (IS_ERR(dsi->txesc_clk))
+               return PTR_ERR(dsi->txesc_clk);
+
+       return 0;
+}
+
+static int cdns_dsi_get_reset(struct device *dev, struct cdns_dsi
+*dsi) {
+       dsi->sys_rst = devm_reset_control_get_exclusive(dev, "sys");
+       if (IS_ERR(dsi->sys_rst))
+               return PTR_ERR(dsi->sys_rst);

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+
+       dsi->dpi_rst = devm_reset_control_get_exclusive(dev, "dpi");
+       if (IS_ERR(dsi->dpi_rst))
+               return PTR_ERR(dsi->dpi_rst);
+
+       dsi->txesc_rst = devm_reset_control_get_exclusive(dev, "txesc");
+       if (IS_ERR(dsi->txesc_rst))
+               return PTR_ERR(dsi->txesc_rst);
+
+       dsi->txbytehs_rst = devm_reset_control_get_exclusive(dev,

"txbytehs");

Quoted 33 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +33 -0
+       if (IS_ERR(dsi->txbytehs_rst))
+               return PTR_ERR(dsi->txbytehs_rst);
+
+       return 0;
+}
+
+static int cdns_dsi_jh7110_init(struct cdns_dsi *dsi) {
+       int ret;
+
+       ret = cdns_dsi_get_clock(dsi->base.dev, dsi);
+       if (ret)
+               return ret;
+
+       return cdns_dsi_get_reset(dsi->base.dev, dsi); }
+
+static void cdns_dsi_jh7110_resume(struct cdns_dsi *dsi) {
+       int ret;
+
+       ret = cdns_dsi_clock_enable(dsi, dsi->base.dev);
+       if (ret) {
+               dev_err(dsi->base.dev, "failed to enable clock\n");
+               return;
+       }
+       ret = cdns_dsi_resets_deassert(dsi, dsi->base.dev);
+       if (ret < 0) {
+               dev_err(dsi->base.dev, "failed to deassert reset\n");
+               return;
+       }
+}
+
+static void cdns_dsi_jh7110_suspend(struct cdns_dsi *dsi) {
+       int ret;
+

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +10 -0
+       ret = cdns_dsi_resets_assert(dsi, dsi->base.dev);
+       if (ret < 0) {
+               dev_err(dsi->base.dev, "failed to deassert reset\n");
+               return;
+       }
+
+       cdns_dsi_clock_disable(dsi);
+}
+
+static int cdns_dsi_jh7110_mode_fixup(struct cdns_dsi *dsi, struct

cdns_dsi_cfg *dsi_cfg,

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 160

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +1 -0
+                                     struct

phy_configure_opts_mipi_dphy *phy_cfg,

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 161

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +1 -0
+                                     unsigned long dpi_hz, unsigned

long dpi_htotal,

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +6 -0
+                                     unsigned long dsi_htotal) {
+       unsigned long long dlane_bps;
+       unsigned long adj_dsi_htotal;
+       unsigned int lanes = dsi->output.dev->lanes;
+
+       phy_cfg->hs_clk_rate = phy_cfg->hs_clk_rate -
Quoted 5 lines

(phy_cfg->hs_clk_rate % 10000000);

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 174

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +1 -0
+       phy_cfg->hs_clk_rate += 100000000;

phy_cfg->hs_clk_rate = roundup(phy_cfg->hs_clk_rate, 100000000);

ok, will fix it
thanks for suggestion.

Quoted 12 lines

drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c line 184

Quoted 9 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +9 -0
+       dlane_bps = phy_cfg->hs_clk_rate * lanes * dpi_htotal / 8;
+       adj_dsi_htotal = dlane_bps / dpi_hz;
+
+       return adj_dsi_htotal;
+}
+
+static void jh7110_cdns_dsi_hs_init(struct cdns_dsi *dsi) {
+       cdns_dsi_hs_init(dsi);
+       reset_control_deassert(dsi->txbytehs_rst);

Is a single deassert enough here? Which funciion asserts the reset?

will follow up this issue
We verified that we may add assert in our rpm suspend API in next version. thanks for mention

Quoted 30 lines
Quoted 30 lines
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.c new file +8 -0
+}
+
+const struct cdns_dsi_platform_ops dsi_ti_jh7110_ops = {
+       .init = cdns_dsi_jh7110_init,
+       .resume = cdns_dsi_jh7110_resume,
+       .suspend = cdns_dsi_jh7110_suspend,
+       .mode_fixup = cdns_dsi_jh7110_mode_fixup,
+       .transfer = jh7110_cdns_dsi_hs_init, };
drivers/gpu/drm/bridge/cadence/cdns-dsi-jh7110.h new file +15 -0
new file mode 100644
index 000000000000..15d6a766b502
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * JH7110 Cadence DSI
+ *
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ * Author: keith.zhao <[email protected]>  */
+
+#ifndef __CDNS_DSI_JH7110_H__
+#define __CDNS_DSI_JH7110_H__
+
+#include "cdns-dsi-core.h"
+
+extern const struct cdns_dsi_platform_ops dsi_ti_jh7110_ops;
+
+#endif /* !__CDNS_DSI_JH7110_H__ */
Quoted 8 lines
Quoted 3 lines

--
2.17.1

--
With best wishes
Dmitry

thanks.

Best Regards,
Shengyang