Skip to contentSkip to conversation

ARM: sunxi: RTC support for A31/A23

PATCH Superseded Chen-Yu Tsai 2 participants 8 messages Jul 25, 2014

Subsystems (4)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover ARM: sunxi: RTC support for A31/A23

Hi everyone,

This is v3 of the sun6i RTC series. This series adds support for the RTC in A31 and A23 SoCs. The series applies to sunxi-next.

The A31 has a new RTC block that is separate from the timer block. It has separate interrupts for each of the alarms, and a different format for the counter alarm. The driver has been tested on the A31 Hummingbird, and the A23 tablet I'm using to work on sun8i support.

Patch 1 adds the driver for the RTC.

Patch 2 is a minor cleanup. This makes rtc-sunxi depend on sun4i or sun7i, the 2 platforms the driver is actually used on.

Patch 3 adds the RTC device node to the sun6i DTSI.

Patch 4 adds the RTC device node to the sun8i DTSI.

Patch 5 adds enables rtc-sun6i in the sunxi defconfig.

Patch 6 adds enables rtc-sun6i in the multi_v7 defconfig. This patch applies to arm-soc/next/defconfig (e9a86d96)

Changes since v2:
- fixed indentation in DT binding docs
- have function argument indentation match open parenthesis
- drop driver owner field

Changes since v1:
- Enable rtc-sun6i in multi_v7_defconfig
- Cleanup the time/date GET/SET macros
- Use GENMASK for control register mask
- Change Kconfig option to show 'A31'
- Remove leftover comment from rtc-sun4i
- Remove extra newline

Cheers
ChenYu

Chen-Yu Tsai (6):
rtc: sun6i: Add sun6i RTC driver
rtc: sunxi: Depend on platforms sun4i/sun7i that actually have the rtc
ARM: dts: sun6i: add rtc device node
ARM: dts: sun8i: add rtc device node
ARM: sunxi: Add A31 RTC driver to sunxi_defconfig
ARM: sunxi: Add A31 RTC driver to multi_v7_defconfig

 .../devicetree/bindings/rtc/sun6i-rtc.txt          |  17 +
 arch/arm/boot/dts/sun6i-a31.dtsi                   |   6 +
 arch/arm/boot/dts/sun8i-a23.dtsi                   |   6 +
 arch/arm/configs/multi_v7_defconfig                |   1 +
 arch/arm/configs/sunxi_defconfig                   |   1 +
 drivers/rtc/Kconfig                                |   9 +-
 drivers/rtc/Makefile                               |   1 +
 drivers/rtc/rtc-sun6i.c                            | 447 +++++++++++++++++++++
 8 files changed, 487 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
 create mode 100644 drivers/rtc/rtc-sun6i.c
Signature · 1 line
2.0.1
#1 lore raw

PATCH v3 1/6 rtc: sun6i: Add sun6i RTC driver

This patch introduces the driver for the RTC in the Allwinner A31 and A23 SoCs.

Unlike the RTC found in A10/A20 SoCs, which was part of the timer, the RTC in A31/A23 are a separate hardware block, which also contain a few controls for the RTC block hardware (a regulator and RTC block GPIO pin latches), while also having separate interrupts for the alarms.

The hardware is different enough to make a different driver for it.

---
 .../devicetree/bindings/rtc/sun6i-rtc.txt          |  17 +
 drivers/rtc/Kconfig                                |   7 +
 drivers/rtc/Makefile                               |   1 +
 drivers/rtc/rtc-sun6i.c                            | 447 +++++++++++++++++++++
 4 files changed, 472 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
 create mode 100644 drivers/rtc/rtc-sun6i.c
Documentation/devicetree/bindings/rtc/sun6i-rtc.txt new file +17 -0
new file mode 100644
index 0000000..b7fb7a8
@@ -0,0 +1,17 @@
+* sun6i Real Time Clock
+
+RTC controller for the Allwinner A31
+
+Required properties:
+- compatible	: Should be "allwinner,sun6i-a31-rtc"
+- reg		: physical base address of the controller and length of
+		  memory mapped region.
+- interrupts	: IRQ line for the RTC alarm 0.
+
+Example:
+
+rtc: rtc at 01f00000 {
+	compatible = "allwinner,sun6i-a31-rtc";
+	reg = <0x01f00000 0x54>;
+	interrupts = <0 40 4>;
+};
drivers/rtc/Kconfig +7 -0
index 0754f5c..dde2b57 100644
@@ -1167,6 +1167,13 @@ config RTC_DRV_SUN4V
 	  If you say Y here you will get support for the Hypervisor
 	  based RTC on SUN4V systems.
 
