2 * System Control and Power Interface (SCPI) Message Protocol driver
4 * Copyright (C) 2014 ARM Ltd.
5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/err.h>
22 #include <linux/export.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/printk.h>
26 #include <linux/mailbox_client.h>
27 #include <linux/slab.h>
28 #include <linux/rockchip/scpi.h>
29 #include <linux/rockchip/rk3368-mailbox.h>
31 #define SCPI_VERSION 0x01000002 /* version: 1.0.0.2 */
33 #define CMD_ID_SHIFT 0
34 #define CMD_ID_MASK 0xff
35 #define CMD_SENDER_ID_SHIFT 8
36 #define CMD_SENDER_ID_MASK 0xff
37 #define CMD_DATA_SIZE_SHIFT 20
38 #define CMD_DATA_SIZE_MASK 0x1ff
39 #define PACK_SCPI_CMD(cmd, sender, txsz) \
40 ((((cmd) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
41 (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \
42 (((txsz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
43 #define SCPI_CMD_DEFAULT_TIMEOUT_MS 1000
45 #define MAX_DVFS_DOMAINS 3
46 #define MAX_DVFS_OPPS 8
47 #define DVFS_LATENCY(hdr) ((hdr) >> 16)
48 #define DVFS_OPP_COUNT(hdr) (((hdr) >> 8) & 0xff)
50 static int max_chan_num = 0;
51 static DECLARE_BITMAP(bm_mbox_chans, 4);
52 static DEFINE_MUTEX(scpi_mtx);
54 enum scpi_error_codes {
55 SCPI_SUCCESS = 0, /* Success */
56 SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
57 SCPI_ERR_ALIGN = 2, /* Invalid alignment */
58 SCPI_ERR_SIZE = 3, /* Invalid size */
59 SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
60 SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
61 SCPI_ERR_RANGE = 6, /* Value out of range */
62 SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
63 SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
64 SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
65 SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
66 SCPI_ERR_DEVICE = 11, /* Device error */
85 SCPI_DDR_AUTO_SELF_REFRESH,
86 SCPI_DDR_BANDWIDTH_GET,
93 SCPI_SYS_REFRESH_MCU_FREQ,
94 SCPI_SYS_SET_MCU_STATE_SUSPEND,
95 SCPI_SYS_SET_MCU_STATE_RESUME,
96 SCPI_SYS_SET_JTAGMUX_ON_OFF,
100 SCPI_CMD_INVALID = 0x00,
101 SCPI_CMD_SCPI_READY = 0x01,
102 SCPI_CMD_SCPI_CAPABILITIES = 0x02,
103 SCPI_CMD_EVENT = 0x03,
104 SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
105 SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
106 SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
107 SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
108 SCPI_CMD_SYS_PWR_STATE = 0x08,
109 SCPI_CMD_L2_READY = 0x09,
110 SCPI_CMD_SET_AP_TIMER = 0x0a,
111 SCPI_CMD_CANCEL_AP_TIME = 0x0b,
112 SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
113 SCPI_CMD_GET_DVFS_INFO = 0x0d,
114 SCPI_CMD_SET_DVFS = 0x0e,
115 SCPI_CMD_GET_DVFS = 0x0f,
116 SCPI_CMD_GET_DVFS_STAT = 0x10,
117 SCPI_CMD_SET_RTC = 0x11,
118 SCPI_CMD_GET_RTC = 0x12,
119 SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
120 SCPI_CMD_SET_CLOCK_INDEX = 0x14,
121 SCPI_CMD_SET_CLOCK_VALUE = 0x15,
122 SCPI_CMD_GET_CLOCK_VALUE = 0x16,
123 SCPI_CMD_PSU_CAPABILITIES = 0x17,
124 SCPI_CMD_SET_PSU = 0x18,
125 SCPI_CMD_GET_PSU = 0x19,
126 SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
127 SCPI_CMD_SENSOR_INFO = 0x1b,
128 SCPI_CMD_SENSOR_VALUE = 0x1c,
129 SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
130 SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
131 SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
135 enum scpi_thermal_cmd {
136 SCPI_THERMAL_GET_TSADC_DATA,
137 SCPI_THERMAL_SET_TSADC_CYCLE,
141 static int high_priority_cmds[] = {
142 SCPI_CMD_GET_CSS_PWR_STATE,
143 SCPI_CMD_CFG_PWR_STATE_STAT,
144 SCPI_CMD_GET_PWR_STATE_STAT,
149 SCPI_CMD_SET_CLOCK_INDEX,
150 SCPI_CMD_SET_CLOCK_VALUE,
151 SCPI_CMD_GET_CLOCK_VALUE,
154 SCPI_CMD_SENSOR_CFG_PERIODIC,
155 SCPI_CMD_SENSOR_CFG_BOUNDS,
158 struct scpi_data_buf {
160 struct rk3368_mbox_msg *data;
161 struct completion complete;
165 struct scpi_mcu_ver {
170 static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
172 static struct device *the_scpi_device;
174 static int scpi_linux_errmap[SCPI_ERR_MAX] = {
175 0, -EINVAL, -ENOEXEC, -EMSGSIZE,
176 -EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
177 -ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
180 static inline int scpi_to_linux_errno(int errno)
182 if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
183 return scpi_linux_errmap[errno];
187 static bool __maybe_unused high_priority_chan_supported(int cmd)
191 for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
192 if (cmd == high_priority_cmds[idx])
197 static int scpi_alloc_mbox_chan(void)
201 mutex_lock(&scpi_mtx);
203 index = find_first_zero_bit(bm_mbox_chans, max_chan_num);
204 if (index >= max_chan_num) {
205 pr_err("alloc mailbox channel failed\n");
206 mutex_unlock(&scpi_mtx);
210 set_bit(index, bm_mbox_chans);
212 mutex_unlock(&scpi_mtx);
216 static void scpi_free_mbox_chan(int chan)
220 mutex_lock(&scpi_mtx);
222 if (index < max_chan_num && index >= 0)
223 clear_bit(index, bm_mbox_chans);
225 mutex_unlock(&scpi_mtx);
228 static void scpi_rx_callback(struct mbox_client *cl, void *msg)
230 struct rk3368_mbox_msg *data = (struct rk3368_mbox_msg *)msg;
231 struct scpi_data_buf *scpi_buf = data->cl_data;
233 complete(&scpi_buf->complete);
236 static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
238 struct mbox_chan *chan;
239 struct mbox_client cl;
240 struct rk3368_mbox_msg *data = scpi_buf->data;
243 int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
245 if (!the_scpi_device) {
246 pr_err("Scpi initializes unsuccessfully\n");
250 cl.dev = the_scpi_device;
251 cl.rx_callback = scpi_rx_callback;
253 cl.tx_prepare = NULL;
255 cl.knows_txdone = false;
257 chan = mbox_request_channel(&cl, index);
259 scpi_free_mbox_chan(index);
260 return PTR_ERR(chan);
263 init_completion(&scpi_buf->complete);
264 if (mbox_send_message(chan, (void *)data) < 0) {
265 status = SCPI_ERR_TIMEOUT;
269 ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
271 status = SCPI_ERR_TIMEOUT;
274 status = *(u32 *)(data->rx_buf); /* read first word */
277 mbox_free_channel(chan);
278 scpi_free_mbox_chan(index);
280 return scpi_to_linux_errno(status);
283 #define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
284 _cmd, _tx_buf, _rx_buf) \
286 struct rk3368_mbox_msg *pdata = &mbox_buf; \
288 pdata->tx_buf = &_tx_buf; \
289 pdata->tx_size = sizeof(_tx_buf); \
290 pdata->rx_buf = &_rx_buf; \
291 pdata->rx_size = sizeof(_rx_buf); \
292 scpi_buf.client_id = _client_id; \
293 scpi_buf.data = pdata; \
294 scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
297 #define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id, \
298 _cmd, _tx_buf, _tx_size, _rx_buf) \
300 struct rk3368_mbox_msg *pdata = &mbox_buf; \
302 pdata->tx_buf = _tx_buf; \
303 pdata->tx_size = _tx_size; \
304 pdata->rx_buf = &_rx_buf; \
305 pdata->rx_size = sizeof(_rx_buf); \
306 scpi_buf.client_id = _client_id; \
307 scpi_buf.data = pdata; \
308 scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
311 static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
313 struct rk3368_mbox_msg *data;
316 if (!scpi_buf || !scpi_buf->data)
319 index = scpi_alloc_mbox_chan();
323 data = scpi_buf->data;
324 data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
326 data->cl_data = scpi_buf;
328 return send_scpi_cmd(scpi_buf, index);
331 unsigned long scpi_clk_get_val(u16 clk_id)
333 struct scpi_data_buf sdata;
334 struct rk3368_mbox_msg mdata;
340 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
341 SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
342 if (scpi_execute_cmd(&sdata))
347 EXPORT_SYMBOL_GPL(scpi_clk_get_val);
349 int scpi_clk_set_val(u16 clk_id, unsigned long rate)
351 struct scpi_data_buf sdata;
352 struct rk3368_mbox_msg mdata;
359 buf.clk_rate = (u32)rate;
362 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
363 SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
364 return scpi_execute_cmd(&sdata);
366 EXPORT_SYMBOL_GPL(scpi_clk_set_val);
368 struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
370 struct scpi_data_buf sdata;
371 struct rk3368_mbox_msg mdata;
375 struct scpi_opp_entry opp[MAX_DVFS_OPPS];
377 struct scpi_opp *opps;
381 if (domain >= MAX_DVFS_DOMAINS)
382 return ERR_PTR(-EINVAL);
384 if (scpi_opps[domain]) /* data already populated */
385 return scpi_opps[domain];
387 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
388 SCPI_CMD_GET_DVFS_INFO, domain, buf);
389 ret = scpi_execute_cmd(&sdata);
393 opps = kmalloc(sizeof(*opps), GFP_KERNEL);
395 return ERR_PTR(-ENOMEM);
397 count = DVFS_OPP_COUNT(buf.header);
398 opps_sz = count * sizeof(*(opps->opp));
401 opps->latency = DVFS_LATENCY(buf.header);
402 opps->opp = kmalloc(opps_sz, GFP_KERNEL);
405 return ERR_PTR(-ENOMEM);
408 memcpy(opps->opp, &buf.opp[0], opps_sz);
409 scpi_opps[domain] = opps;
413 EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
415 int scpi_dvfs_get_idx(u8 domain)
417 struct scpi_data_buf sdata;
418 struct rk3368_mbox_msg mdata;
425 if (domain >= MAX_DVFS_DOMAINS)
428 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
429 SCPI_CMD_GET_DVFS, domain, buf);
430 ret = scpi_execute_cmd(&sdata);
436 EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
438 int scpi_dvfs_set_idx(u8 domain, u8 idx)
440 struct scpi_data_buf sdata;
441 struct rk3368_mbox_msg mdata;
449 buf.dvfs_domain = domain;
451 if (domain >= MAX_DVFS_DOMAINS)
454 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
455 SCPI_CMD_SET_DVFS, buf, stat);
456 return scpi_execute_cmd(&sdata);
458 EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
460 int scpi_get_sensor(char *name)
462 struct scpi_data_buf sdata;
463 struct rk3368_mbox_msg mdata;
478 /* This should be handled by a generic macro */
480 struct rk3368_mbox_msg *pdata = &mdata;
482 pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
484 pdata->rx_buf = &cap_buf;
485 pdata->rx_size = sizeof(cap_buf);
486 sdata.client_id = SCPI_CL_THERMAL;
490 ret = scpi_execute_cmd(&sdata);
495 for (sensor_id = 0; sensor_id < cap_buf.sensors; sensor_id++) {
496 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
497 SCPI_CMD_SENSOR_INFO, sensor_id, info_buf);
498 ret = scpi_execute_cmd(&sdata);
502 if (!strcmp(name, info_buf.name)) {
510 EXPORT_SYMBOL_GPL(scpi_get_sensor);
512 int scpi_get_sensor_value(u16 sensor, u32 *val)
514 struct scpi_data_buf sdata;
515 struct rk3368_mbox_msg mdata;
522 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
525 ret = scpi_execute_cmd(&sdata);
531 EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
533 static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
536 struct scpi_data_buf sdata;
537 struct rk3368_mbox_msg mdata;
540 struct scpi_mcu_ver version;
543 memset(&buf, 0, sizeof(buf));
544 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
547 ret = scpi_execute_cmd(&sdata);
549 pr_err("get scpi version from MCU failed, ret=%d\n", ret);
553 memcpy(ver, &(buf.version), sizeof(*ver));
559 int scpi_sys_set_mcu_state_suspend(void)
561 struct scpi_data_buf sdata;
562 struct rk3368_mbox_msg mdata;
571 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
572 SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
573 return scpi_execute_cmd(&sdata);
575 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
577 int scpi_sys_set_mcu_state_resume(void)
579 struct scpi_data_buf sdata;
580 struct rk3368_mbox_msg mdata;
590 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
591 SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
592 return scpi_execute_cmd(&sdata);
594 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
596 int scpi_sys_set_jtagmux_on_off(u32 en)
599 struct scpi_data_buf sdata;
600 struct rk3368_mbox_msg mdata;
610 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
611 SCPI_SYS_SET_JTAGMUX_ON_OFF, tx_buf, rx_buf);
613 ret = scpi_execute_cmd(&sdata);
615 pr_err("set jtagmux on-off failed, ret=%d\n", ret);
621 EXPORT_SYMBOL_GPL(scpi_sys_set_jtagmux_on_off);
623 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
625 struct scpi_data_buf sdata;
626 struct rk3368_mbox_msg mdata;
637 tx_buf.dram_speed_bin = (u32)dram_speed_bin;
638 tx_buf.freq = (u32)freq;
639 tx_buf.lcdc_type = (u32)lcdc_type;
640 tx_buf.addr_mcu_el3 = addr_mcu_el3;
641 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
642 SCPI_DDR_INIT, tx_buf, rx_buf);
643 return scpi_execute_cmd(&sdata);
645 EXPORT_SYMBOL_GPL(scpi_ddr_init);
647 int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
649 struct scpi_data_buf sdata;
650 struct rk3368_mbox_msg mdata;
659 tx_buf.clk_rate = (u32)rate;
660 tx_buf.lcdc_type = (u32)lcdc_type;
661 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
662 SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
663 return scpi_execute_cmd(&sdata);
665 EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
667 int scpi_ddr_send_timing(u32 *p, u32 size)
669 struct scpi_data_buf sdata;
670 struct rk3368_mbox_msg mdata;
674 SCPI_SETUP_DBUF_BY_SIZE(sdata, mdata, SCPI_CL_DDR,
675 SCPI_DDR_SEND_TIMING, p, size, rx_buf);
676 return scpi_execute_cmd(&sdata);
678 EXPORT_SYMBOL_GPL(scpi_ddr_send_timing);
680 int scpi_ddr_round_rate(u32 m_hz)
682 struct scpi_data_buf sdata;
683 struct rk3368_mbox_msg mdata;
692 tx_buf.clk_rate = (u32)m_hz;
694 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
695 SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
696 if (scpi_execute_cmd(&sdata))
699 return rx_buf.round_rate;
701 EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
703 int scpi_ddr_set_auto_self_refresh(u32 en)
705 struct scpi_data_buf sdata;
706 struct rk3368_mbox_msg mdata;
714 tx_buf.enable = (u32)en;
716 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
717 SCPI_DDR_AUTO_SELF_REFRESH, tx_buf, rx_buf);
718 return scpi_execute_cmd(&sdata);
720 EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
722 int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,
723 struct ddr_bw_info *ddr_bw_ch1)
725 struct scpi_data_buf sdata;
726 struct rk3368_mbox_msg mdata;
732 struct ddr_bw_info ddr_bw_ch0;
733 struct ddr_bw_info ddr_bw_ch1;
738 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
739 SCPI_DDR_BANDWIDTH_GET, tx_buf, rx_buf);
740 if (scpi_execute_cmd(&sdata))
743 memcpy(ddr_bw_ch0, &(rx_buf.ddr_bw_ch0), sizeof(rx_buf.ddr_bw_ch0));
744 memcpy(ddr_bw_ch1, &(rx_buf.ddr_bw_ch1), sizeof(rx_buf.ddr_bw_ch1));
748 EXPORT_SYMBOL_GPL(scpi_ddr_bandwidth_get);
750 int scpi_ddr_get_clk_rate(void)
752 struct scpi_data_buf sdata;
753 struct rk3368_mbox_msg mdata;
763 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
764 SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
765 if (scpi_execute_cmd(&sdata))
768 return rx_buf.clk_rate;
770 EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
772 int scpi_thermal_get_temperature(void)
775 struct scpi_data_buf sdata;
776 struct rk3368_mbox_msg mdata;
787 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
788 SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
790 ret = scpi_execute_cmd(&sdata);
792 pr_err("get temperature from MCU failed, ret=%d\n", ret);
796 return rx_buf.tsadc_data;
798 EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
800 int scpi_thermal_set_clk_cycle(u32 cycle)
802 struct scpi_data_buf sdata;
803 struct rk3368_mbox_msg mdata;
812 tx_buf.clk_cycle = cycle;
813 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
814 SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
816 return scpi_execute_cmd(&sdata);
818 EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
820 static struct of_device_id mobx_scpi_of_match[] = {
821 { .compatible = "rockchip,rk3368-scpi-legacy"},
824 MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
826 static int mobx_scpi_probe(struct platform_device *pdev)
831 struct scpi_mcu_ver mcu_ver;
832 int check_version = 1; /*0: not check version, 1: check version*/
834 the_scpi_device = &pdev->dev;
836 /* try to get mboxes chan nums from DT */
837 if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
838 dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
845 /* try to check up with SCPI version from MCU */
846 while ((retry--) && (check_version != 0)) {
847 memset(&mcu_ver, 0, sizeof(mcu_ver));
849 ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
850 if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
854 if ((retry <= 0) && (check_version != 0)) {
856 "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
857 SCPI_VERSION, mcu_ver.scpi_ver, ret);
862 dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
866 dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
870 the_scpi_device = NULL;
874 static struct platform_driver mbox_scpi_driver = {
875 .probe = mobx_scpi_probe,
878 .of_match_table = of_match_ptr(mobx_scpi_of_match),
882 static int __init rockchip_mbox_scpi_init(void)
884 return platform_driver_register(&mbox_scpi_driver);
886 subsys_initcall(rockchip_mbox_scpi_init);