linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/17] Basical Allwinner R329 support
@ 2021-08-02  6:21 Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 01/17] rtc: sun6i: Fix time overflow handling Icenowy Zheng
                   ` (17 more replies)
  0 siblings, 18 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:21 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

This patchset tries to add basical support for Allwinner R329 SoC to the
Linux kernel, including clock/pintrl driver and MMC support.

Three patches from the H616 patchset, which are used to support the RTC
with linear day, are attached into this patchset. Other RTC-related
patches of that patchset is not included, because the binding of the
clock part there is still under discussion.

Then I added RTC binding and support (which is now only a struct
addition). I added RTC into this patchset, with the same reason that
H616 patchset contains RTC, which is to make the clock tree correct at
the first inclusion.

After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
R329 CCU is something special because PLLs are in R-CCU, no main CCU.

MMC support is added here because it's also a simple struct addition
work, no main driver code change needed.

Finally it comes the DT part. The DT binding of MaixSense, the device
that I am working on now, is added. Then the DTSI for R329 SoC, the DTSI
file for Sipeed Maix IIA SoM (which is utilized on MaixSense) and the
main DT file for MaixSense are added.

Andre Przywara (3):
  rtc: sun6i: Fix time overflow handling
  rtc: sun6i: Add support for linear day storage
  rtc: sun6i: Add support for broken-down alarm registers

Icenowy Zheng (14):
  dt-bindings: rtc: sun6i: add compatible string for R329 RTC
  rtc: sun6i: add support for R329 RTC
  dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  pinctrl: sunxi: add support for R329 CPUX pin controller
  pinctrl: sunxi: add support for R329 R-PIO pin controller
  dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs
  clk: sunxi=ng: add support for R329 R-CCU
  clk: sunxi-ng: add support for Allwinner R329 CCU
  dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
  mmc: sunxi: add support for R329 MMC controllers
  dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
  arm64: allwinner: dts: add DTSI file for R329 SoC
  arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA
  arm64: allwinner: dts: r329: add support for Sipeed MaixSense

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 .../clock/allwinner,sun4i-a10-ccu.yaml        |   4 +
 .../bindings/mmc/allwinner,sun4i-a10-mmc.yaml |   1 +
 .../pinctrl/allwinner,sun4i-a10-pinctrl.yaml  |   4 +
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml |   6 +-
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../dts/allwinner/sun50i-r329-maix-iia.dtsi   |  34 ++
 .../dts/allwinner/sun50i-r329-maixsense.dts   |  37 ++
 .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++
 drivers/clk/sunxi-ng/Kconfig                  |  10 +
 drivers/clk/sunxi-ng/Makefile                 |   2 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 +++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.c        | 526 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.h        |  32 ++
 drivers/mmc/host/sunxi-mmc.c                  |  10 +
 drivers/pinctrl/sunxi/Kconfig                 |  10 +
 drivers/pinctrl/sunxi/Makefile                |   2 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c   | 410 ++++++++++++++
 drivers/rtc/rtc-sun6i.c                       | 154 +++--
 include/dt-bindings/clock/sun50i-r329-ccu.h   |  73 +++
 include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
 include/dt-bindings/reset/sun50i-r329-ccu.h   |  45 ++
 include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 +
 25 files changed, 2320 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
 create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

-- 
2.30.2


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

* [PATCH 01/17] rtc: sun6i: Fix time overflow handling
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
@ 2021-08-02  6:21 ` Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 02/17] rtc: sun6i: Add support for linear day storage Icenowy Zheng
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:21 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

From: Andre Przywara <andre.przywara@arm.com>

Using "unsigned long" for UNIX timestamps is never a good idea, and
comparing the value of such a variable against U32_MAX does not do
anything useful on 32-bit systems.

Use the proper time64_t type when dealing with timestamps, and avoid
cutting down the time range unnecessarily. This also fixes the flawed
check for the alarm time being too far into the future.

The check for this condition is actually somewhat theoretical, as the
RTC counts till 2033 only anyways, and 2^32 seconds from now is not
before the year 2157 - at which point I hope nobody will be using this
hardware anymore.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index adec1b14a8de..c551ebf0ac00 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -138,7 +138,7 @@ struct sun6i_rtc_dev {
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
-	unsigned long alarm;
+	time64_t alarm;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -510,10 +510,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	unsigned long time_now = 0;
-	unsigned long time_set = 0;
-	unsigned long time_gap = 0;
-	int ret = 0;
+	time64_t time_now, time_set;
+	int ret;
 
 	ret = sun6i_rtc_gettime(dev, &tm_now);
 	if (ret < 0) {
@@ -528,9 +526,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 		return -EINVAL;
 	}
 
-	time_gap = time_set - time_now;
-
-	if (time_gap > U32_MAX) {
+	if ((time_set - time_now) > U32_MAX) {
 		dev_err(dev, "Date too far in the future\n");
 		return -EINVAL;
 	}
@@ -539,7 +535,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
 	usleep_range(100, 300);
 
-	writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
+	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.30.2


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

* [PATCH 02/17] rtc: sun6i: Add support for linear day storage
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 01/17] rtc: sun6i: Fix time overflow handling Icenowy Zheng
@ 2021-08-02  6:21 ` Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 03/17] rtc: sun6i: Add support for broken-down alarm registers Icenowy Zheng
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:21 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

From: Andre Przywara <andre.przywara@arm.com>

Newer versions of the Allwinner RTC, as for instance found in the H616
SoC, no longer store a broken-down day/month/year representation in the
RTC_DAY_REG, but just a linear day number.
The user manual does not give any indication about the expected epoch
time of this day count, but the BSP kernel uses the UNIX epoch, which
allows easy support due to existing conversion functions in the kernel.

Allow tagging a compatible string with a flag, and use that to mark
those new RTCs. Then convert between a UNIX day number (converted into
seconds) and the broken-down day representation using mktime64() and
time64_to_tm() in the set_time/get_time functions.

That enables support for the RTC in those new chips.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 69 +++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c551ebf0ac00..a980d4e7408d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -110,6 +110,8 @@
 #define SUN6I_YEAR_MIN				1970
 #define SUN6I_YEAR_OFF				(SUN6I_YEAR_MIN - 1900)
 
+#define SECS_PER_DAY				(24 * 3600ULL)
+
 /*
  * There are other differences between models, including:
  *
@@ -133,12 +135,15 @@ struct sun6i_rtc_clk_data {
 	unsigned int has_auto_swt : 1;
 };
 
+#define RTC_LINEAR_DAY	BIT(0)
+
 struct sun6i_rtc_dev {
 	struct rtc_device *rtc;
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
 	time64_t alarm;
+	unsigned long flags;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -467,22 +472,30 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 	} while ((date != readl(chip->base + SUN6I_RTC_YMD)) ||
 		 (time != readl(chip->base + SUN6I_RTC_HMS)));
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * Newer chips store a linear day number, the manual
+		 * does not mandate any epoch base. The BSP driver uses
+		 * the UNIX epoch, let's just copy that, as it's the
+		 * easiest anyway.
+		 */
+		rtc_time64_to_tm((date & 0xffff) * SECS_PER_DAY, rtc_tm);
+	} else {
+		rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
+		rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date) - 1;
+		rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
+
+		/*
+		 * switch from (data_year->min)-relative offset to
+		 * a (1900)-relative one
+		 */
+		rtc_tm->tm_year += SUN6I_YEAR_OFF;
+	}
+
 	rtc_tm->tm_sec  = SUN6I_TIME_GET_SEC_VALUE(time);
 	rtc_tm->tm_min  = SUN6I_TIME_GET_MIN_VALUE(time);
 	rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time);
 
-	rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
-	rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date);
-	rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
-
-	rtc_tm->tm_mon  -= 1;
-
-	/*
-	 * switch from (data_year->min)-relative offset to
-	 * a (1900)-relative one
-	 */
-	rtc_tm->tm_year += SUN6I_YEAR_OFF;
-
 	return 0;
 }
 
@@ -567,20 +580,25 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
 	u32 date = 0;
 	u32 time = 0;
 
-	rtc_tm->tm_year -= SUN6I_YEAR_OFF;
-	rtc_tm->tm_mon += 1;
-
-	date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
-		SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
-		SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
-
-	if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
-		date |= SUN6I_LEAP_SET_VALUE(1);
-
 	time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec)  |
 		SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min)  |
 		SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/* The division will cut off the H:M:S part of rtc_tm. */
+		date = div_u64(rtc_tm_to_time64(rtc_tm), SECS_PER_DAY);
+	} else {
+		rtc_tm->tm_year -= SUN6I_YEAR_OFF;
+		rtc_tm->tm_mon += 1;
+
+		date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
+			SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
+			SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
+
+		if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
+			date |= SUN6I_LEAP_SET_VALUE(1);
+	}
+
 	/* Check whether registers are writable */
 	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
 			   SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
@@ -674,6 +692,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
+	chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev);
+
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0)
 		return chip->irq;
@@ -720,7 +740,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 		return PTR_ERR(chip->rtc);
 
 	chip->rtc->ops = &sun6i_rtc_ops;
-	chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
+	if (chip->flags & RTC_LINEAR_DAY)
+		chip->rtc->range_max = (65536 * SECS_PER_DAY) - 1;
+	else
+		chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
 
 	ret = devm_rtc_register_device(chip->rtc);
 	if (ret)
-- 
2.30.2


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

* [PATCH 03/17] rtc: sun6i: Add support for broken-down alarm registers
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 01/17] rtc: sun6i: Fix time overflow handling Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 02/17] rtc: sun6i: Add support for linear day storage Icenowy Zheng
@ 2021-08-02  6:21 ` Icenowy Zheng
  2021-08-02  6:21 ` [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC Icenowy Zheng
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:21 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

From: Andre Przywara <andre.przywara@arm.com>

Newer versions of the Allwinner RTC, for instance as found in the H616
SoC, not only store the current day as a linear number, but also change
the way the alarm is handled: There are now two registers, that
explicitly store the wakeup time, in the same format as the current
time.

Add support for that variant by writing the requested wakeup time
directly into the registers, instead of programming the seconds left, as
the old SoCs required.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 57 +++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a980d4e7408d..752bea949050 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -48,7 +48,8 @@
 
 /* Alarm 0 (counter) */
 #define SUN6I_ALRM_COUNTER			0x0020
-#define SUN6I_ALRM_CUR_VAL			0x0024
+/* This holds the remaining alarm seconds on older SoCs (current value) */
+#define SUN6I_ALRM_COUNTER_HMS			0x0024
 #define SUN6I_ALRM_EN				0x0028
 #define SUN6I_ALRM_EN_CNT_EN			BIT(0)
 #define SUN6I_ALRM_IRQ_EN			0x002c
@@ -523,32 +524,54 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	time64_t time_now, time_set;
+	time64_t time_set;
+	u32 counter_val, counter_val_hms;
 	int ret;
 
-	ret = sun6i_rtc_gettime(dev, &tm_now);
-	if (ret < 0) {
-		dev_err(dev, "Error in getting time\n");
-		return -EINVAL;
-	}
-
 	time_set = rtc_tm_to_time64(alrm_tm);
-	time_now = rtc_tm_to_time64(&tm_now);
-	if (time_set <= time_now) {
-		dev_err(dev, "Date to set in the past\n");
-		return -EINVAL;
-	}
 
-	if ((time_set - time_now) > U32_MAX) {
-		dev_err(dev, "Date too far in the future\n");
-		return -EINVAL;
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * The alarm registers hold the actual alarm time, encoded
+		 * in the same way (linear day + HMS) as the current time.
+		 */
+		counter_val_hms = SUN6I_TIME_SET_SEC_VALUE(alrm_tm->tm_sec)  |
+				  SUN6I_TIME_SET_MIN_VALUE(alrm_tm->tm_min)  |
+				  SUN6I_TIME_SET_HOUR_VALUE(alrm_tm->tm_hour);
+		/* The division will cut off the H:M:S part of alrm_tm. */
+		counter_val = div_u64(rtc_tm_to_time64(alrm_tm), SECS_PER_DAY);
+	} else {
+		/* The alarm register holds the number of seconds left. */
+		time64_t time_now;
+
+		ret = sun6i_rtc_gettime(dev, &tm_now);
+		if (ret < 0) {
+			dev_err(dev, "Error in getting time\n");
+			return -EINVAL;
+		}
+
+		time_now = rtc_tm_to_time64(&tm_now);
+		if (time_set <= time_now) {
+			dev_err(dev, "Date to set in the past\n");
+			return -EINVAL;
+		}
+		if ((time_set - time_now) > U32_MAX) {
+			dev_err(dev, "Date too far in the future\n");
+			return -EINVAL;
+		}
+
+		counter_val = time_set - time_now;
 	}
 
 	sun6i_rtc_setaie(0, chip);
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(0, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	usleep_range(100, 300);
 
-	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
+	writel(counter_val, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(counter_val_hms, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.30.2


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

* [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (2 preceding siblings ...)
  2021-08-02  6:21 ` [PATCH 03/17] rtc: sun6i: Add support for broken-down alarm registers Icenowy Zheng
@ 2021-08-02  6:21 ` Icenowy Zheng
  2021-08-06 21:39   ` Rob Herring
  2021-08-02  6:22 ` [PATCH 05/17] rtc: sun6i: add support " Icenowy Zheng
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:21 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 has a RTC similar to previous ones, capable of
controlling LOSC and IOSC and with only one alarm.

Add a compatible string for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml    | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index beeb90e55727..7fd1ad46496b 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -26,6 +26,7 @@ properties:
           - const: allwinner,sun50i-a64-rtc
           - const: allwinner,sun8i-h3-rtc
       - const: allwinner,sun50i-h6-rtc
+      - const: allwinner,sun50i-r329-rtc
 
   reg:
     maxItems: 1
@@ -85,6 +86,7 @@ allOf:
             enum:
               - allwinner,sun8i-h3-rtc
               - allwinner,sun50i-h5-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
       properties:
@@ -108,7 +110,9 @@ allOf:
       properties:
         compatible:
           contains:
-            const: allwinner,sun8i-r40-rtc
+            enum:
+              - allwinner,sun8i-r40-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
       properties:
-- 
2.30.2


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

* [PATCH 05/17] rtc: sun6i: add support for R329 RTC
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (3 preceding siblings ...)
  2021-08-02  6:21 ` [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 SoC has a RTC with similar clock control capability to
H6, but its day storage changed to be linear, similar to the one in H616
RTC.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/rtc/rtc-sun6i.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 752bea949050..06eca57e5215 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -386,6 +386,24 @@ static void __init sun50i_h6_rtc_clk_init(struct device_node *node)
 CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc",
 		      sun50i_h6_rtc_clk_init);
 
+static const struct sun6i_rtc_clk_data sun50i_r329_rtc_data = {
+	.rc_osc_rate = 16000000,
+	.fixed_prescaler = 32,
+	.has_prescaler = 1,
+	.has_out_clk = 1,
+	.export_iosc = 1,
+	.has_losc_en = 1,
+	.has_auto_swt = 1,
+};
+
+static void __init sun50i_r329_rtc_clk_init(struct device_node *node)
+{
+	sun6i_rtc_clk_init(node, &sun50i_r329_rtc_data);
+}
+
+CLK_OF_DECLARE_DRIVER(sun50i_r329_rtc_clk, "allwinner,sun50i-r329-rtc",
+		      sun50i_r329_rtc_clk_init);
+
 /*
  * The R40 user manual is self-conflicting on whether the prescaler is
  * fixed or configurable. The clock diagram shows it as fixed, but there
@@ -791,6 +809,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun8i-v3-rtc" },
 	{ .compatible = "allwinner,sun50i-h5-rtc" },
 	{ .compatible = "allwinner,sun50i-h6-rtc" },
+	{ .compatible = "allwinner,sun50i-r329-rtc",
+		.data = (void *)RTC_LINEAR_DAY },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
-- 
2.30.2


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

* [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (4 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 05/17] rtc: sun6i: add support " Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:40   ` Rob Herring
                     ` (2 more replies)
  2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
                   ` (11 subsequent siblings)
  17 siblings, 3 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 have two pin controllers similar to previous Allwinner
SoCs, PIO and R-PIO.

Add compatible strings for them.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
index cce63c3cc463..802fba3fa34d 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
@@ -55,6 +55,8 @@ properties:
       - allwinner,sun50i-h6-r-pinctrl
       - allwinner,sun50i-h616-pinctrl
       - allwinner,sun50i-h616-r-pinctrl
+      - allwinner,sun50i-r329-pinctrl
+      - allwinner,sun50i-r329-r-pinctrl
       - allwinner,suniv-f1c100s-pinctrl
       - nextthing,gr8-pinctrl
 
@@ -189,6 +191,7 @@ allOf:
             - allwinner,sun6i-a31-pinctrl
             - allwinner,sun6i-a31s-pinctrl
             - allwinner,sun50i-h6-pinctrl
+            - allwinner,sun50i-r329-pinctrl
 
     then:
       properties:
@@ -204,6 +207,7 @@ allOf:
             - allwinner,sun8i-a83t-pinctrl
             - allwinner,sun50i-a64-pinctrl
             - allwinner,sun50i-h5-pinctrl
+            - allwinner,sun50i-r329-r-pinctrl
             - allwinner,suniv-f1c100s-pinctrl
 
     then:
-- 
2.30.2


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

* [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (5 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-11  9:23   ` Linus Walleij
                     ` (2 more replies)
  2021-08-02  6:22 ` [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO " Icenowy Zheng
                   ` (10 subsequent siblings)
  17 siblings, 3 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 SoC has two pin controllers similar to ones on previous
SoCs, one in CPUX power domain and another in CPUS.

This patch adds support for the CPUX domain pin controller.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/pinctrl/sunxi/Kconfig               |   5 +
 drivers/pinctrl/sunxi/Makefile              |   1 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++++++++++
 3 files changed, 416 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 33751a6a0757..c662e8b1b351 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -129,4 +129,9 @@ config PINCTRL_SUN50I_H616_R
 	default ARM64 && ARCH_SUNXI
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN50I_R329
+	bool "Support for the Allwinner R329 PIO"
+	default ARM64 && ARCH_SUNXI
+	select PINCTRL_SUNXI
+
 endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index d3440c42b9d6..e33f7c5f1ff9 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
new file mode 100644
index 000000000000..742f437ec0b6
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner R329 SoC pinctrl driver.
+ *
+ * Copyright (C) 2021 Sipeed
+ * based on the H616 pinctrl driver
+ *   Copyright (C) 2020 Arm Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin r329_pins[] = {
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
+		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* MCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* LRCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* BCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION(0x4, "i2s0_dout0"),
+		  SUNXI_FUNCTION(0x5, "i2s0_din1"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION(0x4, "i2s0_dout1"),
+		  SUNXI_FUNCTION(0x5, "i2s0_din0"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM6 */
+		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT2 */
+		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM7 */
+		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT3 */
+		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir_tx"),
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM8 */
+		  SUNXI_FUNCTION(0x4, "ir_rx"),
+		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* RB0 */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* CS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* RE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* CE0 */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* WP */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* CLE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* ALE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* WE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* HOLD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc0")),		/* RST */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ1 */
+		  SUNXI_FUNCTION(0x5, "boot_sel")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPEN */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PF_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPPP */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PF_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ5 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* PWREN */
+		  SUNXI_FUNCTION(0x4, "uart"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PF_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ4 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PF_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* DATA */
+		  SUNXI_FUNCTION(0x4, "uart"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PF_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ2 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* RST */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PF_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ1 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* DET */
+		  SUNXI_FUNCTION(0x4, "spdif_in"),
+		  SUNXI_FUNCTION(0x5, "spdif_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PF_EINT6 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_clk"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d2"),
+		  /* 0x4 is also mmc1_d2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PG_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_cmd"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d3"),
+		  SUNXI_FUNCTION(0x4, "mmc1_clk"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PG_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d0"),
+		  SUNXI_FUNCTION(0x3, "mmc1_cmd"),
+		  SUNXI_FUNCTION(0x4, "mmc1_d3"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PG_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d1"),
+		  SUNXI_FUNCTION(0x3, "mmc1_clk"),
+		  /* 0x4 is also mmc1_d1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PG_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d2"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d0"),
+		  /* 0x4 is also mmc1_d0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PG_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d3"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d1"),
+		  SUNXI_FUNCTION(0x4, "mmc1_cmd"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PG_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PG_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PG_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PG_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* WP/DBI-TE */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PG_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PG_EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* LRCK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* CS/DBI-CSX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PG_EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* BCLK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PG_EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "i2s1_dout0"),
+		  SUNXI_FUNCTION(0x4, "i2s1_din1"),
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* MOSI/DBI-SDO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PG_EINT13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "i2s1_dout1"),
+		  SUNXI_FUNCTION(0x4, "i2s1_din0"),
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PG_EINT14 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS/DBI-CSX */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)),	/* PH_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)),	/* PH_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MOSI/DBI-SDO */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)),	/* PH_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "spdif"),		/* OUT */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)),	/* PH_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "spi1_cs"),	/* CS/DBI-CSX */
+		  SUNXI_FUNCTION(0x4, "spi1_hold"),	/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)),	/* PH_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "spi1_clk"),	/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION(0x4, "spi1_wp"),	/* WP/DBI-TE */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)),	/* PH_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI/SPI-DBO */
+		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)),	/* PH_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)),	/* PH_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* WP/DBI-TE */
+		  SUNXI_FUNCTION(0x4, "ledc"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)),	/* PH_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION(0x4, "spdif"),		/* IN */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)),	/* PH_EINT9 */
+};
+static const unsigned int r329_irq_bank_map[] = { 1, 5, 6, 7 };
+
+static const struct sunxi_pinctrl_desc r329_pinctrl_data = {
+	.pins = r329_pins,
+	.npins = ARRAY_SIZE(r329_pins),
+	.irq_banks = ARRAY_SIZE(r329_irq_bank_map),
+	.irq_bank_map = r329_irq_bank_map,
+	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int r329_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev, &r329_pinctrl_data);
+}
+
+static const struct of_device_id r329_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun50i-r329-pinctrl", },
+	{}
+};
+
+static struct platform_driver r329_pinctrl_driver = {
+	.probe	= r329_pinctrl_probe,
+	.driver	= {
+		.name		= "sun50i-r329-pinctrl",
+		.of_match_table	= r329_pinctrl_match,
+	},
+};
+builtin_platform_driver(r329_pinctrl_driver);
-- 
2.30.2


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

