398 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver4 *5 * Copyright (C) 2015 Xilinx, Inc.6 *7 */8 9#include <linux/clk.h>10#include <linux/delay.h>11#include <linux/init.h>12#include <linux/io.h>13#include <linux/module.h>14#include <linux/of.h>15#include <linux/platform_device.h>16#include <linux/rtc.h>17 18/* RTC Registers */19#define RTC_SET_TM_WR 0x0020#define RTC_SET_TM_RD 0x0421#define RTC_CALIB_WR 0x0822#define RTC_CALIB_RD 0x0C23#define RTC_CUR_TM 0x1024#define RTC_CUR_TICK 0x1425#define RTC_ALRM 0x1826#define RTC_INT_STS 0x2027#define RTC_INT_MASK 0x2428#define RTC_INT_EN 0x2829#define RTC_INT_DIS 0x2C30#define RTC_CTRL 0x4031 32#define RTC_FR_EN BIT(20)33#define RTC_FR_DATSHIFT 1634#define RTC_TICK_MASK 0xFFFF35#define RTC_INT_SEC BIT(0)36#define RTC_INT_ALRM BIT(1)37#define RTC_OSC_EN BIT(24)38#define RTC_BATT_EN BIT(31)39 40#define RTC_CALIB_DEF 0x7FFF41#define RTC_CALIB_MASK 0x1FFFFF42#define RTC_ALRM_MASK BIT(1)43#define RTC_MSEC 100044#define RTC_FR_MASK 0xF000045#define RTC_FR_MAX_TICKS 1646#define RTC_PPB 1000000000LL47#define RTC_MIN_OFFSET -3276800048#define RTC_MAX_OFFSET 3276700049 50struct xlnx_rtc_dev {51 struct rtc_device *rtc;52 void __iomem *reg_base;53 int alarm_irq;54 int sec_irq;55 struct clk *rtc_clk;56 unsigned int freq;57};58 59static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)60{61 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);62 unsigned long new_time;63 64 /*65 * The value written will be updated after 1 sec into the66 * seconds read register, so we need to program time +1 sec67 * to get the correct time on read.68 */69 new_time = rtc_tm_to_time64(tm) + 1;70 71 writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);72 73 /*74 * Clear the rtc interrupt status register after setting the75 * time. During a read_time function, the code should read the76 * RTC_INT_STATUS register and if bit 0 is still 0, it means77 * that one second has not elapsed yet since RTC was set and78 * the current time should be read from SET_TIME_READ register;79 * otherwise, CURRENT_TIME register is read to report the time80 */81 writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);82 83 return 0;84}85 86static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)87{88 u32 status;89 unsigned long read_time;90 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);91 92 status = readl(xrtcdev->reg_base + RTC_INT_STS);93 94 if (status & RTC_INT_SEC) {95 /*96 * RTC has updated the CURRENT_TIME with the time written into97 * SET_TIME_WRITE register.98 */99 read_time = readl(xrtcdev->reg_base + RTC_CUR_TM);100 } else {101 /*102 * Time written in SET_TIME_WRITE has not yet updated into103 * the seconds read register, so read the time from the104 * SET_TIME_WRITE instead of CURRENT_TIME register.105 * Since we add +1 sec while writing, we need to -1 sec while106 * reading.107 */108 read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;109 }110 rtc_time64_to_tm(read_time, tm);111 112 return 0;113}114 115static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)116{117 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);118 119 rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);120 alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;121 122 return 0;123}124 125static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)126{127 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);128 unsigned int status;129 ulong timeout;130 131 timeout = jiffies + msecs_to_jiffies(RTC_MSEC);132 133 if (enabled) {134 while (1) {135 status = readl(xrtcdev->reg_base + RTC_INT_STS);136 if (!((status & RTC_ALRM_MASK) == RTC_ALRM_MASK))137 break;138 139 if (time_after_eq(jiffies, timeout)) {140 dev_err(dev, "Time out occur, while clearing alarm status bit\n");141 return -ETIMEDOUT;142 }143 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);144 }145 146 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);147 } else {148 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);149 }150 151 return 0;152}153 154static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)155{156 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);157 unsigned long alarm_time;158 159 alarm_time = rtc_tm_to_time64(&alrm->time);160 161 writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));162 163 xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);164 165 return 0;166}167 168static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev)169{170 u32 rtc_ctrl;171 172 /* Enable RTC switch to battery when VCC_PSAUX is not available */173 rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL);174 rtc_ctrl |= RTC_BATT_EN;175 writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL);176}177 178static int xlnx_rtc_read_offset(struct device *dev, long *offset)179{180 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);181 unsigned long long rtc_ppb = RTC_PPB;182 unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq);183 unsigned int calibval;184 long offset_val;185 186 calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD);187 /* Offset with seconds ticks */188 offset_val = calibval & RTC_TICK_MASK;189 offset_val = offset_val - RTC_CALIB_DEF;190 offset_val = offset_val * tick_mult;191 192 /* Offset with fractional ticks */193 if (calibval & RTC_FR_EN)194 offset_val += ((calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT)195 * (tick_mult / RTC_FR_MAX_TICKS);196 *offset = offset_val;197 198 return 0;199}200 201static int xlnx_rtc_set_offset(struct device *dev, long offset)202{203 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);204 unsigned long long rtc_ppb = RTC_PPB;205 unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq);206 unsigned char fract_tick = 0;207 unsigned int calibval;208 short int max_tick;209 int fract_offset;210 211 if (offset < RTC_MIN_OFFSET || offset > RTC_MAX_OFFSET)212 return -ERANGE;213 214 /* Number ticks for given offset */215 max_tick = div_s64_rem(offset, tick_mult, &fract_offset);216 217 /* Number fractional ticks for given offset */218 if (fract_offset) {219 if (fract_offset < 0) {220 fract_offset = fract_offset + tick_mult;221 max_tick--;222 }223 if (fract_offset > (tick_mult / RTC_FR_MAX_TICKS)) {224 for (fract_tick = 1; fract_tick < 16; fract_tick++) {225 if (fract_offset <=226 (fract_tick *227 (tick_mult / RTC_FR_MAX_TICKS)))228 break;229 }230 }231 }232 233 /* Zynqmp RTC uses second and fractional tick234 * counters for compensation235 */236 calibval = max_tick + RTC_CALIB_DEF;237 238 if (fract_tick)239 calibval |= RTC_FR_EN;240 241 calibval |= (fract_tick << RTC_FR_DATSHIFT);242 243 writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));244 245 return 0;246}247 248static const struct rtc_class_ops xlnx_rtc_ops = {249 .set_time = xlnx_rtc_set_time,250 .read_time = xlnx_rtc_read_time,251 .read_alarm = xlnx_rtc_read_alarm,252 .set_alarm = xlnx_rtc_set_alarm,253 .alarm_irq_enable = xlnx_rtc_alarm_irq_enable,254 .read_offset = xlnx_rtc_read_offset,255 .set_offset = xlnx_rtc_set_offset,256};257 258static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)259{260 struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;261 unsigned int status;262 263 status = readl(xrtcdev->reg_base + RTC_INT_STS);264 /* Check if interrupt asserted */265 if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))266 return IRQ_NONE;267 268 /* Disable RTC_INT_ALRM interrupt only */269 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);270 271 if (status & RTC_INT_ALRM)272 rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);273 274 return IRQ_HANDLED;275}276 277static int xlnx_rtc_probe(struct platform_device *pdev)278{279 struct xlnx_rtc_dev *xrtcdev;280 int ret;281 282 xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);283 if (!xrtcdev)284 return -ENOMEM;285 286 platform_set_drvdata(pdev, xrtcdev);287 288 xrtcdev->rtc = devm_rtc_allocate_device(&pdev->dev);289 if (IS_ERR(xrtcdev->rtc))290 return PTR_ERR(xrtcdev->rtc);291 292 xrtcdev->rtc->ops = &xlnx_rtc_ops;293 xrtcdev->rtc->range_max = U32_MAX;294 295 xrtcdev->reg_base = devm_platform_ioremap_resource(pdev, 0);296 if (IS_ERR(xrtcdev->reg_base))297 return PTR_ERR(xrtcdev->reg_base);298 299 xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");300 if (xrtcdev->alarm_irq < 0)301 return xrtcdev->alarm_irq;302 ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,303 xlnx_rtc_interrupt, 0,304 dev_name(&pdev->dev), xrtcdev);305 if (ret) {306 dev_err(&pdev->dev, "request irq failed\n");307 return ret;308 }309 310 xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");311 if (xrtcdev->sec_irq < 0)312 return xrtcdev->sec_irq;313 ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,314 xlnx_rtc_interrupt, 0,315 dev_name(&pdev->dev), xrtcdev);316 if (ret) {317 dev_err(&pdev->dev, "request irq failed\n");318 return ret;319 }320 321 /* Getting the rtc_clk info */322 xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc_clk");323 if (IS_ERR(xrtcdev->rtc_clk)) {324 if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER)325 dev_warn(&pdev->dev, "Device clock not found.\n");326 }327 xrtcdev->freq = clk_get_rate(xrtcdev->rtc_clk);328 if (!xrtcdev->freq) {329 ret = of_property_read_u32(pdev->dev.of_node, "calibration",330 &xrtcdev->freq);331 if (ret)332 xrtcdev->freq = RTC_CALIB_DEF;333 }334 ret = readl(xrtcdev->reg_base + RTC_CALIB_RD);335 if (!ret)336 writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR));337 338 xlnx_init_rtc(xrtcdev);339 340 device_init_wakeup(&pdev->dev, 1);341 342 return devm_rtc_register_device(xrtcdev->rtc);343}344 345static void xlnx_rtc_remove(struct platform_device *pdev)346{347 xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);348 device_init_wakeup(&pdev->dev, 0);349}350 351static int __maybe_unused xlnx_rtc_suspend(struct device *dev)352{353 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);354 355 if (device_may_wakeup(dev))356 enable_irq_wake(xrtcdev->alarm_irq);357 else358 xlnx_rtc_alarm_irq_enable(dev, 0);359 360 return 0;361}362 363static int __maybe_unused xlnx_rtc_resume(struct device *dev)364{365 struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);366 367 if (device_may_wakeup(dev))368 disable_irq_wake(xrtcdev->alarm_irq);369 else370 xlnx_rtc_alarm_irq_enable(dev, 1);371 372 return 0;373}374 375static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume);376 377static const struct of_device_id xlnx_rtc_of_match[] = {378 {.compatible = "xlnx,zynqmp-rtc" },379 { }380};381MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);382 383static struct platform_driver xlnx_rtc_driver = {384 .probe = xlnx_rtc_probe,385 .remove_new = xlnx_rtc_remove,386 .driver = {387 .name = KBUILD_MODNAME,388 .pm = &xlnx_rtc_pm_ops,389 .of_match_table = xlnx_rtc_of_match,390 },391};392 393module_platform_driver(xlnx_rtc_driver);394 395MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");396MODULE_AUTHOR("Xilinx Inc.");397MODULE_LICENSE("GPL v2");398