0001
0002
0003
0004
0005
0006 #include <dt-bindings/firmware/imx/rsrc.h>
0007 #include <linux/arm-smccc.h>
0008 #include <linux/firmware/imx/sci.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/rtc.h>
0013
0014 #define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9
0015 #define IMX_SC_TIMER_FUNC_SET_RTC_ALARM 8
0016 #define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6
0017
0018 #define IMX_SIP_SRTC 0xC2000002
0019 #define IMX_SIP_SRTC_SET_TIME 0x0
0020
0021 #define SC_IRQ_GROUP_RTC 2
0022 #define SC_IRQ_RTC 1
0023
0024 static struct imx_sc_ipc *rtc_ipc_handle;
0025 static struct rtc_device *imx_sc_rtc;
0026
0027 struct imx_sc_msg_timer_get_rtc_time {
0028 struct imx_sc_rpc_msg hdr;
0029 u32 time;
0030 } __packed;
0031
0032 struct imx_sc_msg_timer_rtc_set_alarm {
0033 struct imx_sc_rpc_msg hdr;
0034 u16 year;
0035 u8 mon;
0036 u8 day;
0037 u8 hour;
0038 u8 min;
0039 u8 sec;
0040 } __packed __aligned(4);
0041
0042 static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
0043 {
0044 struct imx_sc_msg_timer_get_rtc_time msg;
0045 struct imx_sc_rpc_msg *hdr = &msg.hdr;
0046 int ret;
0047
0048 hdr->ver = IMX_SC_RPC_VERSION;
0049 hdr->svc = IMX_SC_RPC_SVC_TIMER;
0050 hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970;
0051 hdr->size = 1;
0052
0053 ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
0054 if (ret) {
0055 dev_err(dev, "read rtc time failed, ret %d\n", ret);
0056 return ret;
0057 }
0058
0059 rtc_time64_to_tm(msg.time, tm);
0060
0061 return 0;
0062 }
0063
0064 static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm)
0065 {
0066 struct arm_smccc_res res;
0067
0068
0069 arm_smccc_smc(IMX_SIP_SRTC, IMX_SIP_SRTC_SET_TIME,
0070 ((tm->tm_year + 1900) << 16) | (tm->tm_mon + 1),
0071 (tm->tm_mday << 16) | tm->tm_hour,
0072 (tm->tm_min << 16) | tm->tm_sec,
0073 0, 0, 0, &res);
0074
0075 return res.a0;
0076 }
0077
0078 static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
0079 {
0080 return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable);
0081 }
0082
0083 static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0084 {
0085 struct imx_sc_msg_timer_rtc_set_alarm msg;
0086 struct imx_sc_rpc_msg *hdr = &msg.hdr;
0087 int ret;
0088 struct rtc_time *alrm_tm = &alrm->time;
0089
0090 hdr->ver = IMX_SC_RPC_VERSION;
0091 hdr->svc = IMX_SC_RPC_SVC_TIMER;
0092 hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM;
0093 hdr->size = 3;
0094
0095 msg.year = alrm_tm->tm_year + 1900;
0096 msg.mon = alrm_tm->tm_mon + 1;
0097 msg.day = alrm_tm->tm_mday;
0098 msg.hour = alrm_tm->tm_hour;
0099 msg.min = alrm_tm->tm_min;
0100 msg.sec = alrm_tm->tm_sec;
0101
0102 ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
0103 if (ret) {
0104 dev_err(dev, "set rtc alarm failed, ret %d\n", ret);
0105 return ret;
0106 }
0107
0108 ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled);
0109 if (ret) {
0110 dev_err(dev, "enable rtc alarm failed, ret %d\n", ret);
0111 return ret;
0112 }
0113
0114 return 0;
0115 }
0116
0117 static const struct rtc_class_ops imx_sc_rtc_ops = {
0118 .read_time = imx_sc_rtc_read_time,
0119 .set_time = imx_sc_rtc_set_time,
0120 .set_alarm = imx_sc_rtc_set_alarm,
0121 .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
0122 };
0123
0124 static int imx_sc_rtc_alarm_notify(struct notifier_block *nb,
0125 unsigned long event, void *group)
0126 {
0127
0128 if (!((event & SC_IRQ_RTC) && (*(u8 *)group == SC_IRQ_GROUP_RTC)))
0129 return 0;
0130
0131 rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF);
0132
0133 return 0;
0134 }
0135
0136 static struct notifier_block imx_sc_rtc_alarm_sc_notifier = {
0137 .notifier_call = imx_sc_rtc_alarm_notify,
0138 };
0139
0140 static int imx_sc_rtc_probe(struct platform_device *pdev)
0141 {
0142 int ret;
0143
0144 ret = imx_scu_get_handle(&rtc_ipc_handle);
0145 if (ret)
0146 return ret;
0147
0148 device_init_wakeup(&pdev->dev, true);
0149
0150 imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
0151 if (IS_ERR(imx_sc_rtc))
0152 return PTR_ERR(imx_sc_rtc);
0153
0154 imx_sc_rtc->ops = &imx_sc_rtc_ops;
0155 imx_sc_rtc->range_min = 0;
0156 imx_sc_rtc->range_max = U32_MAX;
0157
0158 ret = devm_rtc_register_device(imx_sc_rtc);
0159 if (ret)
0160 return ret;
0161
0162 imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier);
0163
0164 return 0;
0165 }
0166
0167 static const struct of_device_id imx_sc_dt_ids[] = {
0168 { .compatible = "fsl,imx8qxp-sc-rtc", },
0169 {}
0170 };
0171 MODULE_DEVICE_TABLE(of, imx_sc_dt_ids);
0172
0173 static struct platform_driver imx_sc_rtc_driver = {
0174 .driver = {
0175 .name = "imx-sc-rtc",
0176 .of_match_table = imx_sc_dt_ids,
0177 },
0178 .probe = imx_sc_rtc_probe,
0179 };
0180 module_platform_driver(imx_sc_rtc_driver);
0181
0182 MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
0183 MODULE_DESCRIPTION("NXP i.MX System Controller RTC Driver");
0184 MODULE_LICENSE("GPL");