* [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin controller
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (6 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-18  8:52   ` Maxime Ripard
  2021-08-19  3:22   ` Samuel Holland
  2021-08-02  6:22 ` [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs Icenowy Zheng
                   ` (9 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R320 SoC has a pin controller in the CPUS power domain.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/pinctrl/sunxi/Kconfig                 |   5 +
 drivers/pinctrl/sunxi/Makefile                |   1 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++++++++++
 3 files changed, 298 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index c662e8b1b351..abd60ff8daec 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -134,4 +134,9 @@ config PINCTRL_SUN50I_R329
 	default ARM64 && ARCH_SUNXI
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN50I_R329_R
+	bool "Support for the Allwinner R329 R-PIO"
+	default ARM64 && ARCH_SUNXI
+	select PINCTRL_SUNXI
+
 endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index e33f7c5f1ff9..245840a7959e 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329_R)	+= pinctrl-sun50i-r329-r.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
new file mode 100644
index 000000000000..dc4792c685ba
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner H616 R_PIO pin controller driver
+ *
+ * Copyright (C) 2020 Arm Ltd.
+ * Based on former work, which is:
+ *   Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun50i_r329_r_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* LRCK */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA3 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PL_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* BCLK */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA2 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PL_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s_dout0"),
+		  SUNXI_FUNCTION(0x3, "s_i2s_din1"),
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA1 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PL_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s_dout1"),
+		  SUNXI_FUNCTION(0x3, "s_i2s_din0"),
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA0 */
+		  SUNXI_FUNCTION(0x5, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PL_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* CLK */
+		  SUNXI_FUNCTION(0x5, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PL_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PL_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PL_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PL_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x4, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PL_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PL_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)),	/* PL_EINT10 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* MS */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PM_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* CK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PM_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* DO */
+		  SUNXI_FUNCTION(0x4, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PM_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PM_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PM_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* DI */
+		  SUNXI_FUNCTION(0x4, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PM_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nmi"),
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PM_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)),	/* PM_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 8)),	/* PM_EINT8 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PN_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* MDC */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PN_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* MDIO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PN_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PN_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PN_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PN_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PN_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PN_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXERR */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PN_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXCTL/TXEN */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PN_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PN_EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PN_EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXCTL/CRS_DV */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PN_EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PN_EINT13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PN_EINT14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)),	/* PN_EINT15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* EPHY-25M */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)),	/* PN_EINT16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 17),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* CLKIN */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)),	/* PN_EINT17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 18),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 18)),	/* PN_EINT18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 19),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 19)),	/* PN_EINT19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 20),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 20)),	/* PN_EINT20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 21),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 21)),	/* PN_EINT21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 22),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 22)),	/* PN_EINT22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 23),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 23)),	/* PN_EINT23 */
+};
+
+static const struct sunxi_pinctrl_desc sun50i_r329_r_pinctrl_data = {
+	.pins = sun50i_r329_r_pins,
+	.npins = ARRAY_SIZE(sun50i_r329_r_pins),
+	.pin_base = PL_BASE,
+	.irq_banks = 3,
+	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int sun50i_r329_r_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev,
+				  &sun50i_r329_r_pinctrl_data);
+}
+
+static const struct of_device_id sun50i_r329_r_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun50i-r329-r-pinctrl", },
+	{}
+};
+
+static struct platform_driver sun50i_r329_r_pinctrl_driver = {
+	.probe	= sun50i_r329_r_pinctrl_probe,
+	.driver	= {
+		.name		= "sun50i-r329-r-pinctrl",
+		.of_match_table	= sun50i_r329_r_pinctrl_match,
+	},
+};
+builtin_platform_driver(sun50i_r329_r_pinctrl_driver);
-- 
2.30.2


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

