All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/4] rtc: Add RK808 PMIC RTC
@ 2020-07-10 15:50 ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: Kever Yang, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula, Jagan Teki

This series support RK808 PMIC RTC on rk3399. 

Changes for v4:
- rebase on master
- cleanup of style changes

Any inputs?
Jagan.

Suniel Mahesh (4):
  arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  power: pmic: rk8xx: bind rk808 RTC
  rtc: rk8xx: Add base support for the RK808 PMIC RTC
  roc-rk3399-pc: Enable DM RTC

 arch/arm/dts/rk3399-roc-pc-u-boot.dtsi    |   8 +
 configs/roc-pc-mezzanine-rk3399_defconfig |   1 +
 configs/roc-pc-rk3399_defconfig           |   1 +
 drivers/power/pmic/rk8xx.c                |  19 ++-
 drivers/rtc/Kconfig                       |   8 +
 drivers/rtc/Makefile                      |   1 +
 drivers/rtc/rk808-rtc.c                   | 173 ++++++++++++++++++++++
 7 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 drivers/rtc/rk808-rtc.c

-- 
2.25.1

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

* [PATCH v4 0/4] rtc: Add RK808 PMIC RTC
@ 2020-07-10 15:50 ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: u-boot

This series support RK808 PMIC RTC on rk3399. 

Changes for v4:
- rebase on master
- cleanup of style changes

Any inputs?
Jagan.

Suniel Mahesh (4):
  arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  power: pmic: rk8xx: bind rk808 RTC
  rtc: rk8xx: Add base support for the RK808 PMIC RTC
  roc-rk3399-pc: Enable DM RTC

 arch/arm/dts/rk3399-roc-pc-u-boot.dtsi    |   8 +
 configs/roc-pc-mezzanine-rk3399_defconfig |   1 +
 configs/roc-pc-rk3399_defconfig           |   1 +
 drivers/power/pmic/rk8xx.c                |  19 ++-
 drivers/rtc/Kconfig                       |   8 +
 drivers/rtc/Makefile                      |   1 +
 drivers/rtc/rk808-rtc.c                   | 173 ++++++++++++++++++++++
 7 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 drivers/rtc/rk808-rtc.c

-- 
2.25.1

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

* [PATCH v4 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  2020-07-10 15:50 ` Jagan Teki
@ 2020-07-10 15:50   ` Jagan Teki
  -1 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: Kever Yang, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula

From: Suniel Mahesh <sunil@amarulasolutions.com>

Rockchip RK808 PMIC is a multi function device which hosts a Real Time
Clock along with other devices. Add a child RTC node so that it can be
bound and probed once the master pmic node completes probe.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Change for v4:
- none

 arch/arm/dts/rk3399-roc-pc-u-boot.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
index fc155e6903..16d6417160 100644
--- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
@@ -44,6 +44,14 @@
 	vin-supply = <&vcc_vbus_typec0>;
 };
 
