All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller
@ 2022-04-14  2:31 Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller Yoshihiro Shimoda
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

This patch series adds support Renesas R-Car S4-8 UFS controller.
This controller has some restrictions so adds some quirks for it.
Before using this driver, we have to initialize a clock generator
on the environment board (named "Spider") by using the commands of
U-Boot like below:
 => i2c dev 0
 => i2c mw 0x6c 0x26 0x05
 => i2c olen 0x6c 2
 => i2c mw 0x6c 0x26c 0x2e

To use the UFS controller, we need the following patch too:
https://lore.kernel.org/all/20220411124932.3765571-1-yoshihiro.shimoda.uh@renesas.com/

Changes from v1:
 - Fix dt-binding doc in patch [1/7].
 - Add __maybe_unused for compile test on other platforms in patch [4/7].
 - Fix node names in patch [5/7].
https://lore.kernel.org/all/20220412073647.3808493-1-yoshihiro.shimoda.uh@renesas.com/

Yoshihiro Shimoda (7):
  dt-bindings: ufs: Document Renesas R-Car UFS host controller
  ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
  ufs: add UFSHCD_QUIRK_HIBERN_FASTAUTO
  scsi: ufs-renesas: Add support for Renesas R-Car UFS controller
  scsi: MAINTAINERS: Add maintainer for Renesas UFS driver
  arm64: dts: renesas: r8a779f0: Add UFS node
  arm64: dts: renesas: r8a779f0: spider-cpu: Enable UFS device

 .../devicetree/bindings/ufs/renesas,ufs.yaml  |  61 +++
 MAINTAINERS                                   |   7 +
 .../boot/dts/renesas/r8a779f0-spider-cpu.dtsi |   8 +
 arch/arm64/boot/dts/renesas/r8a779f0.dtsi     |  19 +
 drivers/scsi/ufs/Kconfig                      |  12 +
 drivers/scsi/ufs/Makefile                     |   1 +
 drivers/scsi/ufs/ufs-renesas.c                | 418 ++++++++++++++++++
 drivers/scsi/ufs/ufshcd.c                     |  12 +-
 drivers/scsi/ufs/ufshcd.h                     |  12 +
 9 files changed, 547 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ufs/renesas,ufs.yaml
 create mode 100644 drivers/scsi/ufs/ufs-renesas.c

-- 
2.25.1


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