* [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (7 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO " Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:41   ` Rob Herring
  2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

R329 has a CPUX CCU and a R-CCU.

Add compatible strings for them.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
index c4b7243ddcf2..4c9a50f263c8 100644
--- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
+++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
@@ -43,6 +43,8 @@ properties:
       - allwinner,sun50i-h6-r-ccu
       - allwinner,sun50i-h616-ccu
       - allwinner,sun50i-h616-r-ccu
+      - allwinner,sun50i-r329-ccu
+      - allwinner,sun50i-r329-r-ccu
       - allwinner,suniv-f1c100s-ccu
       - nextthing,gr8-ccu
 
@@ -102,6 +104,8 @@ else:
           - allwinner,sun50i-a100-ccu
           - allwinner,sun50i-h6-ccu
           - allwinner,sun50i-h616-ccu
+          - allwinner,sun50i-r329-ccu
+          - allwinner,sun50i-r329-r-ccu
 
   then:
     properties:
-- 
2.30.2


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

* [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (8 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
                     ` (2 more replies)
  2021-08-02  6:22 ` [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU Icenowy Zheng
                   ` (7 subsequent siblings)
  17 siblings, 3 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 has clock controls in PRCM, like other new Allwinner
SoCs.

Add support for them.

This driver is added before the main CCU because PLLs are controlled by
R-CCU on R329.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/clk/sunxi-ng/Kconfig                  |   5 +
 drivers/clk/sunxi-ng/Makefile                 |   1 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
 include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
 include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
 6 files changed, 470 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index cd46d8853876..e49b2c2fa5b7 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_R329_R_CCU
+	bool "Support for the Allwinner R329 PRCM CCU"
+	default ARM64 && ARCH_SUNXI
+	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN4I_A10_CCU
 	bool "Support for the Allwinner A10/A20 CCU"
 	default MACH_SUN4I
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 96c324306d97..db338a2188fd 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
 obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
 obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
+obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
 obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
 obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
new file mode 100644
index 000000000000..5413a701cb57
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Sipeed
+ * Based on the H616 CCU driver, which is:
+ *   Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329-r.h"
+
+/*
+ * The M factor is present in the register's description, but not in the
+ * frequency formula, and it's documented as "The bit is only for
+ * testing", so it's not modelled and then force to 0.
+ */
+#define SUN50I_R329_PLL_CPUX_REG	0x1000
+static struct ccu_mult pll_cpux_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.common		= {
+		.reg		= 0x1000,
+		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
+					      &ccu_mult_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+#define SUN50I_R329_PLL_PERIPH_REG	0x1010
+static struct ccu_nm pll_periph_base_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= 0x1010,
+		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
+		   0x1010, 16, 3, 0);
+static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-periph-base",
+		   0x1010, 20, 3, 0);
+static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
+			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
+
+#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
+static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
+	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
+};
+
+static struct ccu_nm pll_audio0_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(1, 1),
+	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
+					 BIT(24), 0x1120, BIT(31)),
+	.common		= {
+		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
+		.reg		= 0x1020,
+		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
+		   0x1020, 16, 3, 0);
+static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
+		   0x1020, 20, 3, 0);
+
+/*
+ * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
+ * BSP driver always has M0 = 1 and M1 = 2 (this is also the
+ * reset value in the register).
+ *
+ * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
+ */
+#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
+static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
+	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
+	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
+	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
+	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
+};
+static struct ccu_nm pll_audio1_4x_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(16, 6),
+	.fixed_post_div	= 2,
+	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
+					 BIT(24), 0x1130, BIT(31)),
+	.common		= {
+		.features	= CCU_FEATURE_FIXED_POSTDIV |
+				  CCU_FEATURE_SIGMA_DELTA_MOD,
+		.reg		= 0x1030,
+		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
+			   &pll_audio1_4x_clk.common.hw, 2, 1,
+			   CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
+			   &pll_audio1_4x_clk.common.hw, 4, 1,
+			   CLK_SET_RATE_PARENT);
+
+static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
+					      "pll-periph-2x",
+					      "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
+		      0x0ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c, BIT(0), 0);
+
+static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc" };
+static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents, 0x130,
+			       24, 3,	/* mux */
+			       BIT(31),	/* gate */
+			       0);
+
+static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c, BIT(0), 0);
+
+static const char * const r_audio_parents[] = { "pll-audio0-div5", "pll-audio0-div2",
+						"pll-audio1-1x", "pll-audio1-4x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc", r_audio_parents, 0x140,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac", r_audio_parents, 0x144,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
+		      0x14c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents, 0x150,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
+		      0x16c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents, 0x170,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
+				  r_audio_parents, 0x174,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);
+
+static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
+		      0x1dc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
+		      0x1ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
+		      0x20c, BIT(0), CLK_IS_CRITICAL);
+
+static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
+	&pll_cpux_clk.common,
+	&pll_periph_base_clk.common,
+	&pll_periph_2x_clk.common,
+	&pll_periph_800m_clk.common,
+	&pll_audio0_clk.common,
+	&pll_audio0_div2_clk.common,
+	&pll_audio0_div5_clk.common,
+	&pll_audio1_4x_clk.common,
+	&r_ahb_clk.common,
+	&r_apb1_clk.common,
+	&r_apb2_clk.common,
+	&r_bus_gpadc_clk.common,
+	&r_bus_ths_clk.common,
+	&r_bus_dma_clk.common,
+	&r_pwm_clk.common,
+	&r_bus_pwm_clk.common,
+	&r_codec_adc_clk.common,
+	&r_codec_dac_clk.common,
+	&r_bus_codec_clk.common,
+	&r_dmic_clk.common,
+	&r_bus_dmic_clk.common,
+	&r_bus_lradc_clk.common,
+	&r_i2s_clk.common,
+	&r_i2s_asrc_clk.common,
+	&r_bus_i2s_clk.common,
+	&r_bus_uart_clk.common,
+	&r_bus_i2c_clk.common,
+	&r_ir_clk.common,
+	&r_bus_ir_clk.common,
+	&r_bus_msgbox_clk.common,
+	&r_bus_spinlock_clk.common,
+	&r_bus_rtc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
+	.hws	= {
+		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
+		[CLK_PLL_PERIPH_BASE]	= &pll_periph_base_clk.common.hw,
+		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
+		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
+		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
+		[CLK_PLL_AUDIO0_DIV2]	= &pll_audio0_div2_clk.common.hw,
+		[CLK_PLL_AUDIO0_DIV5]	= &pll_audio0_div5_clk.common.hw,
+		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
+		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
+		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
+		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
+		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
+		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
+		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
+		[CLK_R_BUS_THS]		= &r_bus_ths_clk.common.hw,
+		[CLK_R_BUS_DMA]		= &r_bus_dma_clk.common.hw,
+		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
+		[CLK_R_BUS_PWM]		= &r_bus_pwm_clk.common.hw,
+		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
+		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
+		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
+		[CLK_R_DMIC]		= &r_dmic_clk.common.hw,
+		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
+		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
+		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
+		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
+		[CLK_R_BUS_I2S]		= &r_bus_i2s_clk.common.hw,
+		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
+		[CLK_R_BUS_I2C]		= &r_bus_i2c_clk.common.hw,
+		[CLK_R_IR]		= &r_ir_clk.common.hw,
+		[CLK_R_BUS_IR]		= &r_bus_ir_clk.common.hw,
+		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
+		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
+		[CLK_R_BUS_RTC]		= &r_bus_rtc_clk.common.hw,
+	},
+	.num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
+	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
+	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
+	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
+	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
+	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
+	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
+	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
+	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
+	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
+	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
+	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
+	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
+	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
+	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
+	.ccu_clks	= sun50i_r329_r_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
+
+	.hw_clks	= &sun50i_r329_r_hw_clks,
+
+	.resets		= sun50i_r329_r_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
+};
+
+static const u32 pll_regs[] = {
+	SUN50I_R329_PLL_CPUX_REG,
+	SUN50I_R329_PLL_PERIPH_REG,
+	SUN50I_R329_PLL_AUDIO0_REG,
+	SUN50I_R329_PLL_AUDIO1_REG,
+};
+
+static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+	int i;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%pOF: Could not map clock registers\n", node);
+		return;
+	}
+
+	/* Enable the lock bits and the output enable bits on all PLLs */
+	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
+		val = readl(reg + pll_regs[i]);
+		val |= BIT(29) | BIT(27);
+		writel(val, reg + pll_regs[i]);
+	}
+
+	/*
+	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
+	 *
+	 * See the comment before pll-audio1 definition for the reason.
+	 */
+
+	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
+	val &= ~BIT(1);
+	val |= BIT(0);
+	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
+
+	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
+	if (i)
+		pr_err("%pOF: probing clocks fails: %d\n", node, i);
+}
+
+CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
+	       sun50i_r329_r_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
new file mode 100644
index 000000000000..62cf65322116
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_R_H
+#define _CCU_SUN50I_R329_R_H
+
+#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
+
+#define CLK_PLL_CPUX		0
+#define CLK_PLL_PERIPH_BASE	1
+#define CLK_PLL_PERIPH_2X	2
+#define CLK_PLL_PERIPH_800M	3
+#define CLK_PLL_PERIPH		4
+#define CLK_PLL_AUDIO0		5
+#define CLK_PLL_AUDIO0_DIV2	6
+#define CLK_PLL_AUDIO0_DIV5	7
+#define CLK_PLL_AUDIO1_4X	8
+#define CLK_PLL_AUDIO1_2X	9
+#define CLK_PLL_AUDIO1		10
+#define CLK_R_AHB		11
+
+/* R_APB1 exported for PIO */
+
+#define CLK_R_APB2		13
+
+/* All module / bus gate clocks exported */
+
+#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
+
+#endif /* _CCU_SUN50I_R329_R_H */
diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..df9bc58de5c4
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+
+#define CLK_R_APB1		12
+
+#define CLK_R_BUS_GPADC		14
+#define CLK_R_BUS_THS		15
+#define CLK_R_BUS_DMA		16
+#define CLK_R_PWM		17
+#define CLK_R_BUS_PWM		18
+#define CLK_R_CODEC_ADC		19
+#define CLK_R_CODEC_DAC		20
+#define CLK_R_BUS_CODEC		21
+#define CLK_R_DMIC		22
+#define CLK_R_BUS_DMIC		23
+#define CLK_R_BUS_LRADC		24
+#define CLK_R_I2S		25
+#define CLK_R_I2S_ASRC		26
+#define CLK_R_BUS_I2S		27
+#define CLK_R_BUS_UART		28
+#define CLK_R_BUS_I2C		29
+#define CLK_R_IR		30
+#define CLK_R_BUS_IR		31
+#define CLK_R_BUS_MSGBOX	32
+#define CLK_R_BUS_SPINLOCK	33
+#define CLK_R_BUS_RTC		34
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..40644f2f21c6
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+
+#define RST_R_BUS_GPADC		0
+#define RST_R_BUS_THS		1
+#define RST_R_BUS_DMA		2
+#define RST_R_BUS_PWM		3
+#define RST_R_BUS_CODEC		4
+#define RST_R_BUS_DMIC		5
+#define RST_R_BUS_LRADC		6
+#define RST_R_BUS_I2S		7
+#define RST_R_BUS_UART		8
+#define RST_R_BUS_I2C		9
+#define RST_R_BUS_IR		10
+#define RST_R_BUS_MSGBOX	11
+#define RST_R_BUS_SPINLOCK	12
+#define RST_R_BUS_RTC		13
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
-- 
2.30.2


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

* [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (9 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
  2021-08-20  2:41   ` Samuel Holland
  2021-08-02  6:22 ` [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string Icenowy Zheng
                   ` (6 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
down and have PLLs moved out.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/clk/sunxi-ng/Kconfig                |   5 +
 drivers/clk/sunxi-ng/Makefile               |   1 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
 include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
 include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
 6 files changed, 682 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index e49b2c2fa5b7..4b32d5f81ea8 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_R329_CCU
+	bool "Support for the Allwinner R329 CCU"
+	default ARM64 && ARCH_SUNXI
+	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN50I_R329_R_CCU
 	bool "Support for the Allwinner R329 PRCM CCU"
 	default ARM64 && ARCH_SUNXI
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index db338a2188fd..62f3c5bf331c 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
 obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
 obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
+obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
 obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
 obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
 obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
new file mode 100644
index 000000000000..a0b4cfd6e1db
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
@@ -0,0 +1,526 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Based on the H616 CCU driver, which is:
+ *   Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329.h"
+
+/*
+ * An external divider of PLL-CPUX is controlled here. As it's similar to
+ * the external divider of PLL-CPUX on previous SoCs (only usable under
+ * 288MHz}, ignore it.
+ */
+static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
+					     "pll-cpux", "pll-periph",
+					     "pll-periph-2x",
+					     "pll=periph-800m" };
+static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
+		     0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
+static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
+
+static const char * const ahb_parents[] = { "osc24M", "osc32k",
+					    "iosc", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
+			     ahb_parents, 0x510,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static const char * const apb_parents[] = { "osc24M", "osc32k",
+					    "ahb", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static const char * const ce_parents[] = { "osc24M", "pll-periph-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 1,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
+		      0x68c, BIT(0), 0);
+
+static const char * const aipu_parents[] = { "pll-periph-2x", "pll-periph-800m",
+					     "pll-audio0-div2", "pll-audio0-div5",
+					     "pll-cpux" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents, 0x6f0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
+		      0x6fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
+		      0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
+		      0x71c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
+		      0x72c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
+		      0x73c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
+
+static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
+		      0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
+
+static const char * const dram_parents[] = { "pll-periph-2x",
+					     "pll-periph-800m",
+					     "pll-audio0-div2",
+					     "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
+				  0, 2,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  CLK_IS_CRITICAL);
+
+
+static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
+		      0x804, BIT(0), 0);
+static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
+		      0x804, BIT(2), 0);
+static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
+		      0x804, BIT(3), 0);
+static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
+		      0x804, BIT(5), 0);
+static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
+		      0x804, BIT(16), 0);
+
+static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
+		      0x80c, BIT(0), CLK_IS_CRITICAL);
+
+static const char * const nand_parents[] = { "osc24M", "pll-periph",
+					     "pll-audio-div2",
+					     "pll-periph-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_parents, 0x810,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_parents, 0x814,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
+
+static const char * const mmc_parents[] = { "osc24M", "pll-periph",
+					    "pll-periph-2x",
+					    "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
+					  0, 4,		/* M */
+					  8, 2,		/* P */
+					  24, 2,	/* mux */
+					  BIT(31),	/* gate */
+					  2,		/* post-div */
+					  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
+					  0, 4,		/* M */
+					  8, 2,		/* P */
+					  24, 2,	/* mux */
+					  BIT(31),	/* gate */
+					  2,		/* post-div */
+					  0);
+
+static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c, BIT(0), 0);
+
+static const char * const spi_parents[] = { "osc24M", "pll-periph",
+					    "pll-periph-2x",
+					    "pll-audio0-div2",
+					    "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
+
+static CLK_FIXED_FACTOR(emac_25m_div_clk, "emac-25m-div", "pll-periph",
+			2, 1, 0);
+static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div", 0x970,
+		      BIT(31) | BIT(30), 0);
+
+static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
+
+static const char * const ir_parents[] = { "osc32k", "iosc",
+					   "pll-periph", "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
+
+static const char * const audio_parents[] = { "pll-audio1",
+					      "pll-audio1-4x",
+					      "pll-audio0-div2",
+					      "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents, 0xa14,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spdif_clk, "spdif", audio_parents, 0xa20,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
+
+/*
+ * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
+ * We will force them to 0 (12M divided from 48M).
+ */
+#define SUN50I_R329_USB0_CLK_REG		0xa70
+#define SUN50I_R329_USB1_CLK_REG		0xa74
+
+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
+
+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c, BIT(8), 0);
+
+static const char * const ledc_parents[] = { "osc24M", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0xbf0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 1,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc, BIT(0), 0);
+
+/* Fixed factor clocks */
+static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
+
+static struct ccu_common *sun50i_r329_ccu_clks[] = {
+	&cpux_clk.common,
+	&axi_clk.common,
+	&cpux_apb_clk.common,
+	&ahb_clk.common,
+	&apb1_clk.common,
+	&apb2_clk.common,
+	&ce_clk.common,
+	&bus_ce_clk.common,
+	&aipu_clk.common,
+	&bus_aipu_clk.common,
+	&bus_dma_clk.common,
+	&bus_msgbox_clk.common,
+	&bus_spinlock_clk.common,
+	&bus_hstimer_clk.common,
+	&avs_clk.common,
+	&bus_dbg_clk.common,
+	&bus_pwm_clk.common,
+	&dram_clk.common,
+	&mbus_dma_clk.common,
+	&mbus_ce_clk.common,
+	&mbus_r_dma_clk.common,
+	&mbus_nand_clk.common,
+	&mbus_aipu_clk.common,
+	&bus_dram_clk.common,
+	&nand0_clk.common,
+	&nand1_clk.common,
+	&bus_nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&bus_mmc0_clk.common,
+	&bus_mmc1_clk.common,
+	&bus_uart0_clk.common,
+	&bus_uart1_clk.common,
+	&bus_uart2_clk.common,
+	&bus_uart3_clk.common,
+	&bus_i2c0_clk.common,
+	&bus_i2c1_clk.common,
+	&bus_scr_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&bus_spi0_clk.common,
+	&bus_spi1_clk.common,
+	&emac_25m_clk.common,
+	&bus_emac_clk.common,
+	&ir_rx_clk.common,
+	&bus_ir_rx_clk.common,
+	&ir_tx_clk.common,
+	&bus_ir_tx_clk.common,
+	&i2s0_clk.common,
+	&i2s1_clk.common,
+	&bus_i2s0_clk.common,
+	&bus_i2s1_clk.common,
+	&spdif_clk.common,
+	&bus_spdif_clk.common,
+	&usb_ohci0_clk.common,
+	&usb_phy0_clk.common,
+	&usb_ohci1_clk.common,
+	&usb_phy1_clk.common,
+	&bus_ohci0_clk.common,
+	&bus_ohci1_clk.common,
+	&bus_ehci0_clk.common,
+	&bus_otg_clk.common,
+	&ledc_clk.common,
+	&bus_ledc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
+	.hws	= {
+		[CLK_OSC12M]		= &osc12M_clk.hw,
+		[CLK_CPUX]		= &cpux_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_APB2]		= &apb2_clk.common.hw,
+		[CLK_CE]		= &ce_clk.common.hw,
+		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
+		[CLK_AIPU]		= &aipu_clk.common.hw,
+		[CLK_BUS_AIPU]		= &bus_aipu_clk.common.hw,
+		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
+		[CLK_BUS_MSGBOX]	= &bus_msgbox_clk.common.hw,
+		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
+		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
+		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
+		[CLK_DRAM]		= &dram_clk.common.hw,
+		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
+		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
+		[CLK_MBUS_R_DMA]	= &mbus_r_dma_clk.common.hw,
+		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
+		[CLK_MBUS_AIPU]		= &mbus_aipu_clk.common.hw,
+		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
+		[CLK_NAND0]		= &nand0_clk.common.hw,
+		[CLK_NAND1]		= &nand1_clk.common.hw,
+		[CLK_BUS_NAND]		= &bus_nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
+		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
+		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
+		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
+		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
+		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
+		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
+		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
+		[CLK_BUS_SCR]		= &bus_scr_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
+		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
+		[CLK_EMAC_25M_DIV]	= &emac_25m_div_clk.hw,
+		[CLK_EMAC_25M]		= &emac_25m_clk.common.hw,
+		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
+		[CLK_IR_RX]		= &ir_rx_clk.common.hw,
+		[CLK_BUS_IR_RX]		= &bus_ir_rx_clk.common.hw,
+		[CLK_IR_TX]		= &ir_tx_clk.common.hw,
+		[CLK_BUS_IR_TX]		= &bus_ir_tx_clk.common.hw,
+		[CLK_I2S0]		= &i2s0_clk.common.hw,
+		[CLK_I2S1]		= &i2s1_clk.common.hw,
+		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
+		[CLK_BUS_I2S1]		= &bus_i2s1_clk.common.hw,
+		[CLK_SPDIF]		= &spdif_clk.common.hw,
+		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
+		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
+		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
+		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
+		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
+		[CLK_LEDC]		= &ledc_clk.common.hw,
+		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
+	},
+	.num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
+	[RST_MBUS]		= { 0x540, BIT(30) },
+
+	[RST_BUS_CE]		= { 0x68c, BIT(16) },
+	[RST_BUS_AIPU]		= { 0x6fc, BIT(16) },
+	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
+	[RST_BUS_MSGBOX]	= { 0x71c, BIT(16) },
+	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
+	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
+	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
+	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
+	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
+	[RST_BUS_NAND]		= { 0x82c, BIT(16) },
+	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
+	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
+	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
+	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
+	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
+	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
+	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
+	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
+	[RST_BUS_SCR]		= { 0x93c, BIT(16) },
+	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
+	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
+	[RST_BUS_EMAC]		= { 0x97c, BIT(16) },
+	[RST_BUS_IR_RX]		= { 0x99c, BIT(16) },
+	[RST_BUS_IR_TX]		= { 0x9cc, BIT(16) },
+	[RST_BUS_I2S0]		= { 0xa1c, BIT(16) },
+	[RST_BUS_I2S1]		= { 0xa1c, BIT(17) },
+	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
+
+	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
+	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
+
+	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
+	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
+	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
+	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
+
+	[RST_BUS_LEDC]		= { 0xbfc, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
+	.ccu_clks	= sun50i_r329_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_ccu_clks),
+
+	.hw_clks	= &sun50i_r329_hw_clks,
+
+	.resets		= sun50i_r329_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_r329_ccu_resets),
+};
+
+static const u32 sun50i_r329_usb_clk_regs[] = {
+	SUN50I_R329_USB0_CLK_REG,
+	SUN50I_R329_USB1_CLK_REG,
+};
+
+static int sun50i_r329_ccu_probe(struct platform_device *pdev)
+{
+	void __iomem *reg;
+	u32 val;
+	int i;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	/*
+	 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
+	 *
+	 * This clock mux is still mysterious, and the code just enforces
+	 * it to have a valid clock parent.
+	 */
+	for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++) {
+		val = readl(reg + sun50i_r329_usb_clk_regs[i]);
+		val &= ~GENMASK(25, 24);
+		writel(val, reg + sun50i_r329_usb_clk_regs[i]);
+	}
+
+	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_r329_ccu_desc);
+}
+
+static const struct of_device_id sun50i_r329_ccu_ids[] = {
+	{ .compatible = "allwinner,sun50i-r329-ccu" },
+	{ }
+};
+
+static struct platform_driver sun50i_r329_ccu_driver = {
+	.probe	= sun50i_r329_ccu_probe,
+	.driver	= {
+		.name	= "sun50i-r329-ccu",
+		.of_match_table	= sun50i_r329_ccu_ids,
+	},
+};
+module_platform_driver(sun50i_r329_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
new file mode 100644
index 000000000000..144ac9954ef3
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_H_
+#define _CCU_SUN50I_R329_H_
+
+#include <dt-bindings/clock/sun50i-r329-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-ccu.h>
+
+#define CLK_OSC12M		0
+
+/* CPUX exported for DVFS */
+
+#define CLK_AXI			2
+#define CLK_CPUX_APB		3
+#define CLK_AHB			4
+
+/* APB1 exported for PIO */
+
+#define CLK_APB2		6
+
+/* Peripheral module and gate clock exported except for DRAM ones */
+
+#define CLK_DRAM		18
+
+#define CLK_BUS_DRAM		24
+
+#define CLK_NUMBER		(CLK_BUS_LEDC + 1)
+
+#endif /* _CCU_SUN50I_R329_H_ */
diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..116f8d13a9b3
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+
+#define CLK_CPUX		1
+
+#define CLK_APB1		5
+
+#define CLK_CE			7
+#define CLK_BUS_CE		8
+#define CLK_AIPU		9
+#define CLK_BUS_AIPU		10
+#define CLK_BUS_DMA		11
+#define CLK_BUS_MSGBOX		12
+#define CLK_BUS_SPINLOCK	13
+#define CLK_BUS_HSTIMER		14
+#define CLK_AVS			15
+#define CLK_BUS_DBG		16
+#define CLK_BUS_PWM		17
+
+#define CLK_MBUS_DMA		19
+#define CLK_MBUS_CE		20
+#define CLK_MBUS_R_DMA		21
+#define CLK_MBUS_NAND		22
+#define CLK_MBUS_AIPU		23
+
+#define CLK_NAND0		25
+#define CLK_NAND1		26
+#define CLK_BUS_NAND		27
+#define CLK_MMC0		28
+#define CLK_MMC1		29
+#define CLK_BUS_MMC0		30
+#define CLK_BUS_MMC1		31
+#define CLK_BUS_UART0		32
+#define CLK_BUS_UART1		33
+#define CLK_BUS_UART2		34
+#define CLK_BUS_UART3		35
+#define CLK_BUS_I2C0		36
+#define CLK_BUS_I2C1		37
+#define CLK_BUS_SCR		38
+#define CLK_SPI0		39
+#define CLK_SPI1		40
+#define CLK_BUS_SPI0		41
+#define CLK_BUS_SPI1		42
+#define CLK_EMAC_25M_DIV	43
+#define CLK_EMAC_25M		44
+#define CLK_BUS_EMAC		45
+#define CLK_IR_RX		46
+#define CLK_BUS_IR_RX		47
+#define CLK_IR_TX		48
+#define CLK_BUS_IR_TX		49
+#define CLK_I2S0		50
+#define CLK_I2S1		51
+#define CLK_BUS_I2S0		52
+#define CLK_BUS_I2S1		53
+#define CLK_SPDIF		54
+#define CLK_BUS_SPDIF		55
+#define CLK_USB_OHCI0		56
+#define CLK_USB_PHY0		57
+#define CLK_USB_OHCI1		58
+#define CLK_USB_PHY1		59
+#define CLK_BUS_OHCI0		60
+#define CLK_BUS_OHCI1		61
+#define CLK_BUS_EHCI0		62
+#define CLK_BUS_OTG		63
+#define CLK_LEDC		64
+#define CLK_BUS_LEDC		65
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..bb704a82443f
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+
+#define RST_MBUS		0
+#define RST_BUS_CE		1
+#define RST_BUS_AIPU		2
+#define RST_BUS_DMA		3
+#define RST_BUS_MSGBOX		4
+#define RST_BUS_SPINLOCK	5
+#define RST_BUS_HSTIMER		6
+#define RST_BUS_DBG		7
+#define RST_BUS_PWM		8
+#define RST_BUS_DRAM		9
+#define RST_BUS_NAND		10
+#define RST_BUS_MMC0		11
+#define RST_BUS_MMC1		12
+#define RST_BUS_UART0		13
+#define RST_BUS_UART1		14
+#define RST_BUS_UART2		15
+#define RST_BUS_UART3		16
+#define RST_BUS_I2C0		17
+#define RST_BUS_I2C1		18
+#define RST_BUS_SCR		19
+#define RST_BUS_SPI0		20
+#define RST_BUS_SPI1		21
+#define RST_BUS_EMAC		22
+#define RST_BUS_IR_RX		23
+#define RST_BUS_IR_TX		24
+#define RST_BUS_I2S0		25
+#define RST_BUS_I2S1		26
+#define RST_BUS_SPDIF		27
+#define RST_USB_PHY0		28
+#define RST_USB_PHY1		29
+#define RST_BUS_OHCI0		30
+#define RST_BUS_OHCI1		31
+#define RST_BUS_EHCI0		32
+#define RST_BUS_OTG		33
+#define RST_BUS_LEDC		34
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
-- 
2.30.2


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

* [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (10 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
  2021-08-18  8:47   ` Maxime Ripard
  2021-08-02  6:22 ` [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers Icenowy Zheng
                   ` (5 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

R329 SoC has two MMC controllers similar to ones in the previous
Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
controllers look like a mixture of previous SoCs' ordinary MMC
controller and eMMC controller.

Add a compatible string for R329 MMC controllers.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
index 4f62ad6ce50c..3e8c3c747a9b 100644
--- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -28,6 +28,7 @@ properties:
       - const: allwinner,sun50i-a64-mmc
       - const: allwinner,sun50i-a100-emmc
       - const: allwinner,sun50i-a100-mmc
+      - const: allwinner,sun50i-r329-mmc
       - items:
           - const: allwinner,sun8i-a83t-mmc
           - const: allwinner,sun7i-a20-mmc
-- 
2.30.2


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

* [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (11 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-18  8:47   ` Maxime Ripard
  2021-08-20  2:43   ` Samuel Holland
  2021-08-02  6:22 ` [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense Icenowy Zheng
                   ` (4 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

The two MMC controllers in Allwinner R329 have a mixed feature set
comparing to the previous SoCs' ordinary MMC and eMMC controllers.

Add support for them.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 2702736a1c57..0c9f66785286 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1199,6 +1199,15 @@ static const struct sunxi_mmc_cfg sun50i_a100_emmc_cfg = {
 	.needs_new_timings = true,
 };
 
+static const struct sunxi_mmc_cfg sun50i_r329_cfg = {
+	.idma_des_size_bits = 13,
+	.idma_des_shift = 2,
+	.clk_delays = NULL,
+	.can_calibrate = true,
+	.mask_data0 = true,
+	.needs_new_timings = true,
+};
+
 static const struct of_device_id sunxi_mmc_of_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
 	{ .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
@@ -1209,6 +1218,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
 	{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
 	{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
 	{ .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
+	{ .compatible = "allwinner,sun50i-r329-mmc", .data = &sun50i_r329_cfg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
-- 
2.30.2


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

* [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (12 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-06 21:43   ` Rob Herring
  2021-08-18  9:03   ` Maxime Ripard
  2021-08-02  6:22 ` [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC Icenowy Zheng
                   ` (3 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
SoM.

Add compatible strings for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..bce306908eff 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,12 @@ properties:
           - const: haoyu,a10-marsboard
           - const: allwinner,sun4i-a10
 
+      - description: Sipeed MaixSense
+        items:
+          - const: sipeed,maixsense
+          - const: sipeed,maix-iia
+          - const: allwinner,sun50i-r329
+
       - description: MapleBoard MP130
         items:
           - const: mapleboard,mp130
-- 
2.30.2


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

* [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (13 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-18  9:01   ` Maxime Ripard
  2021-08-20  2:59   ` Samuel Holland
  2021-08-02  6:22 ` [PATCH 16/17] arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA Icenowy Zheng
                   ` (2 subsequent siblings)
  17 siblings, 2 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Allwinner R329 is a new SoC focused on smart audio devices.

Add a DTSI file for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
 1 file changed, 244 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
new file mode 100644
index 000000000000..bfefa2b734b0
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun50i-r329-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-ccu.h>
+#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <1>;
+			enable-method = "psci";
+		};
+	};
+
+	osc24M: osc24M_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		arm,no-tick-in-suspend;
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		pio: pinctrl@2000400 {
+			compatible = "allwinner,sun50i-r329-pinctrl";
+			reg = <0x02000400 0x400>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			uart0_pb_pins: uart0-pb-pins {
+				pins = "PB4", "PB5";
+				function = "uart0";
+			};
+
+			mmc0_pf_pins: mmc0-pf-pins {
+				pins = "PF0", "PF1", "PF2",
+				       "PF3", "PF4", "PF5";
+				function = "mmc0";
+			};
+
+			mmc1_clk_pg0: mmc1-clk-pg0 {
+				pins = "PG0";
+				function = "mmc1_clk";
+			};
+
+			mmc1_cmd_pg1: mmc1-clk-pg1 {
+				pins = "PG1";
+				function = "mmc1_cmd";
+			};
+
+			mmc1_d0_pg2: mmc1-clk-pg2 {
+				pins = "PG2";
+				function = "mmc1_d0";
+			};
+
+			mmc1_d1_pg3: mmc1-clk-pg3 {
+				pins = "PG3";
+				function = "mmc1_d1";
+			};
+
+			mmc1_d2_pg4: mmc1-clk-pg4 {
+				pins = "PG4";
+				function = "mmc1_d2";
+			};
+
+			mmc1_d3_pg5: mmc1-clk-pg5 {
+				pins = "PG5";
+				function = "mmc1_d3";
+			};
+		};
+
+		ccu: clock@2001000 {
+			compatible = "allwinner,sun50i-r329-ccu";
+			reg = <0x02001000 0x1000>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		uart0: serial@2500000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500000 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		uart1: serial@2500400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500400 0x400>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
+			status = "disabled";
+		};
+
+		uart2: serial@2500800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500800 0x400>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
+			status = "disabled";
+		};
+
+		uart3: serial@2500c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500c00 0x400>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART3>;
+			resets = <&ccu RST_BUS_UART3>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@3021000 {
+			compatible = "arm,gic-400";
+			reg = <0x03021000 0x1000>,
+			      <0x03022000 0x2000>,
+			      <0x03024000 0x2000>,
+			      <0x03026000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		mmc0: mmc@4020000 {
+			compatible = "allwinner,sun50i-r329-mmc";
+			reg = <0x04020000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc@4021000 {
+			compatible = "allwinner,sun50i-r329-mmc";
+			reg = <0x04021000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		r_ccu: clock@7010000 {
+			compatible = "allwinner,sun50i-r329-r-ccu";
+			reg = <0x07010000 0x10000>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		r_pio: pinctrl@7022000 {
+			compatible = "allwinner,sun50i-r329-r-pinctrl";
+			reg = <0x07022000 0x400>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		rtc: rtc@7090000 {
+			compatible = "allwinner,sun50i-r329-rtc";
+			reg = <0x07090000 0x400>;
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k", "osc32k-out", "iosc";
+			#clock-cells = <1>;
+		};
+	};
+};
-- 
2.30.2


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

* [PATCH 16/17] arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (14 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-02  6:22 ` [PATCH 17/17] arm64: allwinner: dts: r329: add support for Sipeed MaixSense Icenowy Zheng
  2021-08-10 11:04 ` [PATCH 00/17] Basical Allwinner R329 support Ulf Hansson
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Sipeed Maix IIA is a R329-N4 (AIPU available and 256MiB DRAM) based SoM,
with a Realtek SDIO Wi-Fi module on it.

Add a DTSI file for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 .../dts/allwinner/sun50i-r329-maix-iia.dtsi   | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
new file mode 100644
index 000000000000..15774f8a5445
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+#include "sun50i-r329.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 1 0 GPIO_ACTIVE_LOW>; /* PM0 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_clk_pg0>, <&mmc1_cmd_pg1>, <&mmc1_d0_pg2>,
+		    <&mmc1_d1_pg3>, <&mmc1_d2_pg4>, <&mmc1_d3_pg5>;
+
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
-- 
2.30.2


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

* [PATCH 17/17] arm64: allwinner: dts: r329: add support for Sipeed MaixSense
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (15 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 16/17] arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA Icenowy Zheng
@ 2021-08-02  6:22 ` Icenowy Zheng
  2021-08-10 11:04 ` [PATCH 00/17] Basical Allwinner R329 support Ulf Hansson
  17 siblings, 0 replies; 51+ messages in thread
From: Icenowy Zheng @ 2021-08-02  6:22 UTC (permalink / raw)
  To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel, Icenowy Zheng

Sipeed MaixSense is a R329 devkit based on Maix IIA SoM.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |  1 +
 .../dts/allwinner/sun50i-r329-maixsense.dts   | 37 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index a96d9d2d8dd8..80a336d480ac 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -37,3 +37,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-r329-maixsense.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
new file mode 100644
index 000000000000..1876b9d0b080
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+/dts-v1/;
+
+#include "sun50i-r329-maix-iia.dtsi"
+
+/ {
+	model = "Sipeed MaixSense";
+	compatible = "sipeed,maixsense", "sipeed,maix-iia",
+		     "allwinner,sun50i-r329";
+
+	aliases {
+		serial0 = &uart0;
+		mmc0 = &mmc0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pf_pins>;
+
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
-- 
2.30.2


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

* Re: [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC
  2021-08-02  6:21 ` [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC Icenowy Zheng
@ 2021-08-06 21:39   ` Rob Herring
  0 siblings, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:39 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: devicetree, Alexandre Belloni, Ulf Hansson, Linus Walleij,
	Maxime Ripard, Samuel Holland, Chen-Yu Tsai, linux-sunxi,
	Jernej Skrabec, Rob Herring, Andre Przywara, linux-kernel,
	linux-arm-kernel

On Mon, 02 Aug 2021 14:21:59 +0800, Icenowy Zheng wrote:
> Allwinner R329 has a RTC similar to previous ones, capable of
> controlling LOSC and IOSC and with only one alarm.
> 
> Add a compatible string for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml    | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
@ 2021-08-06 21:40   ` Rob Herring
  2021-08-18  8:48   ` Maxime Ripard
  2021-08-19  2:40   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:40 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Chen-Yu Tsai, Maxime Ripard, Samuel Holland, devicetree,
	Alexandre Belloni, Jernej Skrabec, linux-sunxi, Ulf Hansson,
	linux-kernel, linux-arm-kernel, Andre Przywara, Rob Herring,
	Linus Walleij

On Mon, 02 Aug 2021 14:22:01 +0800, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs
  2021-08-02  6:22 ` [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs Icenowy Zheng
@ 2021-08-06 21:41   ` Rob Herring
  0 siblings, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:41 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Ulf Hansson, linux-kernel, devicetree, Andre Przywara,
	Jernej Skrabec, Linus Walleij, Alexandre Belloni, Samuel Holland,
	linux-arm-kernel, Maxime Ripard, Chen-Yu Tsai, Rob Herring,
	linux-sunxi

On Mon, 02 Aug 2021 14:22:04 +0800, Icenowy Zheng wrote:
> R329 has a CPUX CCU and a R-CCU.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml    | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
@ 2021-08-06 21:42   ` Rob Herring
  2021-08-18  8:50   ` Maxime Ripard
  2021-08-20  0:55   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:42 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On Mon, Aug 02, 2021 at 02:22:05PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                  |   5 +
>  drivers/clk/sunxi-ng/Makefile                 |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
>  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
>  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++

These 2 belong in the binding patch.

>  6 files changed, 470 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

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

* Re: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
  2021-08-02  6:22 ` [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU Icenowy Zheng
@ 2021-08-06 21:42   ` Rob Herring
  2021-08-20  2:41   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:42 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On Mon, Aug 02, 2021 at 02:22:06PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> down and have PLLs moved out.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                |   5 +
>  drivers/clk/sunxi-ng/Makefile               |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
>  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
>  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++

Same here.

>  6 files changed, 682 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h

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

* Re: [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
  2021-08-02  6:22 ` [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string Icenowy Zheng
@ 2021-08-06 21:42   ` Rob Herring
  2021-08-18  8:47   ` Maxime Ripard
  1 sibling, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:42 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Ulf Hansson, devicetree, Linus Walleij, linux-sunxi,
	Alexandre Belloni, linux-arm-kernel, Jernej Skrabec,
	Andre Przywara, linux-kernel, Maxime Ripard, Rob Herring,
	Samuel Holland, Chen-Yu Tsai

On Mon, 02 Aug 2021 14:22:07 +0800, Icenowy Zheng wrote:
> R329 SoC has two MMC controllers similar to ones in the previous
> Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
> controllers look like a mixture of previous SoCs' ordinary MMC
> controller and eMMC controller.
> 
> Add a compatible string for R329 MMC controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml         | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
  2021-08-02  6:22 ` [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense Icenowy Zheng
@ 2021-08-06 21:43   ` Rob Herring
  2021-08-18  9:03   ` Maxime Ripard
  1 sibling, 0 replies; 51+ messages in thread
From: Rob Herring @ 2021-08-06 21:43 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: linux-arm-kernel, linux-kernel, linux-sunxi, Chen-Yu Tsai,
	Samuel Holland, Linus Walleij, Jernej Skrabec, devicetree,
	Rob Herring, Alexandre Belloni, Ulf Hansson, Maxime Ripard,
	Andre Przywara

On Mon, 02 Aug 2021 14:22:09 +0800, Icenowy Zheng wrote:
> Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
> SoM.
> 
> Add compatible strings for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 00/17] Basical Allwinner R329 support
  2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
                   ` (16 preceding siblings ...)
  2021-08-02  6:22 ` [PATCH 17/17] arm64: allwinner: dts: r329: add support for Sipeed MaixSense Icenowy Zheng
@ 2021-08-10 11:04 ` Ulf Hansson
  17 siblings, 0 replies; 51+ messages in thread
From: Ulf Hansson @ 2021-08-10 11:04 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	DTML, Linux ARM, linux-sunxi, Linux Kernel Mailing List

On Mon, 2 Aug 2021 at 08:24, Icenowy Zheng <icenowy@sipeed.com> wrote:
>
> This patchset tries to add basical support for Allwinner R329 SoC to the
> Linux kernel, including clock/pintrl driver and MMC support.
>
> Three patches from the H616 patchset, which are used to support the RTC
> with linear day, are attached into this patchset. Other RTC-related
> patches of that patchset is not included, because the binding of the
> clock part there is still under discussion.
>
> Then I added RTC binding and support (which is now only a struct
> addition). I added RTC into this patchset, with the same reason that
> H616 patchset contains RTC, which is to make the clock tree correct at
> the first inclusion.
>
> After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
> R329 CCU is something special because PLLs are in R-CCU, no main CCU.
>
> MMC support is added here because it's also a simple struct addition
> work, no main driver code change needed.

It sounds like the MMC updates can be posted separately to linux-mmc.
Please do so I can pick them up.

[...]

Kind regards
Uffe

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

* Re: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller
  2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
@ 2021-08-11  9:23   ` Linus Walleij
  2021-08-18  8:48   ` Maxime Ripard
  2021-08-19  3:09   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Linus Walleij @ 2021-08-11  9:23 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Alexandre Belloni, Andre Przywara, Samuel Holland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux ARM, linux-sunxi, linux-kernel

On Mon, Aug 2, 2021 at 8:23 AM Icenowy Zheng <icenowy@sipeed.com> wrote:

> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
>
> This patch adds support for the CPUX domain pin controller.
>
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Can you send the pin control changes separately?
Also the bindings.

Then they can be reviewed and merged separately so I
don't have to pick out the stuff I can apply.

Yours,
Linus Walleij

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

* Re: [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
  2021-08-02  6:22 ` [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
@ 2021-08-18  8:47   ` Maxime Ripard
  1 sibling, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:47 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 476 bytes --]

On Mon, Aug 02, 2021 at 02:22:07PM +0800, Icenowy Zheng wrote:
> R329 SoC has two MMC controllers similar to ones in the previous
> Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
> controllers look like a mixture of previous SoCs' ordinary MMC
> controller and eMMC controller.
> 
> Add a compatible string for R329 MMC controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
  2021-08-02  6:22 ` [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers Icenowy Zheng
@ 2021-08-18  8:47   ` Maxime Ripard
  2021-08-20  2:43   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:47 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 347 bytes --]

On Mon, Aug 02, 2021 at 02:22:08PM +0800, Icenowy Zheng wrote:
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
> 
> Add support for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
  2021-08-06 21:40   ` Rob Herring
@ 2021-08-18  8:48   ` Maxime Ripard
  2021-08-19  2:40   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:48 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 315 bytes --]

On Mon, Aug 02, 2021 at 02:22:01PM +0800, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller
  2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
  2021-08-11  9:23   ` Linus Walleij
@ 2021-08-18  8:48   ` Maxime Ripard
  2021-08-19  3:09   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:48 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 374 bytes --]

On Mon, Aug 02, 2021 at 02:22:02PM +0800, Icenowy Zheng wrote:
> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
> 
> This patch adds support for the CPUX domain pin controller.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
@ 2021-08-18  8:50   ` Maxime Ripard
  2021-08-20  0:55   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:50 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

On Mon, Aug 02, 2021 at 02:22:05PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

The driver looks good, the title has a typo though (sunxi=ng vs sunxi-ng)

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin controller
  2021-08-02  6:22 ` [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO " Icenowy Zheng
@ 2021-08-18  8:52   ` Maxime Ripard
  2021-08-19  3:22   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  8:52 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 274 bytes --]

On Mon, Aug 02, 2021 at 02:22:03PM +0800, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
  2021-08-02  6:22 ` [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC Icenowy Zheng
@ 2021-08-18  9:01   ` Maxime Ripard
       [not found]     ` <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
  2021-08-20  2:59   ` Samuel Holland
  1 sibling, 1 reply; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  9:01 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4202 bytes --]

On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu@1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl@2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +
> +			uart0_pb_pins: uart0-pb-pins {
> +				pins = "PB4", "PB5";
> +				function = "uart0";
> +			};
> +
> +			mmc0_pf_pins: mmc0-pf-pins {
> +				pins = "PF0", "PF1", "PF2",
> +				       "PF3", "PF4", "PF5";
> +				function = "mmc0";
> +			};
> +
> +			mmc1_clk_pg0: mmc1-clk-pg0 {
> +				pins = "PG0";
> +				function = "mmc1_clk";
> +			};

Argh, of course it was bound to happen :)

Make sure your DT pass validation though, all your mmc1 node names will report errors.

> +
> +			mmc1_cmd_pg1: mmc1-clk-pg1 {

s/clk/cmd/ ?

> +				pins = "PG1";
> +				function = "mmc1_cmd";
> +			};
> +
> +			mmc1_d0_pg2: mmc1-clk-pg2 {

s/clk/d0/

> +				pins = "PG2";
> +				function = "mmc1_d0";
> +			};
> +
> +			mmc1_d1_pg3: mmc1-clk-pg3 {

s/clk/d1/

> +				pins = "PG3";
> +				function = "mmc1_d1";
> +			};
> +
> +			mmc1_d2_pg4: mmc1-clk-pg4 {

s/clk/d2/

> +				pins = "PG4";
> +				function = "mmc1_d2";
> +			};
> +
> +			mmc1_d3_pg5: mmc1-clk-pg5 {

s/clk/d3/

> +				pins = "PG5";
> +				function = "mmc1_d3";
> +			};
> +		};
> +
> +		ccu: clock@2001000 {
> +			compatible = "allwinner,sun50i-r329-ccu";
> +			reg = <0x02001000 0x1000>;
> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> +			clock-names = "hosc", "losc", "iosc";

Do we have a clock tree for the RTC? Is it the same than the H616?

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
  2021-08-02  6:22 ` [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense Icenowy Zheng
  2021-08-06 21:43   ` Rob Herring
@ 2021-08-18  9:03   ` Maxime Ripard
  1 sibling, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-18  9:03 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 981 bytes --]

On Mon, Aug 02, 2021 at 02:22:09PM +0800, Icenowy Zheng wrote:
> Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
> SoM.
> 
> Add compatible strings for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index 889128acf49a..bce306908eff 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -444,6 +444,12 @@ properties:
>            - const: haoyu,a10-marsboard
>            - const: allwinner,sun4i-a10
>  
> +      - description: Sipeed MaixSense
> +        items:
> +          - const: sipeed,maixsense
> +          - const: sipeed,maix-iia
> +          - const: allwinner,sun50i-r329
> +

This should be ordered

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
       [not found]     ` <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
@ 2021-08-19  2:32       ` Samuel Holland
  2021-08-20  3:06         ` Samuel Holland
  0 siblings, 1 reply; 51+ messages in thread
From: Samuel Holland @ 2021-08-19  2:32 UTC (permalink / raw)
  To: Icenowy Zheng, Maxime Ripard
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel

On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>> +		ccu: clock@2001000 {
>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>> +			reg = <0x02001000 0x1000>;
>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>> +			clock-names = "hosc", "losc", "iosc";
>>
>> Do we have a clock tree for the RTC? Is it the same than the H616?
> 
> Nope, it's the same with H6 because of external LOSC crystal is
> possible. (Although production M2A SoMs has it NC for cost control.)

It is not the same as the H6, either. The clock tree _is_ identical to the D1,
which has three diagrams on pages 363-364 of its user manual here:

https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf

Compared to the H6, the R329/D1:
 - Loses the LOSC calibration circuit
 - Gains a third mux input for LOSC (not external 32k) to fanout
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

Compared to the H616, the R329/D1:
 - Has an external 32k crystal input
   - Gains the IOSC vs. external 32k crystal mux for LOSC
   - Switches fanout mux input #1 from pll_periph0/N to external 32k
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

So the R329/D1 RTC has three inputs:
 - SPI clock from PRCM
 - 24 MHz DCXO crystal
 - 32 kHz external crystal (optional)

and four outputs:
 - 16 MHz "IOSC" RC oscillator
 - 32 kHz "LOSC"
 - ~1 kHz for RTC timekeeping
 - 32 kHz fanout

(Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
should be an "output" and not an "input".)

Regards,
Samuel

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

* Re: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
  2021-08-06 21:40   ` Rob Herring
  2021-08-18  8:48   ` Maxime Ripard
@ 2021-08-19  2:40   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-19  2:40 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
>  1 file changed, 4 insertions(+)

Reviewed-by: Samuel Holland <samuel@sholland.org>

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

* Re: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller
  2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
  2021-08-11  9:23   ` Linus Walleij
  2021-08-18  8:48   ` Maxime Ripard
@ 2021-08-19  3:09   ` Samuel Holland
  2 siblings, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-19  3:09 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
> 
> This patch adds support for the CPUX domain pin controller.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/pinctrl/sunxi/Kconfig               |   5 +
>  drivers/pinctrl/sunxi/Makefile              |   1 +
>  drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++++++++++
>  3 files changed, 416 insertions(+)
>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> 
> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
> index 33751a6a0757..c662e8b1b351 100644
> --- a/drivers/pinctrl/sunxi/Kconfig
> +++ b/drivers/pinctrl/sunxi/Kconfig
> @@ -129,4 +129,9 @@ config PINCTRL_SUN50I_H616_R
>  	default ARM64 && ARCH_SUNXI
>  	select PINCTRL_SUNXI
>  
> +config PINCTRL_SUN50I_R329
> +	bool "Support for the Allwinner R329 PIO"
> +	default ARM64 && ARCH_SUNXI
> +	select PINCTRL_SUNXI
> +
>  endif
> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> index d3440c42b9d6..e33f7c5f1ff9 100644
> --- a/drivers/pinctrl/sunxi/Makefile
> +++ b/drivers/pinctrl/sunxi/Makefile
> @@ -25,5 +25,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
> +obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> new file mode 100644
> index 000000000000..742f437ec0b6
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> @@ -0,0 +1,410 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Allwinner R329 SoC pinctrl driver.
> + *
> + * Copyright (C) 2021 Sipeed
> + * based on the H616 pinctrl driver
> + *   Copyright (C) 2020 Arm Ltd.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#include "pinctrl-sunxi.h"
> +
> +static const struct sunxi_desc_pin r329_pins[] = {
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM0 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
> +		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM1 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* MCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM2 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* LRCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM3 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* BCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM4 */
> +		  SUNXI_FUNCTION(0x4, "i2s0_dout0"),
> +		  SUNXI_FUNCTION(0x5, "i2s0_din1"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM5 */
> +		  SUNXI_FUNCTION(0x4, "i2s0_dout1"),
> +		  SUNXI_FUNCTION(0x5, "i2s0_din0"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM6 */
> +		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT2 */
> +		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM7 */
> +		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT3 */
> +		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir_tx"),
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM8 */
> +		  SUNXI_FUNCTION(0x4, "ir_rx"),
> +		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* RB0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CLK */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* CS */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* RE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CMD */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* MISO */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* CE0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D2 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* WP */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* CLE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D1 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* MOSI */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* ALE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D0 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* CLK */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* WE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D3 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* HOLD */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0")),		/* RST */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ1 */
> +		  SUNXI_FUNCTION(0x5, "boot_sel")),
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */

Please be consistent between "nand" and "nand0". "nand0" looks like it is much
more common.

> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPEN */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PF_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPPP */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PF_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ5 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* PWREN */
> +		  SUNXI_FUNCTION(0x4, "uart"),		/* TX */

Should be "uart0".

> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PF_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ4 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* CLK */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CMD */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PF_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* DATA */
> +		  SUNXI_FUNCTION(0x4, "uart"),		/* RX */

"uart0" here as well.

> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D3 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PF_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ2 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* RST */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PF_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ1 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* DET */
> +		  SUNXI_FUNCTION(0x4, "spdif_in"),
> +		  SUNXI_FUNCTION(0x5, "spdif_out"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PF_EINT6 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_clk"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d2"),
> +		  /* 0x4 is also mmc1_d2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PG_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_cmd"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d3"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_clk"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PG_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d0"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_cmd"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_d3"),

Missing function 5 "pll".

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PG_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d1"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_clk"),
> +		  /* 0x4 is also mmc1_d1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PG_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d2"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d0"),
> +		  /* 0x4 is also mmc1_d0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PG_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d3"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d1"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_cmd"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PG_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PG_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PG_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PG_EINT8 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* WP/DBI-TE */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PG_EINT9 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* MCLK */
> +		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */

Should be function 4.

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PG_EINT10 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* LRCK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PG_EINT11 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* BCLK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PG_EINT12 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "i2s1_dout0"),
> +		  SUNXI_FUNCTION(0x4, "i2s1_din1"),
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* MOSI/DBI-SDO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PG_EINT13 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "i2s1_dout1"),
> +		  SUNXI_FUNCTION(0x4, "i2s1_din0"),
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PG_EINT14 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)),	/* PH_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)),	/* PH_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* MOSI/DBI-SDO */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)),	/* PH_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "spdif"),		/* OUT */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)),	/* PH_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "spi1_cs"),	/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION(0x4, "spi1_hold"),	/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)),	/* PH_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "spi1_clk"),	/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION(0x4, "spi1_wp"),	/* WP/DBI-TE */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM3 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)),	/* PH_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI/SPI-DBO */
> +		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM4 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)),	/* PH_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM5 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)),	/* PH_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* WP/DBI-TE */
> +		  SUNXI_FUNCTION(0x4, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */

You have PH8 and PH9 functions 2 through 5 swapped.

And I won't be surprised if I missed something too :)

Regards,
Samuel

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)),	/* PH_EINT8 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION(0x4, "spdif"),		/* IN */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)),	/* PH_EINT9 */
> +};
> +static const unsigned int r329_irq_bank_map[] = { 1, 5, 6, 7 };
> +
> +static const struct sunxi_pinctrl_desc r329_pinctrl_data = {
> +	.pins = r329_pins,
> +	.npins = ARRAY_SIZE(r329_pins),
> +	.irq_banks = ARRAY_SIZE(r329_irq_bank_map),
> +	.irq_bank_map = r329_irq_bank_map,
> +	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
> +};
> +
> +static int r329_pinctrl_probe(struct platform_device *pdev)
> +{
> +	return sunxi_pinctrl_init(pdev, &r329_pinctrl_data);
> +}
> +
> +static const struct of_device_id r329_pinctrl_match[] = {
> +	{ .compatible = "allwinner,sun50i-r329-pinctrl", },
> +	{}
> +};
> +
> +static struct platform_driver r329_pinctrl_driver = {
> +	.probe	= r329_pinctrl_probe,
> +	.driver	= {
> +		.name		= "sun50i-r329-pinctrl",
> +		.of_match_table	= r329_pinctrl_match,
> +	},
> +};
> +builtin_platform_driver(r329_pinctrl_driver);
> 


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

