diff options
author | David Hendricks <dhendrix@chromium.org> | 2015-01-12 14:08:10 -0800 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2015-04-15 16:47:04 +0200 |
commit | 3c4951e05f2d3e0265ad892a3a229c1b508c29a8 (patch) | |
tree | b9897fbdda9549ca6ffbfb3bde622e00a7e02b7e /src/soc | |
parent | 4d244214ce56dc89abd74a5d0ee45e77ca61c279 (diff) |
rk808: Implement RTC driver
This adds RTC functions to the existing RK808 driver.
BUG=chrome-os-partner:34436
BRANCH=none
TEST=with eventlog patches applied to pinky, booted and saw eventlog
entries generated with correct timestamps:
localhost ~ # mosys -k eventlog list
entry="0" timestamp="2015-01-06 13:45:33" type="Log area cleared" bytes="4096"
entry="1" timestamp="2015-01-06 13:45:33" type="System boot" count="0"
entry="2" timestamp="2015-01-06 13:45:33" type="Chrome OS Developer Mode"
Change-Id: I1df70a2ca94ff463ffea8d9f02d951d6c62e6b08
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
Original-Commit-Id: a304f7e6954f585f04feef54c4902dcb25a39fcc
Original-Signed-off-by: David Hendricks <dhendrix@chromium.org>
Original-Change-Id: I3a240e342a54b2e7023da71708d0d70f5131f0b9
Original-Reviewed-on: https://chromium-review.googlesource.com/238525
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Julius Werner <jwerner@chromium.org>
Original-Tested-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: http://review.coreboot.org/9643
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/rockchip/rk3288/rk808.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/soc/rockchip/rk3288/rk808.c b/src/soc/rockchip/rk3288/rk808.c index de19a55135..b763454903 100644 --- a/src/soc/rockchip/rk3288/rk808.c +++ b/src/soc/rockchip/rk3288/rk808.c @@ -18,9 +18,11 @@ */ #include <assert.h> +#include <bcd.h> #include <console/console.h> #include <delay.h> #include <device/i2c.h> +#include <rtc.h> #include <soc/rk808.h> #include <stdint.h> #include <stdlib.h> @@ -38,6 +40,20 @@ #define LDO_ONSEL(i) (0x39 + 2 * i) #define LDO_SLPSEL(i) (0x3a + 2 * i) +#define RTC_SECOND 0x00 +#define RTC_MINUTE 0x01 +#define RTC_HOUR 0x02 +#define RTC_DAY 0x03 +#define RTC_MONTH 0x04 +#define RTC_YEAR 0x05 +#define RTC_WEEKS 0x06 +#define RTC_CTRL 0x10 +#define RTC_STATUS 0x11 + +#define RTC_CTRL_STOP_RTC (1 << 0) +#define RTC_CTRL_GET_TIME (1 << 6) +#define RTC_CTRL_RTC_READSEL (1 << 7) + static int rk808_read(uint8_t reg, uint8_t *value) { return i2c_readb(CONFIG_PMIC_BUS, RK808_ADDR, reg, value); @@ -118,3 +134,66 @@ void rk808_configure_buck(int buck, int millivolts) rk808_clrsetbits(buck_reg, 0x3f, vsel); rk808_clrsetbits(DCDC_EN, 0, 1 << (buck - 1)); } + +static void rk808rtc_stop(void) +{ + rk808_clrsetbits(RTC_CTRL, RTC_CTRL_STOP_RTC, 0); +} + +static void rk808rtc_start(void) +{ + rk808_clrsetbits(RTC_CTRL, 0, RTC_CTRL_STOP_RTC); +} + +int rtc_set(const struct rtc_time *time) +{ + int ret = 0; + + /* RTC time can only be set when RTC is frozen */ + rk808rtc_stop(); + + ret |= rk808_write(RTC_SECOND, bin2bcd(time->sec)); + ret |= rk808_write(RTC_MINUTE, bin2bcd(time->min)); + ret |= rk808_write(RTC_HOUR, bin2bcd(time->hour)); + ret |= rk808_write(RTC_DAY, bin2bcd(time->mday)); + ret |= rk808_write(RTC_MONTH, bin2bcd(time->mon)); + ret |= rk808_write(RTC_YEAR, bin2bcd(time->year)); + + rk808rtc_start(); + return ret; +} + +int rtc_get(struct rtc_time *time) +{ + uint8_t value; + int ret = 0; + + /* + * Set RTC_READSEL to cause reads to access shadow registers and + * transition GET_TIME from 0 to 1 to cause dynamic register content + * to be copied into shadow registers. This ensures a coherent reading + * of time values as we access each register using slow I2C transfers. + */ + rk808_clrsetbits(RTC_CTRL, RTC_CTRL_GET_TIME, 0); + rk808_clrsetbits(RTC_CTRL, 0, RTC_CTRL_GET_TIME | RTC_CTRL_RTC_READSEL); + + ret |= rk808_read(RTC_SECOND, &value); + time->sec = bcd2bin(value & 0x7f); + + ret |= rk808_read(RTC_MINUTE, &value); + time->min = bcd2bin(value & 0x7f); + + ret |= rk808_read(RTC_HOUR, &value); + time->hour = bcd2bin(value & 0x3f); + + ret |= rk808_read(RTC_DAY, &value); + time->mday = bcd2bin(value & 0x3f); + + ret |= rk808_read(RTC_MONTH, &value); + time->mon = bcd2bin(value & 0x1f); + + ret |= rk808_read(RTC_YEAR, &value); + time->year = bcd2bin(value); + + return ret; +} |