* [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  7:51   ` Krzysztof Kozlowski
  2022-04-14  2:31 ` [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS Yoshihiro Shimoda
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Document Renesas R-Car UFS host controller for R-Car S4-8 (r8a779f0).

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 .../devicetree/bindings/ufs/renesas,ufs.yaml  | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/renesas,ufs.yaml

diff --git a/Documentation/devicetree/bindings/ufs/renesas,ufs.yaml b/Documentation/devicetree/bindings/ufs/renesas,ufs.yaml
new file mode 100644
index 000000000000..f04f9f61fa9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/renesas,ufs.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ufs/renesas,ufs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Car UFS Host Controller
+
+maintainers:
+  - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+allOf:
+  - $ref: ufs-common.yaml
+
+properties:
+  compatible:
+    const: renesas,r8a779f0-ufs
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: fck
+      - const: ref_clk
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a779f0-cpg-mssr.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/r8a779f0-sysc.h>
+
+    ufs: ufs@e686000 {
+            compatible = "renesas,r8a779f0-ufs";
+            reg = <0xe6860000 0x100>;
+            interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
+            clock-names = "fck", "ref_clk";
+            freq-table-hz = <200000000 200000000>, <38400000 38400000>;
+            power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+            resets = <&cpg 1514>;
+    };
-- 
2.25.1


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

* [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  4:38   ` Alim Akhtar
  2022-04-14  2:31 ` [PATCH v2 3/7] ufs: add UFSHCD_QUIRK_HIBERN_FASTAUTO Yoshihiro Shimoda
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS for a broken host controller
of the 64-bit addressing supported capability.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/scsi/ufs/ufshcd.c | 3 ++-
 drivers/scsi/ufs/ufshcd.h | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 3f9caafa91bf..a7bb3945c7c6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -9513,7 +9513,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
-	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
+	if (!(hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) &&
+	    hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
 		if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
 			return 0;
 	}
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 94f545be183a..1745144eb904 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -602,6 +602,12 @@ enum ufshcd_quirks {
 	 * support physical host configuration.
 	 */
 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
+
+	/*
+	 * This quirk needs to be enabled if the host controller has
+	 * 64-bit addressing supported capability but it doesn't work.
+	 */
+	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
 };
 
 enum ufshcd_caps {
-- 
2.25.1


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

* [PATCH v2 3/7] ufs: add UFSHCD_QUIRK_HIBERN_FASTAUTO
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Add UFSHCD_QUIRK_HIBERN_FASTAUTO for a broken host controller of
the auto-hibernate capability but it's FASTAUTO only.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/scsi/ufs/ufshcd.c | 9 +++++++--
 drivers/scsi/ufs/ufshcd.h | 6 ++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a7bb3945c7c6..adc059a86e1e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4247,8 +4247,13 @@ static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba)
 	if (hba->max_pwr_info.is_valid)
 		return 0;
 
-	pwr_info->pwr_tx = FAST_MODE;
-	pwr_info->pwr_rx = FAST_MODE;
+	if (hba->quirks & UFSHCD_QUIRK_HIBERN_FASTAUTO) {
+		pwr_info->pwr_tx = FASTAUTO_MODE;
+		pwr_info->pwr_rx = FASTAUTO_MODE;
+	} else {
+		pwr_info->pwr_tx = FAST_MODE;
+		pwr_info->pwr_rx = FAST_MODE;
+	}
 	pwr_info->hs_rate = PA_HS_MODE_B;
 
 	/* Get the connected lane count */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1745144eb904..d14cc48226ce 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -608,6 +608,12 @@ enum ufshcd_quirks {
 	 * 64-bit addressing supported capability but it doesn't work.
 	 */
 	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
+
+	/*
+	 * This quirk needs to be enabled if the host controller has
+	 * auto-hibernate capability but it's FASTAUTO only.
+	 */
+	UFSHCD_QUIRK_HIBERN_FASTAUTO			= 1 << 18,
 };
 
 enum ufshcd_caps {
-- 
2.25.1


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

* [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
                   ` (2 preceding siblings ...)
  2022-04-14  2:31 ` [PATCH v2 3/7] ufs: add UFSHCD_QUIRK_HIBERN_FASTAUTO Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  4:59   ` Alim Akhtar
  2022-04-14  2:31 ` [PATCH v2 5/7] scsi: MAINTAINERS: Add maintainer for Renesas UFS driver Yoshihiro Shimoda
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Add support for Renesas R-Car UFS controller which needs vender specific
initialization.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/scsi/ufs/Kconfig       |  12 +
 drivers/scsi/ufs/Makefile      |   1 +
 drivers/scsi/ufs/ufs-renesas.c | 418 +++++++++++++++++++++++++++++++++
 3 files changed, 431 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-renesas.c

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 9fe27b01904e..7e7ec1b26537 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -136,6 +136,18 @@ config SCSI_UFS_HISI
 	  Select this if you have UFS controller on Hisilicon chipset.
 	  If unsure, say N.
 
+config SCSI_UFS_RENESAS
+	tristate "Renesas specific hooks to UFS controller platform driver"
+	depends on (ARCH_RENESAS || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+	help
+	  This selects the Renesas specific additions to UFSHCD platform driver.
+	  UFS host on Renesas needs some vendor specific configuration before
+	  accessing the hardware.
+
+	  Select this if you have UFS controller on Renesas chipset.
+
+	  If unsure, say N.
+
 config SCSI_UFS_TI_J721E
 	tristate "TI glue layer for Cadence UFS Controller"
 	depends on OF && HAS_IOMEM && (ARCH_K3 || COMPILE_TEST)
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 966048875b50..b7e4a739ea44 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -23,4 +23,5 @@ obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
 obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
 obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
+obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
 obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
diff --git a/drivers/scsi/ufs/ufs-renesas.c b/drivers/scsi/ufs/ufs-renesas.c
new file mode 100644
index 000000000000..5fb2484ead64
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-renesas.c
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Renesas UFS host controller driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+
+struct ufs_renesas_priv {
+	bool initialized;	/* The hardware needs initialization once */
+};
+
+enum {
+	SET_PHY_INDEX_LO = 0,
+	SET_PHY_INDEX_HI,
+	TIMER_INDEX,
+	MAX_INDEX
+};
+
+enum ufs_renesas_init_param_mode {
+	MODE_RESTORE,
+	MODE_SET,
+	MODE_SAVE,
+	MODE_POLL,
+	MODE_WAIT,
+	MODE_WRITE,
+};
+
+#define PARAM_RESTORE(_reg, _index) \
+		{ .mode = MODE_RESTORE, .reg = _reg, .index = _index }
+#define PARAM_SET(_index, _set) \
+		{ .mode = MODE_SET, .index = _index, .u.set = _set }
+#define PARAM_SAVE(_reg, _mask, _index) \
+		{ .mode = MODE_SAVE, .reg = _reg, .mask = (u32)(_mask), \
+		  .index = _index }
+#define PARAM_POLL(_reg, _expected, _mask) \
+		{ .mode = MODE_POLL, .reg = _reg, .u.expected = _expected, \
+		  .mask = (u32)(_mask) }
+#define PARAM_WAIT(_delay_us) \
+		{ .mode = MODE_WAIT, .u.delay_us = _delay_us }
+
+#define PARAM_WRITE(_reg, _val) \
+		{ .mode = MODE_WRITE, .reg = _reg, .u.val = _val }
+
+#define PARAM_WRITE_D0_D4(_d0, _d4) \
+		PARAM_WRITE(0xd0, _d0),	PARAM_WRITE(0xd4, _d4)
+
+#define PARAM_WRITE_800_80C_POLL(_addr, _data_800)		\
+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
+		PARAM_WRITE_D0_D4(0x00000800, ((_data_800) << 16) | BIT(8) | (_addr)), \
+		PARAM_WRITE(0xd0, 0x0000080c),			\
+		PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_RESTORE_800_80C_POLL(_index)			\
+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
+		PARAM_WRITE(0xd0, 0x00000800),			\
+		PARAM_RESTORE(0xd4, _index),			\
+		PARAM_WRITE(0xd0, 0x0000080c),			\
+		PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_WRITE_804_80C_POLL(_addr, _data_804)		\
+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
+		PARAM_WRITE_D0_D4(0x00000804, ((_data_804) << 16) | BIT(8) | (_addr)), \
+		PARAM_WRITE(0xd0, 0x0000080c),			\
+		PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_WRITE_828_82C_POLL(_data_828)			\
+		PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),	\
+		PARAM_WRITE_D0_D4(0x00000828, _data_828),	\
+		PARAM_WRITE(0xd0, 0x0000082c),			\
+		PARAM_POLL(0xd4, _data_828, _data_828)
+
+#define PARAM_WRITE_PHY(_addr16, _data16)			\
+		PARAM_WRITE(0xf0, 1),				\
+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x18, (_data16) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x19, ((_data16) >> 8) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
+		PARAM_WRITE(0xf0, 0)
+
+#define PARAM_SET_PHY(_addr16, _data16)				\
+		PARAM_WRITE(0xf0, 1),				\
+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
+		PARAM_WRITE_804_80C_POLL(0x1a, 0),		\
+		PARAM_WRITE(0xd0, 0x00000808),			\
+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_LO),	\
+		PARAM_WRITE_804_80C_POLL(0x1b, 0),		\
+		PARAM_WRITE(0xd0, 0x00000808),			\
+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_HI),	\
+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
+		PARAM_WRITE(0xf0, 0),				\
+		PARAM_WRITE(0xf0, 1),				\
+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+		PARAM_SET(SET_PHY_INDEX_LO, ((_data16 & 0xff) << 16) | BIT(8) | 0x18), \
+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_LO),	\
+		PARAM_SET(SET_PHY_INDEX_HI, (((_data16 >> 8) & 0xff) << 16) | BIT(8) | 0x19), \
+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_HI),	\
+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
+		PARAM_WRITE(0xf0, 0)
+
+#define PARAM_INDIRECT_WRITE(_gpio, _addr, _data_800)		\
+		PARAM_WRITE(0xf0, _gpio),			\
+		PARAM_WRITE_800_80C_POLL(_addr, _data_800),	\
+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
+		PARAM_WRITE(0xf0, 0)
+
+#define PARAM_INDIRECT_POLL(_gpio, _addr, _expected, _mask)	\
+		PARAM_WRITE(0xf0, _gpio),			\
+		PARAM_WRITE_800_80C_POLL(_addr, 0),		\
+		PARAM_WRITE(0xd0, 0x00000808),			\
+		PARAM_POLL(0xd4, _expected, _mask),		\
+		PARAM_WRITE(0xf0, 0)
+
+struct ufs_renesas_init_param {
+	enum ufs_renesas_init_param_mode mode;
+	u32 reg;
+	union {
+		u32 expected;
+		u32 delay_us;
+		u32 set;
+		u32 val;
+	} u;
+	u32 mask;
+	u32 index;
+};
+
+/* This setting is for SERIES B */
+static const struct ufs_renesas_init_param ufs_param[] = {
+	PARAM_WRITE(0xc0, 0x49425308),
+	PARAM_WRITE_D0_D4(0x00000104, 0x00000002),
+	PARAM_WAIT(1),
+	PARAM_WRITE_D0_D4(0x00000828, 0x00000200),
+	PARAM_WAIT(1),
+	PARAM_WRITE_D0_D4(0x00000828, 0x00000000),
+	PARAM_WRITE_D0_D4(0x00000104, 0x00000001),
+	PARAM_WRITE_D0_D4(0x00000940, 0x00000001),
+	PARAM_WAIT(1),
+	PARAM_WRITE_D0_D4(0x00000940, 0x00000000),
+
+	PARAM_WRITE(0xc0, 0x49425308),
+	PARAM_WRITE(0xc0, 0x41584901),
+
+	PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),
+	PARAM_WRITE_D0_D4(0x00000804, 0x00000000),
+	PARAM_WRITE(0xd0, 0x0000080c),
+	PARAM_POLL(0xd4, BIT(8), BIT(8)),
+
+	PARAM_WRITE(REG_CONTROLLER_ENABLE, 0x00000001),
+
+	PARAM_WRITE(0xd0, 0x00000804),
+	PARAM_POLL(0xd4, BIT(8) | BIT(6) | BIT(0), BIT(8) | BIT(6) | BIT(0)),
+
+	PARAM_WRITE(0xd0, 0x00000d00),
+	PARAM_SAVE(0xd4, 0x0000ffff, TIMER_INDEX),
+	PARAM_WRITE(0xd4, 0x00000000),
+	PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),
+	PARAM_WRITE_D0_D4(0x00000828, 0x08000000),
+	PARAM_WRITE(0xd0, 0x0000082c),
+	PARAM_POLL(0xd4, BIT(27), BIT(27)),
+	PARAM_WRITE(0xd0, 0x00000d2c),
+	PARAM_POLL(0xd4, BIT(0), BIT(0)),
+
+	/* phy setup */
+	PARAM_INDIRECT_WRITE(1, 0x01, 0x001f),
+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0014),
+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0003),
+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
+	PARAM_INDIRECT_WRITE(7, 0x5f, 0x0003),
+	PARAM_INDIRECT_WRITE(7, 0x60, 0x0003),
+	PARAM_INDIRECT_WRITE(7, 0x5b, 0x00a6),
+	PARAM_INDIRECT_WRITE(7, 0x5c, 0x0003),
+
+	PARAM_INDIRECT_POLL(7, 0x3c, 0, BIT(7)),
+	PARAM_INDIRECT_POLL(7, 0x4c, 0, BIT(4)),
+
+	PARAM_INDIRECT_WRITE(1, 0x32, 0x0080),
+	PARAM_INDIRECT_WRITE(1, 0x1f, 0x0001),
+	PARAM_INDIRECT_WRITE(0, 0x2c, 0x0001),
+	PARAM_INDIRECT_WRITE(0, 0x32, 0x0087),
+
+	PARAM_INDIRECT_WRITE(1, 0x4d, 0x0061),
+	PARAM_INDIRECT_WRITE(4, 0x9b, 0x0009),
+	PARAM_INDIRECT_WRITE(4, 0xa6, 0x0005),
+	PARAM_INDIRECT_WRITE(4, 0xa5, 0x0058),
+	PARAM_INDIRECT_WRITE(1, 0x39, 0x0027),
+	PARAM_INDIRECT_WRITE(1, 0x47, 0x004c),
+
+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0002),
+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
+
+	PARAM_WRITE_PHY(0x0028, 0x0061),
+	PARAM_WRITE_PHY(0x4014, 0x0061),
+	PARAM_SET_PHY(0x401c, BIT(2)),
+	PARAM_WRITE_PHY(0x4000, 0x0000),
+	PARAM_WRITE_PHY(0x4001, 0x0000),
+
+	PARAM_WRITE_PHY(0x10ae, 0x0001),
+	PARAM_WRITE_PHY(0x10ad, 0x0000),
+	PARAM_WRITE_PHY(0x10af, 0x0001),
+	PARAM_WRITE_PHY(0x10b6, 0x0001),
+	PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+	PARAM_WRITE_PHY(0x10ae, 0x0001),
+	PARAM_WRITE_PHY(0x10ad, 0x0000),
+	PARAM_WRITE_PHY(0x10af, 0x0002),
+	PARAM_WRITE_PHY(0x10b6, 0x0001),
+	PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+	PARAM_WRITE_PHY(0x10ae, 0x0001),
+	PARAM_WRITE_PHY(0x10ad, 0x0080),
+	PARAM_WRITE_PHY(0x10af, 0x0000),
+	PARAM_WRITE_PHY(0x10b6, 0x0001),
+	PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+	PARAM_WRITE_PHY(0x10ae, 0x0001),
+	PARAM_WRITE_PHY(0x10ad, 0x0080),
+	PARAM_WRITE_PHY(0x10af, 0x001a),
+	PARAM_WRITE_PHY(0x10b6, 0x0001),
+	PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+	PARAM_INDIRECT_WRITE(7, 0x70, 0x0016),
+	PARAM_INDIRECT_WRITE(7, 0x71, 0x0016),
+	PARAM_INDIRECT_WRITE(7, 0x72, 0x0014),
+	PARAM_INDIRECT_WRITE(7, 0x73, 0x0014),
+	PARAM_INDIRECT_WRITE(7, 0x74, 0x0000),
+	PARAM_INDIRECT_WRITE(7, 0x75, 0x0000),
+	PARAM_INDIRECT_WRITE(7, 0x76, 0x0010),
+	PARAM_INDIRECT_WRITE(7, 0x77, 0x0010),
+	PARAM_INDIRECT_WRITE(7, 0x78, 0x00ff),
+	PARAM_INDIRECT_WRITE(7, 0x79, 0x0000),
+
+	PARAM_INDIRECT_WRITE(7, 0x19, 0x0007),
+
+	PARAM_INDIRECT_WRITE(7, 0x1a, 0x0007),
+
+	PARAM_INDIRECT_WRITE(7, 0x24, 0x000c),
+
+	PARAM_INDIRECT_WRITE(7, 0x25, 0x000c),
+
+	PARAM_INDIRECT_WRITE(7, 0x62, 0x0000),
+	PARAM_INDIRECT_WRITE(7, 0x63, 0x0000),
+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0004),
+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
+	PARAM_INDIRECT_POLL(7, 0x55, 0, BIT(6)),
+	PARAM_INDIRECT_POLL(7, 0x41, 0, BIT(7)),
+	/* end of phy setup */
+
+	PARAM_WRITE(0xf0, 0),
+	PARAM_WRITE(0xd0, 0x00000d00),
+	PARAM_RESTORE(0xd4, TIMER_INDEX),
+};
+
+static void ufs_renesas_dbg_register_dump(struct ufs_hba *hba)
+{
+	ufshcd_dump_regs(hba, 0xc0, 0x40, "regs: 0xc0 + ");
+}
+
+static void ufs_renesas_reg_control(struct ufs_hba *hba,
+				    const struct ufs_renesas_init_param *p)
+{
+	static u32 save[MAX_INDEX];
+	int ret;
+	u32 val;
+
+	pr_debug("%s: %d %04x %08x, %08x, %d\n", __func__, p->mode, p->reg,
+		 p->u.val, p->mask, p->index);
+
+	BUG_ON(p->index >= MAX_INDEX);
+
+	switch (p->mode) {
+	case MODE_RESTORE:
+		ufshcd_writel(hba, save[p->index], p->reg);
+		break;
+	case MODE_SET:
+		pr_debug("%s: %d %x %x\n", __func__, p->index, save[p->index],
+			 p->u.set);
+		save[p->index] |= p->u.set;
+		break;
+	case MODE_SAVE:
+		save[p->index] = ufshcd_readl(hba, p->reg) & p->mask;
+		pr_debug("%s: index = %d, val = %08x\n", __func__,
+			 p->index, val);
+		break;
+	case MODE_POLL:
+		ret = readl_poll_timeout_atomic(hba->mmio_base + p->reg,
+						val,
+						(val & p->mask) == p->u.expected,
+						10, 1000);
+		if (ret)
+			pr_err("%s: poll failed %d (%08x, %08x, %08x)\n",
+			       __func__, ret, val, p->mask, p->u.expected);
+		break;
+	case MODE_WAIT:
+		if (p->u.delay_us > 1000)
+			mdelay(p->u.delay_us / 1000);
+		else
+			udelay(p->u.delay_us);
+		break;
+	case MODE_WRITE:
+		ufshcd_writel(hba, p->u.val, p->reg);
+		break;
+	default:
+		break;
+	}
+}
+
+static void ufs_renesas_pre_init(struct ufs_hba *hba)
+{
+	const struct ufs_renesas_init_param *p = ufs_param;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ufs_param); i++)
+		ufs_renesas_reg_control(hba, &p[i]);
+}
+
+static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba,
+					 enum ufs_notify_change_status status)
+{
+	struct ufs_renesas_priv *priv = ufshcd_get_variant(hba);
+
+	if (priv->initialized)
+		return 0;
+
+	if (status == PRE_CHANGE)
+		ufs_renesas_pre_init(hba);
+
+	priv->initialized = true;
+
+	return 0;
+}
+
+static int ufs_renesas_setup_clocks(struct ufs_hba *hba, bool on,
+				    enum ufs_notify_change_status status)
+{
+	if (on && status == PRE_CHANGE)
+		pm_runtime_get_sync(hba->dev);
+	else if (!on && status == POST_CHANGE)
+		pm_runtime_put(hba->dev);
+
+	return 0;
+}
+
+static int ufs_renesas_init(struct ufs_hba *hba)
+{
+	struct ufs_renesas_priv *priv;
+
+	priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	ufshcd_set_variant(hba, priv);
+
+	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+
+	return 0;
+}
+
+static const struct ufs_hba_variant_ops ufs_renesas_vops = {
+	.name		= "renesas",
+	.init		= ufs_renesas_init,
+	.setup_clocks	= ufs_renesas_setup_clocks,
+	.hce_enable_notify = ufs_renesas_hce_enable_notify,
+	.dbg_register_dump = ufs_renesas_dbg_register_dump,
+};
+
+static const struct of_device_id __maybe_unused ufs_renesas_of_match[] = {
+	{ .compatible = "renesas,r8a779f0-ufs" },
+};
+MODULE_DEVICE_TABLE(of, ufs_renesas_of_match);
+
+static int ufs_renesas_probe(struct platform_device *pdev)
+{
+	return ufshcd_pltfrm_init(pdev, &ufs_renesas_vops);
+}
+
+static int ufs_renesas_remove(struct platform_device *pdev)
+{
+	struct ufs_hba *hba = platform_get_drvdata(pdev);
+
+	ufshcd_remove(hba);
+
+	return 0;
+}
+
+static struct platform_driver ufs_renesas_platform = {
+	.probe	= ufs_renesas_probe,
+	.remove	= ufs_renesas_remove,
+	.driver	= {
+		.name	= "ufshcd-renesas",
+		.of_match_table	= of_match_ptr(ufs_renesas_of_match),
+	},
+};
+module_platform_driver(ufs_renesas_platform);
+
+MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
+MODULE_DESCRIPTION("Renesas UFS host controller driver");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.25.1


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

