linux/drivers/rtc/rtc-mt2712.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2019 MediaTek Inc.
   4 * Author: Ran Bi <ran.bi@mediatek.com>
   5 */
   6
   7#include <linux/delay.h>
   8#include <linux/init.h>
   9#include <linux/io.h>
  10#include <linux/irqdomain.h>
  11#include <linux/module.h>
  12#include <linux/of_address.h>
  13#include <linux/of_irq.h>
  14#include <linux/platform_device.h>
  15#include <linux/rtc.h>
  16
  17#define MT2712_BBPU             0x0000
  18#define MT2712_BBPU_CLRPKY      BIT(4)
  19#define MT2712_BBPU_RELOAD      BIT(5)
  20#define MT2712_BBPU_CBUSY       BIT(6)
  21#define MT2712_BBPU_KEY         (0x43 << 8)
  22
  23#define MT2712_IRQ_STA          0x0004
  24#define MT2712_IRQ_STA_AL       BIT(0)
  25#define MT2712_IRQ_STA_TC       BIT(1)
  26
  27#define MT2712_IRQ_EN           0x0008
  28#define MT2712_IRQ_EN_AL        BIT(0)
  29#define MT2712_IRQ_EN_TC        BIT(1)
  30#define MT2712_IRQ_EN_ONESHOT   BIT(2)
  31
  32#define MT2712_CII_EN           0x000c
  33
  34#define MT2712_AL_MASK          0x0010
  35#define MT2712_AL_MASK_DOW      BIT(4)
  36
  37#define MT2712_TC_SEC           0x0014
  38#define MT2712_TC_MIN           0x0018
  39#define MT2712_TC_HOU           0x001c
  40#define MT2712_TC_DOM           0x0020
  41#define MT2712_TC_DOW           0x0024
  42#define MT2712_TC_MTH           0x0028
  43#define MT2712_TC_YEA           0x002c
  44
  45#define MT2712_AL_SEC           0x0030
  46#define MT2712_AL_MIN           0x0034
  47#define MT2712_AL_HOU           0x0038
  48#define MT2712_AL_DOM           0x003c
  49#define MT2712_AL_DOW           0x0040
  50#define MT2712_AL_MTH           0x0044
  51#define MT2712_AL_YEA           0x0048
  52
  53#define MT2712_SEC_MASK         0x003f
  54#define MT2712_MIN_MASK         0x003f
  55#define MT2712_HOU_MASK         0x001f
  56#define MT2712_DOM_MASK         0x001f
  57#define MT2712_DOW_MASK         0x0007
  58#define MT2712_MTH_MASK         0x000f
  59#define MT2712_YEA_MASK         0x007f
  60
  61#define MT2712_POWERKEY1        0x004c
  62#define MT2712_POWERKEY2        0x0050
  63#define MT2712_POWERKEY1_KEY    0xa357
  64#define MT2712_POWERKEY2_KEY    0x67d2
  65
  66#define MT2712_CON0             0x005c
  67#define MT2712_CON1             0x0060
  68
  69#define MT2712_PROT             0x0070
  70#define MT2712_PROT_UNLOCK1     0x9136
  71#define MT2712_PROT_UNLOCK2     0x586a
  72
  73#define MT2712_WRTGR            0x0078
  74
  75#define MT2712_RTC_TIMESTAMP_END_2127   4985971199LL
  76
  77struct mt2712_rtc {
  78        struct rtc_device       *rtc;
  79        void __iomem            *base;
  80        int                     irq;
  81        u8                      irq_wake_enabled;
  82        u8                      powerlost;
  83};
  84
  85static inline u32 mt2712_readl(struct mt2712_rtc *mt2712_rtc, u32 reg)
  86{
  87        return readl(mt2712_rtc->base + reg);
  88}
  89
  90static inline void mt2712_writel(struct mt2712_rtc *mt2712_rtc,
  91                                 u32 reg, u32 val)
  92{
  93        writel(val, mt2712_rtc->base + reg);
  94}
  95
  96static void mt2712_rtc_write_trigger(struct mt2712_rtc *mt2712_rtc)
  97{
  98        unsigned long timeout = jiffies + HZ / 10;
  99
 100        mt2712_writel(mt2712_rtc, MT2712_WRTGR, 1);
 101        while (1) {
 102                if (!(mt2712_readl(mt2712_rtc, MT2712_BBPU)
 103                                        & MT2712_BBPU_CBUSY))
 104                        break;
 105
 106                if (time_after(jiffies, timeout)) {
 107                        dev_err(&mt2712_rtc->rtc->dev,
 108                                "%s time out!\n", __func__);
 109                        break;
 110                }
 111                cpu_relax();
 112        }
 113}
 114
 115static void mt2712_rtc_writeif_unlock(struct mt2712_rtc *mt2712_rtc)
 116{
 117        mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK1);
 118        mt2712_rtc_write_trigger(mt2712_rtc);
 119        mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK2);
 120        mt2712_rtc_write_trigger(mt2712_rtc);
 121}
 122
 123static irqreturn_t rtc_irq_handler_thread(int irq, void *data)
 124{
 125        struct mt2712_rtc *mt2712_rtc = data;
 126        u16 irqsta;
 127
 128        /* Clear interrupt */
 129        irqsta = mt2712_readl(mt2712_rtc, MT2712_IRQ_STA);
 130        if (irqsta & MT2712_IRQ_STA_AL) {
 131                rtc_update_irq(mt2712_rtc->rtc, 1, RTC_IRQF | RTC_AF);
 132                return IRQ_HANDLED;
 133        }
 134
 135        return IRQ_NONE;
 136}
 137
 138static void __mt2712_rtc_read_time(struct mt2712_rtc *mt2712_rtc,
 139                                   struct rtc_time *tm, int *sec)
 140{
 141        tm->tm_sec  = mt2712_readl(mt2712_rtc, MT2712_TC_SEC)
 142                        & MT2712_SEC_MASK;
 143        tm->tm_min  = mt2712_readl(mt2712_rtc, MT2712_TC_MIN)
 144                        & MT2712_MIN_MASK;
 145        tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_TC_HOU)
 146                        & MT2712_HOU_MASK;
 147        tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_TC_DOM)
 148                        & MT2712_DOM_MASK;
 149        tm->tm_mon  = (mt2712_readl(mt2712_rtc, MT2712_TC_MTH) - 1)
 150                        & MT2712_MTH_MASK;
 151        tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_TC_YEA) + 100)
 152                        & MT2712_YEA_MASK;
 153
 154        *sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) & MT2712_SEC_MASK;
 155}
 156
 157static int mt2712_rtc_read_time(struct device *dev, struct rtc_time *tm)
 158{
 159        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 160        int sec;
 161
 162        if (mt2712_rtc->powerlost)
 163                return -EINVAL;
 164
 165        do {
 166                __mt2712_rtc_read_time(mt2712_rtc, tm, &sec);
 167        } while (sec < tm->tm_sec);     /* SEC has carried */
 168
 169        return 0;
 170}
 171
 172static int mt2712_rtc_set_time(struct device *dev, struct rtc_time *tm)
 173{
 174        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 175
 176        mt2712_writel(mt2712_rtc, MT2712_TC_SEC, tm->tm_sec  & MT2712_SEC_MASK);
 177        mt2712_writel(mt2712_rtc, MT2712_TC_MIN, tm->tm_min  & MT2712_MIN_MASK);
 178        mt2712_writel(mt2712_rtc, MT2712_TC_HOU, tm->tm_hour & MT2712_HOU_MASK);
 179        mt2712_writel(mt2712_rtc, MT2712_TC_DOM, tm->tm_mday & MT2712_DOM_MASK);
 180        mt2712_writel(mt2712_rtc, MT2712_TC_MTH,
 181                      (tm->tm_mon + 1) & MT2712_MTH_MASK);
 182        mt2712_writel(mt2712_rtc, MT2712_TC_YEA,
 183                      (tm->tm_year - 100) & MT2712_YEA_MASK);
 184
 185        mt2712_rtc_write_trigger(mt2712_rtc);
 186
 187        if (mt2712_rtc->powerlost)
 188                mt2712_rtc->powerlost = false;
 189
 190        return 0;
 191}
 192
 193static int mt2712_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 194{
 195        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 196        struct rtc_time *tm = &alm->time;
 197        u16 irqen;
 198
 199        irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
 200        alm->enabled = !!(irqen & MT2712_IRQ_EN_AL);
 201
 202        tm->tm_sec  = mt2712_readl(mt2712_rtc, MT2712_AL_SEC) & MT2712_SEC_MASK;
 203        tm->tm_min  = mt2712_readl(mt2712_rtc, MT2712_AL_MIN) & MT2712_MIN_MASK;
 204        tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_AL_HOU) & MT2712_HOU_MASK;
 205        tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_AL_DOM) & MT2712_DOM_MASK;
 206        tm->tm_mon  = (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) - 1)
 207                      & MT2712_MTH_MASK;
 208        tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + 100)
 209                      & MT2712_YEA_MASK;
 210
 211        return 0;
 212}
 213
 214static int mt2712_rtc_alarm_irq_enable(struct device *dev,
 215                                       unsigned int enabled)
 216{
 217        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 218        u16 irqen;
 219
 220        irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
 221        if (enabled)
 222                irqen |= MT2712_IRQ_EN_AL;
 223        else
 224                irqen &= ~MT2712_IRQ_EN_AL;
 225        mt2712_writel(mt2712_rtc, MT2712_IRQ_EN, irqen);
 226        mt2712_rtc_write_trigger(mt2712_rtc);
 227
 228        return 0;
 229}
 230
 231static int mt2712_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 232{
 233        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 234        struct rtc_time *tm = &alm->time;
 235
 236        dev_dbg(&mt2712_rtc->rtc->dev, "set al time: %ptR, alm en: %d\n",
 237                tm, alm->enabled);
 238
 239        mt2712_writel(mt2712_rtc, MT2712_AL_SEC,
 240                      (mt2712_readl(mt2712_rtc, MT2712_AL_SEC)
 241                       & ~(MT2712_SEC_MASK)) | (tm->tm_sec  & MT2712_SEC_MASK));
 242        mt2712_writel(mt2712_rtc, MT2712_AL_MIN,
 243                      (mt2712_readl(mt2712_rtc, MT2712_AL_MIN)
 244                       & ~(MT2712_MIN_MASK)) | (tm->tm_min  & MT2712_MIN_MASK));
 245        mt2712_writel(mt2712_rtc, MT2712_AL_HOU,
 246                      (mt2712_readl(mt2712_rtc, MT2712_AL_HOU)
 247                       & ~(MT2712_HOU_MASK)) | (tm->tm_hour & MT2712_HOU_MASK));
 248        mt2712_writel(mt2712_rtc, MT2712_AL_DOM,
 249                      (mt2712_readl(mt2712_rtc, MT2712_AL_DOM)
 250                       & ~(MT2712_DOM_MASK)) | (tm->tm_mday & MT2712_DOM_MASK));
 251        mt2712_writel(mt2712_rtc, MT2712_AL_MTH,
 252                      (mt2712_readl(mt2712_rtc, MT2712_AL_MTH)
 253                       & ~(MT2712_MTH_MASK))
 254                      | ((tm->tm_mon + 1) & MT2712_MTH_MASK));
 255        mt2712_writel(mt2712_rtc, MT2712_AL_YEA,
 256                      (mt2712_readl(mt2712_rtc, MT2712_AL_YEA)
 257                       & ~(MT2712_YEA_MASK))
 258                      | ((tm->tm_year - 100) & MT2712_YEA_MASK));
 259
 260        /* mask day of week */
 261        mt2712_writel(mt2712_rtc, MT2712_AL_MASK, MT2712_AL_MASK_DOW);
 262        mt2712_rtc_write_trigger(mt2712_rtc);
 263
 264        mt2712_rtc_alarm_irq_enable(dev, alm->enabled);
 265
 266        return 0;
 267}
 268
 269/* Init RTC register */
 270static void mt2712_rtc_hw_init(struct mt2712_rtc *mt2712_rtc)
 271{
 272        u32 p1, p2;
 273
 274        mt2712_writel(mt2712_rtc, MT2712_BBPU,
 275                      MT2712_BBPU_KEY | MT2712_BBPU_RELOAD);
 276
 277        mt2712_writel(mt2712_rtc, MT2712_CII_EN, 0);
 278        mt2712_writel(mt2712_rtc, MT2712_AL_MASK, 0);
 279        /* necessary before set MT2712_POWERKEY */
 280        mt2712_writel(mt2712_rtc, MT2712_CON0, 0x4848);
 281        mt2712_writel(mt2712_rtc, MT2712_CON1, 0x0048);
 282
 283        mt2712_rtc_write_trigger(mt2712_rtc);
 284
 285        p1 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY1);
 286        p2 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY2);
 287        if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY) {
 288                mt2712_rtc->powerlost = true;
 289                dev_dbg(&mt2712_rtc->rtc->dev,
 290                        "powerkey not set (lost power)\n");
 291        } else {
 292                mt2712_rtc->powerlost = false;
 293        }
 294
 295        /* RTC need POWERKEY1/2 match, then goto normal work mode */
 296        mt2712_writel(mt2712_rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY);
 297        mt2712_writel(mt2712_rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY);
 298        mt2712_rtc_write_trigger(mt2712_rtc);
 299
 300        mt2712_rtc_writeif_unlock(mt2712_rtc);
 301}
 302
 303static const struct rtc_class_ops mt2712_rtc_ops = {
 304        .read_time      = mt2712_rtc_read_time,
 305        .set_time       = mt2712_rtc_set_time,
 306        .read_alarm     = mt2712_rtc_read_alarm,
 307        .set_alarm      = mt2712_rtc_set_alarm,
 308        .alarm_irq_enable = mt2712_rtc_alarm_irq_enable,
 309};
 310
 311static int mt2712_rtc_probe(struct platform_device *pdev)
 312{
 313        struct mt2712_rtc *mt2712_rtc;
 314        int ret;
 315
 316        mt2712_rtc = devm_kzalloc(&pdev->dev,
 317                                  sizeof(struct mt2712_rtc), GFP_KERNEL);
 318        if (!mt2712_rtc)
 319                return -ENOMEM;
 320
 321        mt2712_rtc->base = devm_platform_ioremap_resource(pdev, 0);
 322        if (IS_ERR(mt2712_rtc->base))
 323                return PTR_ERR(mt2712_rtc->base);
 324
 325        /* rtc hw init */
 326        mt2712_rtc_hw_init(mt2712_rtc);
 327
 328        mt2712_rtc->irq = platform_get_irq(pdev, 0);
 329        if (mt2712_rtc->irq < 0)
 330                return mt2712_rtc->irq;
 331
 332        platform_set_drvdata(pdev, mt2712_rtc);
 333
 334        mt2712_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
 335        if (IS_ERR(mt2712_rtc->rtc))
 336                return PTR_ERR(mt2712_rtc->rtc);
 337
 338        ret = devm_request_threaded_irq(&pdev->dev, mt2712_rtc->irq, NULL,
 339                                        rtc_irq_handler_thread,
 340                                        IRQF_ONESHOT | IRQF_TRIGGER_LOW,
 341                                        dev_name(&mt2712_rtc->rtc->dev),
 342                                        mt2712_rtc);
 343        if (ret) {
 344                dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
 345                        mt2712_rtc->irq, ret);
 346                return ret;
 347        }
 348
 349        device_init_wakeup(&pdev->dev, true);
 350
 351        mt2712_rtc->rtc->ops = &mt2712_rtc_ops;
 352        mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 353        mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
 354
 355        return devm_rtc_register_device(mt2712_rtc->rtc);
 356}
 357
 358#ifdef CONFIG_PM_SLEEP
 359static int mt2712_rtc_suspend(struct device *dev)
 360{
 361        int wake_status = 0;
 362        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 363
 364        if (device_may_wakeup(dev)) {
 365                wake_status = enable_irq_wake(mt2712_rtc->irq);
 366                if (!wake_status)
 367                        mt2712_rtc->irq_wake_enabled = true;
 368        }
 369
 370        return 0;
 371}
 372
 373static int mt2712_rtc_resume(struct device *dev)
 374{
 375        int wake_status = 0;
 376        struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
 377
 378        if (device_may_wakeup(dev) && mt2712_rtc->irq_wake_enabled) {
 379                wake_status = disable_irq_wake(mt2712_rtc->irq);
 380                if (!wake_status)
 381                        mt2712_rtc->irq_wake_enabled = false;
 382        }
 383
 384        return 0;
 385}
 386
 387static SIMPLE_DEV_PM_OPS(mt2712_pm_ops, mt2712_rtc_suspend,
 388                         mt2712_rtc_resume);
 389#endif
 390
 391static const struct of_device_id mt2712_rtc_of_match[] = {
 392        { .compatible = "mediatek,mt2712-rtc", },
 393        { },
 394};
 395
 396MODULE_DEVICE_TABLE(of, mt2712_rtc_of_match);
 397
 398static struct platform_driver mt2712_rtc_driver = {
 399        .driver = {
 400                .name = "mt2712-rtc",
 401                .of_match_table = mt2712_rtc_of_match,
 402#ifdef CONFIG_PM_SLEEP
 403                .pm = &mt2712_pm_ops,
 404#endif
 405        },
 406        .probe  = mt2712_rtc_probe,
 407};
 408
 409module_platform_driver(mt2712_rtc_driver);
 410
 411MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver");
 412MODULE_AUTHOR("Ran Bi <ran.bi@mediatek.com>");
 413MODULE_LICENSE("GPL");
 414