1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * rtc-st-lpc.c - ST's LPC RTC, powered by the Low Power Timer 4 * 5 * Copyright (C) 2014 STMicroelectronics Limited 6 * 7 * Author: David Paris <david.paris@st.com> for STMicroelectronics 8 * Lee Jones <lee.jones@linaro.org> for STMicroelectronics 9 * 10 * Based on the original driver written by Stuart Menefy. 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/delay.h> 15 #include <linux/init.h> 16 #include <linux/io.h> 17 #include <linux/irq.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/platform_device.h> 22 #include <linux/rtc.h> 23 24 #include <dt-bindings/mfd/st-lpc.h> 25 26 /* Low Power Timer */ 27 #define LPC_LPT_LSB_OFF 0x400 28 #define LPC_LPT_MSB_OFF 0x404 29 #define LPC_LPT_START_OFF 0x408 30 31 /* Low Power Alarm */ 32 #define LPC_LPA_LSB_OFF 0x410 33 #define LPC_LPA_MSB_OFF 0x414 34 #define LPC_LPA_START_OFF 0x418 35 36 /* LPC as WDT */ 37 #define LPC_WDT_OFF 0x510 38 #define LPC_WDT_FLAG_OFF 0x514 39 40 struct st_rtc { 41 struct rtc_device *rtc_dev; 42 struct rtc_wkalrm alarm; 43 struct clk *clk; 44 unsigned long clkrate; 45 void __iomem *ioaddr; 46 bool irq_enabled:1; 47 spinlock_t lock; 48 short irq; 49 }; 50 51 static void st_rtc_set_hw_alarm(struct st_rtc *rtc, 52 unsigned long msb, unsigned long lsb) 53 { 54 unsigned long flags; 55 56 spin_lock_irqsave(&rtc->lock, flags); 57 58 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF); 59 60 writel_relaxed(msb, rtc->ioaddr + LPC_LPA_MSB_OFF); 61 writel_relaxed(lsb, rtc->ioaddr + LPC_LPA_LSB_OFF); 62 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF); 63 64 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF); 65 66 spin_unlock_irqrestore(&rtc->lock, flags); 67 } 68 69 static irqreturn_t st_rtc_handler(int this_irq, void *data) 70 { 71 struct st_rtc *rtc = (struct st_rtc *)data; 72 73 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF); 74 75 return IRQ_HANDLED; 76 } 77 78 static int st_rtc_read_time(struct device *dev, struct rtc_time *tm) 79 { 80 struct st_rtc *rtc = dev_get_drvdata(dev); 81 unsigned long lpt_lsb, lpt_msb; 82 unsigned long long lpt; 83 unsigned long flags; 84 85 spin_lock_irqsave(&rtc->lock, flags); 86 87 do { 88 lpt_msb = readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF); 89 lpt_lsb = readl_relaxed(rtc->ioaddr + LPC_LPT_LSB_OFF); 90 } while (readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF) != lpt_msb); 91 92 spin_unlock_irqrestore(&rtc->lock, flags); 93 94 lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb; 95 do_div(lpt, rtc->clkrate); 96 rtc_time64_to_tm(lpt, tm); 97 98 return 0; 99 } 100 101 static int st_rtc_set_time(struct device *dev, struct rtc_time *tm) 102 { 103 struct st_rtc *rtc = dev_get_drvdata(dev); 104 unsigned long long lpt, secs; 105 unsigned long flags; 106 107 secs = rtc_tm_to_time64(tm); 108 109 lpt = (unsigned long long)secs * rtc->clkrate; 110 111 spin_lock_irqsave(&rtc->lock, flags); 112 113 writel_relaxed(lpt >> 32, rtc->ioaddr + LPC_LPT_MSB_OFF); 114 writel_relaxed(lpt, rtc->ioaddr + LPC_LPT_LSB_OFF); 115 writel_relaxed(1, rtc->ioaddr + LPC_LPT_START_OFF); 116 117 spin_unlock_irqrestore(&rtc->lock, flags); 118 119 return 0; 120 } 121 122 static int st_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) 123 { 124 struct st_rtc *rtc = dev_get_drvdata(dev); 125 unsigned long flags; 126 127 spin_lock_irqsave(&rtc->lock, flags); 128 129 memcpy(wkalrm, &rtc->alarm, sizeof(struct rtc_wkalrm)); 130 131 spin_unlock_irqrestore(&rtc->lock, flags); 132 133 return 0; 134 } 135 136 static int st_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 137 { 138 struct st_rtc *rtc = dev_get_drvdata(dev); 139 140 if (enabled && !rtc->irq_enabled) { 141 enable_irq(rtc->irq); 142 rtc->irq_enabled = true; 143 } else if (!enabled && rtc->irq_enabled) { 144 disable_irq(rtc->irq); 145 rtc->irq_enabled = false; 146 } 147 148 return 0; 149 } 150 151 static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) 152 { 153 struct st_rtc *rtc = dev_get_drvdata(dev); 154 struct rtc_time now; 155 unsigned long long now_secs; 156 unsigned long long alarm_secs; 157 unsigned long long lpa; 158 159 st_rtc_read_time(dev, &now); 160 now_secs = rtc_tm_to_time64(&now); 161 alarm_secs = rtc_tm_to_time64(&t->time); 162 163 memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm)); 164 165 /* Now many secs to fire */ 166 alarm_secs -= now_secs; 167 lpa = (unsigned long long)alarm_secs * rtc->clkrate; 168 169 st_rtc_set_hw_alarm(rtc, lpa >> 32, lpa); 170 st_rtc_alarm_irq_enable(dev, t->enabled); 171 172 return 0; 173 } 174 175 static const struct rtc_class_ops st_rtc_ops = { 176 .read_time = st_rtc_read_time, 177 .set_time = st_rtc_set_time, 178 .read_alarm = st_rtc_read_alarm, 179 .set_alarm = st_rtc_set_alarm, 180 .alarm_irq_enable = st_rtc_alarm_irq_enable, 181 }; 182 183 static int st_rtc_probe(struct platform_device *pdev) 184 { 185 struct device_node *np = pdev->dev.of_node; 186 struct st_rtc *rtc; 187 uint32_t mode; 188 int ret = 0; 189 190 ret = of_property_read_u32(np, "st,lpc-mode", &mode); 191 if (ret) { 192 dev_err(&pdev->dev, "An LPC mode must be provided\n"); 193 return -EINVAL; 194 } 195 196 /* LPC can either run as a Clocksource or in RTC or WDT mode */ 197 if (mode != ST_LPC_MODE_RTC) 198 return -ENODEV; 199 200 rtc = devm_kzalloc(&pdev->dev, sizeof(struct st_rtc), GFP_KERNEL); 201 if (!rtc) 202 return -ENOMEM; 203 204 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 205 if (IS_ERR(rtc->rtc_dev)) 206 return PTR_ERR(rtc->rtc_dev); 207 208 spin_lock_init(&rtc->lock); 209 210 rtc->ioaddr = devm_platform_ioremap_resource(pdev, 0); 211 if (IS_ERR(rtc->ioaddr)) 212 return PTR_ERR(rtc->ioaddr); 213 214 rtc->irq = platform_get_irq(pdev, 0); 215 if (rtc->irq < 0) 216 return rtc->irq; 217 218 ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, 219 IRQF_NO_AUTOEN, pdev->name, rtc); 220 if (ret) { 221 dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq); 222 return ret; 223 } 224 225 enable_irq_wake(rtc->irq); 226 227 rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL); 228 if (IS_ERR(rtc->clk)) 229 return dev_err_probe(&pdev->dev, PTR_ERR(rtc->clk), 230 "Unable to request clock\n"); 231 232 rtc->clkrate = clk_get_rate(rtc->clk); 233 if (!rtc->clkrate) { 234 dev_err(&pdev->dev, "Unable to fetch clock rate\n"); 235 return -EINVAL; 236 } 237 238 device_set_wakeup_capable(&pdev->dev, 1); 239 240 platform_set_drvdata(pdev, rtc); 241 242 rtc->rtc_dev->ops = &st_rtc_ops; 243 rtc->rtc_dev->range_max = U64_MAX; 244 do_div(rtc->rtc_dev->range_max, rtc->clkrate); 245 246 ret = devm_rtc_register_device(rtc->rtc_dev); 247 if (ret) 248 return ret; 249 250 return 0; 251 } 252 253 #ifdef CONFIG_PM_SLEEP 254 static int st_rtc_suspend(struct device *dev) 255 { 256 struct st_rtc *rtc = dev_get_drvdata(dev); 257 258 if (device_may_wakeup(dev)) 259 return 0; 260 261 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF); 262 writel_relaxed(0, rtc->ioaddr + LPC_LPA_START_OFF); 263 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF); 264 265 return 0; 266 } 267 268 static int st_rtc_resume(struct device *dev) 269 { 270 struct st_rtc *rtc = dev_get_drvdata(dev); 271 272 rtc_alarm_irq_enable(rtc->rtc_dev, 0); 273 274 /* 275 * clean 'rtc->alarm' to allow a new 276 * .set_alarm to the upper RTC layer 277 */ 278 memset(&rtc->alarm, 0, sizeof(struct rtc_wkalrm)); 279 280 writel_relaxed(0, rtc->ioaddr + LPC_LPA_MSB_OFF); 281 writel_relaxed(0, rtc->ioaddr + LPC_LPA_LSB_OFF); 282 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF); 283 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF); 284 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF); 285 286 return 0; 287 } 288 #endif 289 290 static SIMPLE_DEV_PM_OPS(st_rtc_pm_ops, st_rtc_suspend, st_rtc_resume); 291 292 static const struct of_device_id st_rtc_match[] = { 293 { .compatible = "st,stih407-lpc" }, 294 {} 295 }; 296 MODULE_DEVICE_TABLE(of, st_rtc_match); 297 298 static struct platform_driver st_rtc_platform_driver = { 299 .driver = { 300 .name = "st-lpc-rtc", 301 .pm = &st_rtc_pm_ops, 302 .of_match_table = st_rtc_match, 303 }, 304 .probe = st_rtc_probe, 305 }; 306 307 module_platform_driver(st_rtc_platform_driver); 308 309 MODULE_DESCRIPTION("STMicroelectronics LPC RTC driver"); 310 MODULE_AUTHOR("David Paris <david.paris@st.com>"); 311 MODULE_LICENSE("GPL"); 312