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 rtc_time64_to_tm(ktime_get_real_seconds(), tm); 184 185 return 0; 186 } 187 188 static int ftm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 189 { 190 return 0; 191 } 192 193 /* 194 * 1. Select fixed frequency clock (32KHz) as clock source; 195 * 2. Select 128 (2^7) as divider factor; 196 * So clock is 250 Hz (32KHz/128). 197 * 198 * 3. FlexTimer's CNT register is a 32bit register, 199 * but the register's 16 bit as counter value,it's other 16 bit 200 * is reserved.So minimum counter value is 0x0,maximum counter 201 * value is 0xffff. 202 * So max alarm value is 262 (65536 / 250) seconds 203 */ 204 static int ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 205 { 206 time64_t alm_time; 207 unsigned long long cycle; 208 struct ftm_rtc *rtc = dev_get_drvdata(dev); 209 210 alm_time = rtc_tm_to_time64(&alm->time); 211 212 ftm_clean_alarm(rtc); 213 cycle = (alm_time - ktime_get_real_seconds()) * rtc->alarm_freq; 214 if (cycle > MAX_COUNT_VAL) { 215 pr_err("Out of alarm range {0~262} seconds.\n"); 216 return -ERANGE; 217 } 218 219 ftm_irq_disable(rtc); 220 221 /* 222 * The counter increments until the value of MOD is reached, 223 * at which point the counter is reloaded with the value of CNTIN. 224 * The TOF (the overflow flag) bit is set when the FTM counter 225 * changes from MOD to CNTIN. So we should using the cycle - 1. 226 */ 227 rtc_writel(rtc, FTM_MOD, cycle - 1); 228 229 ftm_counter_enable(rtc); 230 ftm_irq_enable(rtc); 231 232 return 0; 233 234 } 235 236 static const struct rtc_class_ops ftm_rtc_ops = { 237 .read_time = ftm_rtc_read_time, 238 .read_alarm = ftm_rtc_read_alarm, 239 .set_alarm = ftm_rtc_set_alarm, 240 .alarm_irq_enable = ftm_rtc_alarm_irq_enable, 241 }; 242 243 static int ftm_rtc_probe(struct platform_device *pdev) 244 { 245 struct device_node *np = pdev->dev.of_node; 246 int irq; 247 int ret; 248 struct ftm_rtc *rtc; 249 250 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 251 if (unlikely(!rtc)) { 252 dev_err(&pdev->dev, "cannot alloc memory for rtc\n"); 253 return -ENOMEM; 254 } 255 256 platform_set_drvdata(pdev, rtc); 257 258 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 259 if (IS_ERR(rtc->rtc_dev)) 260 return PTR_ERR(rtc->rtc_dev); 261 262 rtc->base = devm_platform_ioremap_resource(pdev, 0); 263 if (IS_ERR(rtc->base)) { 264 dev_err(&pdev->dev, "cannot ioremap resource for rtc\n"); 265 return PTR_ERR(rtc->base); 266 } 267 268 irq = irq_of_parse_and_map(np, 0); 269 if (irq <= 0) { 270 dev_err(&pdev->dev, "unable to get IRQ from DT, %d\n", irq); 271 return -EINVAL; 272 } 273 274 ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt, 275 IRQF_NO_SUSPEND, dev_name(&pdev->dev), rtc); 276 if (ret < 0) { 277 dev_err(&pdev->dev, "failed to request irq\n"); 278 return ret; 279 } 280 281 rtc->big_endian = of_property_read_bool(np, "big-endian"); 282 rtc->alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV; 283 rtc->rtc_dev->ops = &ftm_rtc_ops; 284 285 device_init_wakeup(&pdev->dev, true); 286 287 ret = rtc_register_device(rtc->rtc_dev); 288 if (ret) { 289 dev_err(&pdev->dev, "can't register rtc device\n"); 290 return ret; 291 } 292 293 return 0; 294 } 295 296 static const struct of_device_id ftm_rtc_match[] = { 297 { .compatible = "fsl,ls1012a-ftm-alarm", }, 298 { .compatible = "fsl,ls1021a-ftm-alarm", }, 299 { .compatible = "fsl,ls1028a-ftm-alarm", }, 300 { .compatible = "fsl,ls1043a-ftm-alarm", }, 301 { .compatible = "fsl,ls1046a-ftm-alarm", }, 302 { .compatible = "fsl,ls1088a-ftm-alarm", }, 303 { .compatible = "fsl,ls208xa-ftm-alarm", }, 304 { .compatible = "fsl,lx2160a-ftm-alarm", }, 305 { }, 306 }; 307 308 static struct platform_driver ftm_rtc_driver = { 309 .probe = ftm_rtc_probe, 310 .driver = { 311 .name = "ftm-alarm", 312 .of_match_table = ftm_rtc_match, 313 }, 314 }; 315 316 static int __init ftm_alarm_init(void) 317 { 318 return platform_driver_register(&ftm_rtc_driver); 319 } 320 321 device_initcall(ftm_alarm_init); 322 323 MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver"); 324 MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>"); 325 MODULE_LICENSE("GPL"); 326