+&rk808 {
+	rtc {
+		rkrtc: rk808-rtc {
+			status="okay";
+		};
+	};
+};
+
 &spi1 {
 	spi_flash: flash@0 {
 		u-boot,dm-pre-reloc;
-- 
2.25.1

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

* [PATCH v4 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
@ 2020-07-10 15:50   ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

Rockchip RK808 PMIC is a multi function device which hosts a Real Time
Clock along with other devices. Add a child RTC node so that it can be
bound and probed once the master pmic node completes probe.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Change for v4:
- none

 arch/arm/dts/rk3399-roc-pc-u-boot.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
index fc155e6903..16d6417160 100644
--- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
@@ -44,6 +44,14 @@
 	vin-supply = <&vcc_vbus_typec0>;
 };
 
+&rk808 {
+	rtc {
+		rkrtc: rk808-rtc {
+			status="okay";
+		};
+	};
+};
+
 &spi1 {
 	spi_flash: flash at 0 {
 		u-boot,dm-pre-reloc;
-- 
2.25.1

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

* [PATCH v4 2/4] power: pmic: rk8xx: bind rk808 RTC
  2020-07-10 15:50 ` Jagan Teki
@ 2020-07-10 15:50   ` Jagan Teki
  -1 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: Kever Yang, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula

From: Suniel Mahesh <sunil@amarulasolutions.com>

RK808 PMIC is a multi functional device with an RTC. In order to access
RTC, bind to its parent device i.e. RK808 PMIC.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Change for v4:
- none

 drivers/power/pmic/rk8xx.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 195884bde9..aea9272f8a 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -25,6 +25,11 @@ static const struct pmic_child_info pmic_children_info[] = {
 	{ },
 };
 
+static const struct pmic_child_info rtc_info[] = {
+	{ .prefix = "rk808-rtc", .driver = "rk808_rtc"},
+	{ },
+};
+
 static int rk8xx_reg_count(struct udevice *dev)
 {
 	return RK808_NUM_OF_REGS;
@@ -60,7 +65,7 @@ static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 static int rk8xx_bind(struct udevice *dev)
 {
-	ofnode regulators_node;
+	ofnode regulators_node, rtc_node;
 	int children;
 
 	regulators_node = dev_read_subnode(dev, "regulators");
@@ -76,6 +81,18 @@ static int rk8xx_bind(struct udevice *dev)
 	if (!children)
 		debug("%s: %s - no child found\n", __func__, dev->name);
 
+	rtc_node = dev_read_subnode(dev, "rtc");
+	if (!ofnode_valid(rtc_node)) {
+		debug("%s: %s rtc subnode not found!\n", __func__, dev->name);
+		return -ENXIO;
+	}
+
+	debug("%s: '%s' - found rtc subnode\n", __func__, dev->name);
+
+	children = pmic_bind_children(dev, rtc_node, rtc_info);
+	if (!children)
+		debug("%s: %s - no child found\n", __func__, dev->name);
+
 	/* Always return success for this device */
 	return 0;
 }
-- 
2.25.1

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

* [PATCH v4 2/4] power: pmic: rk8xx: bind rk808 RTC
@ 2020-07-10 15:50   ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

RK808 PMIC is a multi functional device with an RTC. In order to access
RTC, bind to its parent device i.e. RK808 PMIC.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Change for v4:
- none

 drivers/power/pmic/rk8xx.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 195884bde9..aea9272f8a 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -25,6 +25,11 @@ static const struct pmic_child_info pmic_children_info[] = {
 	{ },
 };
 
+static const struct pmic_child_info rtc_info[] = {
+	{ .prefix = "rk808-rtc", .driver = "rk808_rtc"},
+	{ },
+};
+
 static int rk8xx_reg_count(struct udevice *dev)
 {
 	return RK808_NUM_OF_REGS;
@@ -60,7 +65,7 @@ static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 static int rk8xx_bind(struct udevice *dev)
 {
-	ofnode regulators_node;
+	ofnode regulators_node, rtc_node;
 	int children;
 
 	regulators_node = dev_read_subnode(dev, "regulators");
@@ -76,6 +81,18 @@ static int rk8xx_bind(struct udevice *dev)
 	if (!children)
 		debug("%s: %s - no child found\n", __func__, dev->name);
 
+	rtc_node = dev_read_subnode(dev, "rtc");
+	if (!ofnode_valid(rtc_node)) {
+		debug("%s: %s rtc subnode not found!\n", __func__, dev->name);
+		return -ENXIO;
+	}
+
+	debug("%s: '%s' - found rtc subnode\n", __func__, dev->name);
+
+	children = pmic_bind_children(dev, rtc_node, rtc_info);
+	if (!children)
+		debug("%s: %s - no child found\n", __func__, dev->name);
+
 	/* Always return success for this device */
 	return 0;
 }
-- 
2.25.1

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-10 15:50 ` Jagan Teki
@ 2020-07-10 15:50   ` Jagan Teki
  -1 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: Kever Yang, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula, Jagan Teki

From: Suniel Mahesh <sunil@amarulasolutions.com>

Rockchip RK808 PMIC provides an integrated RTC module. It is
commonly used with Rockchip SoCs. Add basic support to access
date and time.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Change for v4:
- rebase
- style fixes
- warning fixes

 drivers/rtc/Kconfig     |   8 ++
 drivers/rtc/Makefile    |   1 +
 drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+)
 create mode 100644 drivers/rtc/rk808-rtc.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 59e2fc44ba..a754d1b4f1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -75,6 +75,14 @@ config RTC_ISL1208
 	  This driver supports reading and writing the RTC/calendar and detects
 	  total power failures.
 
+config RTC_RK808
+	bool "Enable Rockchip RK8XX RTC driver"
+        depends on DM_RTC && PMIC_RK8XX
+	default y
+	help
+	  Basic support for Rockchip RK808 PMIC Real Time Clock devices for
+	  time and date.
+
 config RTC_RV3029
 	bool "Enable RV3029 driver"
 	depends on DM_RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 12eb449583..63e2c3413d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
 obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
 obj-$(CONFIG_RTC_PL031) += pl031.o
 obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
+obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
 obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
 obj-$(CONFIG_RTC_RV3029) += rv3029.o
 obj-$(CONFIG_RTC_RV8803) += rv8803.o
diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
new file mode 100644
index 0000000000..50cca4dd4b
--- /dev/null
+++ b/drivers/rtc/rk808-rtc.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RTC driver for Rockchip RK808 PMIC.
+ *
+ * Copyright (C) 2020 Amarula Solutions(India).
+ * Suniel Mahesh <sunil@amarulasolutions.com>
+ *
+ * Based on code from Linux kernel:
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ * Author: Zhang Qing <zhangqing@rock-chips.com>
+ *
+ * Date & Time support (no alarms and interrupts)
+ */
+
+#include <command.h>
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <rtc.h>
+#include <power/rk8xx_pmic.h>
+#include <power/pmic.h>
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M		BIT(0)
+
+/* RK808 has a shadowed register for saving a "frozen" RTC time.
+ * When user setting "GET_TIME" to 1, the time will save in this shadowed
+ * register. If set "READSEL" to 1, user read rtc time register, actually
+ * get the time of that moment. If we need the real time, clr this bit.
+ */
+
+#define BIT_RTC_CTRL_REG_RTC_GET_TIME		BIT(6)
+#define BIT_RTC_CTRL_REG_RTC_READSEL_M		BIT(7)
+#define RTC_STATUS_MASK				0xFE
+
+#define SECONDS_REG_MSK				0x7F
+#define MINUTES_REG_MAK				0x7F
+#define HOURS_REG_MSK				0x3F
+#define DAYS_REG_MSK				0x3F
+#define MONTHS_REG_MSK				0x1F
+#define YEARS_REG_MSK				0xFF
+#define WEEKS_REG_MSK				0x7
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+
+#define NUM_TIME_REGS	(REG_WEEKS - REG_SECONDS + 1)
+
+static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+	u8 rtc_data[NUM_TIME_REGS];
+
+	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	rtc_data[0] = bin2bcd(tm->tm_sec);
+	rtc_data[1] = bin2bcd(tm->tm_min);
+	rtc_data[2] = bin2bcd(tm->tm_hour);
+	rtc_data[3] = bin2bcd(tm->tm_mday);
+	rtc_data[4] = bin2bcd(tm->tm_mon);
+	rtc_data[5] = bin2bcd(tm->tm_year - 2000);
+	rtc_data[6] = bin2bcd(tm->tm_wday);
+
+	/* Stop RTC while updating the RTC registers */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_STOP_RTC_M);
+	pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
+
+	/* Start RTC again */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
+			BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
+
+	return 0;
+}
+
+static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+	u8 rtc_data[NUM_TIME_REGS];
+
+	/* Force an update of the shadowed registers right now */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_RTC_GET_TIME);
+
+	/*
+	 * After we set the GET_TIME bit, the rtc time can't be read
+	 * immediately. So we should wait up to 31.25 us, about one cycle of
+	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
+	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
+	 */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
+			BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
+	pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
+
+	tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
+	tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
+	tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
+	tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
+	tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
+	tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
+	tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
+
+	/*
+	 * RK808 PMIC RTC h/w counts/has 31 days in november. This is corrected
+	 * when date cmd is invoked on prompt. checks for the current day and
+	 * if it is 31 November, then adjusts it to 1 December.
+	 *
+	 * h/w also has weeks register which counts from 0 to 7(0(sun)-6(sat)).
+	 * 7 is an unknown state, reset it back to 0(sun).
+	 */
+	if (tm->tm_mon == 11 && tm->tm_mday == 31) {
+		debug("correcting Nov 31st to Dec 1st (HW bug)\n");
+		tm->tm_mon += 1;
+		tm->tm_mday = 1;
+		if (tm->tm_wday == 7)
+			tm->tm_wday = 0;
+		rk808_rtc_set(dev, tm);
+	}
+
+	if (tm->tm_wday == 7) {
+		tm->tm_wday = 0;
+		rk808_rtc_set(dev, tm);
+	}
+
+	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+static int rk808_rtc_reset(struct udevice *dev)
+{
+/* Not needed */
+	return 0;
+}
+
+static int rk808_rtc_init(struct udevice *dev)
+{
+	struct rtc_time tm;
+
+	/* start rtc running by default, and use shadowed timer. */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_RTC_READSEL_M);
+	pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
+
+	/* set init time */
+	rk808_rtc_get(dev, &tm);
+
+	return 0;
+}
+
+static int rk808_rtc_probe(struct udevice *dev)
+{
+	rk808_rtc_init(dev);
+
+	return 0;
+}
+
+static const struct rtc_ops rk808_rtc_ops = {
+	.get = rk808_rtc_get,
+	.set = rk808_rtc_set,
+	.reset = rk808_rtc_reset,
+};
+
+U_BOOT_DRIVER(rk808_rtc) = {
+	.name     = "rk808_rtc",
+	.id       = UCLASS_RTC,
+	.ops      = &rk808_rtc_ops,
+	.probe    = rk808_rtc_probe,
+};
-- 
2.25.1

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
@ 2020-07-10 15:50   ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

Rockchip RK808 PMIC provides an integrated RTC module. It is
commonly used with Rockchip SoCs. Add basic support to access
date and time.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Change for v4:
- rebase
- style fixes
- warning fixes

 drivers/rtc/Kconfig     |   8 ++
 drivers/rtc/Makefile    |   1 +
 drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+)
 create mode 100644 drivers/rtc/rk808-rtc.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 59e2fc44ba..a754d1b4f1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -75,6 +75,14 @@ config RTC_ISL1208
 	  This driver supports reading and writing the RTC/calendar and detects
 	  total power failures.
 