* Re: [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin controller
  2021-08-02  6:22 ` [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO " Icenowy Zheng
  2021-08-18  8:52   ` Maxime Ripard
@ 2021-08-19  3:22   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-19  3:22 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/pinctrl/sunxi/Kconfig                 |   5 +
>  drivers/pinctrl/sunxi/Makefile                |   1 +
>  drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++++++++++
>  3 files changed, 298 insertions(+)
>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> 
> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
> index c662e8b1b351..abd60ff8daec 100644
> --- a/drivers/pinctrl/sunxi/Kconfig
> +++ b/drivers/pinctrl/sunxi/Kconfig
> @@ -134,4 +134,9 @@ config PINCTRL_SUN50I_R329
>  	default ARM64 && ARCH_SUNXI
>  	select PINCTRL_SUNXI
>  
> +config PINCTRL_SUN50I_R329_R
> +	bool "Support for the Allwinner R329 R-PIO"
> +	default ARM64 && ARCH_SUNXI
> +	select PINCTRL_SUNXI
> +
>  endif
> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> index e33f7c5f1ff9..245840a7959e 100644
> --- a/drivers/pinctrl/sunxi/Makefile
> +++ b/drivers/pinctrl/sunxi/Makefile
> @@ -26,5 +26,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
> +obj-$(CONFIG_PINCTRL_SUN50I_R329_R)	+= pinctrl-sun50i-r329-r.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..dc4792c685ba
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Allwinner H616 R_PIO pin controller driver

This needs to be updated.

> + *
> + * Copyright (C) 2020 Arm Ltd.
> + * Based on former work, which is:
> + *   Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
> + */
> +
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/reset.h>
> +
> +#include "pinctrl-sunxi.h"
> +
> +static const struct sunxi_desc_pin sun50i_r329_r_pins[] = {
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* LRCK */

"s_i2s0" for these would match existing drivers (and the manual).

Everything else matches the manual.

Regards,
Samuel

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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
  2021-08-18  8:50   ` Maxime Ripard
@ 2021-08-20  0:55   ` Samuel Holland
  2021-08-20  4:34     ` Jernej Škrabec
  2 siblings, 1 reply; 51+ messages in thread
From: Samuel Holland @ 2021-08-20  0:55 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                  |   5 +
>  drivers/clk/sunxi-ng/Makefile                 |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
>  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
>  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
>  6 files changed, 470 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index cd46d8853876..e49b2c2fa5b7 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
>  	default ARM64 && ARCH_SUNXI
>  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
>  
> +config SUN50I_R329_R_CCU
> +	bool "Support for the Allwinner R329 PRCM CCU"
> +	default ARM64 && ARCH_SUNXI
> +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
>  config SUN4I_A10_CCU
>  	bool "Support for the Allwinner A10/A20 CCU"
>  	default MACH_SUN4I
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index 96c324306d97..db338a2188fd 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
>  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
>  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
>  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
>  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
>  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
>  obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..5413a701cb57
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> @@ -0,0 +1,374 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Sipeed
> + * Based on the H616 CCU driver, which is:
> + *   Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329-r.h"
> +
> +/*
> + * The M factor is present in the register's description, but not in the
> + * frequency formula, and it's documented as "The bit is only for
> + * testing", so it's not modelled and then force to 0.
> + */
> +#define SUN50I_R329_PLL_CPUX_REG	0x1000
> +static struct ccu_mult pll_cpux_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.common		= {
> +		.reg		= 0x1000,
> +		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
> +					      &ccu_mult_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +#define SUN50I_R329_PLL_PERIPH_REG	0x1010
> +static struct ccu_nm pll_periph_base_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
> +	.common		= {
> +		.reg		= 0x1010,
> +		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
> +		   0x1010, 16, 3, 0);
> +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-periph-base",
> +		   0x1010, 20, 3, 0);

M as abbreviation for "mega" should be capitalized.

> +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> +			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
> +
> +#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
> +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> +	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
> +};
> +
> +static struct ccu_nm pll_audio0_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(1, 1),
> +	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> +					 BIT(24), 0x1120, BIT(31)),
> +	.common		= {
> +		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
> +		.reg		= 0x1020,
> +		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
> +		   0x1020, 16, 3, 0);
> +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
> +		   0x1020, 20, 3, 0);
> +
> +/*
> + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> + * reset value in the register).
> + *
> + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> + */
> +#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
> +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> +	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
> +	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
> +	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> +	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> +};
> +static struct ccu_nm pll_audio1_4x_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(16, 6),
> +	.fixed_post_div	= 2,
> +	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> +					 BIT(24), 0x1130, BIT(31)),
> +	.common		= {
> +		.features	= CCU_FEATURE_FIXED_POSTDIV |
> +				  CCU_FEATURE_SIGMA_DELTA_MOD,
> +		.reg		= 0x1030,
> +		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> +			   &pll_audio1_4x_clk.common.hw, 2, 1,
> +			   CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> +			   &pll_audio1_4x_clk.common.hw, 4, 1,
> +			   CLK_SET_RATE_PARENT);
> +
> +static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
> +					      "pll-periph-2x",
> +					      "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);

These are numbered 0 and 1 in the manual and in the BSP. Why number them
differently here?

> +
> +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> +		      0x0ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c, BIT(0), 0);

BSP has R_TIMER at 0x11c and R_TWD at 0x12c.

> +
> +static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc" };
> +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents, 0x130,
> +			       24, 3,	/* mux */
> +			       BIT(31),	/* gate */
> +			       0);
> +
> +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c, BIT(0), 0);
> +
> +static const char * const r_audio_parents[] = { "pll-audio0-div5", "pll-audio0-div2",
> +						"pll-audio1-1x", "pll-audio1-4x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc", r_audio_parents, 0x140,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */

I don't think it matters much, but the audio and IR muxes are documented as
being two bits wide.

> +				  BIT(31),	/* gate */
> +				  0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac", r_audio_parents, 0x144,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> +		      0x14c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents, 0x150,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
> +		      0x16c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents, 0x170,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> +				  r_audio_parents, 0x174,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);

The BSP claims there is an R_I2S1 module clock at 0x178. Can you check if that
exists? And the corresponding gate/reset bits in 0x17c?

> +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);

R_PPU is at 0x1ac, and R_DSP is at 0x1bc.

> +
> +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> +		      0x1dc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
> +		      0x1ec, BIT(0), 0);

R_DSP_SRAM is at 0x1fc.

> +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> +		      0x20c, BIT(0), CLK_IS_CRITICAL);

Is this a workaround for the clock consumer missing from the RTC driver?

Also, there is a "PSARM" clock at 0x210 and its gate at 0x21c. I think this may
refer to the NPU from ARM China?

Finally, there is a CPUCFG gate at 0x22c. I'm not sure which CPUCFG this refers to.

> +
> +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> +	&pll_cpux_clk.common,
> +	&pll_periph_base_clk.common,
> +	&pll_periph_2x_clk.common,
> +	&pll_periph_800m_clk.common,
> +	&pll_audio0_clk.common,
> +	&pll_audio0_div2_clk.common,
> +	&pll_audio0_div5_clk.common,
> +	&pll_audio1_4x_clk.common,
> +	&r_ahb_clk.common,
> +	&r_apb1_clk.common,
> +	&r_apb2_clk.common,
> +	&r_bus_gpadc_clk.common,
> +	&r_bus_ths_clk.common,
> +	&r_bus_dma_clk.common,
> +	&r_pwm_clk.common,
> +	&r_bus_pwm_clk.common,
> +	&r_codec_adc_clk.common,
> +	&r_codec_dac_clk.common,
> +	&r_bus_codec_clk.common,
> +	&r_dmic_clk.common,
> +	&r_bus_dmic_clk.common,
> +	&r_bus_lradc_clk.common,
> +	&r_i2s_clk.common,
> +	&r_i2s_asrc_clk.common,
> +	&r_bus_i2s_clk.common,
> +	&r_bus_uart_clk.common,
> +	&r_bus_i2c_clk.common,
> +	&r_ir_clk.common,
> +	&r_bus_ir_clk.common,
> +	&r_bus_msgbox_clk.common,
> +	&r_bus_spinlock_clk.common,
> +	&r_bus_rtc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> +	.hws	= {
> +		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
> +		[CLK_PLL_PERIPH_BASE]	= &pll_periph_base_clk.common.hw,
> +		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
> +		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
> +		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
> +		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
> +		[CLK_PLL_AUDIO0_DIV2]	= &pll_audio0_div2_clk.common.hw,
> +		[CLK_PLL_AUDIO0_DIV5]	= &pll_audio0_div5_clk.common.hw,
> +		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
> +		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
> +		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
> +		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
> +		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
> +		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
> +		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
> +		[CLK_R_BUS_THS]		= &r_bus_ths_clk.common.hw,
> +		[CLK_R_BUS_DMA]		= &r_bus_dma_clk.common.hw,
> +		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
> +		[CLK_R_BUS_PWM]		= &r_bus_pwm_clk.common.hw,
> +		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
> +		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
> +		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
> +		[CLK_R_DMIC]		= &r_dmic_clk.common.hw,
> +		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
> +		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
> +		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
> +		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
> +		[CLK_R_BUS_I2S]		= &r_bus_i2s_clk.common.hw,
> +		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
> +		[CLK_R_BUS_I2C]		= &r_bus_i2c_clk.common.hw,
> +		[CLK_R_IR]		= &r_ir_clk.common.hw,
> +		[CLK_R_BUS_IR]		= &r_bus_ir_clk.common.hw,
> +		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
> +		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
> +		[CLK_R_BUS_RTC]		= &r_bus_rtc_clk.common.hw,
> +	},
> +	.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> +	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
> +	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
> +	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
> +	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
> +	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
> +	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
> +	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
> +	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
> +	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
> +	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
> +	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
> +	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
> +	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
> +	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> +	.ccu_clks	= sun50i_r329_r_ccu_clks,
> +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> +
> +	.hw_clks	= &sun50i_r329_r_hw_clks,
> +
> +	.resets		= sun50i_r329_r_ccu_resets,
> +	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> +};
> +
> +static const u32 pll_regs[] = {
> +	SUN50I_R329_PLL_CPUX_REG,
> +	SUN50I_R329_PLL_PERIPH_REG,
> +	SUN50I_R329_PLL_AUDIO0_REG,
> +	SUN50I_R329_PLL_AUDIO1_REG,
> +};
> +
> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> +{
> +	void __iomem *reg;
> +	u32 val;
> +	int i;
> +
> +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +	if (IS_ERR(reg)) {
> +		pr_err("%pOF: Could not map clock registers\n", node);
> +		return;
> +	}
> +
> +	/* Enable the lock bits and the output enable bits on all PLLs */
> +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> +		val = readl(reg + pll_regs[i]);
> +		val |= BIT(29) | BIT(27);
> +		writel(val, reg + pll_regs[i]);
> +	}
> +
> +	/*
> +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> +	 *
> +	 * See the comment before pll-audio1 definition for the reason.
> +	 */
> +
> +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> +	val &= ~BIT(1);
> +	val |= BIT(0);
> +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> +
> +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> +	if (i)
> +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> +}
> +
> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> +	       sun50i_r329_r_ccu_setup);

Please make this a platform driver. There is no particular reason why it needs
to be an early OF clock provider.

Regards,
Samuel

> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> new file mode 100644
> index 000000000000..62cf65322116
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_R_H
> +#define _CCU_SUN50I_R329_R_H
> +
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +#define CLK_PLL_CPUX		0
> +#define CLK_PLL_PERIPH_BASE	1
> +#define CLK_PLL_PERIPH_2X	2
> +#define CLK_PLL_PERIPH_800M	3
> +#define CLK_PLL_PERIPH		4
> +#define CLK_PLL_AUDIO0		5
> +#define CLK_PLL_AUDIO0_DIV2	6
> +#define CLK_PLL_AUDIO0_DIV5	7
> +#define CLK_PLL_AUDIO1_4X	8
> +#define CLK_PLL_AUDIO1_2X	9
> +#define CLK_PLL_AUDIO1		10
> +#define CLK_R_AHB		11
> +
> +/* R_APB1 exported for PIO */
> +
> +#define CLK_R_APB2		13
> +
> +/* All module / bus gate clocks exported */
> +
> +#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_R_H */
> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..df9bc58de5c4
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +
> +#define CLK_R_APB1		12
> +
> +#define CLK_R_BUS_GPADC		14
> +#define CLK_R_BUS_THS		15
> +#define CLK_R_BUS_DMA		16
> +#define CLK_R_PWM		17
> +#define CLK_R_BUS_PWM		18
> +#define CLK_R_CODEC_ADC		19
> +#define CLK_R_CODEC_DAC		20
> +#define CLK_R_BUS_CODEC		21
> +#define CLK_R_DMIC		22
> +#define CLK_R_BUS_DMIC		23
> +#define CLK_R_BUS_LRADC		24
> +#define CLK_R_I2S		25
> +#define CLK_R_I2S_ASRC		26
> +#define CLK_R_BUS_I2S		27
> +#define CLK_R_BUS_UART		28
> +#define CLK_R_BUS_I2C		29
> +#define CLK_R_IR		30
> +#define CLK_R_BUS_IR		31
> +#define CLK_R_BUS_MSGBOX	32
> +#define CLK_R_BUS_SPINLOCK	33
> +#define CLK_R_BUS_RTC		34
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +
> +#define RST_R_BUS_GPADC		0
> +#define RST_R_BUS_THS		1
> +#define RST_R_BUS_DMA		2
> +#define RST_R_BUS_PWM		3
> +#define RST_R_BUS_CODEC		4
> +#define RST_R_BUS_DMIC		5
> +#define RST_R_BUS_LRADC		6
> +#define RST_R_BUS_I2S		7
> +#define RST_R_BUS_UART		8
> +#define RST_R_BUS_I2C		9
> +#define RST_R_BUS_IR		10
> +#define RST_R_BUS_MSGBOX	11
> +#define RST_R_BUS_SPINLOCK	12
> +#define RST_R_BUS_RTC		13
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
> 


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

* Re: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
  2021-08-02  6:22 ` [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU Icenowy Zheng
  2021-08-06 21:42   ` Rob Herring
@ 2021-08-20  2:41   ` Samuel Holland
  2021-08-25 14:54     ` Maxime Ripard
  1 sibling, 1 reply; 51+ messages in thread
From: Samuel Holland @ 2021-08-20  2:41 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> down and have PLLs moved out.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                |   5 +
>  drivers/clk/sunxi-ng/Makefile               |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
>  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
>  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
>  6 files changed, 682 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index e49b2c2fa5b7..4b32d5f81ea8 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
>  	default ARM64 && ARCH_SUNXI
>  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
>  
> +config SUN50I_R329_CCU
> +	bool "Support for the Allwinner R329 CCU"
> +	default ARM64 && ARCH_SUNXI
> +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
>  config SUN50I_R329_R_CCU
>  	bool "Support for the Allwinner R329 PRCM CCU"
>  	default ARM64 && ARCH_SUNXI
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index db338a2188fd..62f3c5bf331c 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
>  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
>  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
>  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
>  obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
>  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
>  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> new file mode 100644
> index 000000000000..a0b4cfd6e1db
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> @@ -0,0 +1,526 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Based on the H616 CCU driver, which is:
> + *   Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329.h"
> +
> +/*
> + * An external divider of PLL-CPUX is controlled here. As it's similar to
> + * the external divider of PLL-CPUX on previous SoCs (only usable under
> + * 288MHz}, ignore it.

Mismatched (braces} here

> + */
> +static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
> +					     "pll-cpux", "pll-periph",
> +					     "pll-periph-2x",
> +					     "pll=periph-800m" };

= should be a -.

Now that these PLLs are in a different device, how is this supposed to affect
the DT binding? Do we put all of them in the clocks property?

If so, we can use .fw_name at some point. If not, why bother with the clocks
property at all? This is another part of the "let's get the clock tree right
from the start" discussion.

> +static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
> +		     0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
> +static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
> +static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
> +
> +static const char * const ahb_parents[] = { "osc24M", "osc32k",
> +					    "iosc", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
> +			     ahb_parents, 0x510,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static const char * const apb_parents[] = { "osc24M", "osc32k",
> +					    "ahb", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);

Hmm, so Allwinner is inconsistent with these. The manual has APB0/APB1, but the
BSP has APB1/APB2.

> +
> +static const char * const ce_parents[] = { "osc24M", "pll-periph-2x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 1,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
> +		      0x68c, BIT(0), 0);
> +
> +static const char * const aipu_parents[] = { "pll-periph-2x", "pll-periph-800m",
> +					     "pll-audio0-div2", "pll-audio0-div5",
> +					     "pll-cpux" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents, 0x6f0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
> +		      0x6fc, BIT(0), 0);

The manual has separate gates for an AIPU AHB master at bit 1, and an AHB slave
at bit 0.

> +
> +static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
> +		      0x70c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
> +		      0x71c, BIT(0), 0);

There are two message boxes (bits 0 and 1).

> +
> +static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
> +		      0x72c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
> +		      0x73c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
> +
> +static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
> +		      0x78c, BIT(0), 0);

There is a gate for the PSI clock (the parent for the AHB clocks) at 0x79c.

> +
> +static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
> +
> +static const char * const dram_parents[] = { "pll-periph-2x",
> +					     "pll-periph-800m",
> +					     "pll-audio0-div2",
> +					     "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
> +				  0, 2,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  CLK_IS_CRITICAL);
> +
> +
> +static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
> +		      0x804, BIT(0), 0);
> +static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
> +		      0x804, BIT(2), 0);
> +static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
> +		      0x804, BIT(3), 0);
> +static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
> +		      0x804, BIT(5), 0);
> +static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
> +		      0x804, BIT(16), 0);
> +
> +static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
> +		      0x80c, BIT(0), CLK_IS_CRITICAL);

The DRAM bus clock is not critical. It only needs to be enabled for register
access (PMU, DVFS).

> +
> +static const char * const nand_parents[] = { "osc24M", "pll-periph",
> +					     "pll-audio-div2",
> +					     "pll-periph-2x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_parents, 0x810,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_parents, 0x814,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
> +
> +static const char * const mmc_parents[] = { "osc24M", "pll-periph",
> +					    "pll-periph-2x",
> +					    "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
> +					  0, 4,		/* M */
> +					  8, 2,		/* P */
> +					  24, 2,	/* mux */
> +					  BIT(31),	/* gate */
> +					  2,		/* post-div */
> +					  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
> +					  0, 4,		/* M */
> +					  8, 2,		/* P */
> +					  24, 2,	/* mux */
> +					  BIT(31),	/* gate */
> +					  2,		/* post-div */

Where does the post-divider come from?

> +					  0);
> +
> +static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
> +
> +static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
> +static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
> +static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
> +
> +static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
> +
> +static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c, BIT(0), 0);
> +
> +static const char * const spi_parents[] = { "osc24M", "pll-periph",
> +					    "pll-periph-2x",
> +					    "pll-audio0-div2",
> +					    "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
> +
> +static CLK_FIXED_FACTOR(emac_25m_div_clk, "emac-25m-div", "pll-periph",
> +			2, 1, 0);
> +static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div", 0x970,
> +		      BIT(31) | BIT(30), 0);

The divider should be 24, not 2. And you can use CCU_FEATURE_ALL_PREDIV on the
gate to remove the separate divider clock.

> +
> +static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
> +
> +static const char * const ir_parents[] = { "osc32k", "iosc",

Both the manual and the BSP have the second parent as osc24M, not iosc.

> +					   "pll-periph", "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
> +
> +static const char * const audio_parents[] = { "pll-audio1",
> +					      "pll-audio1-4x",
> +					      "pll-audio0-div2",
> +					      "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
> +				  0, 4,		/* M */

All of the audio modules have 5-bit M dividers.

> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents, 0xa14,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spdif_clk, "spdif", audio_parents, 0xa20,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
> +
> +/*
> + * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
> + * We will force them to 0 (12M divided from 48M).
> + */
> +#define SUN50I_R329_USB0_CLK_REG		0xa70
> +#define SUN50I_R329_USB1_CLK_REG		0xa74

This "48M" clock is divided/synchronized from pll-periph, as shown in the
"Module Clock Generation" diagram and USB "PHY Connection Diagram" in the
manual. So I recommend the following structure:

static CLK_FIXED_FACTOR(usb_48M_clk, "usb-48M",
                        "pll-periph", 25, 2, 0);

static CLK_FIXED_FACTOR_HW(usb_12M_clk, "usb-12M",
                           &usb_48M_clk.hw, 4, 1, 0);

static const char *const usb_ohci_parents[] = { "usb-12M", "osc12M",
                                                "osc32k" };
static SUNXI_CCU_MUX_WITH_GATE(usb_ohci0_clk, "usb-ohci0",
                               usb_ohci_parents, 0xa70,
                               24, 2,           /* mux */
                               BIT(31),         /* gate */
                               0);

static SUNXI_CCU_MUX_WITH_GATE(usb_ohci1_clk, "usb-ohci1",
                               usb_ohci_parents, 0xa74,
                               24, 2,           /* mux */
                               BIT(31),         /* gate */
                               0);

For anyone following along without R329 documents, this is all the same as the
D1, though the labels in the diagrams are slightly different. Hooray for finally
documenting this so it is no longer "mysterious"!

Regards,
Samuel

> +
> +static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
> +static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
> +
> +static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
> +static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
> +
> +static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c, BIT(1), 0);
> +static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
> +static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c, BIT(8), 0);
> +
> +static const char * const ledc_parents[] = { "osc24M", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0xbf0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 1,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc, BIT(0), 0);
> +
> +/* Fixed factor clocks */
> +static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
> +
> +static struct ccu_common *sun50i_r329_ccu_clks[] = {
> +	&cpux_clk.common,
> +	&axi_clk.common,
> +	&cpux_apb_clk.common,
> +	&ahb_clk.common,
> +	&apb1_clk.common,
> +	&apb2_clk.common,
> +	&ce_clk.common,
> +	&bus_ce_clk.common,
> +	&aipu_clk.common,
> +	&bus_aipu_clk.common,
> +	&bus_dma_clk.common,
> +	&bus_msgbox_clk.common,
> +	&bus_spinlock_clk.common,
> +	&bus_hstimer_clk.common,
> +	&avs_clk.common,
> +	&bus_dbg_clk.common,
> +	&bus_pwm_clk.common,
> +	&dram_clk.common,
> +	&mbus_dma_clk.common,
> +	&mbus_ce_clk.common,
> +	&mbus_r_dma_clk.common,
> +	&mbus_nand_clk.common,
> +	&mbus_aipu_clk.common,
> +	&bus_dram_clk.common,
> +	&nand0_clk.common,
> +	&nand1_clk.common,
> +	&bus_nand_clk.common,
> +	&mmc0_clk.common,
> +	&mmc1_clk.common,
> +	&bus_mmc0_clk.common,
> +	&bus_mmc1_clk.common,
> +	&bus_uart0_clk.common,
> +	&bus_uart1_clk.common,
> +	&bus_uart2_clk.common,
> +	&bus_uart3_clk.common,
> +	&bus_i2c0_clk.common,
> +	&bus_i2c1_clk.common,
> +	&bus_scr_clk.common,
> +	&spi0_clk.common,
> +	&spi1_clk.common,
> +	&bus_spi0_clk.common,
> +	&bus_spi1_clk.common,
> +	&emac_25m_clk.common,
> +	&bus_emac_clk.common,
> +	&ir_rx_clk.common,
> +	&bus_ir_rx_clk.common,
> +	&ir_tx_clk.common,
> +	&bus_ir_tx_clk.common,
> +	&i2s0_clk.common,
> +	&i2s1_clk.common,
> +	&bus_i2s0_clk.common,
> +	&bus_i2s1_clk.common,
> +	&spdif_clk.common,
> +	&bus_spdif_clk.common,
> +	&usb_ohci0_clk.common,
> +	&usb_phy0_clk.common,
> +	&usb_ohci1_clk.common,
> +	&usb_phy1_clk.common,
> +	&bus_ohci0_clk.common,
> +	&bus_ohci1_clk.common,
> +	&bus_ehci0_clk.common,
> +	&bus_otg_clk.common,
> +	&ledc_clk.common,
> +	&bus_ledc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
> +	.hws	= {
> +		[CLK_OSC12M]		= &osc12M_clk.hw,
> +		[CLK_CPUX]		= &cpux_clk.common.hw,
> +		[CLK_AXI]		= &axi_clk.common.hw,
> +		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
> +		[CLK_AHB]		= &ahb_clk.common.hw,
> +		[CLK_APB1]		= &apb1_clk.common.hw,
> +		[CLK_APB2]		= &apb2_clk.common.hw,
> +		[CLK_CE]		= &ce_clk.common.hw,
> +		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
> +		[CLK_AIPU]		= &aipu_clk.common.hw,
> +		[CLK_BUS_AIPU]		= &bus_aipu_clk.common.hw,
> +		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
> +		[CLK_BUS_MSGBOX]	= &bus_msgbox_clk.common.hw,
> +		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
> +		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
> +		[CLK_AVS]		= &avs_clk.common.hw,
> +		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
> +		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
> +		[CLK_DRAM]		= &dram_clk.common.hw,
> +		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
> +		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
> +		[CLK_MBUS_R_DMA]	= &mbus_r_dma_clk.common.hw,
> +		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
> +		[CLK_MBUS_AIPU]		= &mbus_aipu_clk.common.hw,
> +		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
> +		[CLK_NAND0]		= &nand0_clk.common.hw,
> +		[CLK_NAND1]		= &nand1_clk.common.hw,
> +		[CLK_BUS_NAND]		= &bus_nand_clk.common.hw,
> +		[CLK_MMC0]		= &mmc0_clk.common.hw,
> +		[CLK_MMC1]		= &mmc1_clk.common.hw,
> +		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
> +		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
> +		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
> +		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
> +		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
> +		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
> +		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
> +		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
> +		[CLK_BUS_SCR]		= &bus_scr_clk.common.hw,
> +		[CLK_SPI0]		= &spi0_clk.common.hw,
> +		[CLK_SPI1]		= &spi1_clk.common.hw,
> +		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
> +		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
> +		[CLK_EMAC_25M_DIV]	= &emac_25m_div_clk.hw,
> +		[CLK_EMAC_25M]		= &emac_25m_clk.common.hw,
> +		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
> +		[CLK_IR_RX]		= &ir_rx_clk.common.hw,
> +		[CLK_BUS_IR_RX]		= &bus_ir_rx_clk.common.hw,
> +		[CLK_IR_TX]		= &ir_tx_clk.common.hw,
> +		[CLK_BUS_IR_TX]		= &bus_ir_tx_clk.common.hw,
> +		[CLK_I2S0]		= &i2s0_clk.common.hw,
> +		[CLK_I2S1]		= &i2s1_clk.common.hw,
> +		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
> +		[CLK_BUS_I2S1]		= &bus_i2s1_clk.common.hw,
> +		[CLK_SPDIF]		= &spdif_clk.common.hw,
> +		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
> +		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
> +		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
> +		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
> +		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
> +		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
> +		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
> +		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
> +		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
> +		[CLK_LEDC]		= &ledc_clk.common.hw,
> +		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
> +	},
> +	.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
> +	[RST_MBUS]		= { 0x540, BIT(30) },
> +
> +	[RST_BUS_CE]		= { 0x68c, BIT(16) },
> +	[RST_BUS_AIPU]		= { 0x6fc, BIT(16) },
> +	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
> +	[RST_BUS_MSGBOX]	= { 0x71c, BIT(16) },
> +	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
> +	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
> +	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
> +	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
> +	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
> +	[RST_BUS_NAND]		= { 0x82c, BIT(16) },
> +	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
> +	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
> +	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
> +	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
> +	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
> +	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
> +	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
> +	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
> +	[RST_BUS_SCR]		= { 0x93c, BIT(16) },
> +	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
> +	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
> +	[RST_BUS_EMAC]		= { 0x97c, BIT(16) },
> +	[RST_BUS_IR_RX]		= { 0x99c, BIT(16) },
> +	[RST_BUS_IR_TX]		= { 0x9cc, BIT(16) },
> +	[RST_BUS_I2S0]		= { 0xa1c, BIT(16) },
> +	[RST_BUS_I2S1]		= { 0xa1c, BIT(17) },
> +	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
> +
> +	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
> +	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
> +
> +	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
> +	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
> +	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
> +	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
> +
> +	[RST_BUS_LEDC]		= { 0xbfc, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
> +	.ccu_clks	= sun50i_r329_ccu_clks,
> +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_ccu_clks),
> +
> +	.hw_clks	= &sun50i_r329_hw_clks,
> +
> +	.resets		= sun50i_r329_ccu_resets,
> +	.num_resets	= ARRAY_SIZE(sun50i_r329_ccu_resets),
> +};
> +
> +static const u32 sun50i_r329_usb_clk_regs[] = {
> +	SUN50I_R329_USB0_CLK_REG,
> +	SUN50I_R329_USB1_CLK_REG,
> +};
> +
> +static int sun50i_r329_ccu_probe(struct platform_device *pdev)
> +{
> +	void __iomem *reg;
> +	u32 val;
> +	int i;
> +
> +	reg = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(reg))
> +		return PTR_ERR(reg);
> +
> +	/*
> +	 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
> +	 *
> +	 * This clock mux is still mysterious, and the code just enforces
> +	 * it to have a valid clock parent.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++) {
> +		val = readl(reg + sun50i_r329_usb_clk_regs[i]);
> +		val &= ~GENMASK(25, 24);
> +		writel(val, reg + sun50i_r329_usb_clk_regs[i]);
> +	}
> +
> +	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_r329_ccu_desc);
> +}
> +
> +static const struct of_device_id sun50i_r329_ccu_ids[] = {
> +	{ .compatible = "allwinner,sun50i-r329-ccu" },
> +	{ }
> +};
> +
> +static struct platform_driver sun50i_r329_ccu_driver = {
> +	.probe	= sun50i_r329_ccu_probe,
> +	.driver	= {
> +		.name	= "sun50i-r329-ccu",
> +		.of_match_table	= sun50i_r329_ccu_ids,
> +	},
> +};
> +module_platform_driver(sun50i_r329_ccu_driver);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> new file mode 100644
> index 000000000000..144ac9954ef3
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_H_
> +#define _CCU_SUN50I_R329_H_
> +
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +
> +#define CLK_OSC12M		0
> +
> +/* CPUX exported for DVFS */
> +
> +#define CLK_AXI			2
> +#define CLK_CPUX_APB		3
> +#define CLK_AHB			4
> +
> +/* APB1 exported for PIO */
> +
> +#define CLK_APB2		6
> +
> +/* Peripheral module and gate clock exported except for DRAM ones */
> +
> +#define CLK_DRAM		18
> +
> +#define CLK_BUS_DRAM		24
> +
> +#define CLK_NUMBER		(CLK_BUS_LEDC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_H_ */
> diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..116f8d13a9b3
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +
> +#define CLK_CPUX		1
> +
> +#define CLK_APB1		5
> +
> +#define CLK_CE			7
> +#define CLK_BUS_CE		8
> +#define CLK_AIPU		9
> +#define CLK_BUS_AIPU		10
> +#define CLK_BUS_DMA		11
> +#define CLK_BUS_MSGBOX		12
> +#define CLK_BUS_SPINLOCK	13
> +#define CLK_BUS_HSTIMER		14
> +#define CLK_AVS			15
> +#define CLK_BUS_DBG		16
> +#define CLK_BUS_PWM		17
> +
> +#define CLK_MBUS_DMA		19
> +#define CLK_MBUS_CE		20
> +#define CLK_MBUS_R_DMA		21
> +#define CLK_MBUS_NAND		22
> +#define CLK_MBUS_AIPU		23
> +
> +#define CLK_NAND0		25
> +#define CLK_NAND1		26
> +#define CLK_BUS_NAND		27
> +#define CLK_MMC0		28
> +#define CLK_MMC1		29
> +#define CLK_BUS_MMC0		30
> +#define CLK_BUS_MMC1		31
> +#define CLK_BUS_UART0		32
> +#define CLK_BUS_UART1		33
> +#define CLK_BUS_UART2		34
> +#define CLK_BUS_UART3		35
> +#define CLK_BUS_I2C0		36
> +#define CLK_BUS_I2C1		37
> +#define CLK_BUS_SCR		38
> +#define CLK_SPI0		39
> +#define CLK_SPI1		40
> +#define CLK_BUS_SPI0		41
> +#define CLK_BUS_SPI1		42
> +#define CLK_EMAC_25M_DIV	43
> +#define CLK_EMAC_25M		44
> +#define CLK_BUS_EMAC		45
> +#define CLK_IR_RX		46
> +#define CLK_BUS_IR_RX		47
> +#define CLK_IR_TX		48
> +#define CLK_BUS_IR_TX		49
> +#define CLK_I2S0		50
> +#define CLK_I2S1		51
> +#define CLK_BUS_I2S0		52
> +#define CLK_BUS_I2S1		53
> +#define CLK_SPDIF		54
> +#define CLK_BUS_SPDIF		55
> +#define CLK_USB_OHCI0		56
> +#define CLK_USB_PHY0		57
> +#define CLK_USB_OHCI1		58
> +#define CLK_USB_PHY1		59
> +#define CLK_BUS_OHCI0		60
> +#define CLK_BUS_OHCI1		61
> +#define CLK_BUS_EHCI0		62
> +#define CLK_BUS_OTG		63
> +#define CLK_LEDC		64
> +#define CLK_BUS_LEDC		65
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..bb704a82443f
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +
> +#define RST_MBUS		0
> +#define RST_BUS_CE		1
> +#define RST_BUS_AIPU		2
> +#define RST_BUS_DMA		3
> +#define RST_BUS_MSGBOX		4
> +#define RST_BUS_SPINLOCK	5
> +#define RST_BUS_HSTIMER		6
> +#define RST_BUS_DBG		7
> +#define RST_BUS_PWM		8
> +#define RST_BUS_DRAM		9
> +#define RST_BUS_NAND		10
> +#define RST_BUS_MMC0		11
> +#define RST_BUS_MMC1		12
> +#define RST_BUS_UART0		13
> +#define RST_BUS_UART1		14
> +#define RST_BUS_UART2		15
> +#define RST_BUS_UART3		16
> +#define RST_BUS_I2C0		17
> +#define RST_BUS_I2C1		18
> +#define RST_BUS_SCR		19
> +#define RST_BUS_SPI0		20
> +#define RST_BUS_SPI1		21
> +#define RST_BUS_EMAC		22
> +#define RST_BUS_IR_RX		23
> +#define RST_BUS_IR_TX		24
> +#define RST_BUS_I2S0		25
> +#define RST_BUS_I2S1		26
> +#define RST_BUS_SPDIF		27
> +#define RST_USB_PHY0		28
> +#define RST_USB_PHY1		29
> +#define RST_BUS_OHCI0		30
> +#define RST_BUS_OHCI1		31
> +#define RST_BUS_EHCI0		32
> +#define RST_BUS_OTG		33
> +#define RST_BUS_LEDC		34
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
> 


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

* Re: [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
  2021-08-02  6:22 ` [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers Icenowy Zheng
  2021-08-18  8:47   ` Maxime Ripard
@ 2021-08-20  2:43   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-20  2:43 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
> 
> Add support for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Reviewed-by: Samuel Holland <samuel@sholland.org>

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

* Re: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
  2021-08-02  6:22 ` [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC Icenowy Zheng
  2021-08-18  9:01   ` Maxime Ripard
@ 2021-08-20  2:59   ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-20  2:59 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec, Ulf Hansson, Linus Walleij, Alexandre Belloni,
	Andre Przywara
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi

One comment below.

All of my other concerns are about the CCU and RTC bindings, which I have
commented on elsewhere.

Regards,
Samuel

> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu@1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl@2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,

There is an IRQ documented for port C (at SPI 70). Do those pins possibly have
interrupt capability?

> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;

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

* Re: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
  2021-08-19  2:32       ` Samuel Holland
@ 2021-08-20  3:06         ` Samuel Holland
  2021-08-25 15:00           ` Maxime Ripard
  0 siblings, 1 reply; 51+ messages in thread
From: Samuel Holland @ 2021-08-20  3:06 UTC (permalink / raw)
  To: Icenowy Zheng, Maxime Ripard
  Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel

On 8/18/21 9:32 PM, Samuel Holland wrote:
> On 8/18/21 4:15 AM, Icenowy Zheng wrote:
>> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
>>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>>> +		ccu: clock@2001000 {
>>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>>> +			reg = <0x02001000 0x1000>;
>>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>>> +			clock-names = "hosc", "losc", "iosc";
>>>
>>> Do we have a clock tree for the RTC? Is it the same than the H616?
>>
>> Nope, it's the same with H6 because of external LOSC crystal is
>> possible. (Although production M2A SoMs has it NC for cost control.)
> 
> It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> which has three diagrams on pages 363-364 of its user manual here:
> 
> https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> 
> Compared to the H6, the R329/D1:
>  - Loses the LOSC calibration circuit
>  - Gains a third mux input for LOSC (not external 32k) to fanout
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> Compared to the H616, the R329/D1:
>  - Has an external 32k crystal input
>    - Gains the IOSC vs. external 32k crystal mux for LOSC
>    - Switches fanout mux input #1 from pll_periph0/N to external 32k
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> So the R329/D1 RTC has three^Wfour inputs:
>  - SPI clock from PRCM
>  - 24 MHz DCXO crystal
>  - 32 kHz external crystal (optional)

Whoops, I missed one here:
 - Bus clock from PRCM

The SPI clock is new for R329, but the bus clock has been around since H6.

> and four outputs:
>  - 16 MHz "IOSC" RC oscillator
>  - 32 kHz "LOSC"
>  - ~1 kHz for RTC timekeeping

Even though this is internal to the RTC, it is still useful to model, as it can
be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
unknown error.)

>  - 32 kHz fanout
> 
> (Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
> should be an "output" and not an "input".)
> 
> Regards,
> Samuel
> 


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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-20  0:55   ` Samuel Holland
@ 2021-08-20  4:34     ` Jernej Škrabec
  2021-08-25 14:50       ` Maxime Ripard
  2021-08-26  0:20       ` Samuel Holland
  0 siblings, 2 replies; 51+ messages in thread
From: Jernej Škrabec @ 2021-08-20  4:34 UTC (permalink / raw)
  To: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	Samuel Holland
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

Hi Samuel!

Dne petek, 20. avgust 2021 ob 02:55:10 CEST je Samuel Holland napisal(a):
> On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> > Allwinner R329 has clock controls in PRCM, like other new Allwinner
> > SoCs.
> > 
> > Add support for them.
> > 
> > This driver is added before the main CCU because PLLs are controlled by
> > R-CCU on R329.
> > 
> > Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> > ---
> > 
> >  drivers/clk/sunxi-ng/Kconfig                  |   5 +
> >  drivers/clk/sunxi-ng/Makefile                 |   1 +
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
> >  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
> >  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
> >  6 files changed, 470 insertions(+)
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> >  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> >  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > 
> > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> > index cd46d8853876..e49b2c2fa5b7 100644
> > --- a/drivers/clk/sunxi-ng/Kconfig
> > +++ b/drivers/clk/sunxi-ng/Kconfig
> > @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> > 
> >  	default ARM64 && ARCH_SUNXI
> >  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > 
> > +config SUN50I_R329_R_CCU
> > +	bool "Support for the Allwinner R329 PRCM CCU"
> > +	default ARM64 && ARCH_SUNXI
> > +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > +
> > 
> >  config SUN4I_A10_CCU
> >  
> >  	bool "Support for the Allwinner A10/A20 CCU"
> >  	default MACH_SUN4I
> > 
> > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> > index 96c324306d97..db338a2188fd 100644
> > --- a/drivers/clk/sunxi-ng/Makefile
> > +++ b/drivers/clk/sunxi-ng/Makefile
> > @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-
r.o
> > 
> >  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
> >  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
> >  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> > 
> > +obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
> > 
> >  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
> >  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> >  obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c new file mode 100644
> > index 000000000000..5413a701cb57
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> > @@ -0,0 +1,374 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + * Based on the H616 CCU driver, which is:
> > + *   Copyright (c) 2020 Arm Ltd.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_reset.h"
> > +
> > +#include "ccu_div.h"
> > +#include "ccu_gate.h"
> > +#include "ccu_mp.h"
> > +#include "ccu_mult.h"
> > +#include "ccu_nk.h"
> > +#include "ccu_nkm.h"
> > +#include "ccu_nkmp.h"
> > +#include "ccu_nm.h"
> > +
> > +#include "ccu-sun50i-r329-r.h"
> > +
> > +/*
> > + * The M factor is present in the register's description, but not in the
> > + * frequency formula, and it's documented as "The bit is only for
> > + * testing", so it's not modelled and then force to 0.
> > + */
> > +#define SUN50I_R329_PLL_CPUX_REG	0x1000
> > +static struct ccu_mult pll_cpux_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.common		= {
> > +		.reg		= 0x1000,
> > +		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
> > +					      &ccu_mult_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +#define SUN50I_R329_PLL_PERIPH_REG	0x1010
> > +static struct ccu_nm pll_periph_base_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
> > +	.common		= {
> > +		.reg		= 0x1010,
> > +		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
> > +		   0x1010, 16, 3, 0);
> > +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m",
> > "pll-periph-base", +		   0x1010, 20, 3, 0);
> 
> M as abbreviation for "mega" should be capitalized.
> 
> > +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> > +			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
> > +
> > +#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
> > +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> > +	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
> > +};
> > +
> > +static struct ccu_nm pll_audio0_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(1, 1),
> > +	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> > +					 BIT(24), 0x1120, 
BIT(31)),
> > +	.common		= {
> > +		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
> > +		.reg		= 0x1020,
> > +		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
> > +		   0x1020, 16, 3, 0);
> > +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
> > +		   0x1020, 20, 3, 0);
> > +
> > +/*
> > + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> > + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> > + * reset value in the register).
> > + *
> > + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> > + */
> > +#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
> > +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> > +	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
> > +	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
> > +	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> > +	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> > +};
> > +static struct ccu_nm pll_audio1_4x_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(16, 6),
> > +	.fixed_post_div	= 2,
> > +	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> > +					 BIT(24), 0x1130, 
BIT(31)),
> > +	.common		= {
> > +		.features	= CCU_FEATURE_FIXED_POSTDIV |
> > +				  CCU_FEATURE_SIGMA_DELTA_MOD,
> > +		.reg		= 0x1030,
> > +		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> > +			   &pll_audio1_4x_clk.common.hw, 2, 1,
> > +			   CLK_SET_RATE_PARENT);
> > +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> > +			   &pll_audio1_4x_clk.common.hw, 4, 1,
> > +			   CLK_SET_RATE_PARENT);
> > +
> > +static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
> > +					      "pll-periph-2x",
> > +					      "pll-audio0-
div2" };
> > +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> 
> These are numbered 0 and 1 in the manual and in the BSP. Why number them
> differently here?
> 
> > +
> > +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> > +		      0x0ec, BIT(0), 0);
> > +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc,
> > BIT(0), 0); +
> > +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c,
> > BIT(0), 0);
> BSP has R_TIMER at 0x11c and R_TWD at 0x12c.
> 
> > +
> > +static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc"
> > }; +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents,
> > 0x130, +			       24, 3,	/* mux */
> > +			       BIT(31),	/* gate */
> > +			       0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c,
> > BIT(0), 0); +
> > +static const char * const r_audio_parents[] = { "pll-audio0-div5",
> > "pll-audio0-div2", +						
"pll-audio1-1x", "pll-audio1-4x" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc",
> > r_audio_parents, 0x140, +				  0, 5,	
	/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> 
> I don't think it matters much, but the audio and IR muxes are documented as
> being two bits wide.
> 
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac",
> > r_audio_parents, 0x144, +				  0, 5,	
	/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> > +		      0x14c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents,
> > 0x150, +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c,
> > BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc",
> > "r-apb1",
> > +		      0x16c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents,
> > 0x170, +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> > +				  r_audio_parents, 0x174,
> > +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> 
> The BSP claims there is an R_I2S1 module clock at 0x178. Can you check if
> that exists? And the corresponding gate/reset bits in 0x17c?
> 
> > +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c,
> > BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart",
> > "r-apb2", 0x18c, BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_i2c_clk,
> > "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);
> R_PPU is at 0x1ac, and R_DSP is at 0x1bc.
> 
> > +
> > +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
> > +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0),
> > 0); +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> > +		      0x1dc, BIT(0), 0);
> > +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
> > +		      0x1ec, BIT(0), 0);
> 
> R_DSP_SRAM is at 0x1fc.
> 
> > +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> > +		      0x20c, BIT(0), CLK_IS_CRITICAL);
> 
> Is this a workaround for the clock consumer missing from the RTC driver?
> 
> Also, there is a "PSARM" clock at 0x210 and its gate at 0x21c. I think this
> may refer to the NPU from ARM China?
> 
> Finally, there is a CPUCFG gate at 0x22c. I'm not sure which CPUCFG this
> refers to.
> > +
> > +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> > +	&pll_cpux_clk.common,
> > +	&pll_periph_base_clk.common,
> > +	&pll_periph_2x_clk.common,
> > +	&pll_periph_800m_clk.common,
> > +	&pll_audio0_clk.common,
> > +	&pll_audio0_div2_clk.common,
> > +	&pll_audio0_div5_clk.common,
> > +	&pll_audio1_4x_clk.common,
> > +	&r_ahb_clk.common,
> > +	&r_apb1_clk.common,
> > +	&r_apb2_clk.common,
> > +	&r_bus_gpadc_clk.common,
> > +	&r_bus_ths_clk.common,
> > +	&r_bus_dma_clk.common,
> > +	&r_pwm_clk.common,
> > +	&r_bus_pwm_clk.common,
> > +	&r_codec_adc_clk.common,
> > +	&r_codec_dac_clk.common,
> > +	&r_bus_codec_clk.common,
> > +	&r_dmic_clk.common,
> > +	&r_bus_dmic_clk.common,
> > +	&r_bus_lradc_clk.common,
> > +	&r_i2s_clk.common,
> > +	&r_i2s_asrc_clk.common,
> > +	&r_bus_i2s_clk.common,
> > +	&r_bus_uart_clk.common,
> > +	&r_bus_i2c_clk.common,
> > +	&r_ir_clk.common,
> > +	&r_bus_ir_clk.common,
> > +	&r_bus_msgbox_clk.common,
> > +	&r_bus_spinlock_clk.common,
> > +	&r_bus_rtc_clk.common,
> > +};
> > +
> > +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> > +	.hws	= {
> > +		[CLK_PLL_CPUX]		= 
&pll_cpux_clk.common.hw,
> > +		[CLK_PLL_PERIPH_BASE]	= 
&pll_periph_base_clk.common.hw,
> > +		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
> > +		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
> > +		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
> > +		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
> > +		[CLK_PLL_AUDIO0_DIV2]	= 
&pll_audio0_div2_clk.common.hw,
> > +		[CLK_PLL_AUDIO0_DIV5]	= 
&pll_audio0_div5_clk.common.hw,
> > +		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
> > +		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
> > +		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
> > +		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
> > +		[CLK_R_APB1]		= 
&r_apb1_clk.common.hw,
> > +		[CLK_R_APB2]		= 
&r_apb2_clk.common.hw,
> > +		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
> > +		[CLK_R_BUS_THS]		= 
&r_bus_ths_clk.common.hw,
> > +		[CLK_R_BUS_DMA]		= 
&r_bus_dma_clk.common.hw,
> > +		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
> > +		[CLK_R_BUS_PWM]		= 
&r_bus_pwm_clk.common.hw,
> > +		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
> > +		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
> > +		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
> > +		[CLK_R_DMIC]		= 
&r_dmic_clk.common.hw,
> > +		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
> > +		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
> > +		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
> > +		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
> > +		[CLK_R_BUS_I2S]		= 
&r_bus_i2s_clk.common.hw,
> > +		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
> > +		[CLK_R_BUS_I2C]		= 
&r_bus_i2c_clk.common.hw,
> > +		[CLK_R_IR]		= &r_ir_clk.common.hw,
> > +		[CLK_R_BUS_IR]		= 
&r_bus_ir_clk.common.hw,
> > +		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
> > +		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
> > +		[CLK_R_BUS_RTC]		= 
&r_bus_rtc_clk.common.hw,
> > +	},
> > +	.num = CLK_NUMBER,
> > +};
> > +
> > +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> > +	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
> > +	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
> > +	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
> > +	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
> > +	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
> > +	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
> > +	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
> > +	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
> > +	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
> > +	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
> > +	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
> > +	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
> > +	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
> > +	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
> > +};
> > +
> > +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> > +	.ccu_clks	= sun50i_r329_r_ccu_clks,
> > +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> > +
> > +	.hw_clks	= &sun50i_r329_r_hw_clks,
> > +
> > +	.resets		= sun50i_r329_r_ccu_resets,
> > +	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> > +};
> > +
> > +static const u32 pll_regs[] = {
> > +	SUN50I_R329_PLL_CPUX_REG,
> > +	SUN50I_R329_PLL_PERIPH_REG,
> > +	SUN50I_R329_PLL_AUDIO0_REG,
> > +	SUN50I_R329_PLL_AUDIO1_REG,
> > +};
> > +
> > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > +{
> > +	void __iomem *reg;
> > +	u32 val;
> > +	int i;
> > +
> > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > +	if (IS_ERR(reg)) {
> > +		pr_err("%pOF: Could not map clock registers\n", node);
> > +		return;
> > +	}
> > +
> > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > +		val = readl(reg + pll_regs[i]);
> > +		val |= BIT(29) | BIT(27);
> > +		writel(val, reg + pll_regs[i]);
> > +	}
> > +
> > +	/*
> > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > +	 *
> > +	 * See the comment before pll-audio1 definition for the reason.
> > +	 */
> > +
> > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > +	val &= ~BIT(1);
> > +	val |= BIT(0);
> > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > +
> > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > +	if (i)
> > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > +}
> > +
> > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > +	       sun50i_r329_r_ccu_setup);
> 
> Please make this a platform driver. There is no particular reason why it
> needs to be an early OF clock provider.

