linux/drivers/rtc/rtc-davinci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * DaVinci Power Management and Real Time Clock Driver for TI platforms
   4 *
   5 * Copyright (C) 2009 Texas Instruments, Inc
   6 *
   7 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
   8 */
   9#include <linux/kernel.h>
  10#include <linux/init.h>
  11#include <linux/module.h>
  12#include <linux/ioport.h>
  13#include <linux/delay.h>
  14#include <linux/spinlock.h>
  15#include <linux/rtc.h>
  16#include <linux/bcd.h>
  17#include <linux/platform_device.h>
  18#include <linux/io.h>
  19#include <linux/slab.h>
  20
  21/*
  22 * The DaVinci RTC is a simple RTC with the following
  23 * Sec: 0 - 59 : BCD count
  24 * Min: 0 - 59 : BCD count
  25 * Hour: 0 - 23 : BCD count
  26 * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years )
  27 */
  28
  29/* PRTC interface registers */
  30#define DAVINCI_PRTCIF_PID              0x00
  31#define PRTCIF_CTLR                     0x04
  32#define PRTCIF_LDATA                    0x08
  33#define PRTCIF_UDATA                    0x0C
  34#define PRTCIF_INTEN                    0x10
  35#define PRTCIF_INTFLG                   0x14
  36
  37/* PRTCIF_CTLR bit fields */
  38#define PRTCIF_CTLR_BUSY                BIT(31)
  39#define PRTCIF_CTLR_SIZE                BIT(25)
  40#define PRTCIF_CTLR_DIR                 BIT(24)
  41#define PRTCIF_CTLR_BENU_MSB            BIT(23)
  42#define PRTCIF_CTLR_BENU_3RD_BYTE       BIT(22)
  43#define PRTCIF_CTLR_BENU_2ND_BYTE       BIT(21)
  44#define PRTCIF_CTLR_BENU_LSB            BIT(20)
  45#define PRTCIF_CTLR_BENU_MASK           (0x00F00000)
  46#define PRTCIF_CTLR_BENL_MSB            BIT(19)
  47#define PRTCIF_CTLR_BENL_3RD_BYTE       BIT(18)
  48#define PRTCIF_CTLR_BENL_2ND_BYTE       BIT(17)
  49#define PRTCIF_CTLR_BENL_LSB            BIT(16)
  50#define PRTCIF_CTLR_BENL_MASK           (0x000F0000)
  51
  52/* PRTCIF_INTEN bit fields */
  53#define PRTCIF_INTEN_RTCSS              BIT(1)
  54#define PRTCIF_INTEN_RTCIF              BIT(0)
  55#define PRTCIF_INTEN_MASK               (PRTCIF_INTEN_RTCSS \
  56                                        | PRTCIF_INTEN_RTCIF)
  57
  58/* PRTCIF_INTFLG bit fields */
  59#define PRTCIF_INTFLG_RTCSS             BIT(1)
  60#define PRTCIF_INTFLG_RTCIF             BIT(0)
  61#define PRTCIF_INTFLG_MASK              (PRTCIF_INTFLG_RTCSS \
  62                                        | PRTCIF_INTFLG_RTCIF)
  63
  64/* PRTC subsystem registers */
  65#define PRTCSS_RTC_INTC_EXTENA1         (0x0C)
  66#define PRTCSS_RTC_CTRL                 (0x10)
  67#define PRTCSS_RTC_WDT                  (0x11)
  68#define PRTCSS_RTC_TMR0                 (0x12)
  69#define PRTCSS_RTC_TMR1                 (0x13)
  70#define PRTCSS_RTC_CCTRL                (0x14)
  71#define PRTCSS_RTC_SEC                  (0x15)
  72#define PRTCSS_RTC_MIN                  (0x16)
  73#define PRTCSS_RTC_HOUR                 (0x17)
  74#define PRTCSS_RTC_DAY0                 (0x18)
  75#define PRTCSS_RTC_DAY1                 (0x19)
  76#define PRTCSS_RTC_AMIN                 (0x1A)
  77#define PRTCSS_RTC_AHOUR                (0x1B)
  78#define PRTCSS_RTC_ADAY0                (0x1C)
  79#define PRTCSS_RTC_ADAY1                (0x1D)
  80#define PRTCSS_RTC_CLKC_CNT             (0x20)
  81
  82/* PRTCSS_RTC_INTC_EXTENA1 */
  83#define PRTCSS_RTC_INTC_EXTENA1_MASK    (0x07)
  84
  85/* PRTCSS_RTC_CTRL bit fields */
  86#define PRTCSS_RTC_CTRL_WDTBUS          BIT(7)
  87#define PRTCSS_RTC_CTRL_WEN             BIT(6)
  88#define PRTCSS_RTC_CTRL_WDRT            BIT(5)
  89#define PRTCSS_RTC_CTRL_WDTFLG          BIT(4)
  90#define PRTCSS_RTC_CTRL_TE              BIT(3)
  91#define PRTCSS_RTC_CTRL_TIEN            BIT(2)
  92#define PRTCSS_RTC_CTRL_TMRFLG          BIT(1)
  93#define PRTCSS_RTC_CTRL_TMMD            BIT(0)
  94
  95/* PRTCSS_RTC_CCTRL bit fields */
  96#define PRTCSS_RTC_CCTRL_CALBUSY        BIT(7)
  97#define PRTCSS_RTC_CCTRL_DAEN           BIT(5)
  98#define PRTCSS_RTC_CCTRL_HAEN           BIT(4)
  99#define PRTCSS_RTC_CCTRL_MAEN           BIT(3)
 100#define PRTCSS_RTC_CCTRL_ALMFLG         BIT(2)
 101#define PRTCSS_RTC_CCTRL_AIEN           BIT(1)
 102#define PRTCSS_RTC_CCTRL_CAEN           BIT(0)
 103
 104static DEFINE_SPINLOCK(davinci_rtc_lock);
 105
 106struct davinci_rtc {
 107        struct rtc_device               *rtc;
 108        void __iomem                    *base;
 109        int                             irq;
 110};
 111
 112static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
 113                               u32 val, u32 addr)
 114{
 115        writel(val, davinci_rtc->base + addr);
 116}
 117
 118static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
 119{
 120        return readl(davinci_rtc->base + addr);
 121}
 122
 123static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
 124{
 125        while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
 126                cpu_relax();
 127}
 128
 129static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
 130                               unsigned long val, u8 addr)
 131{
 132        rtcif_wait(davinci_rtc);
 133
 134        rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
 135        rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
 136
 137        rtcif_wait(davinci_rtc);
 138}
 139
 140static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
 141{
 142        rtcif_wait(davinci_rtc);
 143
 144        rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
 145                    PRTCIF_CTLR);
 146
 147        rtcif_wait(davinci_rtc);
 148
 149        return rtcif_read(davinci_rtc, PRTCIF_LDATA);
 150}
 151
 152static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
 153{
 154        while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
 155               PRTCSS_RTC_CCTRL_CALBUSY)
 156                cpu_relax();
 157}
 158
 159static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
 160{
 161        struct davinci_rtc *davinci_rtc = class_dev;
 162        unsigned long events = 0;
 163        u32 irq_flg;
 164        u8 alm_irq, tmr_irq;
 165        u8 rtc_ctrl, rtc_cctrl;
 166        int ret = IRQ_NONE;
 167
 168        irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
 169                  PRTCIF_INTFLG_RTCSS;
 170
 171        alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
 172                  PRTCSS_RTC_CCTRL_ALMFLG;
 173
 174        tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
 175                  PRTCSS_RTC_CTRL_TMRFLG;
 176
 177        if (irq_flg) {
 178                if (alm_irq) {
 179                        events |= RTC_IRQF | RTC_AF;
 180                        rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
 181                        rtc_cctrl |=  PRTCSS_RTC_CCTRL_ALMFLG;
 182                        rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
 183                } else if (tmr_irq) {
 184                        events |= RTC_IRQF | RTC_PF;
 185                        rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
 186                        rtc_ctrl |=  PRTCSS_RTC_CTRL_TMRFLG;
 187                        rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
 188                }
 189
 190                rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
 191                                    PRTCIF_INTFLG);
 192                rtc_update_irq(davinci_rtc->rtc, 1, events);
 193
 194                ret = IRQ_HANDLED;
 195        }
 196
 197        return ret;
 198}
 199
 200static int
 201davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 202{
 203        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 204        u8 rtc_ctrl;
 205        unsigned long flags;
 206        int ret = 0;
 207
 208        spin_lock_irqsave(&davinci_rtc_lock, flags);
 209
 210        rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
 211
 212        switch (cmd) {
 213        case RTC_WIE_ON:
 214                rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG;
 215                break;
 216        case RTC_WIE_OFF:
 217                rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
 218                break;
 219        default:
 220                ret = -ENOIOCTLCMD;
 221        }
 222
 223        rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
 224
 225        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 226
 227        return ret;
 228}
 229
 230static void convertfromdays(u16 days, struct rtc_time *tm)
 231{
 232        int tmp_days, year, mon;
 233
 234        for (year = 2000;; year++) {
 235                tmp_days = rtc_year_days(1, 12, year);
 236                if (days >= tmp_days)
 237                        days -= tmp_days;
 238                else {
 239                        for (mon = 0;; mon++) {
 240                                tmp_days = rtc_month_days(mon, year);
 241                                if (days >= tmp_days) {
 242                                        days -= tmp_days;
 243                                } else {
 244                                        tm->tm_year = year - 1900;
 245                                        tm->tm_mon = mon;
 246                                        tm->tm_mday = days + 1;
 247                                        break;
 248                                }
 249                        }
 250                        break;
 251                }
 252        }
 253}
 254
 255static void convert2days(u16 *days, struct rtc_time *tm)
 256{
 257        int i;
 258        *days = 0;
 259
 260        for (i = 2000; i < 1900 + tm->tm_year; i++)
 261                *days += rtc_year_days(1, 12, i);
 262
 263        *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
 264}
 265
 266static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
 267{
 268        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 269        u16 days = 0;
 270        u8 day0, day1;
 271        unsigned long flags;
 272
 273        spin_lock_irqsave(&davinci_rtc_lock, flags);
 274
 275        davinci_rtcss_calendar_wait(davinci_rtc);
 276        tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
 277
 278        davinci_rtcss_calendar_wait(davinci_rtc);
 279        tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
 280
 281        davinci_rtcss_calendar_wait(davinci_rtc);
 282        tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
 283
 284        davinci_rtcss_calendar_wait(davinci_rtc);
 285        day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
 286
 287        davinci_rtcss_calendar_wait(davinci_rtc);
 288        day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
 289
 290        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 291
 292        days |= day1;
 293        days <<= 8;
 294        days |= day0;
 295
 296        convertfromdays(days, tm);
 297
 298        return 0;
 299}
 300
 301static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
 302{
 303        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 304        u16 days;
 305        u8 rtc_cctrl;
 306        unsigned long flags;
 307
 308        convert2days(&days, tm);
 309
 310        spin_lock_irqsave(&davinci_rtc_lock, flags);
 311
 312        davinci_rtcss_calendar_wait(davinci_rtc);
 313        rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
 314
 315        davinci_rtcss_calendar_wait(davinci_rtc);
 316        rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
 317
 318        davinci_rtcss_calendar_wait(davinci_rtc);
 319        rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
 320
 321        davinci_rtcss_calendar_wait(davinci_rtc);
 322        rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
 323
 324        davinci_rtcss_calendar_wait(davinci_rtc);
 325        rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
 326
 327        rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
 328        rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
 329        rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
 330
 331        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 332
 333        return 0;
 334}
 335
 336static int davinci_rtc_alarm_irq_enable(struct device *dev,
 337                                        unsigned int enabled)
 338{
 339        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 340        unsigned long flags;
 341        u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
 342
 343        spin_lock_irqsave(&davinci_rtc_lock, flags);
 344
 345        if (enabled)
 346                rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
 347                             PRTCSS_RTC_CCTRL_HAEN |
 348                             PRTCSS_RTC_CCTRL_MAEN |
 349                             PRTCSS_RTC_CCTRL_ALMFLG |
 350                             PRTCSS_RTC_CCTRL_AIEN;
 351        else
 352                rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
 353
 354        davinci_rtcss_calendar_wait(davinci_rtc);
 355        rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
 356
 357        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 358
 359        return 0;
 360}
 361
 362static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 363{
 364        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 365        u16 days = 0;
 366        u8 day0, day1;
 367        unsigned long flags;
 368
 369        alm->time.tm_sec = 0;
 370
 371        spin_lock_irqsave(&davinci_rtc_lock, flags);
 372
 373        davinci_rtcss_calendar_wait(davinci_rtc);
 374        alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
 375
 376        davinci_rtcss_calendar_wait(davinci_rtc);
 377        alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
 378
 379        davinci_rtcss_calendar_wait(davinci_rtc);
 380        day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
 381
 382        davinci_rtcss_calendar_wait(davinci_rtc);
 383        day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
 384
 385        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 386        days |= day1;
 387        days <<= 8;
 388        days |= day0;
 389
 390        convertfromdays(days, &alm->time);
 391
 392        alm->pending = !!(rtcss_read(davinci_rtc,
 393                          PRTCSS_RTC_CCTRL) &
 394                        PRTCSS_RTC_CCTRL_AIEN);
 395        alm->enabled = alm->pending && device_may_wakeup(dev);
 396
 397        return 0;
 398}
 399
 400static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 401{
 402        struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
 403        unsigned long flags;
 404        u16 days;
 405
 406        convert2days(&days, &alm->time);
 407
 408        spin_lock_irqsave(&davinci_rtc_lock, flags);
 409
 410        davinci_rtcss_calendar_wait(davinci_rtc);
 411        rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
 412
 413        davinci_rtcss_calendar_wait(davinci_rtc);
 414        rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
 415
 416        davinci_rtcss_calendar_wait(davinci_rtc);
 417        rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
 418
 419        davinci_rtcss_calendar_wait(davinci_rtc);
 420        rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
 421
 422        spin_unlock_irqrestore(&davinci_rtc_lock, flags);
 423
 424        return 0;
 425}
 426
 427static const struct rtc_class_ops davinci_rtc_ops = {
 428        .ioctl                  = davinci_rtc_ioctl,
 429        .read_time              = davinci_rtc_read_time,
 430        .set_time               = davinci_rtc_set_time,
 431        .alarm_irq_enable       = davinci_rtc_alarm_irq_enable,
 432        .read_alarm             = davinci_rtc_read_alarm,
 433        .set_alarm              = davinci_rtc_set_alarm,
 434};
 435
 436static int __init davinci_rtc_probe(struct platform_device *pdev)
 437{
 438        struct device *dev = &pdev->dev;
 439        struct davinci_rtc *davinci_rtc;
 440        int ret = 0;
 441
 442        davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
 443        if (!davinci_rtc)
 444                return -ENOMEM;
 445
 446        davinci_rtc->irq = platform_get_irq(pdev, 0);
 447        if (davinci_rtc->irq < 0)
 448                return davinci_rtc->irq;
 449
 450        davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0);
 451        if (IS_ERR(davinci_rtc->base))
 452                return PTR_ERR(davinci_rtc->base);
 453
 454        platform_set_drvdata(pdev, davinci_rtc);
 455
 456        davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
 457        if (IS_ERR(davinci_rtc->rtc))
 458                return PTR_ERR(davinci_rtc->rtc);
 459
 460        davinci_rtc->rtc->ops = &davinci_rtc_ops;
 461        davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 462        davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1;
 463
 464        rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
 465        rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
 466        rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
 467
 468        rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
 469        rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
 470
 471        ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt,
 472                          0, "davinci_rtc", davinci_rtc);
 473        if (ret < 0) {
 474                dev_err(dev, "unable to register davinci RTC interrupt\n");
 475                return ret;
 476        }
 477
 478        /* Enable interrupts */
 479        rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
 480        rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
 481                            PRTCSS_RTC_INTC_EXTENA1);
 482
 483        rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
 484
 485        device_init_wakeup(&pdev->dev, 0);
 486
 487        return devm_rtc_register_device(davinci_rtc->rtc);
 488}
 489
 490static int __exit davinci_rtc_remove(struct platform_device *pdev)
 491{
 492        struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
 493
 494        device_init_wakeup(&pdev->dev, 0);
 495
 496        rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
 497
 498        return 0;
 499}
 500
 501static struct platform_driver davinci_rtc_driver = {
 502        .remove         = __exit_p(davinci_rtc_remove),
 503        .driver         = {
 504                .name = "rtc_davinci",
 505        },
 506};
 507
 508module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe);
 509
 510MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
 511MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
 512MODULE_LICENSE("GPL");
 513