+config RTC_DRV_SUN6I
+	tristate "Allwinner A31 RTC"
+	depends on MACH_SUN6I || MACH_SUN8I
+	help
+	  If you say Y here you will get support for the RTC found on
+	  Allwinner A31.
+
 config RTC_DRV_SUNXI
 	tristate "Allwinner sun4i/sun7i RTC"
 	depends on ARCH_SUNXI
drivers/rtc/Makefile +1 -0
index 70347d0..a47df29 100644
@@ -123,6 +123,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_STMP)	+= rtc-stmp3xxx.o
 obj-$(CONFIG_RTC_DRV_SUN4V)	+= rtc-sun4v.o
+obj-$(CONFIG_RTC_DRV_SUN6I)	+= rtc-sun6i.o
 obj-$(CONFIG_RTC_DRV_SUNXI)	+= rtc-sunxi.o
 obj-$(CONFIG_RTC_DRV_TEGRA)	+= rtc-tegra.o
 obj-$(CONFIG_RTC_DRV_TEST)	+= rtc-test.o
drivers/rtc/rtc-sun6i.c new file +447 -0

447 lines not on this page · raw message

Signature · 1 line
2.0.1
#2 lore raw

PATCH v3 1/6 rtc: sun6i: Add sun6i RTC driver

Quoted 20 lines · Chen-Yu Tsai

This patch introduces the driver for the RTC in the Allwinner A31 and A23 SoCs.

Unlike the RTC found in A10/A20 SoCs, which was part of the timer, the RTC in A31/A23 are a separate hardware block, which also contain a few controls for the RTC block hardware (a regulator and RTC block GPIO pin latches), while also having separate interrupts for the alarms.

The hardware is different enough to make a different driver for it.

---
  .../devicetree/bindings/rtc/sun6i-rtc.txt          |  17 +
  drivers/rtc/Kconfig                                |   7 +
  drivers/rtc/Makefile                               |   1 +
  drivers/rtc/rtc-sun6i.c                            | 447 +++++++++++++++++++++
  4 files changed, 472 insertions(+)

create mode 100644 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt create mode 100644 drivers/rtc/rtc-sun6i.c

(....)

drivers/rtc/rtc-sun6i.c line 276

Quoted 11 lines
drivers/rtc/rtc-sun6i.c new file +11 -0
+static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
+{
+	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+	u32 date = 0;
+	u32 time = 0;
+	int year;
+
+	year = rtc_tm->tm_year + 1900;
+	if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) {
+		dev_err(dev, "rtc only supports year in range %d - %d\n",
+				SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);

dev_err(dev, "rtc only supports year in range %d - %d\n",

	SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);
Quoted 10 lines
drivers/rtc/rtc-sun6i.c new file +10 -0
+		return -EINVAL;
+	}
+
+	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);
+

drivers/rtc/rtc-sun6i.c line 296

Quoted 10 lines
drivers/rtc/rtc-sun6i.c new file +10 -0
+	if (is_leap_year(year))
+		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);
+
+	/* Check whether registers are writable */
+	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
+				SUN6I_LOSC_CTRL_ACC_MASK, 50)) {

if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,

		   SUN6I_LOSC_CTRL_ACC_MASK, 50)
Quoted 4 lines
drivers/rtc/rtc-sun6i.c new file +4 -0
+		dev_err(dev, "rtc is still busy.\n");
+		return -EBUSY;
+	}
+

drivers/rtc/rtc-sun6i.c line 310

Quoted 10 lines
drivers/rtc/rtc-sun6i.c new file +10 -0
+	writel(time, chip->base + SUN6I_RTC_HMS);
+
+	/*
+	 * After writing the RTC HH-MM-SS register, the
+	 * SUN6I_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not
+	 * be cleared until the real writing operation is finished
+	 */
+
+	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
+				SUN6I_LOSC_CTRL_RTC_HMS_ACC, 50)) {

same..

Quoted 4 lines
drivers/rtc/rtc-sun6i.c new file +4 -0
+		dev_err(dev, "Failed to set rtc time.\n");
+		return -ETIMEDOUT;
+	}
+

drivers/rtc/rtc-sun6i.c line 324