Why? It's good to have it as early clock provider. It has no dependencies and 
other drivers that depends on it, like IR, can be deferred, if this is loaded 
later.

Best regards,
Jernej

> 
> Regards,
> Samuel
> 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h new file mode 100644
> > index 000000000000..62cf65322116
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _CCU_SUN50I_R329_R_H
> > +#define _CCU_SUN50I_R329_R_H
> > +
> > +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> > +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> > +
> > +#define CLK_PLL_CPUX		0
> > +#define CLK_PLL_PERIPH_BASE	1
> > +#define CLK_PLL_PERIPH_2X	2
> > +#define CLK_PLL_PERIPH_800M	3
> > +#define CLK_PLL_PERIPH		4
> > +#define CLK_PLL_AUDIO0		5
> > +#define CLK_PLL_AUDIO0_DIV2	6
> > +#define CLK_PLL_AUDIO0_DIV5	7
> > +#define CLK_PLL_AUDIO1_4X	8
> > +#define CLK_PLL_AUDIO1_2X	9
> > +#define CLK_PLL_AUDIO1		10
> > +#define CLK_R_AHB		11
> > +
> > +/* R_APB1 exported for PIO */
> > +
> > +#define CLK_R_APB2		13
> > +
> > +/* All module / bus gate clocks exported */
> > +
> > +#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
> > +
> > +#endif /* _CCU_SUN50I_R329_R_H */
> > diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > b/include/dt-bindings/clock/sun50i-r329-r-ccu.h new file mode 100644
> > index 000000000000..df9bc58de5c4
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> > +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> > +
> > +#define CLK_R_APB1		12
> > +
> > +#define CLK_R_BUS_GPADC		14
> > +#define CLK_R_BUS_THS		15
> > +#define CLK_R_BUS_DMA		16
> > +#define CLK_R_PWM		17
> > +#define CLK_R_BUS_PWM		18
> > +#define CLK_R_CODEC_ADC		19
> > +#define CLK_R_CODEC_DAC		20
> > +#define CLK_R_BUS_CODEC		21
> > +#define CLK_R_DMIC		22
> > +#define CLK_R_BUS_DMIC		23
> > +#define CLK_R_BUS_LRADC		24
> > +#define CLK_R_I2S		25
> > +#define CLK_R_I2S_ASRC		26
> > +#define CLK_R_BUS_I2S		27
> > +#define CLK_R_BUS_UART		28
> > +#define CLK_R_BUS_I2C		29
> > +#define CLK_R_IR		30
> > +#define CLK_R_BUS_IR		31
> > +#define CLK_R_BUS_MSGBOX	32
> > +#define CLK_R_BUS_SPINLOCK	33
> > +#define CLK_R_BUS_RTC		34
> > +
> > +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> > diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > b/include/dt-bindings/reset/sun50i-r329-r-ccu.h new file mode 100644
> > index 000000000000..40644f2f21c6
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> > +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> > +
> > +#define RST_R_BUS_GPADC		0
> > +#define RST_R_BUS_THS		1
> > +#define RST_R_BUS_DMA		2
> > +#define RST_R_BUS_PWM		3
> > +#define RST_R_BUS_CODEC		4
> > +#define RST_R_BUS_DMIC		5
> > +#define RST_R_BUS_LRADC		6
> > +#define RST_R_BUS_I2S		7
> > +#define RST_R_BUS_UART		8
> > +#define RST_R_BUS_I2C		9
> > +#define RST_R_BUS_IR		10
> > +#define RST_R_BUS_MSGBOX	11
> > +#define RST_R_BUS_SPINLOCK	12
> > +#define RST_R_BUS_RTC		13
> > +
> > +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */





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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-20  4:34     ` Jernej Škrabec
@ 2021-08-25 14:50       ` Maxime Ripard
  2021-08-25 15:03         ` Jernej Škrabec
  2021-08-26  0:20       ` Samuel Holland
  1 sibling, 1 reply; 51+ messages in thread
