1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2018 NXP. 4 */ 5 6 #include <dt-bindings/firmware/imx/rsrc.h> 7 #include <linux/arm-smccc.h> 8 #include <linux/firmware/imx/sci.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/rtc.h> 13 14 #define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9 15 #define IMX_SC_TIMER_FUNC_SET_RTC_ALARM 8 16 #define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6 17 18 #define IMX_SIP_SRTC 0xC2000002 19 #define IMX_SIP_SRTC_SET_TIME 0x0 20 21 #define SC_IRQ_GROUP_RTC 2 22 #define SC_IRQ_RTC 1 23 24 static struct imx_sc_ipc *rtc_ipc_handle; 25 static struct rtc_device *imx_sc_rtc; 26 27 struct imx_sc_msg_timer_get_rtc_time { 28 struct imx_sc_rpc_msg hdr; 29 u32 time; 30 } __packed; 31 32 struct imx_sc_msg_timer_rtc_set_alarm { 33 struct imx_sc_rpc_msg hdr; 34 u16 year; 35 u8 mon; 36 u8 day; 37 u8 hour; 38 u8 min; 39 u8 sec; 40 } __packed __aligned(4); 41 42 static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm) 43 { 44 struct imx_sc_msg_timer_get_rtc_time msg; 45 struct imx_sc_rpc_msg *hdr = &msg.hdr; 46 int ret; 47 48 hdr->ver = IMX_SC_RPC_VERSION; 49 hdr->svc = IMX_SC_RPC_SVC_TIMER; 50 hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970; 51 hdr->size = 1; 52 53 ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true); 54 if (ret) { 55 dev_err(dev, "read rtc time failed, ret %d\n", ret); 56 return ret; 57 } 58 59 rtc_time64_to_tm(msg.time, tm); 60 61 return 0; 62 } 63 64 static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm) 65 { 66 struct arm_smccc_res res; 67 68 /* pack 2 time parameters into 1 register, 16 bits for each */ 69 arm_smccc_smc(IMX_SIP_SRTC, IMX_SIP_SRTC_SET_TIME, 70 ((tm->tm_year + 1900) << 16) | (tm->tm_mon + 1), 71 (tm->tm_mday << 16) | tm->tm_hour, 72 (tm->tm_min << 16) | tm->tm_sec, 73 0, 0, 0, &res); 74 75 return res.a0; 76 } 77 78 static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) 79 { 80 return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable); 81 } 82 83 static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 84 { 85 struct imx_sc_msg_timer_rtc_set_alarm msg; 86 struct imx_sc_rpc_msg *hdr = &msg.hdr; 87 int ret; 88 struct rtc_time *alrm_tm = &alrm->time; 89 90 hdr->ver = IMX_SC_RPC_VERSION; 91 hdr->svc = IMX_SC_RPC_SVC_TIMER; 92 hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM; 93 hdr->size = 3; 94 95 msg.year = alrm_tm->tm_year + 1900; 96 msg.mon = alrm_tm->tm_mon + 1; 97 msg.day = alrm_tm->tm_mday; 98 msg.hour = alrm_tm->tm_hour; 99 msg.min = alrm_tm->tm_min; 100 msg.sec = alrm_tm->tm_sec; 101 102 ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true); 103 if (ret) { 104 dev_err(dev, "set rtc alarm failed, ret %d\n", ret); 105 return ret; 106 } 107 108 ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled); 109 if (ret) { 110 dev_err(dev, "enable rtc alarm failed, ret %d\n", ret); 111 return ret; 112 } 113 114 return 0; 115 } 116 117 static const struct rtc_class_ops imx_sc_rtc_ops = { 118 .read_time = imx_sc_rtc_read_time, 119 .set_time = imx_sc_rtc_set_time, 120 .set_alarm = imx_sc_rtc_set_alarm, 121 .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable, 122 }; 123 124 static int imx_sc_rtc_alarm_notify(struct notifier_block *nb, 125 unsigned long event, void *group) 126 { 127 /* ignore non-rtc irq */ 128 if (!((event & SC_IRQ_RTC) && (*(u8 *)group == SC_IRQ_GROUP_RTC))) 129 return 0; 130 131 rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF); 132 133 return 0; 134 } 135 136 static struct notifier_block imx_sc_rtc_alarm_sc_notifier = { 137 .notifier_call = imx_sc_rtc_alarm_notify, 138 }; 139 140 static int imx_sc_rtc_probe(struct platform_device *pdev) 141 { 142 int ret; 143 144 ret = imx_scu_get_handle(&rtc_ipc_handle); 145 if (ret) 146 return ret; 147 148 device_init_wakeup(&pdev->dev, true); 149 150 imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev); 151 if (IS_ERR(imx_sc_rtc)) 152 return PTR_ERR(imx_sc_rtc); 153 154 imx_sc_rtc->ops = &imx_sc_rtc_ops; 155 imx_sc_rtc->range_min = 0; 156 imx_sc_rtc->range_max = U32_MAX; 157 158 ret = devm_rtc_register_device(imx_sc_rtc); 159 if (ret) 160 return ret; 161 162 imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier); 163 164 return 0; 165 } 166 167 static const struct of_device_id imx_sc_dt_ids[] = { 168 { .compatible = "fsl,imx8qxp-sc-rtc", }, 169 {} 170 }; 171 MODULE_DEVICE_TABLE(of, imx_sc_dt_ids); 172 173 static struct platform_driver imx_sc_rtc_driver = { 174 .driver = { 175 .name = "imx-sc-rtc", 176 .of_match_table = imx_sc_dt_ids, 177 }, 178 .probe = imx_sc_rtc_probe, 179 }; 180 module_platform_driver(imx_sc_rtc_driver); 181 182 MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>"); 183 MODULE_DESCRIPTION("NXP i.MX System Controller RTC Driver"); 184 MODULE_LICENSE("GPL"); 185