Quoted 10 lines
drivers/rtc/rtc-sun6i.c new file +10 -0
+	writel(date, chip->base + SUN6I_RTC_YMD);
+
+	/*
+	 * After writing the RTC YY-MM-DD register, the
+	 * SUN6I_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not
+	 * be cleared until the real writing operation is finished
+	 */
+
+	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
+				SUN6I_LOSC_CTRL_RTC_YMD_ACC, 50)) {

same...

Signature · 2 lines
Regards,
Varka Bhadram.
#3 lore raw

PATCH v3 2/6 rtc: sunxi: Depend on platforms sun4i/sun7i that actually have the rtc

In reply to Chen-Yu Tsai

Now that we have Kconfig options for individual sunxi platforms, let the rtc-sunxi driver depend on the platforms that actually have this hardware, sun4i and sun7i.

---
 drivers/rtc/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/Kconfig +1 -1
index dde2b57..f933b4b 100644
@@ -1176,7 +1176,7 @@ config RTC_DRV_SUN6I
 
 config RTC_DRV_SUNXI
 	tristate "Allwinner sun4i/sun7i RTC"
-	depends on ARCH_SUNXI
+	depends on MACH_SUN4I || MACH_SUN7I
 	help
 	  If you say Y here you will get support for the RTC found on
 	  Allwinner A10/A20.
Signature · 1 line
2.0.1
#4 lore raw

PATCH v3 3/6 ARM: dts: sun6i: add rtc device node

In reply to Chen-Yu Tsai

Now that we have a driver for sun6i's rtc hardware, add a device node for it so we can use it.

---
 arch/arm/boot/dts/sun6i-a31.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/boot/dts/sun6i-a31.dtsi +6 -0
index 44b07e5..6a16019 100644
@@ -779,6 +779,12 @@
 			interrupts = <1 9 0xf04>;
 		};
 
+		rtc: rtc at 01f00000 {
+			compatible = "allwinner,sun6i-a31-rtc";
+			reg = <0x01f00000 0x54>;
+			interrupts = <0 40 4>;
+		};
+
 		nmi_intc: interrupt-controller at 01f00c0c {
 			compatible = "allwinner,sun6i-a31-sc-nmi";
 			interrupt-controller;
Signature · 1 line
2.0.1
#5 lore raw

PATCH v3 4/6 ARM: dts: sun8i: add rtc device node

In reply to Chen-Yu Tsai

sun8i shares the same rtc hardware as sun6i. Now that we have a driver for it, add a device node to the DTSI for it so we can use it.

---
 arch/arm/boot/dts/sun8i-a23.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/boot/dts/sun8i-a23.dtsi +6 -0
index 54ac0787..e0d1048 100644
@@ -285,6 +285,12 @@
 			interrupts = <1 9 0xf04>;
 		};
 
+		rtc: rtc at 01f00000 {
+			compatible = "allwinner,sun6i-a31-rtc";
+			reg = <0x01f00000 0x54>;
+			interrupts = <0 40 4>;
+		};
+
 		prcm at 01f01400 {
 			compatible = "allwinner,sun8i-a23-prcm";
 			reg = <0x01f01400 0x200>;
Signature · 1 line
2.0.1
#6 lore raw

PATCH v3 5/6 ARM: sunxi: Add A31 RTC driver to sunxi_defconfig

In reply to Chen-Yu Tsai

Now that we have a driver for A31's RTC, enable it in the default sunxi config.

---
 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/configs/sunxi_defconfig +1 -0
index 7209bfd..0abc2ab 100644
@@ -93,6 +93,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_INTF_SYSFS is not set
 # CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_DRV_SUN6I=y
 CONFIG_RTC_DRV_SUNXI=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_PHY_SUN4I_USB=y
Signature · 1 line
2.0.1
#7 lore raw

PATCH v3 6/6 ARM: sunxi: Add A31 RTC driver to multi_v7_defconfig

In reply to Chen-Yu Tsai

Now that we have a driver for A31's RTC, enable it in multi_v7_defconfig.

---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/configs/multi_v7_defconfig +1 -0
index a62ca27..130dd8d 100644
@@ -346,6 +346,7 @@ CONFIG_RTC_DRV_TPS65910=y
 CONFIG_RTC_DRV_EM3027=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_VT8500=y
+CONFIG_RTC_DRV_SUN6I=y
 CONFIG_RTC_DRV_SUNXI=y
 CONFIG_RTC_DRV_MV=y
 CONFIG_RTC_DRV_TEGRA=y
Signature · 1 line
2.0.1