From: Maxime Ripard @ 2021-08-25 14:50 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2212 bytes --]

Hi,

On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej Škrabec wrote:
> > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > +{
> > > +	void __iomem *reg;
> > > +	u32 val;
> > > +	int i;
> > > +
> > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > +	if (IS_ERR(reg)) {
> > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > +		return;
> > > +	}
> > > +
> > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > +		val = readl(reg + pll_regs[i]);
> > > +		val |= BIT(29) | BIT(27);
> > > +		writel(val, reg + pll_regs[i]);
> > > +	}
> > > +
> > > +	/*
> > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > +	 *
> > > +	 * See the comment before pll-audio1 definition for the reason.
> > > +	 */
> > > +
> > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > +	val &= ~BIT(1);
> > > +	val |= BIT(0);
> > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > +
> > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > +	if (i)
> > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > +}
> > > +
> > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > +	       sun50i_r329_r_ccu_setup);
> > 
> > Please make this a platform driver. There is no particular reason why it
> > needs to be an early OF clock provider.
> 
> Why? It's good to have it as early clock provider. It has no dependencies and 
> other drivers that depends on it, like IR, can be deferred, if this is loaded 
> later.

No, Samuel is right, we should make them regular drivers as much as we
can.

The reason we had CLK_OF_DECLARE in the first place is that timers
usually have a parent clock, and you need the timers before the device
model is set up.

