1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Freescale FlexTimer Module (FTM) alarm device driver. 4 * 5 * Copyright 2014 Freescale Semiconductor, Inc. 6 * Copyright 2019 NXP 7 * 8 */ 9 10 #include <linux/device.h> 11 #include <linux/err.h> 12 #include <linux/interrupt.h> 13 #include <linux/io.h> 14 #include <linux/of_address.h> 15 #include <linux/of_irq.h> 16 #include <linux/platform_device.h> 17 #include <linux/of.h> 18 #include <linux/of_device.h> 19 #include <linux/module.h> 20 #include <linux/fsl/ftm.h> 21 #include <linux/rtc.h> 22 #include <linux/time.h> 23 24 #define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_MASK_SHIFT) 25 26 /* 27 * Select Fixed frequency clock (32KHz) as clock source 28 * of FlexTimer Module 29 */ 30 #define FTM_SC_CLKS_FIXED_FREQ 0x02 31 #define FIXED_FREQ_CLK 32000 32 33 /* Select 128 (2^7) as divider factor */ 34 #define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK) 35 36 /* Maximum counter value in FlexTimer's CNT registers */ 37 #define MAX_COUNT_VAL 0xffff 38 39 struct ftm_rtc { 40 struct rtc_device *rtc_dev; 41 void __iomem *base; 42 bool big_endian; 43 u32 alarm_freq; 44 }; 45 46 static inline u32 rtc_readl(struct ftm_rtc *dev, u32 reg) 47 { 48 if (dev->big_endian) 49 return ioread32be(dev->base + reg); 50 else 51 return ioread32(dev->base + reg); 52 } 53 54 static inline void rtc_writel(struct ftm_rtc *dev, u32 reg, u32 val) 55 { 56 if (dev->big_endian) 57 iowrite32be(val, dev->base + reg); 58 else 59 iowrite32(val, dev->base + reg); 60 } 61 62 static inline void ftm_counter_enable(struct ftm_rtc *rtc) 63 { 64 u32 val; 65 66 /* select and enable counter clock source */ 67 val = rtc_readl(rtc, FTM_SC); 68 val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); 69 val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ)); 70 rtc_writel(rtc, FTM_SC, val); 71 } 72 73 static inline void ftm_counter_disable(struct ftm_rtc *rtc) 74 { 75 u32 val; 76 77 /* disable counter clock source */ 78 val = rtc_readl(rtc, FTM_SC); 79 val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); 80 rtc_writel(rtc, FTM_SC, val); 81 } 82 83 static inline void ftm_irq_acknowledge(struct ftm_rtc *rtc) 84 { 85 unsigned int timeout = 100; 86 87 /* 88 *Fix errata A-007728 for flextimer 89 * If the FTM counter reaches the FTM_MOD value between 90 * the reading of the TOF bit and the writing of 0 to 91 * the TOF bit, the process of clearing the TOF bit 92 * does not work as expected when FTMx_CONF[NUMTOF] != 0 93 * and the current TOF count is less than FTMx_CONF[NUMTOF]. 94 * If the above condition is met, the TOF bit remains set. 95 * If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1),the 96 * TOF interrupt also remains asserted. 97 * 98 * Above is the errata discription 99 * 100 * In one word: software clearing TOF bit not works when 101 * FTMx_CONF[NUMTOF] was seted as nonzero and FTM counter 102 * reaches the FTM_MOD value. 103 * 104 * The workaround is clearing TOF bit until it works 105 * (FTM counter doesn't always reache the FTM_MOD anyway), 106 * which may cost some cycles. 107 */ 108 while ((FTM_SC_TOF & rtc_readl(rtc, FTM_SC)) && timeout--) 109 rtc_writel(rtc, FTM_SC, rtc_readl(rtc, FTM_SC) & (~FTM_SC_TOF)); 110 } 111 112 static inline void ftm_irq_enable(struct ftm_rtc *rtc) 113 { 114 u32 val; 115 116 val = rtc_readl(rtc, FTM_SC); 117 val |= FTM_SC_TOIE; 118 rtc_writel(rtc, FTM_SC, val); 119 } 120 121 static inline void ftm_irq_disable(struct ftm_rtc *rtc) 122 { 123 u32 val; 124 125 val = rtc_readl(rtc, FTM_SC); 126 val &= ~FTM_SC_TOIE; 127 rtc_writel(rtc, FTM_SC, val); 128 } 129 130 static inline void ftm_reset_counter(struct ftm_rtc *rtc) 131 { 132 /* 133 * The CNT register contains the FTM counter value. 134 * Reset clears the CNT register. Writing any value to COUNT 135 * updates the counter with its initial value, CNTIN. 136 */ 137 rtc_writel(rtc, FTM_CNT, 0x00); 138 } 139 140 static void ftm_clean_alarm(struct ftm_rtc *rtc) 141 { 142 ftm_counter_disable(rtc); 143 144 rtc_writel(rtc, FTM_CNTIN, 0x00); 145 rtc_writel(rtc, FTM_MOD, ~0U); 146 147 ftm_reset_counter(rtc); 148 } 149 150 static irqreturn_t ftm_rtc_alarm_interrupt(int irq, void *dev) 151 { 152 struct ftm_rtc *rtc = dev; 153 154 ftm_irq_acknowledge(rtc); 155 ftm_irq_disable(rtc); 156 ftm_clean_alarm(rtc); 157 158 return IRQ_HANDLED; 159 } 160 161 static int ftm_rtc_alarm_irq_enable(struct device *dev, 162 unsigned int enabled) 163 { 164 struct ftm_rtc *rtc = dev_get_drvdata(dev); 165 166 if (enabled) 167 ftm_irq_enable(rtc); 168 else 169 ftm_irq_disable(rtc); 170 171 return 0; 172 } 173 174 /* 175 * Note: 176 * The function is not really getting time from the RTC 177 * since FlexTimer is not a RTC device, but we need to 178 * get time to setup alarm, so we are using system time 179 * for now. 180 */ 181 static int ftm_rtc_read_time(struct device *dev, struct rtc_time *tm) 182 { 183 struct timespec64 ts64; 184 185 ktime_get_real_ts64(&ts64); 186 rtc_time_to_tm(ts64.tv_sec, tm); 187 188 return 0; 189 } 190 191 static int ftm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 192 { 193 return 0; 194 } 195 196 /* 197 * 1. Select fixed frequency clock (32KHz) as clock source; 198 * 2. Select 128 (2^7) as divider factor; 199 * So clock is 250 Hz (32KHz/128). 200 * 201 * 3. FlexTimer's CNT register is a 32bit register, 202 * but the register's 16 bit as counter value,it's other 16 bit 203 * is reserved.So minimum counter value is 0x0,maximum counter 204 * value is 0xffff. 205 * So max alarm value is 262 (65536 / 250) seconds 206 */ 207 static int ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 208 { 209 struct rtc_time tm; 210 unsigned long now, alm_time, cycle; 211 struct ftm_rtc *rtc = dev_get_drvdata(dev); 212 213 ftm_rtc_read_time(dev, &tm); 214 rtc_tm_to_time(&tm, &now); 215 rtc_tm_to_time(&alm->time, &alm_time); 216 217 ftm_clean_alarm(rtc); 218 cycle = (alm_time - now) * rtc->alarm_freq; 219 if (cycle > MAX_COUNT_VAL) { 220 pr_err("Out of alarm range {0~262} seconds.\n"); 221 return -ERANGE; 222 } 223 224 ftm_irq_disable(rtc); 225 226 /* 227 * The counter increments until the value of MOD is reached, 228 * at which point the counter is reloaded with the value of CNTIN. 229 * The TOF (the overflow flag) bit is set when the FTM counter 230 * changes from MOD to CNTIN. So we should using the cycle - 1. 231 */ 232 rtc_writel(rtc, FTM_MOD, cycle - 1); 233 234 ftm_counter_enable(rtc); 235 ftm_irq_enable(rtc); 236 237 return 0; 238 239 } 240 241 static const struct rtc_class_ops ftm_rtc_ops = { 242 .read_time = ftm_rtc_read_time, 243 .read_alarm = ftm_rtc_read_alarm, 244 .set_alarm = ftm_rtc_set_alarm, 245 .alarm_irq_enable = ftm_rtc_alarm_irq_enable, 246 }; 247 248 static int ftm_rtc_probe(struct platform_device *pdev) 249 { 250 struct device_node *np = pdev->dev.of_node; 251 struct resource *r; 252 int irq; 253 int ret; 254 struct ftm_rtc *rtc; 255 256 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 257 if (unlikely(!rtc)) { 258 dev_err(&pdev->dev, "cannot alloc memory for rtc\n"); 259 return -ENOMEM; 260 } 261 262 platform_set_drvdata(pdev, rtc); 263 264 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 265 if (IS_ERR(rtc->rtc_dev)) 266 return PTR_ERR(rtc->rtc_dev); 267 268 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 269 if (!r) { 270 dev_err(&pdev->dev, "cannot get resource for rtc\n"); 271 return -ENODEV; 272 } 273 274 rtc->base = devm_ioremap_resource(&pdev->dev, r); 275 if (IS_ERR(rtc->base)) { 276 dev_err(&pdev->dev, "cannot ioremap resource for rtc\n"); 277 return PTR_ERR(rtc->base); 278 } 279 280 irq = irq_of_parse_and_map(np, 0); 281 if (irq <= 0) { 282 dev_err(&pdev->dev, "unable to get IRQ from DT, %d\n", irq); 283 return -EINVAL; 284 } 285 286 ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt, 287 IRQF_NO_SUSPEND, dev_name(&pdev->dev), rtc); 288 if (ret < 0) { 289 dev_err(&pdev->dev, "failed to request irq\n"); 290 return ret; 291 } 292 293 rtc->big_endian = of_property_read_bool(np, "big-endian"); 294 rtc->alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV; 295 rtc->rtc_dev->ops = &ftm_rtc_ops; 296 297 device_init_wakeup(&pdev->dev, true); 298 299 ret = rtc_register_device(rtc->rtc_dev); 300 if (ret) { 301 dev_err(&pdev->dev, "can't register rtc device\n"); 302 return ret; 303 } 304 305 return 0; 306 } 307 308 static const struct of_device_id ftm_rtc_match[] = { 309 { .compatible = "fsl,ls1012a-ftm-alarm", }, 310 { .compatible = "fsl,ls1021a-ftm-alarm", }, 311 { .compatible = "fsl,ls1028a-ftm-alarm", }, 312 { .compatible = "fsl,ls1043a-ftm-alarm", }, 313 { .compatible = "fsl,ls1046a-ftm-alarm", }, 314 { .compatible = "fsl,ls1088a-ftm-alarm", }, 315 { .compatible = "fsl,ls208xa-ftm-alarm", }, 316 { .compatible = "fsl,lx2160a-ftm-alarm", }, 317 { }, 318 }; 319 320 static struct platform_driver ftm_rtc_driver = { 321 .probe = ftm_rtc_probe, 322 .driver = { 323 .name = "ftm-alarm", 324 .of_match_table = ftm_rtc_match, 325 }, 326 }; 327 328 static int __init ftm_alarm_init(void) 329 { 330 return platform_driver_register(&ftm_rtc_driver); 331 } 332 333 device_initcall(ftm_alarm_init); 334 335 MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver"); 336 MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>"); 337 MODULE_LICENSE("GPL"); 338