Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for the RTC in Marvell SoCs.
0004  */
0005 
0006 #include <linux/init.h>
0007 #include <linux/kernel.h>
0008 #include <linux/rtc.h>
0009 #include <linux/bcd.h>
0010 #include <linux/bitops.h>
0011 #include <linux/io.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/of.h>
0014 #include <linux/delay.h>
0015 #include <linux/clk.h>
0016 #include <linux/gfp.h>
0017 #include <linux/module.h>
0018 
0019 
0020 #define RTC_TIME_REG_OFFS   0
0021 #define RTC_SECONDS_OFFS    0
0022 #define RTC_MINUTES_OFFS    8
0023 #define RTC_HOURS_OFFS      16
0024 #define RTC_WDAY_OFFS       24
0025 #define RTC_HOURS_12H_MODE  BIT(22) /* 12 hour mode */
0026 
0027 #define RTC_DATE_REG_OFFS   4
0028 #define RTC_MDAY_OFFS       0
0029 #define RTC_MONTH_OFFS      8
0030 #define RTC_YEAR_OFFS       16
0031 
0032 #define RTC_ALARM_TIME_REG_OFFS 8
0033 #define RTC_ALARM_DATE_REG_OFFS 0xc
0034 #define RTC_ALARM_VALID     BIT(7)
0035 
0036 #define RTC_ALARM_INTERRUPT_MASK_REG_OFFS   0x10
0037 #define RTC_ALARM_INTERRUPT_CASUE_REG_OFFS  0x14
0038 
0039 struct rtc_plat_data {
0040     struct rtc_device *rtc;
0041     void __iomem *ioaddr;
0042     int     irq;
0043     struct clk  *clk;
0044 };
0045 
0046 static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
0047 {
0048     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0049     void __iomem *ioaddr = pdata->ioaddr;
0050     u32 rtc_reg;
0051 
0052     rtc_reg = (bin2bcd(tm->tm_sec) << RTC_SECONDS_OFFS) |
0053         (bin2bcd(tm->tm_min) << RTC_MINUTES_OFFS) |
0054         (bin2bcd(tm->tm_hour) << RTC_HOURS_OFFS) |
0055         (bin2bcd(tm->tm_wday) << RTC_WDAY_OFFS);
0056     writel(rtc_reg, ioaddr + RTC_TIME_REG_OFFS);
0057 
0058     rtc_reg = (bin2bcd(tm->tm_mday) << RTC_MDAY_OFFS) |
0059         (bin2bcd(tm->tm_mon + 1) << RTC_MONTH_OFFS) |
0060         (bin2bcd(tm->tm_year - 100) << RTC_YEAR_OFFS);
0061     writel(rtc_reg, ioaddr + RTC_DATE_REG_OFFS);
0062 
0063     return 0;
0064 }
0065 
0066 static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm)
0067 {
0068     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0069     void __iomem *ioaddr = pdata->ioaddr;
0070     u32 rtc_time, rtc_date;
0071     unsigned int year, month, day, hour, minute, second, wday;
0072 
0073     rtc_time = readl(ioaddr + RTC_TIME_REG_OFFS);
0074     rtc_date = readl(ioaddr + RTC_DATE_REG_OFFS);
0075 
0076     second = rtc_time & 0x7f;
0077     minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f;
0078     hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hour mode */
0079     wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7;
0080 
0081     day = rtc_date & 0x3f;
0082     month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f;
0083     year = (rtc_date >> RTC_YEAR_OFFS) & 0xff;
0084 
0085     tm->tm_sec = bcd2bin(second);
0086     tm->tm_min = bcd2bin(minute);
0087     tm->tm_hour = bcd2bin(hour);
0088     tm->tm_mday = bcd2bin(day);
0089     tm->tm_wday = bcd2bin(wday);
0090     tm->tm_mon = bcd2bin(month) - 1;
0091     /* hw counts from year 2000, but tm_year is relative to 1900 */
0092     tm->tm_year = bcd2bin(year) + 100;
0093 
0094     return 0;
0095 }
0096 
0097 static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0098 {
0099     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0100     void __iomem *ioaddr = pdata->ioaddr;
0101     u32 rtc_time, rtc_date;
0102     unsigned int year, month, day, hour, minute, second, wday;
0103 
0104     rtc_time = readl(ioaddr + RTC_ALARM_TIME_REG_OFFS);
0105     rtc_date = readl(ioaddr + RTC_ALARM_DATE_REG_OFFS);
0106 
0107     second = rtc_time & 0x7f;
0108     minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f;
0109     hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hour mode */
0110     wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7;
0111 
0112     day = rtc_date & 0x3f;
0113     month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f;
0114     year = (rtc_date >> RTC_YEAR_OFFS) & 0xff;
0115 
0116     alm->time.tm_sec = bcd2bin(second);
0117     alm->time.tm_min = bcd2bin(minute);
0118     alm->time.tm_hour = bcd2bin(hour);
0119     alm->time.tm_mday = bcd2bin(day);
0120     alm->time.tm_wday = bcd2bin(wday);
0121     alm->time.tm_mon = bcd2bin(month) - 1;
0122     /* hw counts from year 2000, but tm_year is relative to 1900 */
0123     alm->time.tm_year = bcd2bin(year) + 100;
0124 
0125     alm->enabled = !!readl(ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0126 
0127     return rtc_valid_tm(&alm->time);
0128 }
0129 
0130 static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0131 {
0132     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0133     void __iomem *ioaddr = pdata->ioaddr;
0134     u32 rtc_reg = 0;
0135 
0136     if (alm->time.tm_sec >= 0)
0137         rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_sec))
0138             << RTC_SECONDS_OFFS;
0139     if (alm->time.tm_min >= 0)
0140         rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_min))
0141             << RTC_MINUTES_OFFS;
0142     if (alm->time.tm_hour >= 0)
0143         rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_hour))
0144             << RTC_HOURS_OFFS;
0145 
0146     writel(rtc_reg, ioaddr + RTC_ALARM_TIME_REG_OFFS);
0147 
0148     if (alm->time.tm_mday >= 0)
0149         rtc_reg = (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mday))
0150             << RTC_MDAY_OFFS;
0151     else
0152         rtc_reg = 0;
0153 
0154     if (alm->time.tm_mon >= 0)
0155         rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mon + 1))
0156             << RTC_MONTH_OFFS;
0157 
0158     if (alm->time.tm_year >= 0)
0159         rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_year - 100))
0160             << RTC_YEAR_OFFS;
0161 
0162     writel(rtc_reg, ioaddr + RTC_ALARM_DATE_REG_OFFS);
0163     writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
0164     writel(alm->enabled ? 1 : 0,
0165            ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0166 
0167     return 0;
0168 }
0169 
0170 static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
0171 {
0172     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0173     void __iomem *ioaddr = pdata->ioaddr;
0174 
0175     if (pdata->irq < 0)
0176         return -EINVAL; /* fall back into rtc-dev's emulation */
0177 
0178     if (enabled)
0179         writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0180     else
0181         writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0182     return 0;
0183 }
0184 
0185 static irqreturn_t mv_rtc_interrupt(int irq, void *data)
0186 {
0187     struct rtc_plat_data *pdata = data;
0188     void __iomem *ioaddr = pdata->ioaddr;
0189 
0190     /* alarm irq? */
0191     if (!readl(ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS))
0192         return IRQ_NONE;
0193 
0194     /* clear interrupt */
0195     writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
0196     rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
0197     return IRQ_HANDLED;
0198 }
0199 
0200 static const struct rtc_class_ops mv_rtc_ops = {
0201     .read_time  = mv_rtc_read_time,
0202     .set_time   = mv_rtc_set_time,
0203     .read_alarm = mv_rtc_read_alarm,
0204     .set_alarm  = mv_rtc_set_alarm,
0205     .alarm_irq_enable = mv_rtc_alarm_irq_enable,
0206 };
0207 
0208 static int __init mv_rtc_probe(struct platform_device *pdev)
0209 {
0210     struct rtc_plat_data *pdata;
0211     u32 rtc_time;
0212     int ret = 0;
0213 
0214     pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0215     if (!pdata)
0216         return -ENOMEM;
0217 
0218     pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
0219     if (IS_ERR(pdata->ioaddr))
0220         return PTR_ERR(pdata->ioaddr);
0221 
0222     pdata->clk = devm_clk_get(&pdev->dev, NULL);
0223     /* Not all SoCs require a clock.*/
0224     if (!IS_ERR(pdata->clk))
0225         clk_prepare_enable(pdata->clk);
0226 
0227     /* make sure the 24 hour mode is enabled */
0228     rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
0229     if (rtc_time & RTC_HOURS_12H_MODE) {
0230         dev_err(&pdev->dev, "12 Hour mode is enabled but not supported.\n");
0231         ret = -EINVAL;
0232         goto out;
0233     }
0234 
0235     /* make sure it is actually functional */
0236     if (rtc_time == 0x01000000) {
0237         ssleep(1);
0238         rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
0239         if (rtc_time == 0x01000000) {
0240             dev_err(&pdev->dev, "internal RTC not ticking\n");
0241             ret = -ENODEV;
0242             goto out;
0243         }
0244     }
0245 
0246     pdata->irq = platform_get_irq(pdev, 0);
0247 
0248     platform_set_drvdata(pdev, pdata);
0249 
0250     pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
0251     if (IS_ERR(pdata->rtc)) {
0252         ret = PTR_ERR(pdata->rtc);
0253         goto out;
0254     }
0255 
0256     if (pdata->irq >= 0) {
0257         writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0258         if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
0259                      IRQF_SHARED,
0260                      pdev->name, pdata) < 0) {
0261             dev_warn(&pdev->dev, "interrupt not available.\n");
0262             pdata->irq = -1;
0263         }
0264     }
0265 
0266     if (pdata->irq >= 0)
0267         device_init_wakeup(&pdev->dev, 1);
0268     else
0269         clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
0270 
0271     pdata->rtc->ops = &mv_rtc_ops;
0272     pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0273     pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
0274 
0275     ret = devm_rtc_register_device(pdata->rtc);
0276     if (!ret)
0277         return 0;
0278 out:
0279     if (!IS_ERR(pdata->clk))
0280         clk_disable_unprepare(pdata->clk);
0281 
0282     return ret;
0283 }
0284 
0285 static int __exit mv_rtc_remove(struct platform_device *pdev)
0286 {
0287     struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
0288 
0289     if (pdata->irq >= 0)
0290         device_init_wakeup(&pdev->dev, 0);
0291 
0292     if (!IS_ERR(pdata->clk))
0293         clk_disable_unprepare(pdata->clk);
0294 
0295     return 0;
0296 }
0297 
0298 #ifdef CONFIG_OF
0299 static const struct of_device_id rtc_mv_of_match_table[] = {
0300     { .compatible = "marvell,orion-rtc", },
0301     {}
0302 };
0303 MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);
0304 #endif
0305 
0306 static struct platform_driver mv_rtc_driver = {
0307     .remove     = __exit_p(mv_rtc_remove),
0308     .driver     = {
0309         .name   = "rtc-mv",
0310         .of_match_table = of_match_ptr(rtc_mv_of_match_table),
0311     },
0312 };
0313 
0314 module_platform_driver_probe(mv_rtc_driver, mv_rtc_probe);
0315 
0316 MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
0317 MODULE_DESCRIPTION("Marvell RTC driver");
0318 MODULE_LICENSE("GPL");
0319 MODULE_ALIAS("platform:rtc-mv");