Fortunately for us, since the A20, the architected timers don't require
a parent clock from us, and we can thus boot up fine.

Since the dependencies are minimal, it should probe fairly early and
with the on-demand probing from the device links you might not even tell
the difference for most consumers.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
  2021-08-20  2:41   ` Samuel Holland
@ 2021-08-25 14:54     ` Maxime Ripard
  0 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-25 14:54 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4062 bytes --]

On Thu, Aug 19, 2021 at 09:41:26PM -0500, Samuel Holland wrote:
> On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> > Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> > down and have PLLs moved out.
> > 
> > Add support for it.
> > 
> > Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> > ---
> >  drivers/clk/sunxi-ng/Kconfig                |   5 +
> >  drivers/clk/sunxi-ng/Makefile               |   1 +
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
> >  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
> >  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
> >  6 files changed, 682 insertions(+)
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> >  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> >  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> > 
> > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> > index e49b2c2fa5b7..4b32d5f81ea8 100644
> > --- a/drivers/clk/sunxi-ng/Kconfig
> > +++ b/drivers/clk/sunxi-ng/Kconfig
> > @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> >  	default ARM64 && ARCH_SUNXI
> >  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> >  
> > +config SUN50I_R329_CCU
> > +	bool "Support for the Allwinner R329 CCU"
> > +	default ARM64 && ARCH_SUNXI
> > +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > +
> >  config SUN50I_R329_R_CCU
> >  	bool "Support for the Allwinner R329 PRCM CCU"
> >  	default ARM64 && ARCH_SUNXI
> > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> > index db338a2188fd..62f3c5bf331c 100644
> > --- a/drivers/clk/sunxi-ng/Makefile
> > +++ b/drivers/clk/sunxi-ng/Makefile
> > @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
> >  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
> >  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
> >  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> > +obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
> >  obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
> >  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
> >  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > new file mode 100644
> > index 000000000000..a0b4cfd6e1db
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > @@ -0,0 +1,526 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Based on the H616 CCU driver, which is:
> > + *   Copyright (c) 2020 Arm Ltd.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_reset.h"
> > +
> > +#include "ccu_div.h"
> > +#include "ccu_gate.h"
> > +#include "ccu_mp.h"
> > +#include "ccu_mult.h"
> > +#include "ccu_nk.h"
> > +#include "ccu_nkm.h"
> > +#include "ccu_nkmp.h"
> > +#include "ccu_nm.h"
> > +
> > +#include "ccu-sun50i-r329.h"
> > +
> > +/*
> > + * An external divider of PLL-CPUX is controlled here. As it's similar to
> > + * the external divider of PLL-CPUX on previous SoCs (only usable under
> > + * 288MHz}, ignore it.
> 
> Mismatched (braces} here
> 
> > + */
> > +static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
> > +					     "pll-cpux", "pll-periph",
> > +					     "pll-periph-2x",
> > +					     "pll=periph-800m" };
> 
> = should be a -.
> 
> Now that these PLLs are in a different device, how is this supposed to affect
> the DT binding? Do we put all of them in the clocks property?
> 
> If so, we can use .fw_name at some point. If not, why bother with the clocks
> property at all? This is another part of the "let's get the clock tree right
> from the start" discussion.