+config RTC_RK808
+	bool "Enable Rockchip RK8XX RTC driver"
+        depends on DM_RTC && PMIC_RK8XX
+	default y
+	help
+	  Basic support for Rockchip RK808 PMIC Real Time Clock devices for
+	  time and date.
+
 config RTC_RV3029
 	bool "Enable RV3029 driver"
 	depends on DM_RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 12eb449583..63e2c3413d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
 obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
 obj-$(CONFIG_RTC_PL031) += pl031.o
 obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
+obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
 obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
 obj-$(CONFIG_RTC_RV3029) += rv3029.o
 obj-$(CONFIG_RTC_RV8803) += rv8803.o
diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
new file mode 100644
index 0000000000..50cca4dd4b
--- /dev/null
+++ b/drivers/rtc/rk808-rtc.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RTC driver for Rockchip RK808 PMIC.
+ *
+ * Copyright (C) 2020 Amarula Solutions(India).
+ * Suniel Mahesh <sunil@amarulasolutions.com>
+ *
+ * Based on code from Linux kernel:
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ * Author: Zhang Qing <zhangqing@rock-chips.com>
+ *
+ * Date & Time support (no alarms and interrupts)
+ */
+
+#include <command.h>
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <rtc.h>
+#include <power/rk8xx_pmic.h>
+#include <power/pmic.h>
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M		BIT(0)
+
+/* RK808 has a shadowed register for saving a "frozen" RTC time.
+ * When user setting "GET_TIME" to 1, the time will save in this shadowed
+ * register. If set "READSEL" to 1, user read rtc time register, actually
+ * get the time of that moment. If we need the real time, clr this bit.
+ */
+
+#define BIT_RTC_CTRL_REG_RTC_GET_TIME		BIT(6)
+#define BIT_RTC_CTRL_REG_RTC_READSEL_M		BIT(7)
+#define RTC_STATUS_MASK				0xFE
+
+#define SECONDS_REG_MSK				0x7F
+#define MINUTES_REG_MAK				0x7F
+#define HOURS_REG_MSK				0x3F
+#define DAYS_REG_MSK				0x3F
+#define MONTHS_REG_MSK				0x1F
+#define YEARS_REG_MSK				0xFF
+#define WEEKS_REG_MSK				0x7
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+
+#define NUM_TIME_REGS	(REG_WEEKS - REG_SECONDS + 1)
+
+static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+	u8 rtc_data[NUM_TIME_REGS];
+
+	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	rtc_data[0] = bin2bcd(tm->tm_sec);
+	rtc_data[1] = bin2bcd(tm->tm_min);
+	rtc_data[2] = bin2bcd(tm->tm_hour);
+	rtc_data[3] = bin2bcd(tm->tm_mday);
+	rtc_data[4] = bin2bcd(tm->tm_mon);
+	rtc_data[5] = bin2bcd(tm->tm_year - 2000);
+	rtc_data[6] = bin2bcd(tm->tm_wday);
+
+	/* Stop RTC while updating the RTC registers */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_STOP_RTC_M);
+	pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
+
+	/* Start RTC again */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
+			BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
+
+	return 0;
+}
+
+static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+	u8 rtc_data[NUM_TIME_REGS];
+
+	/* Force an update of the shadowed registers right now */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_RTC_GET_TIME);
+
+	/*
+	 * After we set the GET_TIME bit, the rtc time can't be read
+	 * immediately. So we should wait up to 31.25 us, about one cycle of
+	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
+	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
+	 */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
+			BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
+	pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
+
+	tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
+	tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
+	tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
+	tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
+	tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
+	tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
+	tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
+
+	/*
+	 * RK808 PMIC RTC h/w counts/has 31 days in november. This is corrected
+	 * when date cmd is invoked on prompt. checks for the current day and
+	 * if it is 31 November, then adjusts it to 1 December.
+	 *
+	 * h/w also has weeks register which counts from 0 to 7(0(sun)-6(sat)).
+	 * 7 is an unknown state, reset it back to 0(sun).
+	 */
+	if (tm->tm_mon == 11 && tm->tm_mday == 31) {
+		debug("correcting Nov 31st to Dec 1st (HW bug)\n");
+		tm->tm_mon += 1;
+		tm->tm_mday = 1;
+		if (tm->tm_wday == 7)
+			tm->tm_wday = 0;
+		rk808_rtc_set(dev, tm);
+	}
+
+	if (tm->tm_wday == 7) {
+		tm->tm_wday = 0;
+		rk808_rtc_set(dev, tm);
+	}
+
+	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday,
+	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+static int rk808_rtc_reset(struct udevice *dev)
+{
+/* Not needed */
+	return 0;
+}
+
+static int rk808_rtc_init(struct udevice *dev)
+{
+	struct rtc_time tm;
+
+	/* start rtc running by default, and use shadowed timer. */
+	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
+			BIT_RTC_CTRL_REG_RTC_READSEL_M);
+	pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
+
+	/* set init time */
+	rk808_rtc_get(dev, &tm);
+
+	return 0;
+}
+
+static int rk808_rtc_probe(struct udevice *dev)
+{
+	rk808_rtc_init(dev);
+
+	return 0;
+}
+
+static const struct rtc_ops rk808_rtc_ops = {
+	.get = rk808_rtc_get,
+	.set = rk808_rtc_set,
+	.reset = rk808_rtc_reset,
+};
+
+U_BOOT_DRIVER(rk808_rtc) = {
+	.name     = "rk808_rtc",
+	.id       = UCLASS_RTC,
+	.ops      = &rk808_rtc_ops,
+	.probe    = rk808_rtc_probe,
+};
-- 
2.25.1

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

* [PATCH v4 4/4] roc-rk3399-pc: Enable DM RTC
  2020-07-10 15:50 ` Jagan Teki
@ 2020-07-10 15:50   ` Jagan Teki
  -1 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: Kever Yang, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula, Jagan Teki

From: Suniel Mahesh <sunil@amarulasolutions.com>

Enable rtc driver DM for rk808 PMIC's.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Change for v4:
- drop CMD_DATE

 configs/roc-pc-mezzanine-rk3399_defconfig | 1 +
 configs/roc-pc-rk3399_defconfig           | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig
index 3ceecf753f..20a0e03b12 100644
--- a/configs/roc-pc-mezzanine-rk3399_defconfig
+++ b/configs/roc-pc-mezzanine-rk3399_defconfig
@@ -57,6 +57,7 @@ CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_DM_RESET=y
+CONFIG_DM_RTC=y
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_ROCKCHIP_SPI=y
diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index 6943d4fd54..e6627ac56a 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -54,6 +54,7 @@ CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_DM_RESET=y
+CONFIG_DM_RTC=y
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_ROCKCHIP_SPI=y
-- 
2.25.1

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

* [PATCH v4 4/4] roc-rk3399-pc: Enable DM RTC
@ 2020-07-10 15:50   ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-10 15:50 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

Enable rtc driver DM for rk808 PMIC's.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Change for v4:
- drop CMD_DATE

 configs/roc-pc-mezzanine-rk3399_defconfig | 1 +
 configs/roc-pc-rk3399_defconfig           | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig
