All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for Rockchip RK808 PMIC RTC device
@ 2020-04-22 16:11 sunil at amarulasolutions.com
  2020-04-22 16:11 ` [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-22 16:11 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

This patch series adds support for Rockchip RK808 PMIC RTC device.

Patch #1, adds a child node under RK808 PMIC node. Patch #2 binds
this child device with its parent RK808 PMIC. Patch #3 adds the rtc
driver. 

The RK808 PMIC RTC has a hardware bug. It counts 31 days for november
month and the weeks register counts 0 - 7.

This driver does a temporary fix, where as in if date is Nov 31, then it resets
the date to Dec 1(this happens only if date cmd is queried from u-boot command line/script).
Similarly for the weeks register, 0(sun) - 6(sat). If 7 is encountered then it is reset to zero.

u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202 

Is this changeset acceptable ? please comment.

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

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

-- 
2.7.4

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

* [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  2020-04-22 16:11 [PATCH 0/3] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
@ 2020-04-22 16:11 ` sunil at amarulasolutions.com
  2020-04-28 14:05   ` Kever Yang
  2020-04-22 16:11 ` [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
  2020-04-22 16:11 ` [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
  2 siblings, 1 reply; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-22 16:11 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>
---
 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 5746442..7d189c8 100644
--- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
@@ -20,3 +20,11 @@
 	regulator-min-microvolt = <430000>;
 	regulator-init-microvolt = <950000>;
 };
+
+&rk808 {
+	rtc {
+		rkrtc: rk808-rtc {
+			status="okay";
+		};
+	};
+};
-- 
2.7.4

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

* [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC
  2020-04-22 16:11 [PATCH 0/3] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-22 16:11 ` [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
@ 2020-04-22 16:11 ` sunil at amarulasolutions.com
  2020-04-28 14:05   ` Kever Yang
  2020-05-15  8:01   ` Kever Yang
  2020-04-22 16:11 ` [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
  2 siblings, 2 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-22 16:11 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>
---
 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 52e6d9d..8d6b64e 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -24,6 +24,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;
@@ -59,7 +64,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");
@@ -75,6 +80,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.7.4

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

* [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC
  2020-04-22 16:11 [PATCH 0/3] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-22 16:11 ` [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
  2020-04-22 16:11 ` [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
@ 2020-04-22 16:11 ` sunil at amarulasolutions.com
  2020-04-28 14:09   ` Kever Yang
  2 siblings, 1 reply; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-22 16:11 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: Suniel Mahesh <sunil@amarulasolutions.com>
---
Note:
1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
for november month and the weeks register counts 0 - 7.

2. This driver does a temporary fix, where as in if date is Nov 31,
then it resets the date to Dec 1(this happens only if date cmd is queried
from u-boot command line/script). Similarly for the weeks register, 0(sun)
- 6(sat). If 7 is encountered then it is reset to zero.

3. u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202

4. Is this change acceptable ? please comment
---
 configs/roc-pc-rk3399_defconfig |   2 +
 drivers/rtc/Kconfig             |   8 ++
 drivers/rtc/Makefile            |   1 +
 drivers/rtc/rk808-rtc.c         | 165 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 176 insertions(+)
 create mode 100644 drivers/rtc/rk808-rtc.c

diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index be76524..e98d680 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DATE=y
 CONFIG_CMD_TIME=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-roc-pc"
@@ -39,6 +40,7 @@ CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
+CONFIG_DM_RTC=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_BAUDRATE=1500000
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 59e2fc4..6cf1abb 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 12eb449..63e2c34 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 0000000..b63cced
--- /dev/null
+++ b/drivers/rtc/rk808-rtc.c
@@ -0,0 +1,165 @@
+// 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>
+
+/* 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.7.4

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

* [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  2020-04-22 16:11 ` [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
@ 2020-04-28 14:05   ` Kever Yang
  0 siblings, 0 replies; 21+ messages in thread
From: Kever Yang @ 2020-04-28 14:05 UTC (permalink / raw)
  To: u-boot


On 2020/4/23 ??12:11, sunil at amarulasolutions.com wrote:
> 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>

Thanks,
- Kever
> ---
>   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 5746442..7d189c8 100644
> --- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
> +++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
> @@ -20,3 +20,11 @@
>   	regulator-min-microvolt = <430000>;
>   	regulator-init-microvolt = <950000>;
>   };
> +
> +&rk808 {
> +	rtc {
> +		rkrtc: rk808-rtc {
> +			status="okay";
> +		};
> +	};
> +};

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

* [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC
  2020-04-22 16:11 ` [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
@ 2020-04-28 14:05   ` Kever Yang
  2020-05-15  8:01   ` Kever Yang
  1 sibling, 0 replies; 21+ messages in thread
From: Kever Yang @ 2020-04-28 14:05 UTC (permalink / raw)
  To: u-boot


On 2020/4/23 ??12:11, sunil at amarulasolutions.com wrote:
> 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>

Thanks,
- Kever
> ---
>   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 52e6d9d..8d6b64e 100644
> --- a/drivers/power/pmic/rk8xx.c
> +++ b/drivers/power/pmic/rk8xx.c
> @@ -24,6 +24,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;
> @@ -59,7 +64,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");
> @@ -75,6 +80,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;
>   }

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

* [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC
  2020-04-22 16:11 ` [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
@ 2020-04-28 14:09   ` Kever Yang
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  0 siblings, 2 replies; 21+ messages in thread
From: Kever Yang @ 2020-04-28 14:09 UTC (permalink / raw)
  To: u-boot

Hi Sunil,

 ??? Thanks for your patch, see comments below.

On 2020/4/23 ??12:11, sunil at 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: Suniel Mahesh <sunil@amarulasolutions.com>
> ---
> Note:
> 1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
> for november month and the weeks register counts 0 - 7.
>
> 2. This driver does a temporary fix, where as in if date is Nov 31,
> then it resets the date to Dec 1(this happens only if date cmd is queried
> from u-boot command line/script). Similarly for the weeks register, 0(sun)
> - 6(sat). If 7 is encountered then it is reset to zero.
>
> 3. u-boot generally loads linux/other binary. Linux has a full fledged
> driver implemented along with a workaround.
> https://lkml.org/lkml/2015/12/2/1202
>
> 4. Is this change acceptable ? please comment
> ---
>   configs/roc-pc-rk3399_defconfig |   2 +

Please split the defconfig update to a separate patch.

Thanks,

- Kever

>   drivers/rtc/Kconfig             |   8 ++
>   drivers/rtc/Makefile            |   1 +
>   drivers/rtc/rk808-rtc.c         | 165 ++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 176 insertions(+)
>   create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
> index be76524..e98d680 100644
> --- a/configs/roc-pc-rk3399_defconfig
> +++ b/configs/roc-pc-rk3399_defconfig
> @@ -20,6 +20,7 @@ CONFIG_CMD_GPT=y
>   CONFIG_CMD_MMC=y
>   CONFIG_CMD_USB=y
>   # CONFIG_CMD_SETEXPR is not set
> +CONFIG_CMD_DATE=y
>   CONFIG_CMD_TIME=y
>   CONFIG_SPL_OF_CONTROL=y
>   CONFIG_DEFAULT_DEVICE_TREE="rk3399-roc-pc"
> @@ -39,6 +40,7 @@ CONFIG_GMAC_ROCKCHIP=y
>   CONFIG_PMIC_RK8XX=y
>   CONFIG_REGULATOR_PWM=y
>   CONFIG_REGULATOR_RK8XX=y
> +CONFIG_DM_RTC=y
>   CONFIG_PWM_ROCKCHIP=y
>   CONFIG_RAM_RK3399_LPDDR4=y
>   CONFIG_BAUDRATE=1500000
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc4..6cf1abb 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 12eb449..63e2c34 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 0000000..b63cced
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,165 @@
> +// 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>
> +
> +/* 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] 21+ messages in thread

* [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device
  2020-04-28 14:09   ` Kever Yang
@ 2020-04-28 15:57     ` sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
                         ` (3 more replies)
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  1 sibling, 4 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 15:57 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

This patch series adds support for Rockchip RK808 PMIC RTC device.

Patch #1, adds a child node under RK808 PMIC node. Patch #2 binds
this child device with its parent RK808 PMIC. Patch #3 adds the rtc
driver. Patch #4 enables DM RTC, adds date command for the target.

The RK808 PMIC RTC has a hardware bug. It counts 31 days for november
month and the weeks register counts 0 - 7.

This driver does a temporary fix, where as in if date is Nov 31, then it resets
the date to Dec 1(this happens only if date cmd is queried from u-boot command line/script).
Similarly for the weeks register, 0(sun) - 6(sat). If 7 is encountered then it is reset to zero.

u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202
---
changes for v2:
- changed the description of the patch
- earlier it was a three patch series. code which was enabling RTC DM and date command
  is split into a seperate patch as suggested by kever yang. patch#3 is split into patch#4.
---
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
  configs: roc-rk3399-pc: Enable DM for RTC and commands

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

-- 
2.7.4

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

* [PATCH v2 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
@ 2020-04-28 15:57       ` sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 15:57 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>
---
Changes for v2:
- no changes
---
 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 5746442..7d189c8 100644
--- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
@@ -20,3 +20,11 @@
 	regulator-min-microvolt = <430000>;
 	regulator-init-microvolt = <950000>;
 };
+
+&rk808 {
+	rtc {
+		rkrtc: rk808-rtc {
+			status="okay";
+		};
+	};
+};
-- 
2.7.4

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

* [PATCH v2 2/4] power: pmic: rk8xx: bind rk808 RTC
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
@ 2020-04-28 15:57       ` sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 15:57 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>
---
Changes for v2:
- no changes
---
 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 52e6d9d..8d6b64e 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -24,6 +24,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;
@@ -59,7 +64,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");
@@ -75,6 +80,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.7.4

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

* [PATCH v2 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
@ 2020-04-28 15:57       ` sunil at amarulasolutions.com
  2020-04-28 15:57       ` [PATCH v2 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 15:57 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: Suniel Mahesh <sunil@amarulasolutions.com>
---
Changes for v2:
-  moved corresponding configs which enable rtc into a seperate
   patch.
- changed subject line.

Note:
1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
for november month and the weeks register counts 0 - 7.

2. This driver does a temporary fix, where as in if date is Nov 31,
then it resets the date to Dec 1(this happens only if date cmd is queried
from u-boot command line/script). Similarly for the weeks register, 0(sun)
- 6(sat). If 7 is encountered then it is reset to zero.

3. u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202

4. Is this change acceptable ? please comment
---
 drivers/rtc/Kconfig     |   8 +++
 drivers/rtc/Makefile    |   1 +
 drivers/rtc/rk808-rtc.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+)
 create mode 100644 drivers/rtc/rk808-rtc.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 59e2fc4..a754d1b 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 12eb449..63e2c34 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 0000000..b63cced
--- /dev/null
+++ b/drivers/rtc/rk808-rtc.c
@@ -0,0 +1,165 @@
+// 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>
+
+/* 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.7.4

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

* [PATCH v2 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
                         ` (2 preceding siblings ...)
  2020-04-28 15:57       ` [PATCH v2 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
@ 2020-04-28 15:57       ` sunil at amarulasolutions.com
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 15:57 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

Enable rtc driver DM for rk808 PMIC's, also enable date command.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
---
Changes for v2:
- new patch
---
 configs/roc-pc-rk3399_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index be76524..e98d680 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DATE=y
 CONFIG_CMD_TIME=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-roc-pc"
@@ -39,6 +40,7 @@ CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
+CONFIG_DM_RTC=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_BAUDRATE=1500000
-- 
2.7.4

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

* [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device
  2020-04-28 14:09   ` Kever Yang
  2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
@ 2020-04-28 16:14     ` sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
                         ` (3 more replies)
  1 sibling, 4 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 16:14 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

This patch series adds support for Rockchip RK808 PMIC RTC device.

Patch #1, adds a child node under RK808 PMIC node. Patch #2 binds
this child device with its parent RK808 PMIC. Patch #3 adds the rtc
driver. Patch #4 enables DM RTC, adds date command for the target.

The RK808 PMIC RTC has a hardware bug. It counts 31 days for november
month and the weeks register counts 0 - 7.

This driver does a temporary fix, where as in if date is Nov 31, then it resets
the date to Dec 1(this happens only if date cmd is queried from u-boot command line/script).
Similarly for the weeks register, 0(sun) - 6(sat). If 7 is encountered then it is reset to zero.

u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202
---
Changes for v3:
- forgot to add reviewed by tag for first two patches, added the tag.

Changes for v2:
- changed the description of the patch
- earlier it was a three patch series. code which was enabling RTC DM and date command
  is split into a seperate patch as suggested by kever yang. patch#3 is split into patch#4.
---
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
  configs: roc-rk3399-pc: Enable DM for RTC and commands

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

-- 
2.7.4

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

* [PATCH v3 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
@ 2020-04-28 16:14       ` sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 16:14 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>
---
Changes for v3:
- added reviewed by tag

Changes for v2:
- no changes
---
 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 5746442..7d189c8 100644
--- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
@@ -20,3 +20,11 @@
 	regulator-min-microvolt = <430000>;
 	regulator-init-microvolt = <950000>;
 };
+
+&rk808 {
+	rtc {
+		rkrtc: rk808-rtc {
+			status="okay";
+		};
+	};
+};
-- 
2.7.4

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

* [PATCH v3 2/4] power: pmic: rk8xx: bind rk808 RTC
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
@ 2020-04-28 16:14       ` sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 16:14 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>
---
Changes for v3:
- added reviewed by tag

Changes for v2:
- no changes
---
 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 52e6d9d..8d6b64e 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -24,6 +24,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;
@@ -59,7 +64,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");
@@ -75,6 +80,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.7.4

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

* [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
  2020-04-28 16:14       ` [PATCH v3 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
@ 2020-04-28 16:14       ` sunil at amarulasolutions.com
  2020-04-29  2:39         ` Kever Yang
  2020-04-28 16:14       ` [PATCH v3 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com
  3 siblings, 1 reply; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 16:14 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: Suniel Mahesh <sunil@amarulasolutions.com>
---
Changes for v3:
- no changes

Changes for v2:
-  moved corresponding configs which enable rtc into a seperate
   patch.
-  changed subject line.

Note:
1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
for november month and the weeks register counts 0 - 7.

2. This driver does a temporary fix, where as in if date is Nov 31,
then it resets the date to Dec 1(this happens only if date cmd is queried
from u-boot command line/script). Similarly for the weeks register, 0(sun)
- 6(sat). If 7 is encountered then it is reset to zero.

3. u-boot generally loads linux/other binary. Linux has a full fledged
driver implemented along with a workaround.
https://lkml.org/lkml/2015/12/2/1202

4. Is this change acceptable ? please comment
---
 drivers/rtc/Kconfig     |   8 +++
 drivers/rtc/Makefile    |   1 +
 drivers/rtc/rk808-rtc.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+)
 create mode 100644 drivers/rtc/rk808-rtc.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 59e2fc4..a754d1b 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 12eb449..63e2c34 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 0000000..b63cced
--- /dev/null
+++ b/drivers/rtc/rk808-rtc.c
@@ -0,0 +1,165 @@
+// 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>
+
+/* 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.7.4

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

* [PATCH v3 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands
  2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
                         ` (2 preceding siblings ...)
  2020-04-28 16:14       ` [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
@ 2020-04-28 16:14       ` sunil at amarulasolutions.com
  3 siblings, 0 replies; 21+ messages in thread
From: sunil at amarulasolutions.com @ 2020-04-28 16:14 UTC (permalink / raw)
  To: u-boot

From: Suniel Mahesh <sunil@amarulasolutions.com>

Enable rtc driver DM for rk808 PMIC's, also enable date command.

Signed-off-by: Suniel Mahesh <sunil@amarulasolutions.com>
---
Changes for v3:
- no changes

Changes for v2:
- new patch
---
 configs/roc-pc-rk3399_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index be76524..e98d680 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DATE=y
 CONFIG_CMD_TIME=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-roc-pc"
@@ -39,6 +40,7 @@ CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
+CONFIG_DM_RTC=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_BAUDRATE=1500000
-- 
2.7.4

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

* [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-04-28 16:14       ` [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
@ 2020-04-29  2:39         ` Kever Yang
  2020-04-29  3:27           ` elaine.zhang
  0 siblings, 1 reply; 21+ messages in thread
From: Kever Yang @ 2020-04-29  2:39 UTC (permalink / raw)
  To: u-boot

+Elaine,

Please help to review this patch.


Thanks,

- Kever

On 2020/4/29 ??12:14, sunil at 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: Suniel Mahesh <sunil@amarulasolutions.com>
> ---
> Changes for v3:
> - no changes
>
> Changes for v2:
> -  moved corresponding configs which enable rtc into a seperate
>     patch.
> -  changed subject line.
>
> Note:
> 1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
> for november month and the weeks register counts 0 - 7.
>
> 2. This driver does a temporary fix, where as in if date is Nov 31,
> then it resets the date to Dec 1(this happens only if date cmd is queried
> from u-boot command line/script). Similarly for the weeks register, 0(sun)
> - 6(sat). If 7 is encountered then it is reset to zero.
>
> 3. u-boot generally loads linux/other binary. Linux has a full fledged
> driver implemented along with a workaround.
> https://lkml.org/lkml/2015/12/2/1202
>
> 4. Is this change acceptable ? please comment
> ---
>   drivers/rtc/Kconfig     |   8 +++
>   drivers/rtc/Makefile    |   1 +
>   drivers/rtc/rk808-rtc.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 174 insertions(+)
>   create mode 100644 drivers/rtc/rk808-rtc.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 59e2fc4..a754d1b 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 12eb449..63e2c34 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 0000000..b63cced
> --- /dev/null
> +++ b/drivers/rtc/rk808-rtc.c
> @@ -0,0 +1,165 @@
> +// 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>
> +
> +/* 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] 21+ messages in thread

* [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC
  2020-04-29  2:39         ` Kever Yang
@ 2020-04-29  3:27           ` elaine.zhang
  0 siblings, 0 replies; 21+ messages in thread
From: elaine.zhang @ 2020-04-29  3:27 UTC (permalink / raw)
  To: u-boot

Hi Sunil,

What scenarios need RTC?

If it is to add hardware driver support, the function is still missing 
an alarm.
Direct copy of the kernel is recommended.

About 31 days for november month, I need to explain this hardware Bug:
1?There will be 31 in November after 2016, and there will be no such 
problem before 2016.
2?After 2016, each 11.31 will add one more day.
e.g:
Actually 2017-12-3, RTC hardware register: 2017-12-5, two days more
Actually 2019-10-3, RTC hardware register: 2019-10-6, three more days
After 2016, every 11.31 will be an extra day, which should be corrected 
back.
Therefore, it is recommended to use the kernel's correction method:

/*
 ?* The Rockchip calendar used by the RK808 counts November with 31 
days. We use
 ?* these translation functions to convert its dates to/from the Gregorian
 ?* calendar used by the rest of the world. We arbitrarily define Jan 
1st, 2016
 ?* as the day when both calendars were in sync, and treat all other dates
 ?* relative to that.
 ?* NOTE: Other system software (e.g. firmware) that reads the same 
hardware must
 ?* implement this exact same conversion algorithm, with the same anchor 
date.
 ?*/
static time64_t nov2dec_transitions(struct rtc_time *tm)
{
 ??? return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0);
}

static void rockchip_to_gregorian(struct rtc_time *tm)
{
 ??? /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */
 ??? time64_t time = rtc_tm_to_time64(tm);
 ??? rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm);
}

static void gregorian_to_rockchip(struct rtc_time *tm)
{
 ??? time64_t extra_days = nov2dec_transitions(tm);
 ??? time64_t time = rtc_tm_to_time64(tm);
 ??? rtc_time64_to_tm(time - extra_days * 86400, tm);

 ??? /* Compensate if we went back over Nov 31st (will work up to 2381) */
 ??? if (nov2dec_transitions(tm) < extra_days) {
 ??? ??? if (tm->tm_mon + 1 == 11)
 ??? ??? ??? tm->tm_mday++;??? /* This may result in 31! */
 ??? ??? else
 ??? ??? ??? rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm);
 ??? }
}

? 2020/4/29 ??10:39, Kever Yang ??:
> +Elaine,
>
> Please help to review this patch.
>
>
> Thanks,
>
> - Kever
>
> On 2020/4/29 ??12:14, sunil at 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: Suniel Mahesh <sunil@amarulasolutions.com>
>> ---
>> Changes for v3:
>> - no changes
>>
>> Changes for v2:
>> -? moved corresponding configs which enable rtc into a seperate
>> ??? patch.
>> -? changed subject line.
>>
>> Note:
>> 1. The RK808 PMIC RTC has a hardware bug. It counts 31 days
>> for november month and the weeks register counts 0 - 7.
>>
>> 2. This driver does a temporary fix, where as in if date is Nov 31,
>> then it resets the date to Dec 1(this happens only if date cmd is 
>> queried
>> from u-boot command line/script). Similarly for the weeks register, 
>> 0(sun)
>> - 6(sat). If 7 is encountered then it is reset to zero.
>>
>> 3. u-boot generally loads linux/other binary. Linux has a full fledged
>> driver implemented along with a workaround.
>> https://lkml.org/lkml/2015/12/2/1202
>>
>> 4. Is this change acceptable ? please comment
>> ---
>> ? drivers/rtc/Kconfig???? |?? 8 +++
>> ? drivers/rtc/Makefile??? |?? 1 +
>> ? drivers/rtc/rk808-rtc.c | 165 
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>> ? 3 files changed, 174 insertions(+)
>> ? create mode 100644 drivers/rtc/rk808-rtc.c
>>
>> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
>> index 59e2fc4..a754d1b 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 12eb449..63e2c34 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 0000000..b63cced
>> --- /dev/null
>> +++ b/drivers/rtc/rk808-rtc.c
>> @@ -0,0 +1,165 @@
>> +// 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>
>> +
>> +/* 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);

It's usually used as(The same below):

pmic_clrsetbits(dev->parent, REG_RTC_CTRL, BIT_RTC_CTRL_REG_STOP_RTC_M,
+??????????????????????? 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);
>> +??? }
Error use.
>> +
>> +??? if (tm->tm_wday == 7) {
>> +??????? tm->tm_wday = 0;

No problems were found in the kernel.
Please describe your problem in detail.

Our RTC weeks_reg is:

Bit 3-0 WEEK: Set the second digit of the RTC weeks.

Note BCD coding from 1 to 7
>> +??????? 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] 21+ messages in thread

* [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC
  2020-04-22 16:11 ` [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
  2020-04-28 14:05   ` Kever Yang
@ 2020-05-15  8:01   ` Kever Yang
  2020-05-15  8:54     ` Suniel Mahesh
  1 sibling, 1 reply; 21+ messages in thread
From: Kever Yang @ 2020-05-15  8:01 UTC (permalink / raw)
  To: u-boot

Hi Suniel,

 ??? Do you have plan to update this patch set?


Thanks,

- Kever

On 2020/4/23 ??12:11, sunil at amarulasolutions.com wrote:
> 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>
> ---
>   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 52e6d9d..8d6b64e 100644
> --- a/drivers/power/pmic/rk8xx.c
> +++ b/drivers/power/pmic/rk8xx.c
> @@ -24,6 +24,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;
> @@ -59,7 +64,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");
> @@ -75,6 +80,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;
>   }

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

* [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC
  2020-05-15  8:01   ` Kever Yang
@ 2020-05-15  8:54     ` Suniel Mahesh
  0 siblings, 0 replies; 21+ messages in thread
From: Suniel Mahesh @ 2020-05-15  8:54 UTC (permalink / raw)
  To: u-boot

On Fri, May 15, 2020 at 1:31 PM Kever Yang <kever.yang@rock-chips.com>
wrote:

> Hi Suniel,
>
>      Do you have plan to update this patch set?,
>

Hi Kever,
Yes I do have plan to update this patch. Any timeline's you are looking at ?
Please let me know.

Thanks
Suniel

>
>
> Thanks,
>
> - Kever
>
> On 2020/4/23 ??12:11, sunil at amarulasolutions.com wrote:
> > 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>
> > ---
> >   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 52e6d9d..8d6b64e 100644
> > --- a/drivers/power/pmic/rk8xx.c
> > +++ b/drivers/power/pmic/rk8xx.c
> > @@ -24,6 +24,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;
> > @@ -59,7 +64,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");
> > @@ -75,6 +80,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;
> >   }
>
>
>

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

end of thread, other threads:[~2020-05-15  8:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-22 16:11 [PATCH 0/3] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
2020-04-22 16:11 ` [PATCH 1/3] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
2020-04-28 14:05   ` Kever Yang
2020-04-22 16:11 ` [PATCH 2/3] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
2020-04-28 14:05   ` Kever Yang
2020-05-15  8:01   ` Kever Yang
2020-05-15  8:54     ` Suniel Mahesh
2020-04-22 16:11 ` [PATCH 3/3] rtc: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
2020-04-28 14:09   ` Kever Yang
2020-04-28 15:57     ` [PATCH v2 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
2020-04-28 15:57       ` [PATCH v2 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
2020-04-28 15:57       ` [PATCH v2 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
2020-04-28 15:57       ` [PATCH v2 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
2020-04-28 15:57       ` [PATCH v2 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com
2020-04-28 16:14     ` [PATCH v3 0/4] Add support for Rockchip RK808 PMIC RTC device sunil at amarulasolutions.com
2020-04-28 16:14       ` [PATCH v3 1/4] arm: dts: rockchip: rk3399-roc-pc: Add RTC child node for RK808 PMIC sunil at amarulasolutions.com
2020-04-28 16:14       ` [PATCH v3 2/4] power: pmic: rk8xx: bind rk808 RTC sunil at amarulasolutions.com
2020-04-28 16:14       ` [PATCH v3 3/4] rtc: rk8xx: Add base support for the RK808 PMIC RTC sunil at amarulasolutions.com
2020-04-29  2:39         ` Kever Yang
2020-04-29  3:27           ` elaine.zhang
2020-04-28 16:14       ` [PATCH v3 4/4] configs: roc-rk3399-pc: Enable DM for RTC and commands sunil at amarulasolutions.com

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.