Agreed

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
  2021-08-20  3:06         ` Samuel Holland
@ 2021-08-25 15:00           ` Maxime Ripard
  0 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-25 15:00 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Jernej Skrabec,
	Ulf Hansson, Linus Walleij, Alexandre Belloni, Andre Przywara,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2588 bytes --]

On Thu, Aug 19, 2021 at 10:06:43PM -0500, Samuel Holland wrote:
> On 8/18/21 9:32 PM, Samuel Holland wrote:
> > On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> >> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
> >>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> >>>> +		ccu: clock@2001000 {
> >>>> +			compatible = "allwinner,sun50i-r329-ccu";
> >>>> +			reg = <0x02001000 0x1000>;
> >>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> >>>> +			clock-names = "hosc", "losc", "iosc";
> >>>
> >>> Do we have a clock tree for the RTC? Is it the same than the H616?
> >>
> >> Nope, it's the same with H6 because of external LOSC crystal is
> >> possible. (Although production M2A SoMs has it NC for cost control.)
> > 
> > It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> > which has three diagrams on pages 363-364 of its user manual here:
> > 
> > https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> > 
> > Compared to the H6, the R329/D1:
> >  - Loses the LOSC calibration circuit
> >  - Gains a third mux input for LOSC (not external 32k) to fanout
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > Compared to the H616, the R329/D1:
> >  - Has an external 32k crystal input
> >    - Gains the IOSC vs. external 32k crystal mux for LOSC
> >    - Switches fanout mux input #1 from pll_periph0/N to external 32k
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > So the R329/D1 RTC has three^Wfour inputs:
> >  - SPI clock from PRCM
> >  - 24 MHz DCXO crystal
> >  - 32 kHz external crystal (optional)
> 
> Whoops, I missed one here:
>  - Bus clock from PRCM
> 
> The SPI clock is new for R329, but the bus clock has been around since H6.
> 
> > and four outputs:
> >  - 16 MHz "IOSC" RC oscillator
> >  - 32 kHz "LOSC"
> >  - ~1 kHz for RTC timekeeping
> 
> Even though this is internal to the RTC, it is still useful to model, as it can
> be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
> instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
> unknown error.)

If it's not useful to any other device, there's no real reason to model
it in the clock framework. We should still force the source of the RTC
to the most accurate option we have, but we can do that without the CCF.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-25 14:50       ` Maxime Ripard
@ 2021-08-25 15:03         ` Jernej Škrabec
  2021-08-25 15:37           ` Maxime Ripard
  0 siblings, 1 reply; 51+ messages in thread
From: Jernej Škrabec @ 2021-08-25 15:03 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

Dne sreda, 25. avgust 2021 ob 16:50:27 CEST je Maxime Ripard napisal(a):
> Hi,
> 
> On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej Škrabec wrote:
> > > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > > +{
> > > > +	void __iomem *reg;
> > > > +	u32 val;
> > > > +	int i;
> > > > +
> > > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > > +	if (IS_ERR(reg)) {
> > > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > > +		val = readl(reg + pll_regs[i]);
> > > > +		val |= BIT(29) | BIT(27);
> > > > +		writel(val, reg + pll_regs[i]);
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > > +	 *
> > > > +	 * See the comment before pll-audio1 definition for the reason.
> > > > +	 */
> > > > +
> > > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > +	val &= ~BIT(1);
> > > > +	val |= BIT(0);
> > > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > +
> > > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > > +	if (i)
> > > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > > +}
> > > > +
> > > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > > +	       sun50i_r329_r_ccu_setup);
> > > 
> > > Please make this a platform driver. There is no particular reason why it
> > > needs to be an early OF clock provider.
> > 
> > Why? It's good to have it as early clock provider. It has no dependencies
> > and other drivers that depends on it, like IR, can be deferred, if this
> > is loaded later.
> 
> No, Samuel is right, we should make them regular drivers as much as we
> can.
> 
> The reason we had CLK_OF_DECLARE in the first place is that timers
> usually have a parent clock, and you need the timers before the device
> model is set up.
> 
> Fortunately for us, since the A20, the architected timers don't require
> a parent clock from us, and we can thus boot up fine.

There are other timers. A lot of SoCs, newer than A20 (like H6), have High 
Speed Timer, which requires parent clock to be enabled. We just choose not to 
add node for it to DT, even if it's there and driver already exists.

Best regards,
Jernej

> 
> Since the dependencies are minimal, it should probe fairly early and
> with the on-demand probing from the device links you might not even tell
> the difference for most consumers.
> 
> Maxime





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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-25 15:03         ` Jernej Škrabec
@ 2021-08-25 15:37           ` Maxime Ripard
  0 siblings, 0 replies; 51+ messages in thread
From: Maxime Ripard @ 2021-08-25 15:37 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2841 bytes --]

On Wed, Aug 25, 2021 at 05:03:30PM +0200, Jernej Škrabec wrote:
> Dne sreda, 25. avgust 2021 ob 16:50:27 CEST je Maxime Ripard napisal(a):
> > Hi,
> > 
> > On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej Škrabec wrote:
> > > > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > > > +{
> > > > > +	void __iomem *reg;
> > > > > +	u32 val;
> > > > > +	int i;
> > > > > +
> > > > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > > > +	if (IS_ERR(reg)) {
> > > > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > > > +		return;
> > > > > +	}
> > > > > +
> > > > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > > > +		val = readl(reg + pll_regs[i]);
> > > > > +		val |= BIT(29) | BIT(27);
> > > > > +		writel(val, reg + pll_regs[i]);
> > > > > +	}
> > > > > +
> > > > > +	/*
> > > > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > > > +	 *
> > > > > +	 * See the comment before pll-audio1 definition for the reason.
> > > > > +	 */
> > > > > +
> > > > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > > +	val &= ~BIT(1);
> > > > > +	val |= BIT(0);
> > > > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > > +
> > > > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > > > +	if (i)
> > > > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > > > +}
> > > > > +
> > > > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > > > +	       sun50i_r329_r_ccu_setup);
> > > > 
> > > > Please make this a platform driver. There is no particular reason why it
> > > > needs to be an early OF clock provider.
> > > 
> > > Why? It's good to have it as early clock provider. It has no dependencies
> > > and other drivers that depends on it, like IR, can be deferred, if this
> > > is loaded later.
> > 
> > No, Samuel is right, we should make them regular drivers as much as we
> > can.
> > 
> > The reason we had CLK_OF_DECLARE in the first place is that timers
> > usually have a parent clock, and you need the timers before the device
> > model is set up.
> > 
> > Fortunately for us, since the A20, the architected timers don't require
> > a parent clock from us, and we can thus boot up fine.
> 
> There are other timers. A lot of SoCs, newer than A20 (like H6), have High 
> Speed Timer, which requires parent clock to be enabled. We just choose not to 
> add node for it to DT, even if it's there and driver already exists.

Yeah, I know. The thing is, we just need one timer in order to boot to
the point where the DM is there. We can totally have a timer driver
probing just like any other driver, through the DM, later on.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
  2021-08-20  4:34     ` Jernej Škrabec
  2021-08-25 14:50       ` Maxime Ripard
@ 2021-08-26  0:20       ` Samuel Holland
  1 sibling, 0 replies; 51+ messages in thread
From: Samuel Holland @ 2021-08-26  0:20 UTC (permalink / raw)
  To: Jernej Škrabec, Maxime Ripard
  Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
	Icenowy Zheng, Rob Herring, Chen-Yu Tsai, Ulf Hansson,
	Linus Walleij, Alexandre Belloni, Andre Przywara

On 8/19/21 11:34 PM, Jernej Škrabec wrote:
>>> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
>>> +{
>>> +	void __iomem *reg;
>>> +	u32 val;
>>> +	int i;
>>> +
>>> +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
>>> +	if (IS_ERR(reg)) {
>>> +		pr_err("%pOF: Could not map clock registers\n", node);
>>> +		return;
>>> +	}
>>> +
>>> +	/* Enable the lock bits and the output enable bits on all PLLs */
>>> +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
>>> +		val = readl(reg + pll_regs[i]);
>>> +		val |= BIT(29) | BIT(27);
>>> +		writel(val, reg + pll_regs[i]);
>>> +	}
>>> +
>>> +	/*
>>> +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
>>> +	 *
>>> +	 * See the comment before pll-audio1 definition for the reason.
>>> +	 */
>>> +
>>> +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
>>> +	val &= ~BIT(1);
>>> +	val |= BIT(0);
>>> +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
>>> +
>>> +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
>>> +	if (i)
>>> +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
>>> +}
>>> +
>>> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
>>> +	       sun50i_r329_r_ccu_setup);
>>
>> Please make this a platform driver. There is no particular reason why it
>> needs to be an early OF clock provider.
> 
> Why? It's good to have it as early clock provider. It has no dependencies and 
> other drivers that depends on it, like IR, can be deferred, if this is loaded 
> later.

Another reason is so the driver can be built as a module. Each of these
CCU drivers has 30k-70k of data in it (lots of pointers, plus lots of
relocations). So it saves some RAM to only load the ones you need,
especially if that is none of them.

Regards,
Samuel

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

end of thread, other threads:[~2021-08-26  0:21 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-02  6:21 [PATCH 00/17] Basical Allwinner R329 support Icenowy Zheng
2021-08-02  6:21 ` [PATCH 01/17] rtc: sun6i: Fix time overflow handling Icenowy Zheng
2021-08-02  6:21 ` [PATCH 02/17] rtc: sun6i: Add support for linear day storage Icenowy Zheng
2021-08-02  6:21 ` [PATCH 03/17] rtc: sun6i: Add support for broken-down alarm registers Icenowy Zheng
2021-08-02  6:21 ` [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329 RTC Icenowy Zheng
2021-08-06 21:39   ` Rob Herring
2021-08-02  6:22 ` [PATCH 05/17] rtc: sun6i: add support " Icenowy Zheng
2021-08-02  6:22 ` [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO Icenowy Zheng
2021-08-06 21:40   ` Rob Herring
2021-08-18  8:48   ` Maxime Ripard
2021-08-19  2:40   ` Samuel Holland
2021-08-02  6:22 ` [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller Icenowy Zheng
2021-08-11  9:23   ` Linus Walleij
2021-08-18  8:48   ` Maxime Ripard
2021-08-19  3:09   ` Samuel Holland
2021-08-02  6:22 ` [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO " Icenowy Zheng
2021-08-18  8:52   ` Maxime Ripard
2021-08-19  3:22   ` Samuel Holland
2021-08-02  6:22 ` [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs Icenowy Zheng
2021-08-06 21:41   ` Rob Herring
2021-08-02  6:22 ` [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU Icenowy Zheng
2021-08-06 21:42   ` Rob Herring
2021-08-18  8:50   ` Maxime Ripard
2021-08-20  0:55   ` Samuel Holland
2021-08-20  4:34     ` Jernej Škrabec
2021-08-25 14:50       ` Maxime Ripard
2021-08-25 15:03         ` Jernej Škrabec
2021-08-25 15:37           ` Maxime Ripard
2021-08-26  0:20       ` Samuel Holland
2021-08-02  6:22 ` [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU Icenowy Zheng
2021-08-06 21:42   ` Rob Herring
2021-08-20  2:41   ` Samuel Holland
2021-08-25 14:54     ` Maxime Ripard
2021-08-02  6:22 ` [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string Icenowy Zheng
2021-08-06 21:42   ` Rob Herring
2021-08-18  8:47   ` Maxime Ripard
2021-08-02  6:22 ` [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers Icenowy Zheng
2021-08-18  8:47   ` Maxime Ripard
2021-08-20  2:43   ` Samuel Holland
2021-08-02  6:22 ` [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense Icenowy Zheng
2021-08-06 21:43   ` Rob Herring
2021-08-18  9:03   ` Maxime Ripard
2021-08-02  6:22 ` [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC Icenowy Zheng
2021-08-18  9:01   ` Maxime Ripard
     [not found]     ` <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
2021-08-19  2:32       ` Samuel Holland
2021-08-20  3:06         ` Samuel Holland
2021-08-25 15:00           ` Maxime Ripard
2021-08-20  2:59   ` Samuel Holland
2021-08-02  6:22 ` [PATCH 16/17] arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA Icenowy Zheng
2021-08-02  6:22 ` [PATCH 17/17] arm64: allwinner: dts: r329: add support for Sipeed MaixSense Icenowy Zheng
2021-08-10 11:04 ` [PATCH 00/17] Basical Allwinner R329 support Ulf Hansson

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