index 3ceecf753f..20a0e03b12 100644
--- a/configs/roc-pc-mezzanine-rk3399_defconfig
+++ b/configs/roc-pc-mezzanine-rk3399_defconfig
@@ -57,6 +57,7 @@ CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_DM_RESET=y
+CONFIG_DM_RTC=y
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_ROCKCHIP_SPI=y
diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index 6943d4fd54..e6627ac56a 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -54,6 +54,7 @@ CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_DM_RESET=y
+CONFIG_DM_RTC=y
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_ROCKCHIP_SPI=y
-- 
2.25.1

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

* Re: [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-10 15:50   ` Jagan Teki
@ 2020-07-10 15:59     ` Suniel Mahesh
  -1 siblings, 0 replies; 18+ messages in thread
From: Suniel Mahesh @ 2020-07-10 15:59 UTC (permalink / raw)
  To: Jagan Teki
  Cc: Kever Yang, Philipp Tomsich, Simon Glass, U-Boot-Denx,
	linux-rockchip, linux-amarula

On Fri, Jul 10, 2020 at 9:21 PM Jagan Teki <jagan@amarulasolutions.com>
wrote:

> From: Suniel Mahesh <sunil@amarulasolutions.com>
>
> Rockchip RK808 PMIC provides an integrated RTC module. It is
> commonly used with Rockchip SoCs. Add basic support to access
> date and time.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>

---
> Change for v4:
> - rebase
> - style fixes
> - warning fixes
>
>  drivers/rtc/Kconfig     |   8 ++
>  drivers/rtc/Makefile    |   1 +
>  drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 182 insertions(+)
>  create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc44ba..a754d1b4f1 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -75,6 +75,14 @@ config RTC_ISL1208
>           This driver supports reading and writing the RTC/calendar and
> detects
>           total power failures.
>
> +config RTC_RK808
> +       bool "Enable Rockchip RK8XX RTC driver"
> +        depends on DM_RTC && PMIC_RK8XX
> +       default y
> +       help
> +         Basic support for Rockchip RK808 PMIC Real Time Clock devices for
> +         time and date.
> +
>  config RTC_RV3029
>         bool "Enable RV3029 driver"
>         depends on DM_RTC
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 12eb449583..63e2c3413d 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
>  obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
>  obj-$(CONFIG_RTC_PL031) += pl031.o
>  obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
> +obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
>  obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
>  obj-$(CONFIG_RTC_RV3029) += rv3029.o
>  obj-$(CONFIG_RTC_RV8803) += rv8803.o
> diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
> new file mode 100644
> index 0000000000..50cca4dd4b
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * RTC driver for Rockchip RK808 PMIC.
> + *
> + * Copyright (C) 2020 Amarula Solutions(India).
> + * Suniel Mahesh <sunil@amarulasolutions.com>
> + *
> + * Based on code from Linux kernel:
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + *
> + * Date & Time support (no alarms and interrupts)
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <rtc.h>
> +#include <power/rk8xx_pmic.h>
> +#include <power/pmic.h>
> +#include <linux/bitops.h>
> +#include <linux/compat.h>
> +
> +/* RTC_CTRL_REG bitfields */
> +#define BIT_RTC_CTRL_REG_STOP_RTC_M            BIT(0)
> +
> +/* RK808 has a shadowed register for saving a "frozen" RTC time.
> + * When user setting "GET_TIME" to 1, the time will save in this shadowed
> + * register. If set "READSEL" to 1, user read rtc time register, actually
> + * get the time of that moment. If we need the real time, clr this bit.
> + */
> +
> +#define BIT_RTC_CTRL_REG_RTC_GET_TIME          BIT(6)
> +#define BIT_RTC_CTRL_REG_RTC_READSEL_M         BIT(7)
> +#define RTC_STATUS_MASK                                0xFE
> +
> +#define SECONDS_REG_MSK                                0x7F
> +#define MINUTES_REG_MAK                                0x7F
> +#define HOURS_REG_MSK                          0x3F
> +#define DAYS_REG_MSK                           0x3F
> +#define MONTHS_REG_MSK                         0x1F
> +#define YEARS_REG_MSK                          0xFF
> +#define WEEKS_REG_MSK                          0x7
> +
> +/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
> +
> +#define NUM_TIME_REGS  (REG_WEEKS - REG_SECONDS + 1)
> +
> +static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
> +{
> +       u8 rtc_data[NUM_TIME_REGS];
> +
> +       debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +             tm->tm_year, tm->tm_mon, tm->tm_mday,
> +             tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +       rtc_data[0] = bin2bcd(tm->tm_sec);
> +       rtc_data[1] = bin2bcd(tm->tm_min);
> +       rtc_data[2] = bin2bcd(tm->tm_hour);
> +       rtc_data[3] = bin2bcd(tm->tm_mday);
> +       rtc_data[4] = bin2bcd(tm->tm_mon);
> +       rtc_data[5] = bin2bcd(tm->tm_year - 2000);
> +       rtc_data[6] = bin2bcd(tm->tm_wday);
> +
> +       /* Stop RTC while updating the RTC registers */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_STOP_RTC_M);
> +       pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +       /* Start RTC again */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +                       BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
> +{
> +       u8 rtc_data[NUM_TIME_REGS];
> +
> +       /* Force an update of the shadowed registers right now */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_RTC_GET_TIME);
> +
> +       /*
> +        * After we set the GET_TIME bit, the rtc time can't be read
> +        * immediately. So we should wait up to 31.25 us, about one cycle
> of
> +        * 32khz. If we clear the GET_TIME bit here, the time of i2c
> transfer
> +        * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
> +        */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +                       BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
> +       pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +       tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
> +       tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
> +       tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
> +       tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
> +       tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
> +       tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
> +       tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
> +
> +       /*
> +        * RK808 PMIC RTC h/w counts/has 31 days in november. This is
> corrected
> +        * when date cmd is invoked on prompt. checks for the current day
> and
> +        * if it is 31 November, then adjusts it to 1 December.
> +        *
> +        * h/w also has weeks register which counts from 0 to
> 7(0(sun)-6(sat)).
> +        * 7 is an unknown state, reset it back to 0(sun).
> +        */
> +       if (tm->tm_mon == 11 && tm->tm_mday == 31) {
> +               debug("correcting Nov 31st to Dec 1st (HW bug)\n");
> +               tm->tm_mon += 1;
> +               tm->tm_mday = 1;
> +               if (tm->tm_wday == 7)
> +                       tm->tm_wday = 0;
> +               rk808_rtc_set(dev, tm);
> +       }
> +
> +       if (tm->tm_wday == 7) {
> +               tm->tm_wday = 0;
> +               rk808_rtc_set(dev, tm);
> +       }
> +
> +       debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +             tm->tm_year, tm->tm_mon, tm->tm_mday,
> +             tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_reset(struct udevice *dev)
> +{
> +/* Not needed */
> +       return 0;
> +}
> +
> +static int rk808_rtc_init(struct udevice *dev)
> +{
> +       struct rtc_time tm;
> +
> +       /* start rtc running by default, and use shadowed timer. */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_RTC_READSEL_M);
> +       pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
> +
> +       /* set init time */
> +       rk808_rtc_get(dev, &tm);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_probe(struct udevice *dev)
> +{
> +       rk808_rtc_init(dev);
> +
> +       return 0;
> +}
> +
> +static const struct rtc_ops rk808_rtc_ops = {
> +       .get = rk808_rtc_get,
> +       .set = rk808_rtc_set,
> +       .reset = rk808_rtc_reset,
> +};
> +
> +U_BOOT_DRIVER(rk808_rtc) = {
> +       .name     = "rk808_rtc",
> +       .id       = UCLASS_RTC,
> +       .ops      = &rk808_rtc_ops,
> +       .probe    = rk808_rtc_probe,
> +};
> --
> 2.25.1
>
>

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
@ 2020-07-10 15:59     ` Suniel Mahesh
  0 siblings, 0 replies; 18+ messages in thread
From: Suniel Mahesh @ 2020-07-10 15:59 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 10, 2020 at 9:21 PM Jagan Teki <jagan@amarulasolutions.com>
wrote:

> From: Suniel Mahesh <sunil@amarulasolutions.com>
>
> Rockchip RK808 PMIC provides an integrated RTC module. It is
> commonly used with Rockchip SoCs. Add basic support to access
> date and time.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>

---
> Change for v4:
> - rebase
> - style fixes
> - warning fixes
>
>  drivers/rtc/Kconfig     |   8 ++
>  drivers/rtc/Makefile    |   1 +
>  drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 182 insertions(+)
>  create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc44ba..a754d1b4f1 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -75,6 +75,14 @@ config RTC_ISL1208
>           This driver supports reading and writing the RTC/calendar and
> detects
>           total power failures.
>
> +config RTC_RK808
> +       bool "Enable Rockchip RK8XX RTC driver"
> +        depends on DM_RTC && PMIC_RK8XX
> +       default y
> +       help
> +         Basic support for Rockchip RK808 PMIC Real Time Clock devices for
> +         time and date.
> +
>  config RTC_RV3029
>         bool "Enable RV3029 driver"
>         depends on DM_RTC
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 12eb449583..63e2c3413d 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
>  obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
>  obj-$(CONFIG_RTC_PL031) += pl031.o
>  obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
> +obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
>  obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
>  obj-$(CONFIG_RTC_RV3029) += rv3029.o
>  obj-$(CONFIG_RTC_RV8803) += rv8803.o
> diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
> new file mode 100644
> index 0000000000..50cca4dd4b
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * RTC driver for Rockchip RK808 PMIC.
> + *
> + * Copyright (C) 2020 Amarula Solutions(India).
> + * Suniel Mahesh <sunil@amarulasolutions.com>
> + *
> + * Based on code from Linux kernel:
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + *
> + * Date & Time support (no alarms and interrupts)
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <rtc.h>
> +#include <power/rk8xx_pmic.h>
> +#include <power/pmic.h>
> +#include <linux/bitops.h>
> +#include <linux/compat.h>
> +
> +/* RTC_CTRL_REG bitfields */
> +#define BIT_RTC_CTRL_REG_STOP_RTC_M            BIT(0)
> +
> +/* RK808 has a shadowed register for saving a "frozen" RTC time.
> + * When user setting "GET_TIME" to 1, the time will save in this shadowed
> + * register. If set "READSEL" to 1, user read rtc time register, actually
> + * get the time of that moment. If we need the real time, clr this bit.
> + */
> +
> +#define BIT_RTC_CTRL_REG_RTC_GET_TIME          BIT(6)
> +#define BIT_RTC_CTRL_REG_RTC_READSEL_M         BIT(7)
> +#define RTC_STATUS_MASK                                0xFE
> +
> +#define SECONDS_REG_MSK                                0x7F
> +#define MINUTES_REG_MAK                                0x7F
> +#define HOURS_REG_MSK                          0x3F
> +#define DAYS_REG_MSK                           0x3F
> +#define MONTHS_REG_MSK                         0x1F
> +#define YEARS_REG_MSK                          0xFF
> +#define WEEKS_REG_MSK                          0x7
> +
> +/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
> +
> +#define NUM_TIME_REGS  (REG_WEEKS - REG_SECONDS + 1)
> +
> +static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
> +{
> +       u8 rtc_data[NUM_TIME_REGS];
> +
> +       debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +             tm->tm_year, tm->tm_mon, tm->tm_mday,
> +             tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +       rtc_data[0] = bin2bcd(tm->tm_sec);
> +       rtc_data[1] = bin2bcd(tm->tm_min);
> +       rtc_data[2] = bin2bcd(tm->tm_hour);
> +       rtc_data[3] = bin2bcd(tm->tm_mday);
> +       rtc_data[4] = bin2bcd(tm->tm_mon);
> +       rtc_data[5] = bin2bcd(tm->tm_year - 2000);
> +       rtc_data[6] = bin2bcd(tm->tm_wday);
> +
> +       /* Stop RTC while updating the RTC registers */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_STOP_RTC_M);
> +       pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +       /* Start RTC again */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +                       BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
> +{
> +       u8 rtc_data[NUM_TIME_REGS];
> +
> +       /* Force an update of the shadowed registers right now */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_RTC_GET_TIME);
> +
> +       /*
> +        * After we set the GET_TIME bit, the rtc time can't be read
> +        * immediately. So we should wait up to 31.25 us, about one cycle
> of
> +        * 32khz. If we clear the GET_TIME bit here, the time of i2c
> transfer
> +        * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
> +        */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +                       BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
> +       pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +       tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
> +       tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
> +       tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
> +       tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
> +       tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
> +       tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
> +       tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
> +
> +       /*
> +        * RK808 PMIC RTC h/w counts/has 31 days in november. This is
> corrected
> +        * when date cmd is invoked on prompt. checks for the current day
> and
> +        * if it is 31 November, then adjusts it to 1 December.
> +        *
> +        * h/w also has weeks register which counts from 0 to
> 7(0(sun)-6(sat)).
> +        * 7 is an unknown state, reset it back to 0(sun).
> +        */
> +       if (tm->tm_mon == 11 && tm->tm_mday == 31) {
> +               debug("correcting Nov 31st to Dec 1st (HW bug)\n");
> +               tm->tm_mon += 1;
> +               tm->tm_mday = 1;
> +               if (tm->tm_wday == 7)
> +                       tm->tm_wday = 0;
> +               rk808_rtc_set(dev, tm);
> +       }
> +
> +       if (tm->tm_wday == 7) {
> +               tm->tm_wday = 0;
> +               rk808_rtc_set(dev, tm);
> +       }
> +
> +       debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +             tm->tm_year, tm->tm_mon, tm->tm_mday,
> +             tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_reset(struct udevice *dev)
> +{
> +/* Not needed */
> +       return 0;
> +}
> +
> +static int rk808_rtc_init(struct udevice *dev)
> +{
> +       struct rtc_time tm;
> +
> +       /* start rtc running by default, and use shadowed timer. */
> +       pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +                       BIT_RTC_CTRL_REG_RTC_READSEL_M);
> +       pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
> +
> +       /* set init time */
> +       rk808_rtc_get(dev, &tm);
> +
> +       return 0;
> +}
> +
> +static int rk808_rtc_probe(struct udevice *dev)
> +{
> +       rk808_rtc_init(dev);
> +
> +       return 0;
> +}
> +
> +static const struct rtc_ops rk808_rtc_ops = {
> +       .get = rk808_rtc_get,
> +       .set = rk808_rtc_set,
> +       .reset = rk808_rtc_reset,
> +};
> +
> +U_BOOT_DRIVER(rk808_rtc) = {
> +       .name     = "rk808_rtc",
> +       .id       = UCLASS_RTC,
> +       .ops      = &rk808_rtc_ops,
> +       .probe    = rk808_rtc_probe,
> +};
> --
> 2.25.1
>
>

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

* Re: [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-10 15:50   ` Jagan Teki
@ 2020-07-18 12:11     ` Kever Yang
  -1 siblings, 0 replies; 18+ messages in thread
From: Kever Yang @ 2020-07-18 12:11 UTC (permalink / raw)
  To: Jagan Teki, Philipp Tomsich, Simon Glass
  Cc: Suniel Mahesh, U-Boot-Denx, linux-rockchip, linux-amarula

Hi Jagan,

On 2020/7/10 下午11:50, Jagan Teki wrote:
> From: Suniel Mahesh <sunil@amarulasolutions.com>
>
> Rockchip RK808 PMIC provides an integrated RTC module. It is
> commonly used with Rockchip SoCs. Add basic support to access
> date and time.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> ---
> Change for v4:
> - rebase
> - style fixes
> - warning fixes


Seems like the change request by Elaine in previous version does not 
update ?


Thanks,

- Kever

>
>   drivers/rtc/Kconfig     |   8 ++
>   drivers/rtc/Makefile    |   1 +
>   drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 182 insertions(+)
>   create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc44ba..a754d1b4f1 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -75,6 +75,14 @@ config RTC_ISL1208
>   	  This driver supports reading and writing the RTC/calendar and detects
>   	  total power failures.
>   
> +config RTC_RK808
> +	bool "Enable Rockchip RK8XX RTC driver"
> +        depends on DM_RTC && PMIC_RK8XX
> +	default y
> +	help
> +	  Basic support for Rockchip RK808 PMIC Real Time Clock devices for
> +	  time and date.
> +
>   config RTC_RV3029
>   	bool "Enable RV3029 driver"
>   	depends on DM_RTC
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 12eb449583..63e2c3413d 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
>   obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
>   obj-$(CONFIG_RTC_PL031) += pl031.o
>   obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
> +obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
>   obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
>   obj-$(CONFIG_RTC_RV3029) += rv3029.o
>   obj-$(CONFIG_RTC_RV8803) += rv8803.o
> diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
> new file mode 100644
> index 0000000000..50cca4dd4b
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * RTC driver for Rockchip RK808 PMIC.
> + *
> + * Copyright (C) 2020 Amarula Solutions(India).
> + * Suniel Mahesh <sunil@amarulasolutions.com>
> + *
> + * Based on code from Linux kernel:
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + *
> + * Date & Time support (no alarms and interrupts)
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <rtc.h>
> +#include <power/rk8xx_pmic.h>
> +#include <power/pmic.h>
> +#include <linux/bitops.h>
> +#include <linux/compat.h>
> +
> +/* RTC_CTRL_REG bitfields */
> +#define BIT_RTC_CTRL_REG_STOP_RTC_M		BIT(0)
> +
> +/* RK808 has a shadowed register for saving a "frozen" RTC time.
> + * When user setting "GET_TIME" to 1, the time will save in this shadowed
> + * register. If set "READSEL" to 1, user read rtc time register, actually
> + * get the time of that moment. If we need the real time, clr this bit.
> + */
> +
> +#define BIT_RTC_CTRL_REG_RTC_GET_TIME		BIT(6)
> +#define BIT_RTC_CTRL_REG_RTC_READSEL_M		BIT(7)
> +#define RTC_STATUS_MASK				0xFE
> +
> +#define SECONDS_REG_MSK				0x7F
> +#define MINUTES_REG_MAK				0x7F
> +#define HOURS_REG_MSK				0x3F
> +#define DAYS_REG_MSK				0x3F
> +#define MONTHS_REG_MSK				0x1F
> +#define YEARS_REG_MSK				0xFF
> +#define WEEKS_REG_MSK				0x7
> +
> +/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
> +
> +#define NUM_TIME_REGS	(REG_WEEKS - REG_SECONDS + 1)
> +
> +static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
> +{
> +	u8 rtc_data[NUM_TIME_REGS];
> +
> +	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +	      tm->tm_year, tm->tm_mon, tm->tm_mday,
> +	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +	rtc_data[0] = bin2bcd(tm->tm_sec);
> +	rtc_data[1] = bin2bcd(tm->tm_min);
> +	rtc_data[2] = bin2bcd(tm->tm_hour);
> +	rtc_data[3] = bin2bcd(tm->tm_mday);
> +	rtc_data[4] = bin2bcd(tm->tm_mon);
> +	rtc_data[5] = bin2bcd(tm->tm_year - 2000);
> +	rtc_data[6] = bin2bcd(tm->tm_wday);
> +
> +	/* Stop RTC while updating the RTC registers */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_STOP_RTC_M);
> +	pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +	/* Start RTC again */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +			BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
> +{
> +	u8 rtc_data[NUM_TIME_REGS];
> +
> +	/* Force an update of the shadowed registers right now */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_RTC_GET_TIME);
> +
> +	/*
> +	 * After we set the GET_TIME bit, the rtc time can't be read
> +	 * immediately. So we should wait up to 31.25 us, about one cycle of
> +	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
> +	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
> +	 */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +			BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
> +	pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +	tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
> +	tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
> +	tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
> +	tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
> +	tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
> +	tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
> +	tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
> +
> +	/*
> +	 * RK808 PMIC RTC h/w counts/has 31 days in november. This is corrected
> +	 * when date cmd is invoked on prompt. checks for the current day and
> +	 * if it is 31 November, then adjusts it to 1 December.
> +	 *
> +	 * h/w also has weeks register which counts from 0 to 7(0(sun)-6(sat)).
> +	 * 7 is an unknown state, reset it back to 0(sun).
> +	 */
> +	if (tm->tm_mon == 11 && tm->tm_mday == 31) {
> +		debug("correcting Nov 31st to Dec 1st (HW bug)\n");
> +		tm->tm_mon += 1;
> +		tm->tm_mday = 1;
> +		if (tm->tm_wday == 7)
> +			tm->tm_wday = 0;
> +		rk808_rtc_set(dev, tm);
> +	}
> +
> +	if (tm->tm_wday == 7) {
> +		tm->tm_wday = 0;
> +		rk808_rtc_set(dev, tm);
> +	}
> +
> +	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +	      tm->tm_year, tm->tm_mon, tm->tm_mday,
> +	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_reset(struct udevice *dev)
> +{
> +/* Not needed */
> +	return 0;
> +}
> +
> +static int rk808_rtc_init(struct udevice *dev)
> +{
> +	struct rtc_time tm;
> +
> +	/* start rtc running by default, and use shadowed timer. */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_RTC_READSEL_M);
> +	pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
> +
> +	/* set init time */
> +	rk808_rtc_get(dev, &tm);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_probe(struct udevice *dev)
> +{
> +	rk808_rtc_init(dev);
> +
> +	return 0;
> +}
> +
> +static const struct rtc_ops rk808_rtc_ops = {
> +	.get = rk808_rtc_get,
> +	.set = rk808_rtc_set,
> +	.reset = rk808_rtc_reset,
> +};
> +
> +U_BOOT_DRIVER(rk808_rtc) = {
> +	.name     = "rk808_rtc",
> +	.id       = UCLASS_RTC,
> +	.ops      = &rk808_rtc_ops,
> +	.probe    = rk808_rtc_probe,
> +};

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
@ 2020-07-18 12:11     ` Kever Yang
  0 siblings, 0 replies; 18+ messages in thread
From: Kever Yang @ 2020-07-18 12:11 UTC (permalink / raw)
  To: u-boot

Hi Jagan,

On 2020/7/10 ??11:50, Jagan Teki wrote:
> From: Suniel Mahesh <sunil@amarulasolutions.com>
>
> Rockchip RK808 PMIC provides an integrated RTC module. It is
> commonly used with Rockchip SoCs. Add basic support to access
> date and time.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> ---
> Change for v4:
> - rebase
> - style fixes
> - warning fixes


Seems like the change request by Elaine in previous version does not 
update ?


Thanks,

- Kever

>
>   drivers/rtc/Kconfig     |   8 ++
>   drivers/rtc/Makefile    |   1 +
>   drivers/rtc/rk808-rtc.c | 173 ++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 182 insertions(+)
>   create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc44ba..a754d1b4f1 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -75,6 +75,14 @@ config RTC_ISL1208
>   	  This driver supports reading and writing the RTC/calendar and detects
>   	  total power failures.
>   
> +config RTC_RK808
> +	bool "Enable Rockchip RK8XX RTC driver"
> +        depends on DM_RTC && PMIC_RK8XX
> +	default y
> +	help
> +	  Basic support for Rockchip RK808 PMIC Real Time Clock devices for
> +	  time and date.
> +
>   config RTC_RV3029
>   	bool "Enable RV3029 driver"
>   	depends on DM_RTC
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 12eb449583..63e2c3413d 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
>   obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
>   obj-$(CONFIG_RTC_PL031) += pl031.o
>   obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
> +obj-$(CONFIG_RTC_RK808) += rk808-rtc.o
>   obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
>   obj-$(CONFIG_RTC_RV3029) += rv3029.o
>   obj-$(CONFIG_RTC_RV8803) += rv8803.o
> diff --git a/drivers/rtc/rk808-rtc.c b/drivers/rtc/rk808-rtc.c
> new file mode 100644
> index 0000000000..50cca4dd4b
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * RTC driver for Rockchip RK808 PMIC.
> + *
> + * Copyright (C) 2020 Amarula Solutions(India).
> + * Suniel Mahesh <sunil@amarulasolutions.com>
> + *
> + * Based on code from Linux kernel:
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + *
> + * Date & Time support (no alarms and interrupts)
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <rtc.h>
> +#include <power/rk8xx_pmic.h>
> +#include <power/pmic.h>
> +#include <linux/bitops.h>
> +#include <linux/compat.h>
> +
> +/* RTC_CTRL_REG bitfields */
> +#define BIT_RTC_CTRL_REG_STOP_RTC_M		BIT(0)
> +
> +/* RK808 has a shadowed register for saving a "frozen" RTC time.
> + * When user setting "GET_TIME" to 1, the time will save in this shadowed
> + * register. If set "READSEL" to 1, user read rtc time register, actually
> + * get the time of that moment. If we need the real time, clr this bit.
> + */
> +
> +#define BIT_RTC_CTRL_REG_RTC_GET_TIME		BIT(6)
> +#define BIT_RTC_CTRL_REG_RTC_READSEL_M		BIT(7)
> +#define RTC_STATUS_MASK				0xFE
> +
> +#define SECONDS_REG_MSK				0x7F
> +#define MINUTES_REG_MAK				0x7F
> +#define HOURS_REG_MSK				0x3F
> +#define DAYS_REG_MSK				0x3F
> +#define MONTHS_REG_MSK				0x1F
> +#define YEARS_REG_MSK				0xFF
> +#define WEEKS_REG_MSK				0x7
> +
> +/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
> +
> +#define NUM_TIME_REGS	(REG_WEEKS - REG_SECONDS + 1)
> +
> +static int rk808_rtc_set(struct udevice *dev, const struct rtc_time *tm)
> +{
> +	u8 rtc_data[NUM_TIME_REGS];
> +
> +	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +	      tm->tm_year, tm->tm_mon, tm->tm_mday,
> +	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +	rtc_data[0] = bin2bcd(tm->tm_sec);
> +	rtc_data[1] = bin2bcd(tm->tm_min);
> +	rtc_data[2] = bin2bcd(tm->tm_hour);
> +	rtc_data[3] = bin2bcd(tm->tm_mday);
> +	rtc_data[4] = bin2bcd(tm->tm_mon);
> +	rtc_data[5] = bin2bcd(tm->tm_year - 2000);
> +	rtc_data[6] = bin2bcd(tm->tm_wday);
> +
> +	/* Stop RTC while updating the RTC registers */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_STOP_RTC_M);
> +	pmic_write(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +	/* Start RTC again */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +			BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_get(struct udevice *dev, struct rtc_time *tm)
> +{
> +	u8 rtc_data[NUM_TIME_REGS];
> +
> +	/* Force an update of the shadowed registers right now */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_RTC_GET_TIME);
> +
> +	/*
> +	 * After we set the GET_TIME bit, the rtc time can't be read
> +	 * immediately. So we should wait up to 31.25 us, about one cycle of
> +	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
> +	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
> +	 */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL,
> +			BIT_RTC_CTRL_REG_RTC_GET_TIME, 0);
> +	pmic_read(dev->parent, REG_SECONDS, rtc_data, NUM_TIME_REGS);
> +
> +	tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
> +	tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
> +	tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
> +	tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
> +	tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK));
> +	tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 2000;
> +	tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
> +
> +	/*
> +	 * RK808 PMIC RTC h/w counts/has 31 days in november. This is corrected
> +	 * when date cmd is invoked on prompt. checks for the current day and
> +	 * if it is 31 November, then adjusts it to 1 December.
> +	 *
> +	 * h/w also has weeks register which counts from 0 to 7(0(sun)-6(sat)).
> +	 * 7 is an unknown state, reset it back to 0(sun).
> +	 */
> +	if (tm->tm_mon == 11 && tm->tm_mday == 31) {
> +		debug("correcting Nov 31st to Dec 1st (HW bug)\n");
> +		tm->tm_mon += 1;
> +		tm->tm_mday = 1;
> +		if (tm->tm_wday == 7)
> +			tm->tm_wday = 0;
> +		rk808_rtc_set(dev, tm);
> +	}
> +
> +	if (tm->tm_wday == 7) {
> +		tm->tm_wday = 0;
> +		rk808_rtc_set(dev, tm);
> +	}
> +
> +	debug("RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
> +	      tm->tm_year, tm->tm_mon, tm->tm_mday,
> +	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_reset(struct udevice *dev)
> +{
> +/* Not needed */
> +	return 0;
> +}
> +
> +static int rk808_rtc_init(struct udevice *dev)
> +{
> +	struct rtc_time tm;
> +
> +	/* start rtc running by default, and use shadowed timer. */
> +	pmic_clrsetbits(dev->parent, REG_RTC_CTRL, 0,
> +			BIT_RTC_CTRL_REG_RTC_READSEL_M);
> +	pmic_reg_write(dev->parent, REG_RTC_STATUS, RTC_STATUS_MASK);
> +
> +	/* set init time */
> +	rk808_rtc_get(dev, &tm);
> +
> +	return 0;
> +}
> +
> +static int rk808_rtc_probe(struct udevice *dev)
> +{
> +	rk808_rtc_init(dev);
> +
> +	return 0;
> +}
> +
> +static const struct rtc_ops rk808_rtc_ops = {
> +	.get = rk808_rtc_get,
> +	.set = rk808_rtc_set,
> +	.reset = rk808_rtc_reset,
> +};
> +
> +U_BOOT_DRIVER(rk808_rtc) = {
> +	.name     = "rk808_rtc",
> +	.id       = UCLASS_RTC,
> +	.ops      = &rk808_rtc_ops,
> +	.probe    = rk808_rtc_probe,
> +};

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

* Re: [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-18 12:11     ` Kever Yang
@ 2020-07-20 10:53       ` Jagan Teki
  -1 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-20 10:53 UTC (permalink / raw)
  To: Kever Yang
  Cc: Philipp Tomsich, Simon Glass, Suniel Mahesh, U-Boot-Denx,
	open list:ARM/Rockchip SoC...,
	linux-amarula

Hi Kever,

On Sat, Jul 18, 2020 at 5:41 PM Kever Yang <kever.yang@rock-chips.com> wrote:
>
> Hi Jagan,
>
> On 2020/7/10 下午11:50, Jagan Teki wrote:
> > From: Suniel Mahesh <sunil@amarulasolutions.com>
> >
> > Rockchip RK808 PMIC provides an integrated RTC module. It is
> > commonly used with Rockchip SoCs. Add basic support to access
> > date and time.
> >
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> > ---
> > Change for v4:
> > - rebase
> > - style fixes
> > - warning fixes
>
>
> Seems like the change request by Elaine in previous version does not
> update ?

Yes, It requires the additional function to add that feature. We are
still working on it in proper shape and thinking this series as
initial support. Can you push this so-that we can send that feature
before rc2 or rc3?

Jagan.

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
@ 2020-07-20 10:53       ` Jagan Teki
  0 siblings, 0 replies; 18+ messages in thread
From: Jagan Teki @ 2020-07-20 10:53 UTC (permalink / raw)
  To: u-boot

Hi Kever,

On Sat, Jul 18, 2020 at 5:41 PM Kever Yang <kever.yang@rock-chips.com> wrote:
>
> Hi Jagan,
>
> On 2020/7/10 ??11:50, Jagan Teki wrote:
> > From: Suniel Mahesh <sunil@amarulasolutions.com>
> >
> > Rockchip RK808 PMIC provides an integrated RTC module. It is
> > commonly used with Rockchip SoCs. Add basic support to access
> > date and time.
> >
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> > ---
> > Change for v4:
> > - rebase
> > - style fixes
> > - warning fixes
>
>
> Seems like the change request by Elaine in previous version does not
> update ?

Yes, It requires the additional function to add that feature. We are
still working on it in proper shape and thinking this series as
initial support. Can you push this so-that we can send that feature
before rc2 or rc3?

Jagan.

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-20 10:53       ` Jagan Teki
  (?)
@ 2020-07-21  3:12       ` Kever Yang
  2020-07-21 13:22         ` Suniel Mahesh
  -1 siblings, 1 reply; 18+ messages in thread
From: Kever Yang @ 2020-07-21  3:12 UTC (permalink / raw)
  To: u-boot


On 2020/7/20 ??6:53, Jagan Teki wrote:
> Hi Kever,
>
> On Sat, Jul 18, 2020 at 5:41 PM Kever Yang <kever.yang@rock-chips.com> wrote:
>> Hi Jagan,
>>
>> On 2020/7/10 ??11:50, Jagan Teki wrote:
>>> From: Suniel Mahesh <sunil@amarulasolutions.com>
>>>
>>> Rockchip RK808 PMIC provides an integrated RTC module. It is
>>> commonly used with Rockchip SoCs. Add basic support to access
>>> date and time.
>>>
>>> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>>> ---
>>> Change for v4:
>>> - rebase
>>> - style fixes
>>> - warning fixes
>>
>> Seems like the change request by Elaine in previous version does not
>> update ?
> Yes, It requires the additional function to add that feature.

No only new feature required, but also wrong implementation for function.

Again, what do you want the RTC in U-Boot used for?


Thanks,

- Kever

> We are
> still working on it in proper shape and thinking this series as
> initial support. Can you push this so-that we can send that feature
> before rc2 or rc3?
>
> Jagan.
>
>

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

* [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-07-21  3:12       ` Kever Yang
@ 2020-07-21 13:22         ` Suniel Mahesh
  0 siblings, 0 replies; 18+ messages in thread
From: Suniel Mahesh @ 2020-07-21 13:22 UTC (permalink / raw)
  To: u-boot

Hi kever,

On Tue, Jul 21, 2020 at 8:43 AM Kever Yang <kever.yang@rock-chips.com>
wrote:

>
> On 2020/7/20 ??6:53, Jagan Teki wrote:
> > Hi Kever,
> >
> > On Sat, Jul 18, 2020 at 5:41 PM Kever Yang <kever.yang@rock-chips.com>
> wrote:
> >> Hi Jagan,
> >>
> >> On 2020/7/10 ??11:50, Jagan Teki wrote:
> >>> From: Suniel Mahesh <sunil@amarulasolutions.com>
> >>>
> >>> Rockchip RK808 PMIC provides an integrated RTC module. It is
> >>> commonly used with Rockchip SoCs. Add basic support to access
> >>> date and time.
> >>>
> >>> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> >>> ---
> >>> Change for v4:
> >>> - rebase
> >>> - style fixes
> >>> - warning fixes
> >>
> >> Seems like the change request by Elaine in previous version does not
> >> update ?
> > Yes, It requires the additional function to add that feature.
>
> No only new feature required, but also wrong implementation for function.
>

Yes the implementation doesn't take into effect the hardware bug (31 days
for november month).
Elaine also pointed out the same in the past.

Again, what do you want the RTC in U-Boot used for?
>

The intention here is to add hardware driver support for any usage in
uboot. Cant this
patch be considered as the initial support, we will send the corrections as
per Linux ASAP.

Regards
 Suniel

>
>
> Thanks,
>
> - Kever
>
> > We are
> > still working on it in proper shape and thinking this series as
> > initial support. Can you push this so-that we can send that feature
> > before rc2 or rc3?
> >
> > Jagan.
> >
> >
>
>
>

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

end of thread, other threads:[~2020-07-21 13:22 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-10 15:50 [PATCH v4 0/4] rtc: Add RK808 PMIC RTC Jagan Teki
2020-07-10 15:50 ` Jagan Teki
2020-07-10 15:50 ` [PATCH v4 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC Jagan Teki
2020-07-10 15:50   ` Jagan Teki
2020-07-10 15:50 ` [PATCH v4 2/4] power: pmic: rk8xx: bind rk808 RTC Jagan Teki
2020-07-10 15:50   ` Jagan Teki
2020-07-10 15:50 ` [PATCH v4 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC Jagan Teki
2020-07-10 15:50   ` Jagan Teki
2020-07-10 15:59   ` Suniel Mahesh
2020-07-10 15:59     ` Suniel Mahesh
2020-07-18 12:11   ` Kever Yang
2020-07-18 12:11     ` Kever Yang
2020-07-20 10:53     ` Jagan Teki
2020-07-20 10:53       ` Jagan Teki
2020-07-21  3:12       ` Kever Yang
2020-07-21 13:22         ` Suniel Mahesh
2020-07-10 15:50 ` [PATCH v4 4/4] roc-rk3399-pc: Enable DM RTC Jagan Teki
2020-07-10 15:50   ` Jagan Teki

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