xref: /openbmc/linux/drivers/rtc/rtc-imx-sc.c (revision e01b5781958de08942af341ce26768d5e0fbcdf5)
1*e01b5781SAnson Huang // SPDX-License-Identifier: GPL-2.0+
2*e01b5781SAnson Huang /*
3*e01b5781SAnson Huang  * Copyright 2018 NXP.
4*e01b5781SAnson Huang  */
5*e01b5781SAnson Huang 
6*e01b5781SAnson Huang #include <linux/firmware/imx/sci.h>
7*e01b5781SAnson Huang #include <linux/module.h>
8*e01b5781SAnson Huang #include <linux/of.h>
9*e01b5781SAnson Huang #include <linux/platform_device.h>
10*e01b5781SAnson Huang #include <linux/rtc.h>
11*e01b5781SAnson Huang 
12*e01b5781SAnson Huang #define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970	9
13*e01b5781SAnson Huang #define IMX_SC_TIMER_FUNC_SET_RTC_TIME		6
14*e01b5781SAnson Huang 
15*e01b5781SAnson Huang static struct imx_sc_ipc *rtc_ipc_handle;
16*e01b5781SAnson Huang static struct rtc_device *imx_sc_rtc;
17*e01b5781SAnson Huang 
18*e01b5781SAnson Huang struct imx_sc_msg_timer_get_rtc_time {
19*e01b5781SAnson Huang 	struct imx_sc_rpc_msg hdr;
20*e01b5781SAnson Huang 	u32 time;
21*e01b5781SAnson Huang } __packed;
22*e01b5781SAnson Huang 
23*e01b5781SAnson Huang static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
24*e01b5781SAnson Huang {
25*e01b5781SAnson Huang 	struct imx_sc_msg_timer_get_rtc_time msg;
26*e01b5781SAnson Huang 	struct imx_sc_rpc_msg *hdr = &msg.hdr;
27*e01b5781SAnson Huang 	int ret;
28*e01b5781SAnson Huang 
29*e01b5781SAnson Huang 	hdr->ver = IMX_SC_RPC_VERSION;
30*e01b5781SAnson Huang 	hdr->svc = IMX_SC_RPC_SVC_TIMER;
31*e01b5781SAnson Huang 	hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970;
32*e01b5781SAnson Huang 	hdr->size = 1;
33*e01b5781SAnson Huang 
34*e01b5781SAnson Huang 	ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
35*e01b5781SAnson Huang 	if (ret) {
36*e01b5781SAnson Huang 		dev_err(dev, "read rtc time failed, ret %d\n", ret);
37*e01b5781SAnson Huang 		return ret;
38*e01b5781SAnson Huang 	}
39*e01b5781SAnson Huang 
40*e01b5781SAnson Huang 	rtc_time_to_tm(msg.time, tm);
41*e01b5781SAnson Huang 
42*e01b5781SAnson Huang 	return 0;
43*e01b5781SAnson Huang }
44*e01b5781SAnson Huang 
45*e01b5781SAnson Huang static const struct rtc_class_ops imx_sc_rtc_ops = {
46*e01b5781SAnson Huang 	.read_time = imx_sc_rtc_read_time,
47*e01b5781SAnson Huang };
48*e01b5781SAnson Huang 
49*e01b5781SAnson Huang static int imx_sc_rtc_probe(struct platform_device *pdev)
50*e01b5781SAnson Huang {
51*e01b5781SAnson Huang 	int ret;
52*e01b5781SAnson Huang 
53*e01b5781SAnson Huang 	ret = imx_scu_get_handle(&rtc_ipc_handle);
54*e01b5781SAnson Huang 	if (ret)
55*e01b5781SAnson Huang 		return ret;
56*e01b5781SAnson Huang 
57*e01b5781SAnson Huang 	imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
58*e01b5781SAnson Huang 	if (IS_ERR(imx_sc_rtc))
59*e01b5781SAnson Huang 		return PTR_ERR(imx_sc_rtc);
60*e01b5781SAnson Huang 
61*e01b5781SAnson Huang 	imx_sc_rtc->ops = &imx_sc_rtc_ops;
62*e01b5781SAnson Huang 	imx_sc_rtc->range_min = 0;
63*e01b5781SAnson Huang 	imx_sc_rtc->range_max = U32_MAX;
64*e01b5781SAnson Huang 
65*e01b5781SAnson Huang 	ret = rtc_register_device(imx_sc_rtc);
66*e01b5781SAnson Huang 	if (ret) {
67*e01b5781SAnson Huang 		dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
68*e01b5781SAnson Huang 		return ret;
69*e01b5781SAnson Huang 	}
70*e01b5781SAnson Huang 
71*e01b5781SAnson Huang 	return 0;
72*e01b5781SAnson Huang }
73*e01b5781SAnson Huang 
74*e01b5781SAnson Huang static const struct of_device_id imx_sc_dt_ids[] = {
75*e01b5781SAnson Huang 	{ .compatible = "fsl,imx8qxp-sc-rtc", },
76*e01b5781SAnson Huang 	{}
77*e01b5781SAnson Huang };
78*e01b5781SAnson Huang MODULE_DEVICE_TABLE(of, imx_sc_dt_ids);
79*e01b5781SAnson Huang 
80*e01b5781SAnson Huang static struct platform_driver imx_sc_rtc_driver = {
81*e01b5781SAnson Huang 	.driver = {
82*e01b5781SAnson Huang 		.name	= "imx-sc-rtc",
83*e01b5781SAnson Huang 		.of_match_table = imx_sc_dt_ids,
84*e01b5781SAnson Huang 	},
85*e01b5781SAnson Huang 	.probe		= imx_sc_rtc_probe,
86*e01b5781SAnson Huang };
87*e01b5781SAnson Huang module_platform_driver(imx_sc_rtc_driver);
88*e01b5781SAnson Huang 
89*e01b5781SAnson Huang MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
90*e01b5781SAnson Huang MODULE_DESCRIPTION("NXP i.MX System Controller RTC Driver");
91*e01b5781SAnson Huang MODULE_LICENSE("GPL");
92