Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: zynqmp: Write Calibration value before setting time

It is suggested to program CALIB_WRITE register with the calibration
value before updating the SET_TIME_WRITE register, doing so will
clear the Tick Counter and force the next second to be signaled
exactly in 1 second.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

authored by

Anurag Kumar Vulisha and committed by
Alexandre Belloni
58c4ed3b 9092984f

+14 -7
+14 -7
drivers/rtc/rtc-zynqmp.c
··· 56 56 void __iomem *reg_base; 57 57 int alarm_irq; 58 58 int sec_irq; 59 + int calibval; 59 60 }; 60 61 61 62 static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) ··· 68 67 69 68 if (new_time > RTC_SEC_MAX_VAL) 70 69 return -EINVAL; 70 + 71 + /* 72 + * Writing into calibration register will clear the Tick Counter and 73 + * force the next second to be signaled exactly in 1 second period 74 + */ 75 + xrtcdev->calibval &= RTC_CALIB_MASK; 76 + writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); 71 77 72 78 writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); 73 79 ··· 129 121 return 0; 130 122 } 131 123 132 - static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) 124 + static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev) 133 125 { 134 126 u32 rtc_ctrl; 135 127 ··· 144 136 * to default value suggested as per design spec 145 137 * to correct RTC delay in frequency over period of time. 146 138 */ 147 - calibval &= RTC_CALIB_MASK; 148 - writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); 139 + xrtcdev->calibval &= RTC_CALIB_MASK; 140 + writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); 149 141 } 150 142 151 143 static const struct rtc_class_ops xlnx_rtc_ops = { ··· 182 174 struct xlnx_rtc_dev *xrtcdev; 183 175 struct resource *res; 184 176 int ret; 185 - unsigned int calibvalue; 186 177 187 178 xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); 188 179 if (!xrtcdev) ··· 222 215 } 223 216 224 217 ret = of_property_read_u32(pdev->dev.of_node, "calibration", 225 - &calibvalue); 218 + &xrtcdev->calibval); 226 219 if (ret) 227 - calibvalue = RTC_CALIB_DEF; 220 + xrtcdev->calibval = RTC_CALIB_DEF; 228 221 229 - xlnx_init_rtc(xrtcdev, calibvalue); 222 + xlnx_init_rtc(xrtcdev); 230 223 231 224 device_init_wakeup(&pdev->dev, 1); 232 225