Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * DaVinci Power Management and Real Time Clock Driver for TI platforms
0004  *
0005  * Copyright (C) 2009 Texas Instruments, Inc
0006  *
0007  * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
0008  */
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/ioport.h>
0013 #include <linux/delay.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/rtc.h>
0016 #include <linux/bcd.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/io.h>
0019 #include <linux/slab.h>
0020 
0021 /*
0022  * The DaVinci RTC is a simple RTC with the following
0023  * Sec: 0 - 59 : BCD count
0024  * Min: 0 - 59 : BCD count
0025  * Hour: 0 - 23 : BCD count
0026  * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years )
0027  */
0028 
0029 /* PRTC interface registers */
0030 #define DAVINCI_PRTCIF_PID      0x00
0031 #define PRTCIF_CTLR         0x04
0032 #define PRTCIF_LDATA            0x08
0033 #define PRTCIF_UDATA            0x0C
0034 #define PRTCIF_INTEN            0x10
0035 #define PRTCIF_INTFLG           0x14
0036 
0037 /* PRTCIF_CTLR bit fields */
0038 #define PRTCIF_CTLR_BUSY        BIT(31)
0039 #define PRTCIF_CTLR_SIZE        BIT(25)
0040 #define PRTCIF_CTLR_DIR         BIT(24)
0041 #define PRTCIF_CTLR_BENU_MSB        BIT(23)
0042 #define PRTCIF_CTLR_BENU_3RD_BYTE   BIT(22)
0043 #define PRTCIF_CTLR_BENU_2ND_BYTE   BIT(21)
0044 #define PRTCIF_CTLR_BENU_LSB        BIT(20)
0045 #define PRTCIF_CTLR_BENU_MASK       (0x00F00000)
0046 #define PRTCIF_CTLR_BENL_MSB        BIT(19)
0047 #define PRTCIF_CTLR_BENL_3RD_BYTE   BIT(18)
0048 #define PRTCIF_CTLR_BENL_2ND_BYTE   BIT(17)
0049 #define PRTCIF_CTLR_BENL_LSB        BIT(16)
0050 #define PRTCIF_CTLR_BENL_MASK       (0x000F0000)
0051 
0052 /* PRTCIF_INTEN bit fields */
0053 #define PRTCIF_INTEN_RTCSS      BIT(1)
0054 #define PRTCIF_INTEN_RTCIF      BIT(0)
0055 #define PRTCIF_INTEN_MASK       (PRTCIF_INTEN_RTCSS \
0056                     | PRTCIF_INTEN_RTCIF)
0057 
0058 /* PRTCIF_INTFLG bit fields */
0059 #define PRTCIF_INTFLG_RTCSS     BIT(1)
0060 #define PRTCIF_INTFLG_RTCIF     BIT(0)
0061 #define PRTCIF_INTFLG_MASK      (PRTCIF_INTFLG_RTCSS \
0062                     | PRTCIF_INTFLG_RTCIF)
0063 
0064 /* PRTC subsystem registers */
0065 #define PRTCSS_RTC_INTC_EXTENA1     (0x0C)
0066 #define PRTCSS_RTC_CTRL         (0x10)
0067 #define PRTCSS_RTC_WDT          (0x11)
0068 #define PRTCSS_RTC_TMR0         (0x12)
0069 #define PRTCSS_RTC_TMR1         (0x13)
0070 #define PRTCSS_RTC_CCTRL        (0x14)
0071 #define PRTCSS_RTC_SEC          (0x15)
0072 #define PRTCSS_RTC_MIN          (0x16)
0073 #define PRTCSS_RTC_HOUR         (0x17)
0074 #define PRTCSS_RTC_DAY0         (0x18)
0075 #define PRTCSS_RTC_DAY1         (0x19)
0076 #define PRTCSS_RTC_AMIN         (0x1A)
0077 #define PRTCSS_RTC_AHOUR        (0x1B)
0078 #define PRTCSS_RTC_ADAY0        (0x1C)
0079 #define PRTCSS_RTC_ADAY1        (0x1D)
0080 #define PRTCSS_RTC_CLKC_CNT     (0x20)
0081 
0082 /* PRTCSS_RTC_INTC_EXTENA1 */
0083 #define PRTCSS_RTC_INTC_EXTENA1_MASK    (0x07)
0084 
0085 /* PRTCSS_RTC_CTRL bit fields */
0086 #define PRTCSS_RTC_CTRL_WDTBUS      BIT(7)
0087 #define PRTCSS_RTC_CTRL_WEN     BIT(6)
0088 #define PRTCSS_RTC_CTRL_WDRT        BIT(5)
0089 #define PRTCSS_RTC_CTRL_WDTFLG      BIT(4)
0090 #define PRTCSS_RTC_CTRL_TE      BIT(3)
0091 #define PRTCSS_RTC_CTRL_TIEN        BIT(2)
0092 #define PRTCSS_RTC_CTRL_TMRFLG      BIT(1)
0093 #define PRTCSS_RTC_CTRL_TMMD        BIT(0)
0094 
0095 /* PRTCSS_RTC_CCTRL bit fields */
0096 #define PRTCSS_RTC_CCTRL_CALBUSY    BIT(7)
0097 #define PRTCSS_RTC_CCTRL_DAEN       BIT(5)
0098 #define PRTCSS_RTC_CCTRL_HAEN       BIT(4)
0099 #define PRTCSS_RTC_CCTRL_MAEN       BIT(3)
0100 #define PRTCSS_RTC_CCTRL_ALMFLG     BIT(2)
0101 #define PRTCSS_RTC_CCTRL_AIEN       BIT(1)
0102 #define PRTCSS_RTC_CCTRL_CAEN       BIT(0)
0103 
0104 static DEFINE_SPINLOCK(davinci_rtc_lock);
0105 
0106 struct davinci_rtc {
0107     struct rtc_device       *rtc;
0108     void __iomem            *base;
0109     int             irq;
0110 };
0111 
0112 static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
0113                    u32 val, u32 addr)
0114 {
0115     writel(val, davinci_rtc->base + addr);
0116 }
0117 
0118 static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
0119 {
0120     return readl(davinci_rtc->base + addr);
0121 }
0122 
0123 static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
0124 {
0125     while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
0126         cpu_relax();
0127 }
0128 
0129 static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
0130                    unsigned long val, u8 addr)
0131 {
0132     rtcif_wait(davinci_rtc);
0133 
0134     rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
0135     rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
0136 
0137     rtcif_wait(davinci_rtc);
0138 }
0139 
0140 static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
0141 {
0142     rtcif_wait(davinci_rtc);
0143 
0144     rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
0145             PRTCIF_CTLR);
0146 
0147     rtcif_wait(davinci_rtc);
0148 
0149     return rtcif_read(davinci_rtc, PRTCIF_LDATA);
0150 }
0151 
0152 static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
0153 {
0154     while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
0155            PRTCSS_RTC_CCTRL_CALBUSY)
0156         cpu_relax();
0157 }
0158 
0159 static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
0160 {
0161     struct davinci_rtc *davinci_rtc = class_dev;
0162     unsigned long events = 0;
0163     u32 irq_flg;
0164     u8 alm_irq, tmr_irq;
0165     u8 rtc_ctrl, rtc_cctrl;
0166     int ret = IRQ_NONE;
0167 
0168     irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
0169           PRTCIF_INTFLG_RTCSS;
0170 
0171     alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
0172           PRTCSS_RTC_CCTRL_ALMFLG;
0173 
0174     tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
0175           PRTCSS_RTC_CTRL_TMRFLG;
0176 
0177     if (irq_flg) {
0178         if (alm_irq) {
0179             events |= RTC_IRQF | RTC_AF;
0180             rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0181             rtc_cctrl |=  PRTCSS_RTC_CCTRL_ALMFLG;
0182             rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0183         } else if (tmr_irq) {
0184             events |= RTC_IRQF | RTC_PF;
0185             rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
0186             rtc_ctrl |=  PRTCSS_RTC_CTRL_TMRFLG;
0187             rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
0188         }
0189 
0190         rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
0191                     PRTCIF_INTFLG);
0192         rtc_update_irq(davinci_rtc->rtc, 1, events);
0193 
0194         ret = IRQ_HANDLED;
0195     }
0196 
0197     return ret;
0198 }
0199 
0200 static int
0201 davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
0202 {
0203     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0204     u8 rtc_ctrl;
0205     unsigned long flags;
0206     int ret = 0;
0207 
0208     spin_lock_irqsave(&davinci_rtc_lock, flags);
0209 
0210     rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
0211 
0212     switch (cmd) {
0213     case RTC_WIE_ON:
0214         rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG;
0215         break;
0216     case RTC_WIE_OFF:
0217         rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
0218         break;
0219     default:
0220         ret = -ENOIOCTLCMD;
0221     }
0222 
0223     rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
0224 
0225     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0226 
0227     return ret;
0228 }
0229 
0230 static void convertfromdays(u16 days, struct rtc_time *tm)
0231 {
0232     int tmp_days, year, mon;
0233 
0234     for (year = 2000;; year++) {
0235         tmp_days = rtc_year_days(1, 12, year);
0236         if (days >= tmp_days)
0237             days -= tmp_days;
0238         else {
0239             for (mon = 0;; mon++) {
0240                 tmp_days = rtc_month_days(mon, year);
0241                 if (days >= tmp_days) {
0242                     days -= tmp_days;
0243                 } else {
0244                     tm->tm_year = year - 1900;
0245                     tm->tm_mon = mon;
0246                     tm->tm_mday = days + 1;
0247                     break;
0248                 }
0249             }
0250             break;
0251         }
0252     }
0253 }
0254 
0255 static void convert2days(u16 *days, struct rtc_time *tm)
0256 {
0257     int i;
0258     *days = 0;
0259 
0260     for (i = 2000; i < 1900 + tm->tm_year; i++)
0261         *days += rtc_year_days(1, 12, i);
0262 
0263     *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
0264 }
0265 
0266 static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
0267 {
0268     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0269     u16 days = 0;
0270     u8 day0, day1;
0271     unsigned long flags;
0272 
0273     spin_lock_irqsave(&davinci_rtc_lock, flags);
0274 
0275     davinci_rtcss_calendar_wait(davinci_rtc);
0276     tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
0277 
0278     davinci_rtcss_calendar_wait(davinci_rtc);
0279     tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
0280 
0281     davinci_rtcss_calendar_wait(davinci_rtc);
0282     tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
0283 
0284     davinci_rtcss_calendar_wait(davinci_rtc);
0285     day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
0286 
0287     davinci_rtcss_calendar_wait(davinci_rtc);
0288     day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
0289 
0290     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0291 
0292     days |= day1;
0293     days <<= 8;
0294     days |= day0;
0295 
0296     convertfromdays(days, tm);
0297 
0298     return 0;
0299 }
0300 
0301 static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
0302 {
0303     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0304     u16 days;
0305     u8 rtc_cctrl;
0306     unsigned long flags;
0307 
0308     convert2days(&days, tm);
0309 
0310     spin_lock_irqsave(&davinci_rtc_lock, flags);
0311 
0312     davinci_rtcss_calendar_wait(davinci_rtc);
0313     rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
0314 
0315     davinci_rtcss_calendar_wait(davinci_rtc);
0316     rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
0317 
0318     davinci_rtcss_calendar_wait(davinci_rtc);
0319     rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
0320 
0321     davinci_rtcss_calendar_wait(davinci_rtc);
0322     rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
0323 
0324     davinci_rtcss_calendar_wait(davinci_rtc);
0325     rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
0326 
0327     rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0328     rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
0329     rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0330 
0331     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0332 
0333     return 0;
0334 }
0335 
0336 static int davinci_rtc_alarm_irq_enable(struct device *dev,
0337                     unsigned int enabled)
0338 {
0339     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0340     unsigned long flags;
0341     u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0342 
0343     spin_lock_irqsave(&davinci_rtc_lock, flags);
0344 
0345     if (enabled)
0346         rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
0347                  PRTCSS_RTC_CCTRL_HAEN |
0348                  PRTCSS_RTC_CCTRL_MAEN |
0349                  PRTCSS_RTC_CCTRL_ALMFLG |
0350                  PRTCSS_RTC_CCTRL_AIEN;
0351     else
0352         rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
0353 
0354     davinci_rtcss_calendar_wait(davinci_rtc);
0355     rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0356 
0357     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0358 
0359     return 0;
0360 }
0361 
0362 static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0363 {
0364     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0365     u16 days = 0;
0366     u8 day0, day1;
0367     unsigned long flags;
0368 
0369     alm->time.tm_sec = 0;
0370 
0371     spin_lock_irqsave(&davinci_rtc_lock, flags);
0372 
0373     davinci_rtcss_calendar_wait(davinci_rtc);
0374     alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
0375 
0376     davinci_rtcss_calendar_wait(davinci_rtc);
0377     alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
0378 
0379     davinci_rtcss_calendar_wait(davinci_rtc);
0380     day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
0381 
0382     davinci_rtcss_calendar_wait(davinci_rtc);
0383     day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
0384 
0385     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0386     days |= day1;
0387     days <<= 8;
0388     days |= day0;
0389 
0390     convertfromdays(days, &alm->time);
0391 
0392     alm->pending = !!(rtcss_read(davinci_rtc,
0393               PRTCSS_RTC_CCTRL) &
0394             PRTCSS_RTC_CCTRL_AIEN);
0395     alm->enabled = alm->pending && device_may_wakeup(dev);
0396 
0397     return 0;
0398 }
0399 
0400 static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0401 {
0402     struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0403     unsigned long flags;
0404     u16 days;
0405 
0406     convert2days(&days, &alm->time);
0407 
0408     spin_lock_irqsave(&davinci_rtc_lock, flags);
0409 
0410     davinci_rtcss_calendar_wait(davinci_rtc);
0411     rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
0412 
0413     davinci_rtcss_calendar_wait(davinci_rtc);
0414     rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
0415 
0416     davinci_rtcss_calendar_wait(davinci_rtc);
0417     rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
0418 
0419     davinci_rtcss_calendar_wait(davinci_rtc);
0420     rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
0421 
0422     spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0423 
0424     return 0;
0425 }
0426 
0427 static const struct rtc_class_ops davinci_rtc_ops = {
0428     .ioctl          = davinci_rtc_ioctl,
0429     .read_time      = davinci_rtc_read_time,
0430     .set_time       = davinci_rtc_set_time,
0431     .alarm_irq_enable   = davinci_rtc_alarm_irq_enable,
0432     .read_alarm     = davinci_rtc_read_alarm,
0433     .set_alarm      = davinci_rtc_set_alarm,
0434 };
0435 
0436 static int __init davinci_rtc_probe(struct platform_device *pdev)
0437 {
0438     struct device *dev = &pdev->dev;
0439     struct davinci_rtc *davinci_rtc;
0440     int ret = 0;
0441 
0442     davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
0443     if (!davinci_rtc)
0444         return -ENOMEM;
0445 
0446     davinci_rtc->irq = platform_get_irq(pdev, 0);
0447     if (davinci_rtc->irq < 0)
0448         return davinci_rtc->irq;
0449 
0450     davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0);
0451     if (IS_ERR(davinci_rtc->base))
0452         return PTR_ERR(davinci_rtc->base);
0453 
0454     platform_set_drvdata(pdev, davinci_rtc);
0455 
0456     davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
0457     if (IS_ERR(davinci_rtc->rtc))
0458         return PTR_ERR(davinci_rtc->rtc);
0459 
0460     davinci_rtc->rtc->ops = &davinci_rtc_ops;
0461     davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0462     davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1;
0463 
0464     rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
0465     rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
0466     rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
0467 
0468     rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
0469     rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
0470 
0471     ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt,
0472               0, "davinci_rtc", davinci_rtc);
0473     if (ret < 0) {
0474         dev_err(dev, "unable to register davinci RTC interrupt\n");
0475         return ret;
0476     }
0477 
0478     /* Enable interrupts */
0479     rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
0480     rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
0481                 PRTCSS_RTC_INTC_EXTENA1);
0482 
0483     rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
0484 
0485     device_init_wakeup(&pdev->dev, 0);
0486 
0487     return devm_rtc_register_device(davinci_rtc->rtc);
0488 }
0489 
0490 static int __exit davinci_rtc_remove(struct platform_device *pdev)
0491 {
0492     struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
0493 
0494     device_init_wakeup(&pdev->dev, 0);
0495 
0496     rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
0497 
0498     return 0;
0499 }
0500 
0501 static struct platform_driver davinci_rtc_driver = {
0502     .remove     = __exit_p(davinci_rtc_remove),
0503     .driver     = {
0504         .name = "rtc_davinci",
0505     },
0506 };
0507 
0508 module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe);
0509 
0510 MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
0511 MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
0512 MODULE_LICENSE("GPL");