uboot/drivers/rtc/stm32_rtc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
   4 */
   5#include <common.h>
   6#include <clk.h>
   7#include <dm.h>
   8#include <malloc.h>
   9#include <rtc.h>
  10#include <asm/io.h>
  11#include <dm/device_compat.h>
  12#include <linux/bitops.h>
  13#include <linux/iopoll.h>
  14
  15#define STM32_RTC_TR            0x00
  16#define STM32_RTC_DR            0x04
  17#define STM32_RTC_ISR           0x0C
  18#define STM32_RTC_PRER          0x10
  19#define STM32_RTC_CR            0x18
  20#define STM32_RTC_WPR           0x24
  21
  22/* STM32_RTC_TR bit fields  */
  23#define STM32_RTC_SEC_SHIFT     0
  24#define STM32_RTC_SEC           GENMASK(6, 0)
  25#define STM32_RTC_MIN_SHIFT     8
  26#define STM32_RTC_MIN           GENMASK(14, 8)
  27#define STM32_RTC_HOUR_SHIFT    16
  28#define STM32_RTC_HOUR          GENMASK(21, 16)
  29
  30/* STM32_RTC_DR bit fields */
  31#define STM32_RTC_DATE_SHIFT    0
  32#define STM32_RTC_DATE          GENMASK(5, 0)
  33#define STM32_RTC_MONTH_SHIFT   8
  34#define STM32_RTC_MONTH         GENMASK(12, 8)
  35#define STM32_RTC_WDAY_SHIFT    13
  36#define STM32_RTC_WDAY          GENMASK(15, 13)
  37#define STM32_RTC_YEAR_SHIFT    16
  38#define STM32_RTC_YEAR          GENMASK(23, 16)
  39
  40/* STM32_RTC_CR bit fields */
  41#define STM32_RTC_CR_FMT        BIT(6)
  42
  43/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
  44#define STM32_RTC_ISR_INITS     BIT(4)
  45#define STM32_RTC_ISR_RSF       BIT(5)
  46#define STM32_RTC_ISR_INITF     BIT(6)
  47#define STM32_RTC_ISR_INIT      BIT(7)
  48
  49/* STM32_RTC_PRER bit fields */
  50#define STM32_RTC_PRER_PRED_S_SHIFT     0
  51#define STM32_RTC_PRER_PRED_S           GENMASK(14, 0)
  52#define STM32_RTC_PRER_PRED_A_SHIFT     16
  53#define STM32_RTC_PRER_PRED_A           GENMASK(22, 16)
  54
  55/* STM32_RTC_WPR key constants */
  56#define RTC_WPR_1ST_KEY         0xCA
  57#define RTC_WPR_2ND_KEY         0x53
  58#define RTC_WPR_WRONG_KEY       0xFF
  59
  60struct stm32_rtc_priv {
  61        fdt_addr_t base;
  62};
  63
  64static int stm32_rtc_get(struct udevice *dev, struct rtc_time *tm)
  65{
  66        struct stm32_rtc_priv *priv = dev_get_priv(dev);
  67        u32 tr, dr;
  68
  69        tr = readl(priv->base + STM32_RTC_TR);
  70        dr = readl(priv->base + STM32_RTC_DR);
  71
  72        tm->tm_sec = bcd2bin((tr & STM32_RTC_SEC) >> STM32_RTC_SEC_SHIFT);
  73        tm->tm_min = bcd2bin((tr & STM32_RTC_MIN) >> STM32_RTC_MIN_SHIFT);
  74        tm->tm_hour = bcd2bin((tr & STM32_RTC_HOUR) >> STM32_RTC_HOUR_SHIFT);
  75
  76        tm->tm_mday = bcd2bin((dr & STM32_RTC_DATE) >> STM32_RTC_DATE_SHIFT);
  77        tm->tm_mon = bcd2bin((dr & STM32_RTC_MONTH) >> STM32_RTC_MONTH_SHIFT);
  78        tm->tm_year = 2000 +
  79                      bcd2bin((dr & STM32_RTC_YEAR) >> STM32_RTC_YEAR_SHIFT);
  80        tm->tm_wday = bcd2bin((dr & STM32_RTC_WDAY) >> STM32_RTC_WDAY_SHIFT);
  81        tm->tm_yday = 0;
  82        tm->tm_isdst = 0;
  83
  84        dev_dbg(dev, "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
  85                tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
  86                tm->tm_hour, tm->tm_min, tm->tm_sec);
  87
  88        return 0;
  89}
  90
  91static void stm32_rtc_unlock(struct udevice *dev)
  92{
  93        struct stm32_rtc_priv *priv = dev_get_priv(dev);
  94
  95        writel(RTC_WPR_1ST_KEY, priv->base + STM32_RTC_WPR);
  96        writel(RTC_WPR_2ND_KEY, priv->base + STM32_RTC_WPR);
  97}
  98
  99static void stm32_rtc_lock(struct udevice *dev)
 100{
 101        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 102
 103        writel(RTC_WPR_WRONG_KEY, priv->base + STM32_RTC_WPR);
 104}
 105
 106static int stm32_rtc_enter_init_mode(struct udevice *dev)
 107{
 108        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 109        u32 isr = readl(priv->base + STM32_RTC_ISR);
 110
 111        if (!(isr & STM32_RTC_ISR_INITF)) {
 112                isr |= STM32_RTC_ISR_INIT;
 113                writel(isr, priv->base + STM32_RTC_ISR);
 114
 115                return readl_poll_timeout(priv->base + STM32_RTC_ISR,
 116                                          isr,
 117                                          (isr & STM32_RTC_ISR_INITF),
 118                                          100000);
 119        }
 120
 121        return 0;
 122}
 123
 124static int stm32_rtc_wait_sync(struct udevice *dev)
 125{
 126        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 127        u32 isr = readl(priv->base + STM32_RTC_ISR);
 128
 129        isr &= ~STM32_RTC_ISR_RSF;
 130        writel(isr, priv->base + STM32_RTC_ISR);
 131
 132        /*
 133         * Wait for RSF to be set to ensure the calendar registers are
 134         * synchronised, it takes around 2 rtc_ck clock cycles
 135         */
 136        return readl_poll_timeout(priv->base + STM32_RTC_ISR,
 137                                  isr, (isr & STM32_RTC_ISR_RSF),
 138                                  100000);
 139}
 140
 141static void stm32_rtc_exit_init_mode(struct udevice *dev)
 142{
 143        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 144        u32 isr = readl(priv->base + STM32_RTC_ISR);
 145
 146        isr &= ~STM32_RTC_ISR_INIT;
 147        writel(isr, priv->base + STM32_RTC_ISR);
 148}
 149
 150static int stm32_rtc_set_time(struct udevice *dev, u32 time, u32 date)
 151{
 152        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 153        int ret;
 154
 155        stm32_rtc_unlock(dev);
 156
 157        ret = stm32_rtc_enter_init_mode(dev);
 158        if (ret)
 159                goto lock;
 160
 161        writel(time, priv->base + STM32_RTC_TR);
 162        writel(date, priv->base + STM32_RTC_DR);
 163
 164        stm32_rtc_exit_init_mode(dev);
 165
 166        ret = stm32_rtc_wait_sync(dev);
 167
 168lock:
 169        stm32_rtc_lock(dev);
 170        return ret;
 171}
 172
 173static int stm32_rtc_set(struct udevice *dev, const struct rtc_time *tm)
 174{
 175        u32 t, d;
 176
 177        dev_dbg(dev, "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 178                tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
 179                tm->tm_hour, tm->tm_min, tm->tm_sec);
 180
 181        if (tm->tm_year < 2000 || tm->tm_year > 2099)
 182                return -EINVAL;
 183
 184        /* Time in BCD format */
 185        t = (bin2bcd(tm->tm_sec) << STM32_RTC_SEC_SHIFT) & STM32_RTC_SEC;
 186        t |= (bin2bcd(tm->tm_min) << STM32_RTC_MIN_SHIFT) & STM32_RTC_MIN;
 187        t |= (bin2bcd(tm->tm_hour) << STM32_RTC_HOUR_SHIFT) & STM32_RTC_HOUR;
 188
 189        /* Date in BCD format */
 190        d = (bin2bcd(tm->tm_mday) << STM32_RTC_DATE_SHIFT) & STM32_RTC_DATE;
 191        d |= (bin2bcd(tm->tm_mon) << STM32_RTC_MONTH_SHIFT) & STM32_RTC_MONTH;
 192        d |= (bin2bcd(tm->tm_year - 2000) << STM32_RTC_YEAR_SHIFT) &
 193              STM32_RTC_YEAR;
 194        d |= (bin2bcd(tm->tm_wday) << STM32_RTC_WDAY_SHIFT) & STM32_RTC_WDAY;
 195
 196        return stm32_rtc_set_time(dev, t, d);
 197}
 198
 199static int stm32_rtc_reset(struct udevice *dev)
 200{
 201        dev_dbg(dev, "Reset DATE\n");
 202
 203        return stm32_rtc_set_time(dev, 0, 0);
 204}
 205
 206static int stm32_rtc_init(struct udevice *dev)
 207{
 208        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 209        unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 210        unsigned int rate;
 211        struct clk clk;
 212        int ret;
 213        u32 isr = readl(priv->base + STM32_RTC_ISR);
 214
 215        if (isr & STM32_RTC_ISR_INITS)
 216                return  0;
 217
 218        ret = clk_get_by_index(dev, 1, &clk);
 219        if (ret)
 220                return ret;
 221
 222        ret = clk_enable(&clk);
 223        if (ret) {
 224                clk_free(&clk);
 225                return ret;
 226        }
 227
 228        rate = clk_get_rate(&clk);
 229
 230        /* Find prediv_a and prediv_s to obtain the 1Hz calendar clock */
 231        pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
 232        pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
 233
 234        for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
 235                pred_s = (rate / (pred_a + 1)) - 1;
 236
 237                if (((pred_s + 1) * (pred_a + 1)) == rate)
 238                        break;
 239        }
 240
 241        /*
 242         * Can't find a 1Hz, so give priority to RTC power consumption
 243         * by choosing the higher possible value for prediv_a
 244         */
 245        if (pred_s > pred_s_max || pred_a > pred_a_max) {
 246                pred_a = pred_a_max;
 247                pred_s = (rate / (pred_a + 1)) - 1;
 248        }
 249
 250        stm32_rtc_unlock(dev);
 251
 252        ret = stm32_rtc_enter_init_mode(dev);
 253        if (ret) {
 254                dev_err(dev,
 255                        "Can't enter in init mode. Prescaler config failed.\n");
 256                goto unlock;
 257        }
 258
 259        prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
 260        prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
 261        writel(prer, priv->base + STM32_RTC_PRER);
 262
 263        /* Force 24h time format */
 264        cr = readl(priv->base + STM32_RTC_CR);
 265        cr &= ~STM32_RTC_CR_FMT;
 266        writel(cr, priv->base + STM32_RTC_CR);
 267
 268        stm32_rtc_exit_init_mode(dev);
 269
 270        ret = stm32_rtc_wait_sync(dev);
 271
 272unlock:
 273        stm32_rtc_lock(dev);
 274
 275        if (ret) {
 276                clk_disable(&clk);
 277                clk_free(&clk);
 278        }
 279
 280        return ret;
 281}
 282
 283static int stm32_rtc_probe(struct udevice *dev)
 284{
 285        struct stm32_rtc_priv *priv = dev_get_priv(dev);
 286        struct clk clk;
 287        int ret;
 288
 289        priv->base = dev_read_addr(dev);
 290        if (priv->base == FDT_ADDR_T_NONE)
 291                return -EINVAL;
 292
 293        ret = clk_get_by_index(dev, 0, &clk);
 294        if (ret)
 295                return ret;
 296
 297        ret = clk_enable(&clk);
 298        if (ret) {
 299                clk_free(&clk);
 300                return ret;
 301        }
 302
 303        ret = stm32_rtc_init(dev);
 304
 305        if (ret) {
 306                clk_disable(&clk);
 307                clk_free(&clk);
 308        }
 309
 310        return ret;
 311}
 312
 313static const struct rtc_ops stm32_rtc_ops = {
 314        .get = stm32_rtc_get,
 315        .set = stm32_rtc_set,
 316        .reset = stm32_rtc_reset,
 317};
 318
 319static const struct udevice_id stm32_rtc_ids[] = {
 320        { .compatible = "st,stm32mp1-rtc" },
 321        { }
 322};
 323
 324U_BOOT_DRIVER(rtc_stm32) = {
 325        .name   = "rtc-stm32",
 326        .id     = UCLASS_RTC,
 327        .probe  = stm32_rtc_probe,
 328        .of_match = stm32_rtc_ids,
 329        .ops    = &stm32_rtc_ops,
 330        .priv_auto_alloc_size = sizeof(struct stm32_rtc_priv),
 331};
 332