* [PATCH v2 5/7] scsi: MAINTAINERS: Add maintainer for Renesas UFS driver
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
                   ` (3 preceding siblings ...)
  2022-04-14  2:31 ` [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 6/7] arm64: dts: renesas: r8a779f0: Add UFS node Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 7/7] arm64: dts: renesas: r8a779f0: spider-cpu: Enable UFS device Yoshihiro Shimoda
  6 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Add maintainer for Renesas UFS driver.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f8db959c10a5..3a10f293ded9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20219,6 +20219,13 @@ L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	drivers/scsi/ufs/ufs-mediatek*
 
+UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER RENESAS HOOKS
+M:	Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+L:	linux-renesas-soc@vger.kernel.org
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+F:	drivers/scsi/ufs/*renesas*
+
 UNSORTED BLOCK IMAGES (UBI)
 M:	Richard Weinberger <richard@nod.at>
 L:	linux-mtd@lists.infradead.org
-- 
2.25.1


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

* [PATCH v2 6/7] arm64: dts: renesas: r8a779f0: Add UFS node
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
                   ` (4 preceding siblings ...)
  2022-04-14  2:31 ` [PATCH v2 5/7] scsi: MAINTAINERS: Add maintainer for Renesas UFS driver Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  2022-04-14  2:31 ` [PATCH v2 7/7] arm64: dts: renesas: r8a779f0: spider-cpu: Enable UFS device Yoshihiro Shimoda
  6 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Add UFS node for R-Car S4-8 (r8a779f0).

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 arch/arm64/boot/dts/renesas/r8a779f0.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
index b0241aa29fc8..9639b50fb62b 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -40,6 +40,13 @@ extalr_clk: extalr {
 		clock-frequency = <0>;
 	};
 
+	ufs30_clk: ufs30-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
 	pmu_a55 {
 		compatible = "arm,cortex-a55-pmu";
 		interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
@@ -258,6 +265,18 @@ i2c5: i2c@e66e0000 {
 			status = "disabled";
 		};
 
+		ufs: ufs@e6860000 {
+			compatible = "renesas,r8a779f0-ufs";
+			reg = <0 0xe6860000 0 0x100>;
+			interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
+			clock-names = "fck", "ref_clk";
+			freq-table-hz = <200000000 200000000>, <38400000 38400000>;
+			power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+			resets = <&cpg 1514>;
+			status = "disabled";
+		};
+
 		scif3: serial@e6c50000 {
 			compatible = "renesas,scif-r8a779f0",
 				     "renesas,rcar-gen4-scif", "renesas,scif";
-- 
2.25.1


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

* [PATCH v2 7/7] arm64: dts: renesas: r8a779f0: spider-cpu: Enable UFS device
  2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
                   ` (5 preceding siblings ...)
  2022-04-14  2:31 ` [PATCH v2 6/7] arm64: dts: renesas: r8a779f0: Add UFS node Yoshihiro Shimoda
@ 2022-04-14  2:31 ` Yoshihiro Shimoda
  6 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14  2:31 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc,
	Yoshihiro Shimoda

Enable UFS device for R-Car S4-8 Spider CPU board.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
index 41aa8591b3b1..999c823719bc 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
@@ -82,3 +82,11 @@ &scif3 {
 &scif_clk {
 	clock-frequency = <24000000>;
 };
+
+&ufs {
+	status = "okay";
+};
+
+&ufs30_clk {
+	clock-frequency = <38400000>;
+};
-- 
2.25.1


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

* RE: [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
  2022-04-14  2:31 ` [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS Yoshihiro Shimoda
@ 2022-04-14  4:38   ` Alim Akhtar
  2022-04-14 11:39     ` Yoshihiro Shimoda
  0 siblings, 1 reply; 13+ messages in thread
From: Alim Akhtar @ 2022-04-14  4:38 UTC (permalink / raw)
  To: 'Yoshihiro Shimoda', avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc

Hi Yoshihiro

>-----Original Message-----
>From: Yoshihiro Shimoda [mailto:yoshihiro.shimoda.uh@renesas.com]
>Sent: Thursday, April 14, 2022 8:01 AM
>To: alim.akhtar@samsung.com; avri.altman@wdc.com; robh+dt@kernel.org;
>krzk+dt@kernel.org
>Cc: jejb@linux.ibm.com; martin.petersen@oracle.com; linux-
>scsi@vger.kernel.org; devicetree@vger.kernel.org; linux-renesas-
>soc@vger.kernel.org; Yoshihiro Shimoda
><yoshihiro.shimoda.uh@renesas.com>
>Subject: [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
>
>Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS for a broken host controller of
>the 64-bit addressing supported capability.
>
A little more details in the commit message will help to understand the
changes more.
Does it mean this HCI has other addressing mode (other than 32 and 64)?
Like a 36bit address? In that case, does Host controller is behind any
IOMMU?


>Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>---
> drivers/scsi/ufs/ufshcd.c | 3 ++-
> drivers/scsi/ufs/ufshcd.h | 6 ++++++
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index
>3f9caafa91bf..a7bb3945c7c6 100644
>--- a/drivers/scsi/ufs/ufshcd.c
>+++ b/drivers/scsi/ufs/ufshcd.c
>@@ -9513,7 +9513,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
>  */
> static int ufshcd_set_dma_mask(struct ufs_hba *hba)  {
>-	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
>+	if (!(hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) &&
>+	    hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
> 		if (!dma_set_mask_and_coherent(hba->dev,
>DMA_BIT_MASK(64)))
> 			return 0;
> 	}
>diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index
>94f545be183a..1745144eb904 100644
>--- a/drivers/scsi/ufs/ufshcd.h
>+++ b/drivers/scsi/ufs/ufshcd.h
>@@ -602,6 +602,12 @@ enum ufshcd_quirks {
> 	 * support physical host configuration.
> 	 */
> 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
>+
>+	/*
>+	 * This quirk needs to be enabled if the host controller has
>+	 * 64-bit addressing supported capability but it doesn't work.
>+	 */
>+	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
> };
>
> enum ufshcd_caps {
>--
>2.25.1



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

* RE: [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller
  2022-04-14  2:31 ` [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
@ 2022-04-14  4:59   ` Alim Akhtar
  2022-04-14 11:39     ` Yoshihiro Shimoda
  0 siblings, 1 reply; 13+ messages in thread
From: Alim Akhtar @ 2022-04-14  4:59 UTC (permalink / raw)
  To: 'Yoshihiro Shimoda', avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc

Hi Yoshihiro

>-----Original Message-----
>From: Yoshihiro Shimoda [mailto:yoshihiro.shimoda.uh@renesas.com]
>Sent: Thursday, April 14, 2022 8:01 AM
>To: alim.akhtar@samsung.com; avri.altman@wdc.com; robh+dt@kernel.org;
>krzk+dt@kernel.org
>Cc: jejb@linux.ibm.com; martin.petersen@oracle.com; linux-
>scsi@vger.kernel.org; devicetree@vger.kernel.org; linux-renesas-
>soc@vger.kernel.org; Yoshihiro Shimoda
><yoshihiro.shimoda.uh@renesas.com>
>Subject: [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car
UFS
>controller
>
>Add support for Renesas R-Car UFS controller which needs vender specific
>initialization.
>
>Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>---
> drivers/scsi/ufs/Kconfig       |  12 +
> drivers/scsi/ufs/Makefile      |   1 +
> drivers/scsi/ufs/ufs-renesas.c | 418
>+++++++++++++++++++++++++++++++++
> 3 files changed, 431 insertions(+)
> create mode 100644 drivers/scsi/ufs/ufs-renesas.c
>
>diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index
>9fe27b01904e..7e7ec1b26537 100644
>--- a/drivers/scsi/ufs/Kconfig
>+++ b/drivers/scsi/ufs/Kconfig
>@@ -136,6 +136,18 @@ config SCSI_UFS_HISI
> 	  Select this if you have UFS controller on Hisilicon chipset.
> 	  If unsure, say N.
>
>+config SCSI_UFS_RENESAS
>+	tristate "Renesas specific hooks to UFS controller platform driver"
>+	depends on (ARCH_RENESAS || COMPILE_TEST) &&
>SCSI_UFSHCD_PLATFORM
>+	help
>+	  This selects the Renesas specific additions to UFSHCD platform
driver.
>+	  UFS host on Renesas needs some vendor specific configuration
>before
>+	  accessing the hardware.
>+
>+	  Select this if you have UFS controller on Renesas chipset.
>+
>+	  If unsure, say N.
>+
> config SCSI_UFS_TI_J721E
> 	tristate "TI glue layer for Cadence UFS Controller"
> 	depends on OF && HAS_IOMEM && (ARCH_K3 || COMPILE_TEST) diff
>--git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index
>966048875b50..b7e4a739ea44 100644
>--- a/drivers/scsi/ufs/Makefile
>+++ b/drivers/scsi/ufs/Makefile
>@@ -23,4 +23,5 @@ obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
> obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
> obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
>+obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
> obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o diff --git
>a/drivers/scsi/ufs/ufs-renesas.c b/drivers/scsi/ufs/ufs-renesas.c new file
>mode 100644 index 000000000000..5fb2484ead64
>--- /dev/null
>+++ b/drivers/scsi/ufs/ufs-renesas.c
>@@ -0,0 +1,418 @@
>+// SPDX-License-Identifier: GPL-2.0 OR MIT
>+/*
>+ * Renesas UFS host controller driver
>+ *
>+ * Copyright (C) 2022 Renesas Electronics Corporation  */
>+
>+#include <linux/clk.h>
>+#include <linux/delay.h>
>+#include <linux/err.h>
>+#include <linux/iopoll.h>
>+#include <linux/kernel.h>
>+#include <linux/module.h>
>+#include <linux/of.h>
>+#include <linux/of_device.h>
>+#include <linux/pm_runtime.h>
>+
>+#include "ufshcd.h"
>+#include "ufshcd-pltfrm.h"
>+
>+struct ufs_renesas_priv {
>+	bool initialized;	/* The hardware needs initialization once */
>+};
>+
>+enum {
>+	SET_PHY_INDEX_LO = 0,
>+	SET_PHY_INDEX_HI,
>+	TIMER_INDEX,
>+	MAX_INDEX
>+};
>+
>+enum ufs_renesas_init_param_mode {
>+	MODE_RESTORE,
>+	MODE_SET,
>+	MODE_SAVE,
>+	MODE_POLL,
>+	MODE_WAIT,
>+	MODE_WRITE,
>+};
>+
>+#define PARAM_RESTORE(_reg, _index) \
>+		{ .mode = MODE_RESTORE, .reg = _reg, .index = _index }
>#define
>+PARAM_SET(_index, _set) \
>+		{ .mode = MODE_SET, .index = _index, .u.set = _set } #define
>+PARAM_SAVE(_reg, _mask, _index) \
>+		{ .mode = MODE_SAVE, .reg = _reg, .mask = (u32)(_mask), \
>+		  .index = _index }
>+#define PARAM_POLL(_reg, _expected, _mask) \
>+		{ .mode = MODE_POLL, .reg = _reg, .u.expected = _expected,
>\
>+		  .mask = (u32)(_mask) }
>+#define PARAM_WAIT(_delay_us) \
>+		{ .mode = MODE_WAIT, .u.delay_us = _delay_us }
>+
>+#define PARAM_WRITE(_reg, _val) \
>+		{ .mode = MODE_WRITE, .reg = _reg, .u.val = _val }
>+
>+#define PARAM_WRITE_D0_D4(_d0, _d4) \
>+		PARAM_WRITE(0xd0, _d0),	PARAM_WRITE(0xd4, _d4)
>+
>+#define PARAM_WRITE_800_80C_POLL(_addr, _data_800)		\
>+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
>+		PARAM_WRITE_D0_D4(0x00000800, ((_data_800) << 16) |
>BIT(8) | (_addr)), \
>+		PARAM_WRITE(0xd0, 0x0000080c),			\
>+		PARAM_POLL(0xd4, BIT(8), BIT(8))
>+
>+#define PARAM_RESTORE_800_80C_POLL(_index)			\
>+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
>+		PARAM_WRITE(0xd0, 0x00000800),			\
>+		PARAM_RESTORE(0xd4, _index),			\
>+		PARAM_WRITE(0xd0, 0x0000080c),			\
>+		PARAM_POLL(0xd4, BIT(8), BIT(8))
>+
>+#define PARAM_WRITE_804_80C_POLL(_addr, _data_804)		\
>+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
>+		PARAM_WRITE_D0_D4(0x00000804, ((_data_804) << 16) |
>BIT(8) | (_addr)), \
>+		PARAM_WRITE(0xd0, 0x0000080c),			\
>+		PARAM_POLL(0xd4, BIT(8), BIT(8))
>+
>+#define PARAM_WRITE_828_82C_POLL(_data_828)			\
>+		PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),	\
>+		PARAM_WRITE_D0_D4(0x00000828, _data_828),	\
>+		PARAM_WRITE(0xd0, 0x0000082c),			\
>+		PARAM_POLL(0xd4, _data_828, _data_828)
>+
>+#define PARAM_WRITE_PHY(_addr16, _data16)			\
>+		PARAM_WRITE(0xf0, 1),				\
>+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
>+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
>\
>+		PARAM_WRITE_800_80C_POLL(0x18, (_data16) & 0xff), \
>+		PARAM_WRITE_800_80C_POLL(0x19, ((_data16) >> 8) & 0xff),
>\
>+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
>+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
>+		PARAM_WRITE(0xf0, 0)
>+
>+#define PARAM_SET_PHY(_addr16, _data16)				\
>+		PARAM_WRITE(0xf0, 1),				\
>+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
>+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
>\
>+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
>+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
>+		PARAM_WRITE_804_80C_POLL(0x1a, 0),		\
>+		PARAM_WRITE(0xd0, 0x00000808),			\
>+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_LO),	\
>+		PARAM_WRITE_804_80C_POLL(0x1b, 0),		\
>+		PARAM_WRITE(0xd0, 0x00000808),			\
>+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_HI),	\
>+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
>+		PARAM_WRITE(0xf0, 0),				\
>+		PARAM_WRITE(0xf0, 1),				\
>+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
>+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
>\
>+		PARAM_SET(SET_PHY_INDEX_LO, ((_data16 & 0xff) << 16) |
>BIT(8) | 0x18), \
>+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_LO),
>	\
>+		PARAM_SET(SET_PHY_INDEX_HI, (((_data16 >> 8) & 0xff) <<
>16) | BIT(8) | 0x19), \
>+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_HI),
>	\
>+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
>+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
>+		PARAM_WRITE(0xf0, 0)
>+
>+#define PARAM_INDIRECT_WRITE(_gpio, _addr, _data_800)		\
>+		PARAM_WRITE(0xf0, _gpio),			\
>+		PARAM_WRITE_800_80C_POLL(_addr, _data_800),	\
>+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
>+		PARAM_WRITE(0xf0, 0)
>+
>+#define PARAM_INDIRECT_POLL(_gpio, _addr, _expected, _mask)	\
>+		PARAM_WRITE(0xf0, _gpio),			\
>+		PARAM_WRITE_800_80C_POLL(_addr, 0),		\
>+		PARAM_WRITE(0xd0, 0x00000808),			\
>+		PARAM_POLL(0xd4, _expected, _mask),		\
>+		PARAM_WRITE(0xf0, 0)
>+

These above macro gives lot of checkpatch error, please fix the same.

>+struct ufs_renesas_init_param {
>+	enum ufs_renesas_init_param_mode mode;
>+	u32 reg;
>+	union {
>+		u32 expected;
>+		u32 delay_us;
>+		u32 set;
>+		u32 val;
>+	} u;
>+	u32 mask;
>+	u32 index;
>+};
>+
>+/* This setting is for SERIES B */
>+static const struct ufs_renesas_init_param ufs_param[] = {
>+	PARAM_WRITE(0xc0, 0x49425308),
>+	PARAM_WRITE_D0_D4(0x00000104, 0x00000002),
>+	PARAM_WAIT(1),
>+	PARAM_WRITE_D0_D4(0x00000828, 0x00000200),
>+	PARAM_WAIT(1),
>+	PARAM_WRITE_D0_D4(0x00000828, 0x00000000),
>+	PARAM_WRITE_D0_D4(0x00000104, 0x00000001),
>+	PARAM_WRITE_D0_D4(0x00000940, 0x00000001),
>+	PARAM_WAIT(1),
>+	PARAM_WRITE_D0_D4(0x00000940, 0x00000000),
>+
>+	PARAM_WRITE(0xc0, 0x49425308),
>+	PARAM_WRITE(0xc0, 0x41584901),
>+
>+	PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),
>+	PARAM_WRITE_D0_D4(0x00000804, 0x00000000),
>+	PARAM_WRITE(0xd0, 0x0000080c),
>+	PARAM_POLL(0xd4, BIT(8), BIT(8)),
>+
>+	PARAM_WRITE(REG_CONTROLLER_ENABLE, 0x00000001),
>+
>+	PARAM_WRITE(0xd0, 0x00000804),
>+	PARAM_POLL(0xd4, BIT(8) | BIT(6) | BIT(0), BIT(8) | BIT(6) |
BIT(0)),
>+
>+	PARAM_WRITE(0xd0, 0x00000d00),
>+	PARAM_SAVE(0xd4, 0x0000ffff, TIMER_INDEX),
>+	PARAM_WRITE(0xd4, 0x00000000),
>+	PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),
>+	PARAM_WRITE_D0_D4(0x00000828, 0x08000000),
>+	PARAM_WRITE(0xd0, 0x0000082c),
>+	PARAM_POLL(0xd4, BIT(27), BIT(27)),
>+	PARAM_WRITE(0xd0, 0x00000d2c),
>+	PARAM_POLL(0xd4, BIT(0), BIT(0)),
>+
>+	/* phy setup */
>+	PARAM_INDIRECT_WRITE(1, 0x01, 0x001f),
>+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
>+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0014),
>+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0003),
>+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
>+	PARAM_INDIRECT_WRITE(7, 0x5f, 0x0003),
>+	PARAM_INDIRECT_WRITE(7, 0x60, 0x0003),
>+	PARAM_INDIRECT_WRITE(7, 0x5b, 0x00a6),
>+	PARAM_INDIRECT_WRITE(7, 0x5c, 0x0003),
>+
>+	PARAM_INDIRECT_POLL(7, 0x3c, 0, BIT(7)),
>+	PARAM_INDIRECT_POLL(7, 0x4c, 0, BIT(4)),
>+
>+	PARAM_INDIRECT_WRITE(1, 0x32, 0x0080),
>+	PARAM_INDIRECT_WRITE(1, 0x1f, 0x0001),
>+	PARAM_INDIRECT_WRITE(0, 0x2c, 0x0001),
>+	PARAM_INDIRECT_WRITE(0, 0x32, 0x0087),
>+
>+	PARAM_INDIRECT_WRITE(1, 0x4d, 0x0061),
>+	PARAM_INDIRECT_WRITE(4, 0x9b, 0x0009),
>+	PARAM_INDIRECT_WRITE(4, 0xa6, 0x0005),
>+	PARAM_INDIRECT_WRITE(4, 0xa5, 0x0058),
>+	PARAM_INDIRECT_WRITE(1, 0x39, 0x0027),
>+	PARAM_INDIRECT_WRITE(1, 0x47, 0x004c),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0002),
>+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
>+
>+	PARAM_WRITE_PHY(0x0028, 0x0061),
>+	PARAM_WRITE_PHY(0x4014, 0x0061),
>+	PARAM_SET_PHY(0x401c, BIT(2)),
>+	PARAM_WRITE_PHY(0x4000, 0x0000),
>+	PARAM_WRITE_PHY(0x4001, 0x0000),
>+
>+	PARAM_WRITE_PHY(0x10ae, 0x0001),
>+	PARAM_WRITE_PHY(0x10ad, 0x0000),
>+	PARAM_WRITE_PHY(0x10af, 0x0001),
>+	PARAM_WRITE_PHY(0x10b6, 0x0001),
>+	PARAM_WRITE_PHY(0x10ae, 0x0000),
>+
>+	PARAM_WRITE_PHY(0x10ae, 0x0001),
>+	PARAM_WRITE_PHY(0x10ad, 0x0000),
>+	PARAM_WRITE_PHY(0x10af, 0x0002),
>+	PARAM_WRITE_PHY(0x10b6, 0x0001),
>+	PARAM_WRITE_PHY(0x10ae, 0x0000),
>+
>+	PARAM_WRITE_PHY(0x10ae, 0x0001),
>+	PARAM_WRITE_PHY(0x10ad, 0x0080),
>+	PARAM_WRITE_PHY(0x10af, 0x0000),
>+	PARAM_WRITE_PHY(0x10b6, 0x0001),
>+	PARAM_WRITE_PHY(0x10ae, 0x0000),
>+
>+	PARAM_WRITE_PHY(0x10ae, 0x0001),
>+	PARAM_WRITE_PHY(0x10ad, 0x0080),
>+	PARAM_WRITE_PHY(0x10af, 0x001a),
>+	PARAM_WRITE_PHY(0x10b6, 0x0001),
>+	PARAM_WRITE_PHY(0x10ae, 0x0000),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x70, 0x0016),
>+	PARAM_INDIRECT_WRITE(7, 0x71, 0x0016),
>+	PARAM_INDIRECT_WRITE(7, 0x72, 0x0014),
>+	PARAM_INDIRECT_WRITE(7, 0x73, 0x0014),
>+	PARAM_INDIRECT_WRITE(7, 0x74, 0x0000),
>+	PARAM_INDIRECT_WRITE(7, 0x75, 0x0000),
>+	PARAM_INDIRECT_WRITE(7, 0x76, 0x0010),
>+	PARAM_INDIRECT_WRITE(7, 0x77, 0x0010),
>+	PARAM_INDIRECT_WRITE(7, 0x78, 0x00ff),
>+	PARAM_INDIRECT_WRITE(7, 0x79, 0x0000),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x19, 0x0007),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x1a, 0x0007),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x24, 0x000c),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x25, 0x000c),
>+
>+	PARAM_INDIRECT_WRITE(7, 0x62, 0x0000),
>+	PARAM_INDIRECT_WRITE(7, 0x63, 0x0000),
>+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
>+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
>+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0004),
>+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
>+	PARAM_INDIRECT_POLL(7, 0x55, 0, BIT(6)),
>+	PARAM_INDIRECT_POLL(7, 0x41, 0, BIT(7)),
>+	/* end of phy setup */
>+
>+	PARAM_WRITE(0xf0, 0),
>+	PARAM_WRITE(0xd0, 0x00000d00),
>+	PARAM_RESTORE(0xd4, TIMER_INDEX),
>+};
>+
>+static void ufs_renesas_dbg_register_dump(struct ufs_hba *hba) {
>+	ufshcd_dump_regs(hba, 0xc0, 0x40, "regs: 0xc0 + "); }
>+
>+static void ufs_renesas_reg_control(struct ufs_hba *hba,
>+				    const struct ufs_renesas_init_param *p)
{
>+	static u32 save[MAX_INDEX];
>+	int ret;
>+	u32 val;
>+
>+	pr_debug("%s: %d %04x %08x, %08x, %d\n", __func__, p->mode, p-
>>reg,
>+		 p->u.val, p->mask, p->index);
>+
>+	BUG_ON(p->index >= MAX_INDEX);

Do you really need a BUG_ON here? May be a WARN_ON?

>+
>+	switch (p->mode) {
>+	case MODE_RESTORE:
>+		ufshcd_writel(hba, save[p->index], p->reg);
>+		break;
>+	case MODE_SET:
>+		pr_debug("%s: %d %x %x\n", __func__, p->index, save[p-
>>index],
>+			 p->u.set);
>+		save[p->index] |= p->u.set;
>+		break;
>+	case MODE_SAVE:
>+		save[p->index] = ufshcd_readl(hba, p->reg) & p->mask;
>+		pr_debug("%s: index = %d, val = %08x\n", __func__,
>+			 p->index, val);
>+		break;
>+	case MODE_POLL:
>+		ret = readl_poll_timeout_atomic(hba->mmio_base + p->reg,
>+						val,
>+						(val & p->mask) == p-
>>u.expected,
>+						10, 1000);
>+		if (ret)
>+			pr_err("%s: poll failed %d (%08x, %08x, %08x)\n",
>+			       __func__, ret, val, p->mask, p->u.expected);
>+		break;
>+	case MODE_WAIT:
>+		if (p->u.delay_us > 1000)
>+			mdelay(p->u.delay_us / 1000);
>+		else
>+			udelay(p->u.delay_us);
>+		break;
>+	case MODE_WRITE:
>+		ufshcd_writel(hba, p->u.val, p->reg);
>+		break;
>+	default:
>+		break;
>+	}
>+}
>+
>+static void ufs_renesas_pre_init(struct ufs_hba *hba) {
>+	const struct ufs_renesas_init_param *p = ufs_param;
>+	int i;
>+
>+	for (i = 0; i < ARRAY_SIZE(ufs_param); i++)
>+		ufs_renesas_reg_control(hba, &p[i]);
>+}
>+
>+static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba,
>+					 enum ufs_notify_change_status
>status) {
>+	struct ufs_renesas_priv *priv = ufshcd_get_variant(hba);
>+
>+	if (priv->initialized)
>+		return 0;
>+
>+	if (status == PRE_CHANGE)
>+		ufs_renesas_pre_init(hba);
>+
>+	priv->initialized = true;
>+
>+	return 0;
>+}
>+
>+static int ufs_renesas_setup_clocks(struct ufs_hba *hba, bool on,
>+				    enum ufs_notify_change_status status) {
>+	if (on && status == PRE_CHANGE)
>+		pm_runtime_get_sync(hba->dev);
>+	else if (!on && status == POST_CHANGE)
>+		pm_runtime_put(hba->dev);
>+
>+	return 0;
>+}
>+
>+static int ufs_renesas_init(struct ufs_hba *hba) {
>+	struct ufs_renesas_priv *priv;
>+
>+	priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL);
>+	if (!priv)
>+		return -ENOMEM;
>+	ufshcd_set_variant(hba, priv);
>+
>+	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS |
>+UFSHCD_QUIRK_HIBERN_FASTAUTO;
>+
>+	return 0;
>+}
>+
>+static const struct ufs_hba_variant_ops ufs_renesas_vops = {
>+	.name		= "renesas",
>+	.init		= ufs_renesas_init,
>+	.setup_clocks	= ufs_renesas_setup_clocks,
>+	.hce_enable_notify = ufs_renesas_hce_enable_notify,
>+	.dbg_register_dump = ufs_renesas_dbg_register_dump, };
>+
>+static const struct of_device_id __maybe_unused ufs_renesas_of_match[]
>= {
>+	{ .compatible = "renesas,r8a779f0-ufs" }, };
>MODULE_DEVICE_TABLE(of,
>+ufs_renesas_of_match);
>+
>+static int ufs_renesas_probe(struct platform_device *pdev) {
>+	return ufshcd_pltfrm_init(pdev, &ufs_renesas_vops); }
>+
>+static int ufs_renesas_remove(struct platform_device *pdev) {
>+	struct ufs_hba *hba = platform_get_drvdata(pdev);
>+
>+	ufshcd_remove(hba);
>+
>+	return 0;
>+}
>+
>+static struct platform_driver ufs_renesas_platform = {
>+	.probe	= ufs_renesas_probe,
>+	.remove	= ufs_renesas_remove,
>+	.driver	= {
>+		.name	= "ufshcd-renesas",
>+		.of_match_table	=
>of_match_ptr(ufs_renesas_of_match),
>+	},
>+};
>+module_platform_driver(ufs_renesas_platform);
>+
>+MODULE_AUTHOR("Yoshihiro Shimoda
><yoshihiro.shimoda.uh@renesas.com>");
>+MODULE_DESCRIPTION("Renesas UFS host controller driver");
>+MODULE_LICENSE("Dual MIT/GPL");
>--
>2.25.1



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

* Re: [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller
  2022-04-14  2:31 ` [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller Yoshihiro Shimoda
@ 2022-04-14  7:51   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 13+ messages in thread
From: Krzysztof Kozlowski @ 2022-04-14  7:51 UTC (permalink / raw)
  To: Yoshihiro Shimoda, alim.akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc

On 14/04/2022 04:31, Yoshihiro Shimoda wrote:
> Document Renesas R-Car UFS host controller for R-Car S4-8 (r8a779f0).
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  .../devicetree/bindings/ufs/renesas,ufs.yaml  | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ufs/renesas,ufs.yaml
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>


Best regards,
Krzysztof

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

* RE: [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
  2022-04-14  4:38   ` Alim Akhtar
@ 2022-04-14 11:39     ` Yoshihiro Shimoda
  0 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14 11:39 UTC (permalink / raw)
  To: Alim Akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc

Hi Alim,

Thank you for your review!

> From: Alim Akhtar, Sent: Thursday, April 14, 2022 1:39 PM
> 
> Hi Yoshihiro
> 
> >From: Yoshihiro Shimoda [mailto:yoshihiro.shimoda.uh@renesas.com]
> >Sent: Thursday, April 14, 2022 8:01 AM
> >
> >Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS for a broken host controller of
> >the 64-bit addressing supported capability.
> >
> A little more details in the commit message will help to understand the
> changes more.
> Does it mean this HCI has other addressing mode (other than 32 and 64)?
> Like a 36bit address? In that case, does Host controller is behind any
> IOMMU?

No, this HCI only has a 32bit address, but the MASK_64_ADDRESSING_SUPPORT is set...

Best regards,
Yoshihiro Shimoda

> 
> >Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> >---
> > drivers/scsi/ufs/ufshcd.c | 3 ++-
> > drivers/scsi/ufs/ufshcd.h | 6 ++++++
> > 2 files changed, 8 insertions(+), 1 deletion(-)
> >
> >diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index
> >3f9caafa91bf..a7bb3945c7c6 100644
> >--- a/drivers/scsi/ufs/ufshcd.c
> >+++ b/drivers/scsi/ufs/ufshcd.c
> >@@ -9513,7 +9513,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
> >  */
> > static int ufshcd_set_dma_mask(struct ufs_hba *hba)  {
> >-	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
> >+	if (!(hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) &&
> >+	    hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
> > 		if (!dma_set_mask_and_coherent(hba->dev,
> >DMA_BIT_MASK(64)))
> > 			return 0;
> > 	}
> >diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index
> >94f545be183a..1745144eb904 100644
> >--- a/drivers/scsi/ufs/ufshcd.h
> >+++ b/drivers/scsi/ufs/ufshcd.h
> >@@ -602,6 +602,12 @@ enum ufshcd_quirks {
> > 	 * support physical host configuration.
> > 	 */
> > 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
> >+
> >+	/*
> >+	 * This quirk needs to be enabled if the host controller has
> >+	 * 64-bit addressing supported capability but it doesn't work.
> >+	 */
> >+	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
> > };
> >
> > enum ufshcd_caps {
> >--
> >2.25.1
> 


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

* RE: [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller
  2022-04-14  4:59   ` Alim Akhtar
@ 2022-04-14 11:39     ` Yoshihiro Shimoda
  0 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2022-04-14 11:39 UTC (permalink / raw)
  To: Alim Akhtar, avri.altman, robh+dt, krzk+dt
  Cc: jejb, martin.petersen, linux-scsi, devicetree, linux-renesas-soc

Hi Alim,

Thank you for your review!

> From: Alim Akhtar, Sent: Thursday, April 14, 2022 1:59 PM
> 
> Hi Yoshihiro
> 
> >-----Original Message-----
> >From: Yoshihiro Shimoda [mailto:yoshihiro.shimoda.uh@renesas.com]
> >Sent: Thursday, April 14, 2022 8:01 AM
> >
> >Add support for Renesas R-Car UFS controller which needs vender specific
> >initialization.
> >
> >Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> >---
> > drivers/scsi/ufs/Kconfig       |  12 +
> > drivers/scsi/ufs/Makefile      |   1 +
> > drivers/scsi/ufs/ufs-renesas.c | 418
> >+++++++++++++++++++++++++++++++++
> > 3 files changed, 431 insertions(+)
> > create mode 100644 drivers/scsi/ufs/ufs-renesas.c
> >
> >diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index
> >9fe27b01904e..7e7ec1b26537 100644
> >--- a/drivers/scsi/ufs/Kconfig
> >+++ b/drivers/scsi/ufs/Kconfig
> >@@ -136,6 +136,18 @@ config SCSI_UFS_HISI
> > 	  Select this if you have UFS controller on Hisilicon chipset.
> > 	  If unsure, say N.
> >
> >+config SCSI_UFS_RENESAS
> >+	tristate "Renesas specific hooks to UFS controller platform driver"
> >+	depends on (ARCH_RENESAS || COMPILE_TEST) &&
> >SCSI_UFSHCD_PLATFORM
> >+	help
> >+	  This selects the Renesas specific additions to UFSHCD platform
> driver.
> >+	  UFS host on Renesas needs some vendor specific configuration
> >before
> >+	  accessing the hardware.
> >+
> >+	  Select this if you have UFS controller on Renesas chipset.
> >+
> >+	  If unsure, say N.
> >+
> > config SCSI_UFS_TI_J721E
> > 	tristate "TI glue layer for Cadence UFS Controller"
> > 	depends on OF && HAS_IOMEM && (ARCH_K3 || COMPILE_TEST) diff
> >--git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index
> >966048875b50..b7e4a739ea44 100644
> >--- a/drivers/scsi/ufs/Makefile
> >+++ b/drivers/scsi/ufs/Makefile
> >@@ -23,4 +23,5 @@ obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
> > obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> > obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
> > obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
> >+obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
> > obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o diff --git
> >a/drivers/scsi/ufs/ufs-renesas.c b/drivers/scsi/ufs/ufs-renesas.c new file
> >mode 100644 index 000000000000..5fb2484ead64
> >--- /dev/null
> >+++ b/drivers/scsi/ufs/ufs-renesas.c
> >@@ -0,0 +1,418 @@
> >+// SPDX-License-Identifier: GPL-2.0 OR MIT
> >+/*
> >+ * Renesas UFS host controller driver
> >+ *
> >+ * Copyright (C) 2022 Renesas Electronics Corporation  */
> >+
> >+#include <linux/clk.h>
> >+#include <linux/delay.h>
> >+#include <linux/err.h>
> >+#include <linux/iopoll.h>
> >+#include <linux/kernel.h>
> >+#include <linux/module.h>
> >+#include <linux/of.h>
> >+#include <linux/of_device.h>
> >+#include <linux/pm_runtime.h>
> >+
> >+#include "ufshcd.h"
> >+#include "ufshcd-pltfrm.h"
> >+
> >+struct ufs_renesas_priv {
> >+	bool initialized;	/* The hardware needs initialization once */
> >+};
> >+
> >+enum {
> >+	SET_PHY_INDEX_LO = 0,
> >+	SET_PHY_INDEX_HI,
> >+	TIMER_INDEX,
> >+	MAX_INDEX
> >+};
> >+
> >+enum ufs_renesas_init_param_mode {
> >+	MODE_RESTORE,
> >+	MODE_SET,
> >+	MODE_SAVE,
> >+	MODE_POLL,
> >+	MODE_WAIT,
> >+	MODE_WRITE,
> >+};
> >+
> >+#define PARAM_RESTORE(_reg, _index) \
> >+		{ .mode = MODE_RESTORE, .reg = _reg, .index = _index }
> >#define
> >+PARAM_SET(_index, _set) \
> >+		{ .mode = MODE_SET, .index = _index, .u.set = _set } #define
> >+PARAM_SAVE(_reg, _mask, _index) \
> >+		{ .mode = MODE_SAVE, .reg = _reg, .mask = (u32)(_mask), \
> >+		  .index = _index }
> >+#define PARAM_POLL(_reg, _expected, _mask) \
> >+		{ .mode = MODE_POLL, .reg = _reg, .u.expected = _expected,
> >\
> >+		  .mask = (u32)(_mask) }
> >+#define PARAM_WAIT(_delay_us) \
> >+		{ .mode = MODE_WAIT, .u.delay_us = _delay_us }
> >+
> >+#define PARAM_WRITE(_reg, _val) \
> >+		{ .mode = MODE_WRITE, .reg = _reg, .u.val = _val }
> >+
> >+#define PARAM_WRITE_D0_D4(_d0, _d4) \
> >+		PARAM_WRITE(0xd0, _d0),	PARAM_WRITE(0xd4, _d4)
> >+
> >+#define PARAM_WRITE_800_80C_POLL(_addr, _data_800)		\
> >+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
> >+		PARAM_WRITE_D0_D4(0x00000800, ((_data_800) << 16) |
> >BIT(8) | (_addr)), \
> >+		PARAM_WRITE(0xd0, 0x0000080c),			\
> >+		PARAM_POLL(0xd4, BIT(8), BIT(8))
> >+
> >+#define PARAM_RESTORE_800_80C_POLL(_index)			\
> >+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
> >+		PARAM_WRITE(0xd0, 0x00000800),			\
> >+		PARAM_RESTORE(0xd4, _index),			\
> >+		PARAM_WRITE(0xd0, 0x0000080c),			\
> >+		PARAM_POLL(0xd4, BIT(8), BIT(8))
> >+
> >+#define PARAM_WRITE_804_80C_POLL(_addr, _data_804)		\
> >+		PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),	\
> >+		PARAM_WRITE_D0_D4(0x00000804, ((_data_804) << 16) |
> >BIT(8) | (_addr)), \
> >+		PARAM_WRITE(0xd0, 0x0000080c),			\
> >+		PARAM_POLL(0xd4, BIT(8), BIT(8))
> >+
> >+#define PARAM_WRITE_828_82C_POLL(_data_828)			\
> >+		PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),	\
> >+		PARAM_WRITE_D0_D4(0x00000828, _data_828),	\
> >+		PARAM_WRITE(0xd0, 0x0000082c),			\
> >+		PARAM_POLL(0xd4, _data_828, _data_828)
> >+
> >+#define PARAM_WRITE_PHY(_addr16, _data16)			\
> >+		PARAM_WRITE(0xf0, 1),				\
> >+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
> >+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
> >\
> >+		PARAM_WRITE_800_80C_POLL(0x18, (_data16) & 0xff), \
> >+		PARAM_WRITE_800_80C_POLL(0x19, ((_data16) >> 8) & 0xff),
> >\
> >+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
> >+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
> >+		PARAM_WRITE(0xf0, 0)
> >+
> >+#define PARAM_SET_PHY(_addr16, _data16)				\
> >+		PARAM_WRITE(0xf0, 1),				\
> >+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
> >+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
> >\
> >+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
> >+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
> >+		PARAM_WRITE_804_80C_POLL(0x1a, 0),		\
> >+		PARAM_WRITE(0xd0, 0x00000808),			\
> >+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_LO),	\
> >+		PARAM_WRITE_804_80C_POLL(0x1b, 0),		\
> >+		PARAM_WRITE(0xd0, 0x00000808),			\
> >+		PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_HI),	\
> >+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
> >+		PARAM_WRITE(0xf0, 0),				\
> >+		PARAM_WRITE(0xf0, 1),				\
> >+		PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
> >+		PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff),
> >\
> >+		PARAM_SET(SET_PHY_INDEX_LO, ((_data16 & 0xff) << 16) |
> >BIT(8) | 0x18), \
> >+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_LO),
> >	\
> >+		PARAM_SET(SET_PHY_INDEX_HI, (((_data16 >> 8) & 0xff) <<
> >16) | BIT(8) | 0x19), \
> >+		PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_HI),
> >	\
> >+		PARAM_WRITE_800_80C_POLL(0x1c, 0x01),		\
> >+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
> >+		PARAM_WRITE(0xf0, 0)
> >+
> >+#define PARAM_INDIRECT_WRITE(_gpio, _addr, _data_800)		\
> >+		PARAM_WRITE(0xf0, _gpio),			\
> >+		PARAM_WRITE_800_80C_POLL(_addr, _data_800),	\
> >+		PARAM_WRITE_828_82C_POLL(0x0f000000),		\
> >+		PARAM_WRITE(0xf0, 0)
> >+
> >+#define PARAM_INDIRECT_POLL(_gpio, _addr, _expected, _mask)	\
> >+		PARAM_WRITE(0xf0, _gpio),			\
> >+		PARAM_WRITE_800_80C_POLL(_addr, 0),		\
> >+		PARAM_WRITE(0xd0, 0x00000808),			\
> >+		PARAM_POLL(0xd4, _expected, _mask),		\
> >+		PARAM_WRITE(0xf0, 0)
> >+
> 
> These above macro gives lot of checkpatch error, please fix the same.

The error is:
ERROR: Macros with complex values should be enclosed in parentheses

In general, we should fix a checkpatch error. However, these macros
can add multiple entries of struct ufs_renesas_init_param by a line.
In other words, we cannot add parentheses for it because build error
happens. If these macros are not acceptable, I need to write a lot
of lines to the entries instead and I think it will be less readability.

> >+struct ufs_renesas_init_param {
> >+	enum ufs_renesas_init_param_mode mode;
> >+	u32 reg;
> >+	union {
> >+		u32 expected;
> >+		u32 delay_us;
> >+		u32 set;
> >+		u32 val;
> >+	} u;
> >+	u32 mask;
> >+	u32 index;
> >+};
> >+
> >+/* This setting is for SERIES B */
> >+static const struct ufs_renesas_init_param ufs_param[] = {
> >+	PARAM_WRITE(0xc0, 0x49425308),
> >+	PARAM_WRITE_D0_D4(0x00000104, 0x00000002),
> >+	PARAM_WAIT(1),
> >+	PARAM_WRITE_D0_D4(0x00000828, 0x00000200),
> >+	PARAM_WAIT(1),
> >+	PARAM_WRITE_D0_D4(0x00000828, 0x00000000),
> >+	PARAM_WRITE_D0_D4(0x00000104, 0x00000001),
> >+	PARAM_WRITE_D0_D4(0x00000940, 0x00000001),
> >+	PARAM_WAIT(1),
> >+	PARAM_WRITE_D0_D4(0x00000940, 0x00000000),
> >+
> >+	PARAM_WRITE(0xc0, 0x49425308),
> >+	PARAM_WRITE(0xc0, 0x41584901),
> >+
> >+	PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),
> >+	PARAM_WRITE_D0_D4(0x00000804, 0x00000000),
> >+	PARAM_WRITE(0xd0, 0x0000080c),
> >+	PARAM_POLL(0xd4, BIT(8), BIT(8)),
> >+
> >+	PARAM_WRITE(REG_CONTROLLER_ENABLE, 0x00000001),
> >+
> >+	PARAM_WRITE(0xd0, 0x00000804),
> >+	PARAM_POLL(0xd4, BIT(8) | BIT(6) | BIT(0), BIT(8) | BIT(6) |
> BIT(0)),
> >+
> >+	PARAM_WRITE(0xd0, 0x00000d00),
> >+	PARAM_SAVE(0xd4, 0x0000ffff, TIMER_INDEX),
> >+	PARAM_WRITE(0xd4, 0x00000000),
> >+	PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),
> >+	PARAM_WRITE_D0_D4(0x00000828, 0x08000000),
> >+	PARAM_WRITE(0xd0, 0x0000082c),
> >+	PARAM_POLL(0xd4, BIT(27), BIT(27)),
> >+	PARAM_WRITE(0xd0, 0x00000d2c),
> >+	PARAM_POLL(0xd4, BIT(0), BIT(0)),
> >+
> >+	/* phy setup */
> >+	PARAM_INDIRECT_WRITE(1, 0x01, 0x001f),
> >+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
> >+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0014),
> >+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0003),
> >+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
> >+	PARAM_INDIRECT_WRITE(7, 0x5f, 0x0003),
> >+	PARAM_INDIRECT_WRITE(7, 0x60, 0x0003),
> >+	PARAM_INDIRECT_WRITE(7, 0x5b, 0x00a6),
> >+	PARAM_INDIRECT_WRITE(7, 0x5c, 0x0003),
> >+
> >+	PARAM_INDIRECT_POLL(7, 0x3c, 0, BIT(7)),
> >+	PARAM_INDIRECT_POLL(7, 0x4c, 0, BIT(4)),
> >+
> >+	PARAM_INDIRECT_WRITE(1, 0x32, 0x0080),
> >+	PARAM_INDIRECT_WRITE(1, 0x1f, 0x0001),
> >+	PARAM_INDIRECT_WRITE(0, 0x2c, 0x0001),
> >+	PARAM_INDIRECT_WRITE(0, 0x32, 0x0087),
> >+
> >+	PARAM_INDIRECT_WRITE(1, 0x4d, 0x0061),
> >+	PARAM_INDIRECT_WRITE(4, 0x9b, 0x0009),
> >+	PARAM_INDIRECT_WRITE(4, 0xa6, 0x0005),
> >+	PARAM_INDIRECT_WRITE(4, 0xa5, 0x0058),
> >+	PARAM_INDIRECT_WRITE(1, 0x39, 0x0027),
> >+	PARAM_INDIRECT_WRITE(1, 0x47, 0x004c),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x0d, 0x0002),
> >+	PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
> >+
> >+	PARAM_WRITE_PHY(0x0028, 0x0061),
> >+	PARAM_WRITE_PHY(0x4014, 0x0061),
> >+	PARAM_SET_PHY(0x401c, BIT(2)),
> >+	PARAM_WRITE_PHY(0x4000, 0x0000),
> >+	PARAM_WRITE_PHY(0x4001, 0x0000),
> >+
> >+	PARAM_WRITE_PHY(0x10ae, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ad, 0x0000),
> >+	PARAM_WRITE_PHY(0x10af, 0x0001),
> >+	PARAM_WRITE_PHY(0x10b6, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ae, 0x0000),
> >+
> >+	PARAM_WRITE_PHY(0x10ae, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ad, 0x0000),
> >+	PARAM_WRITE_PHY(0x10af, 0x0002),
> >+	PARAM_WRITE_PHY(0x10b6, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ae, 0x0000),
> >+
> >+	PARAM_WRITE_PHY(0x10ae, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ad, 0x0080),
> >+	PARAM_WRITE_PHY(0x10af, 0x0000),
> >+	PARAM_WRITE_PHY(0x10b6, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ae, 0x0000),
> >+
> >+	PARAM_WRITE_PHY(0x10ae, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ad, 0x0080),
> >+	PARAM_WRITE_PHY(0x10af, 0x001a),
> >+	PARAM_WRITE_PHY(0x10b6, 0x0001),
> >+	PARAM_WRITE_PHY(0x10ae, 0x0000),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x70, 0x0016),
> >+	PARAM_INDIRECT_WRITE(7, 0x71, 0x0016),
> >+	PARAM_INDIRECT_WRITE(7, 0x72, 0x0014),
> >+	PARAM_INDIRECT_WRITE(7, 0x73, 0x0014),
> >+	PARAM_INDIRECT_WRITE(7, 0x74, 0x0000),
> >+	PARAM_INDIRECT_WRITE(7, 0x75, 0x0000),
> >+	PARAM_INDIRECT_WRITE(7, 0x76, 0x0010),
> >+	PARAM_INDIRECT_WRITE(7, 0x77, 0x0010),
> >+	PARAM_INDIRECT_WRITE(7, 0x78, 0x00ff),
> >+	PARAM_INDIRECT_WRITE(7, 0x79, 0x0000),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x19, 0x0007),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x1a, 0x0007),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x24, 0x000c),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x25, 0x000c),
> >+
> >+	PARAM_INDIRECT_WRITE(7, 0x62, 0x0000),
> >+	PARAM_INDIRECT_WRITE(7, 0x63, 0x0000),
> >+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
> >+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
> >+	PARAM_INDIRECT_WRITE(7, 0x5d, 0x0004),
> >+	PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
> >+	PARAM_INDIRECT_POLL(7, 0x55, 0, BIT(6)),
> >+	PARAM_INDIRECT_POLL(7, 0x41, 0, BIT(7)),
> >+	/* end of phy setup */
> >+
> >+	PARAM_WRITE(0xf0, 0),
> >+	PARAM_WRITE(0xd0, 0x00000d00),
> >+	PARAM_RESTORE(0xd4, TIMER_INDEX),
> >+};
> >+
> >+static void ufs_renesas_dbg_register_dump(struct ufs_hba *hba) {
> >+	ufshcd_dump_regs(hba, 0xc0, 0x40, "regs: 0xc0 + "); }
> >+
> >+static void ufs_renesas_reg_control(struct ufs_hba *hba,
> >+				    const struct ufs_renesas_init_param *p)
> {
> >+	static u32 save[MAX_INDEX];
> >+	int ret;
> >+	u32 val;
> >+
> >+	pr_debug("%s: %d %04x %08x, %08x, %d\n", __func__, p->mode, p-
> >>reg,
> >+		 p->u.val, p->mask, p->index);
> >+
> >+	BUG_ON(p->index >= MAX_INDEX);
> 
> Do you really need a BUG_ON here? May be a WARN_ON?

WARN_ON() is OK to me. So, I'll fix it.

Best regards,
Yoshihiro Shimoda

> >+
> >+	switch (p->mode) {
> >+	case MODE_RESTORE:
> >+		ufshcd_writel(hba, save[p->index], p->reg);
> >+		break;
> >+	case MODE_SET:
> >+		pr_debug("%s: %d %x %x\n", __func__, p->index, save[p-
> >>index],
> >+			 p->u.set);
> >+		save[p->index] |= p->u.set;
> >+		break;
> >+	case MODE_SAVE:
> >+		save[p->index] = ufshcd_readl(hba, p->reg) & p->mask;
> >+		pr_debug("%s: index = %d, val = %08x\n", __func__,
> >+			 p->index, val);
> >+		break;
> >+	case MODE_POLL:
> >+		ret = readl_poll_timeout_atomic(hba->mmio_base + p->reg,
> >+						val,
> >+						(val & p->mask) == p-
> >>u.expected,
> >+						10, 1000);
> >+		if (ret)
> >+			pr_err("%s: poll failed %d (%08x, %08x, %08x)\n",
> >+			       __func__, ret, val, p->mask, p->u.expected);
> >+		break;
> >+	case MODE_WAIT:
> >+		if (p->u.delay_us > 1000)
> >+			mdelay(p->u.delay_us / 1000);
> >+		else
> >+			udelay(p->u.delay_us);
> >+		break;
> >+	case MODE_WRITE:
> >+		ufshcd_writel(hba, p->u.val, p->reg);
> >+		break;
> >+	default:
> >+		break;
> >+	}
> >+}
> >+
> >+static void ufs_renesas_pre_init(struct ufs_hba *hba) {
> >+	const struct ufs_renesas_init_param *p = ufs_param;
> >+	int i;
> >+
> >+	for (i = 0; i < ARRAY_SIZE(ufs_param); i++)
> >+		ufs_renesas_reg_control(hba, &p[i]);
> >+}
> >+
> >+static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba,
> >+					 enum ufs_notify_change_status
> >status) {
> >+	struct ufs_renesas_priv *priv = ufshcd_get_variant(hba);
> >+
> >+	if (priv->initialized)
> >+		return 0;
> >+
> >+	if (status == PRE_CHANGE)
> >+		ufs_renesas_pre_init(hba);
> >+
> >+	priv->initialized = true;
> >+
> >+	return 0;
> >+}
> >+
> >+static int ufs_renesas_setup_clocks(struct ufs_hba *hba, bool on,
> >+				    enum ufs_notify_change_status status) {
> >+	if (on && status == PRE_CHANGE)
> >+		pm_runtime_get_sync(hba->dev);
> >+	else if (!on && status == POST_CHANGE)
> >+		pm_runtime_put(hba->dev);
> >+
> >+	return 0;
> >+}
> >+
> >+static int ufs_renesas_init(struct ufs_hba *hba) {
> >+	struct ufs_renesas_priv *priv;
> >+
> >+	priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL);
> >+	if (!priv)
> >+		return -ENOMEM;
> >+	ufshcd_set_variant(hba, priv);
> >+
> >+	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS |
> >+UFSHCD_QUIRK_HIBERN_FASTAUTO;
> >+
> >+	return 0;
> >+}
> >+
> >+static const struct ufs_hba_variant_ops ufs_renesas_vops = {
> >+	.name		= "renesas",
> >+	.init		= ufs_renesas_init,
> >+	.setup_clocks	= ufs_renesas_setup_clocks,
> >+	.hce_enable_notify = ufs_renesas_hce_enable_notify,
> >+	.dbg_register_dump = ufs_renesas_dbg_register_dump, };
> >+
> >+static const struct of_device_id __maybe_unused ufs_renesas_of_match[]
> >= {
> >+	{ .compatible = "renesas,r8a779f0-ufs" }, };
> >MODULE_DEVICE_TABLE(of,
> >+ufs_renesas_of_match);
> >+
> >+static int ufs_renesas_probe(struct platform_device *pdev) {
> >+	return ufshcd_pltfrm_init(pdev, &ufs_renesas_vops); }
> >+
> >+static int ufs_renesas_remove(struct platform_device *pdev) {
> >+	struct ufs_hba *hba = platform_get_drvdata(pdev);
> >+
> >+	ufshcd_remove(hba);
> >+
> >+	return 0;
> >+}
> >+
> >+static struct platform_driver ufs_renesas_platform = {
> >+	.probe	= ufs_renesas_probe,
> >+	.remove	= ufs_renesas_remove,
> >+	.driver	= {
> >+		.name	= "ufshcd-renesas",
> >+		.of_match_table	=
> >of_match_ptr(ufs_renesas_of_match),
> >+	},
> >+};
> >+module_platform_driver(ufs_renesas_platform);
> >+
> >+MODULE_AUTHOR("Yoshihiro Shimoda
> ><yoshihiro.shimoda.uh@renesas.com>");
> >+MODULE_DESCRIPTION("Renesas UFS host controller driver");
> >+MODULE_LICENSE("Dual MIT/GPL");
> >--
> >2.25.1
> 


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

end of thread, other threads:[~2022-04-14 11:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-14  2:31 [PATCH v2 0/7] treewide: scsi: ufs: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 1/7] dt-bindings: ufs: Document Renesas R-Car UFS host controller Yoshihiro Shimoda
2022-04-14  7:51   ` Krzysztof Kozlowski
2022-04-14  2:31 ` [PATCH v2 2/7] ufs: add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS Yoshihiro Shimoda
2022-04-14  4:38   ` Alim Akhtar
2022-04-14 11:39     ` Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 3/7] ufs: add UFSHCD_QUIRK_HIBERN_FASTAUTO Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 4/7] scsi: ufs-renesas: Add support for Renesas R-Car UFS controller Yoshihiro Shimoda
2022-04-14  4:59   ` Alim Akhtar
2022-04-14 11:39     ` Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 5/7] scsi: MAINTAINERS: Add maintainer for Renesas UFS driver Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 6/7] arm64: dts: renesas: r8a779f0: Add UFS node Yoshihiro Shimoda
2022-04-14  2:31 ` [PATCH v2 7/7] arm64: dts: renesas: r8a779f0: spider-cpu: Enable UFS device Yoshihiro Shimoda

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.