RK3368 DDR: new ddr change freq method
[firefly-linux-kernel-4.4.55.git] / drivers / mailbox / scpi_protocol.c
1 /*
2  * System Control and Power Interface (SCPI) Message Protocol driver
3  *
4  * Copyright (C) 2014 ARM Ltd.
5  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
6  *
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.
10  *
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
14  * more details.
15  *
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/>.
18  */
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/scpi_protocol.h>
28 #include <linux/slab.h>
29 #include <linux/rockchip-mailbox.h>
30 #include <linux/rockchip/common.h>
31
32 #include "scpi_cmd.h"
33
34 #define CMD_ID_SHIFT            0
35 #define CMD_ID_MASK             0xff
36 #define CMD_SENDER_ID_SHIFT     8
37 #define CMD_SENDER_ID_MASK      0xff
38 #define CMD_DATA_SIZE_SHIFT     20
39 #define CMD_DATA_SIZE_MASK      0x1ff
40 #define PACK_SCPI_CMD(cmd, sender, txsz)                                \
41         ((((cmd) & CMD_ID_MASK) << CMD_ID_SHIFT) |                      \
42         (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) |      \
43         (((txsz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
44 #define SCPI_CMD_DEFAULT_TIMEOUT_MS  1000
45
46 #define MAX_DVFS_DOMAINS        3
47 #define MAX_DVFS_OPPS           8
48 #define DVFS_LATENCY(hdr)       ((hdr) >> 16)
49 #define DVFS_OPP_COUNT(hdr)     (((hdr) >> 8) & 0xff)
50
51 static int max_chan_num = 0;
52 static DECLARE_BITMAP(bm_mbox_chans, 4);
53 static DEFINE_MUTEX(scpi_mtx);
54
55 struct scpi_data_buf {
56         int client_id;
57         struct rockchip_mbox_msg *data;
58         struct completion complete;
59         int timeout_ms;
60 };
61
62 struct scpi_mcu_ver {
63         u32  scpi_ver;
64         char mcu_ver[16];
65 };
66
67 static int high_priority_cmds[] = {
68         SCPI_CMD_GET_CSS_PWR_STATE,
69         SCPI_CMD_CFG_PWR_STATE_STAT,
70         SCPI_CMD_GET_PWR_STATE_STAT,
71         SCPI_CMD_SET_DVFS,
72         SCPI_CMD_GET_DVFS,
73         SCPI_CMD_SET_RTC,
74         SCPI_CMD_GET_RTC,
75         SCPI_CMD_SET_CLOCK_INDEX,
76         SCPI_CMD_SET_CLOCK_VALUE,
77         SCPI_CMD_GET_CLOCK_VALUE,
78         SCPI_CMD_SET_PSU,
79         SCPI_CMD_GET_PSU,
80         SCPI_CMD_SENSOR_CFG_PERIODIC,
81         SCPI_CMD_SENSOR_CFG_BOUNDS,
82 };
83
84 static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
85
86 static struct device *the_scpi_device;
87
88 static int scpi_linux_errmap[SCPI_ERR_MAX] = {
89         0, -EINVAL, -ENOEXEC, -EMSGSIZE,
90         -EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
91         -ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
92 };
93
94 static inline int scpi_to_linux_errno(int errno)
95 {
96         if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
97                 return scpi_linux_errmap[errno];
98         return -EIO;
99 }
100
101 static bool __maybe_unused high_priority_chan_supported(int cmd)
102 {
103         int idx;
104
105         for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
106                 if (cmd == high_priority_cmds[idx])
107                         return true;
108         return false;
109 }
110
111 static int scpi_alloc_mbox_chan(void)
112 {
113         int index;
114
115         mutex_lock(&scpi_mtx);
116
117         index = find_first_zero_bit(bm_mbox_chans, max_chan_num);
118         if (index >= max_chan_num) {
119                 pr_err("alloc mailbox channel failed\n");
120                 mutex_unlock(&scpi_mtx);
121                 return -EBUSY;
122         }
123
124         set_bit(index, bm_mbox_chans);
125
126         mutex_unlock(&scpi_mtx);
127         return index;
128 }
129
130 static void scpi_free_mbox_chan(int chan)
131 {
132         int index = chan;
133
134         mutex_lock(&scpi_mtx);
135
136         if (index < max_chan_num && index >= 0)
137                 clear_bit(index, bm_mbox_chans);
138
139         mutex_unlock(&scpi_mtx);
140 }
141
142 static void scpi_rx_callback(struct mbox_client *cl, void *msg)
143 {
144         struct rockchip_mbox_msg *data = (struct rockchip_mbox_msg *)msg;
145         struct scpi_data_buf *scpi_buf = data->cl_data;
146
147         complete(&scpi_buf->complete);
148 }
149
150 static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
151 {
152         struct mbox_chan *chan;
153         struct mbox_client cl;
154         struct rockchip_mbox_msg *data = scpi_buf->data;
155         u32 status;
156         int ret;
157         int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
158
159         if (!the_scpi_device) {
160                 pr_err("Scpi initializes unsuccessfully\n");
161                 return -EIO;
162         }
163
164         cl.dev = the_scpi_device;
165         cl.rx_callback = scpi_rx_callback;
166         cl.tx_done = NULL;
167         cl.tx_block = false;
168         cl.knows_txdone = false;
169
170         chan = mbox_request_channel(&cl, index);
171         if (IS_ERR(chan)) {
172                 scpi_free_mbox_chan(index);
173                 return PTR_ERR(chan);
174         }
175
176         init_completion(&scpi_buf->complete);
177         if (mbox_send_message(chan, (void *)data) < 0) {
178                 status = SCPI_ERR_TIMEOUT;
179                 goto free_channel;
180         }
181
182         ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
183         if (ret == 0) {
184                 status = SCPI_ERR_TIMEOUT;
185                 goto free_channel;
186         }
187         status = *(u32 *)(data->rx_buf); /* read first word */
188
189 free_channel:
190         mbox_free_channel(chan);
191         scpi_free_mbox_chan(index);
192
193         return scpi_to_linux_errno(status);
194 }
195
196 #define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
197                         _cmd, _tx_buf, _rx_buf) \
198 do {                                            \
199         struct rockchip_mbox_msg *pdata = &mbox_buf;    \
200         pdata->cmd = _cmd;                      \
201         pdata->tx_buf = &_tx_buf;               \
202         pdata->tx_size = sizeof(_tx_buf);       \
203         pdata->rx_buf = &_rx_buf;               \
204         pdata->rx_size = sizeof(_rx_buf);       \
205         scpi_buf.client_id = _client_id;        \
206         scpi_buf.data = pdata;                  \
207         scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
208 } while (0)
209
210 static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
211 {
212         struct rockchip_mbox_msg *data;
213         int index;
214
215         if (!scpi_buf || !scpi_buf->data)
216                 return -EINVAL;
217
218         index = scpi_alloc_mbox_chan();
219         if (index < 0)
220                 return -EBUSY;
221
222         data = scpi_buf->data;
223         data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
224                                   data->tx_size);
225         data->cl_data = scpi_buf;
226
227         return send_scpi_cmd(scpi_buf, index);
228 }
229
230 unsigned long scpi_clk_get_val(u16 clk_id)
231 {
232         struct scpi_data_buf sdata;
233         struct rockchip_mbox_msg mdata;
234         struct __packed {
235                 u32 status;
236                 u32 clk_rate;
237         } buf;
238
239         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
240                         SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
241         if (scpi_execute_cmd(&sdata))
242                 return 0;
243
244         return buf.clk_rate;
245 }
246 EXPORT_SYMBOL_GPL(scpi_clk_get_val);
247
248 int scpi_clk_set_val(u16 clk_id, unsigned long rate)
249 {
250         struct scpi_data_buf sdata;
251         struct rockchip_mbox_msg mdata;
252         int stat;
253         struct __packed {
254                 u32 clk_rate;
255                 u16 clk_id;
256         } buf;
257
258         buf.clk_rate = (u32)rate;
259         buf.clk_id = clk_id;
260
261         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
262                         SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
263         return scpi_execute_cmd(&sdata);
264 }
265 EXPORT_SYMBOL_GPL(scpi_clk_set_val);
266
267 struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
268 {
269         struct scpi_data_buf sdata;
270         struct rockchip_mbox_msg mdata;
271         struct __packed {
272                 u32 status;
273                 u32 header;
274                 struct scpi_opp_entry opp[MAX_DVFS_OPPS];
275         } buf;
276         struct scpi_opp *opps;
277         size_t opps_sz;
278         int count, ret;
279
280         if (domain >= MAX_DVFS_DOMAINS)
281                 return ERR_PTR(-EINVAL);
282
283         if (scpi_opps[domain])  /* data already populated */
284                 return scpi_opps[domain];
285
286         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
287                         SCPI_CMD_GET_DVFS_INFO, domain, buf);
288         ret = scpi_execute_cmd(&sdata);
289         if (ret)
290                 return ERR_PTR(ret);
291
292         opps = kmalloc(sizeof(*opps), GFP_KERNEL);
293         if (!opps)
294                 return ERR_PTR(-ENOMEM);
295
296         count = DVFS_OPP_COUNT(buf.header);
297         opps_sz = count * sizeof(*(opps->opp));
298
299         opps->count = count;
300         opps->latency = DVFS_LATENCY(buf.header);
301         opps->opp = kmalloc(opps_sz, GFP_KERNEL);
302         if (!opps->opp) {
303                 kfree(opps);
304                 return ERR_PTR(-ENOMEM);
305         }
306
307         memcpy(opps->opp, &buf.opp[0], opps_sz);
308         scpi_opps[domain] = opps;
309
310         return opps;
311 }
312 EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
313
314 int scpi_dvfs_get_idx(u8 domain)
315 {
316         struct scpi_data_buf sdata;
317         struct rockchip_mbox_msg mdata;
318         struct __packed {
319                 u32 status;
320                 u8 dvfs_idx;
321         } buf;
322         int ret;
323
324         if (domain >= MAX_DVFS_DOMAINS)
325                 return -EINVAL;
326
327         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
328                         SCPI_CMD_GET_DVFS, domain, buf);
329         ret = scpi_execute_cmd(&sdata);
330
331         if (!ret)
332                 ret = buf.dvfs_idx;
333         return ret;
334 }
335 EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
336
337 int scpi_dvfs_set_idx(u8 domain, u8 idx)
338 {
339         struct scpi_data_buf sdata;
340         struct rockchip_mbox_msg mdata;
341         struct __packed {
342                 u8 dvfs_domain;
343                 u8 dvfs_idx;
344         } buf;
345         int stat;
346
347         buf.dvfs_idx = idx;
348         buf.dvfs_domain = domain;
349
350         if (domain >= MAX_DVFS_DOMAINS)
351                 return -EINVAL;
352
353         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
354                         SCPI_CMD_SET_DVFS, buf, stat);
355         return scpi_execute_cmd(&sdata);
356 }
357 EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
358
359 int scpi_get_sensor(char *name)
360 {
361         struct scpi_data_buf sdata;
362         struct rockchip_mbox_msg mdata;
363         struct __packed {
364                 u32 status;
365                 u16 sensors;
366         } cap_buf;
367         struct __packed {
368                 u32 status;
369                 u16 sensor;
370                 u8 class;
371                 u8 trigger;
372                 char name[20];
373         } info_buf;
374         int ret;
375         u16 sensor_id;
376
377         /* This should be handled by a generic macro */
378         do {
379                 struct rockchip_mbox_msg *pdata = &mdata;
380
381                 pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
382                 pdata->tx_size = 0;
383                 pdata->rx_buf = &cap_buf;
384                 pdata->rx_size = sizeof(cap_buf);
385                 sdata.client_id = SCPI_CL_THERMAL;
386                 sdata.data = pdata;
387         } while (0);
388
389         ret = scpi_execute_cmd(&sdata);
390         if (ret)
391                 goto out;
392
393         ret = -ENODEV;
394         for (sensor_id = 0; sensor_id < cap_buf.sensors; sensor_id++) {
395                 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
396                                 SCPI_CMD_SENSOR_INFO, sensor_id, info_buf);
397                 ret = scpi_execute_cmd(&sdata);
398                 if (ret)
399                         break;
400
401                 if (!strcmp(name, info_buf.name)) {
402                         ret = sensor_id;
403                         break;
404                 }
405         }
406 out:
407         return ret;
408 }
409 EXPORT_SYMBOL_GPL(scpi_get_sensor);
410
411 int scpi_get_sensor_value(u16 sensor, u32 *val)
412 {
413         struct scpi_data_buf sdata;
414         struct rockchip_mbox_msg mdata;
415         struct __packed {
416                 u32 status;
417                 u32 val;
418         } buf;
419         int ret;
420
421         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
422                         sensor, buf);
423
424         ret = scpi_execute_cmd(&sdata);
425         if (ret)
426                 *val = buf.val;
427
428         return ret;
429 }
430 EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
431
432 static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
433 {
434         int ret;
435         struct scpi_data_buf sdata;
436         struct rockchip_mbox_msg mdata;
437         struct __packed {
438                 u32 status;
439                 struct scpi_mcu_ver version;
440         } buf;
441
442         memset(&buf, 0, sizeof(buf));
443         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
444                         old, buf);
445
446         ret = scpi_execute_cmd(&sdata);
447         if (ret) {
448                 pr_err("get scpi version from MCU failed, ret=%d\n", ret);
449                 goto OUT;
450         }
451
452         memcpy(ver, &(buf.version), sizeof(*ver));
453
454 OUT:
455         return ret;
456 }
457
458 int scpi_sys_set_mcu_state_suspend(void)
459 {
460         struct scpi_data_buf sdata;
461         struct rockchip_mbox_msg mdata;
462         struct __packed1 {
463                 u32 status;
464         } tx_buf;
465         struct __packed2 {
466                 u32 status;
467         } rx_buf;
468
469         tx_buf.status = 0;
470         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
471                         SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
472         return scpi_execute_cmd(&sdata);
473 }
474 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
475
476 int scpi_sys_set_mcu_state_resume(void)
477 {
478         struct scpi_data_buf sdata;
479         struct rockchip_mbox_msg mdata;
480         struct __packed1 {
481                 u32 status;
482         } tx_buf;
483         struct __packed2 {
484                 u32 status;
485         } rx_buf;
486
487         tx_buf.status = 0;
488
489         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
490                         SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
491         return scpi_execute_cmd(&sdata);
492 }
493 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
494
495 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
496 {
497         struct scpi_data_buf sdata;
498         struct rockchip_mbox_msg mdata;
499         struct __packed1 {
500                 u32 dram_speed_bin;
501                 u32 freq;
502                 u32 lcdc_type;
503                 u32 addr_mcu_el3;
504         } tx_buf;
505         struct __packed2 {
506                 u32 status;
507         } rx_buf;
508
509         tx_buf.dram_speed_bin = (u32)dram_speed_bin;
510         tx_buf.freq = (u32)freq;
511         tx_buf.lcdc_type = (u32)lcdc_type;
512         tx_buf.addr_mcu_el3 = addr_mcu_el3;
513         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
514                         SCPI_DDR_INIT, tx_buf, rx_buf);
515         return scpi_execute_cmd(&sdata);
516 }
517 EXPORT_SYMBOL_GPL(scpi_ddr_init);
518
519 int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
520 {
521         struct scpi_data_buf sdata;
522         struct rockchip_mbox_msg mdata;
523         struct __packed1 {
524                 u32 clk_rate;
525                 u32 lcdc_type;
526         } tx_buf;
527         struct __packed2 {
528                 u32 status;
529         } rx_buf;
530
531         tx_buf.clk_rate = (u32)rate;
532         tx_buf.lcdc_type = (u32)lcdc_type;
533         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
534                         SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
535         return scpi_execute_cmd(&sdata);
536 }
537 EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
538
539 int scpi_ddr_round_rate(u32 m_hz)
540 {
541         struct scpi_data_buf sdata;
542         struct rockchip_mbox_msg mdata;
543         struct __packed1 {
544                 u32 clk_rate;
545         } tx_buf;
546         struct __packed2 {
547                 u32 status;
548                 u32 round_rate;
549         } rx_buf;
550
551         tx_buf.clk_rate = (u32)m_hz;
552
553         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
554                         SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
555         if (scpi_execute_cmd(&sdata))
556                 return 0;
557
558         return rx_buf.round_rate;
559 }
560 EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
561
562 int scpi_ddr_set_auto_self_refresh(u32 en)
563 {
564         struct scpi_data_buf sdata;
565         struct rockchip_mbox_msg mdata;
566         struct __packed1 {
567                 u32 enable;
568         } tx_buf;
569         struct __packed2 {
570                 u32 status;
571         } rx_buf;
572
573         tx_buf.enable = (u32)en;
574
575         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
576                         SCPI_DDR_AUTO_SELF_REFRESH, tx_buf, rx_buf);
577         return scpi_execute_cmd(&sdata);
578 }
579 EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
580
581 int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,
582                            struct ddr_bw_info *ddr_bw_ch1)
583 {
584         struct scpi_data_buf sdata;
585         struct rockchip_mbox_msg mdata;
586         struct __packed1 {
587                 u32 status;
588         } tx_buf;
589         struct __packed2 {
590                 u32 status;
591                 struct ddr_bw_info ddr_bw_ch0;
592                 struct ddr_bw_info ddr_bw_ch1;
593         } rx_buf;
594
595         tx_buf.status = 0;
596
597         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
598                         SCPI_DDR_BANDWIDTH_GET, tx_buf, rx_buf);
599         if (scpi_execute_cmd(&sdata))
600                 return 0;
601
602         memcpy(ddr_bw_ch0, &(rx_buf.ddr_bw_ch0), sizeof(rx_buf.ddr_bw_ch0));
603         memcpy(ddr_bw_ch1, &(rx_buf.ddr_bw_ch1), sizeof(rx_buf.ddr_bw_ch1));
604
605         return 0;
606 }
607 EXPORT_SYMBOL_GPL(scpi_ddr_bandwidth_get);
608
609 int scpi_ddr_get_clk_rate(void)
610 {
611         struct scpi_data_buf sdata;
612         struct rockchip_mbox_msg mdata;
613         struct __packed1 {
614                 u32 status;
615         } tx_buf;
616         struct __packed2 {
617                 u32 status;
618                 u32 clk_rate;
619         } rx_buf;
620
621         tx_buf.status = 0;
622         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
623                         SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
624         if (scpi_execute_cmd(&sdata))
625                 return 0;
626
627         return rx_buf.clk_rate;
628 }
629 EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
630
631 int scpi_thermal_get_temperature(void)
632 {
633         int ret;
634         struct scpi_data_buf sdata;
635         struct rockchip_mbox_msg mdata;
636         struct __packed1 {
637                 u32 status;
638         } tx_buf;
639
640         struct __packed2 {
641                 u32 status;
642                 u32 tsadc_data;
643         } rx_buf;
644
645         tx_buf.status = 0;
646         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
647                         SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
648
649         ret = scpi_execute_cmd(&sdata);
650         if (ret) {
651                 pr_err("get temperature from MCU failed, ret=%d\n", ret);
652                 return ret;
653         }
654
655         return rx_buf.tsadc_data;
656 }
657 EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
658
659 int scpi_thermal_set_clk_cycle(u32 cycle)
660 {
661         struct scpi_data_buf sdata;
662         struct rockchip_mbox_msg mdata;
663         struct __packed1 {
664                 u32 clk_cycle;
665         } tx_buf;
666
667         struct __packed2 {
668                 u32 status;
669         } rx_buf;
670
671         tx_buf.clk_cycle = cycle;
672         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
673                         SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
674
675         return scpi_execute_cmd(&sdata);
676 }
677 EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
678
679 static struct of_device_id mobx_scpi_of_match[] = {
680         { .compatible = "rockchip,mbox-scpi"},
681         { },
682 };
683 MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
684
685 static int mobx_scpi_probe(struct platform_device *pdev)
686 {
687         int ret = 0;
688         int retry = 3;
689         int val = 0;
690         struct scpi_mcu_ver mcu_ver;
691         int check_version = 1; /*0: not check version, 1: check version*/
692
693         the_scpi_device = &pdev->dev;
694
695         /* try to get mboxes chan nums from DT */
696         if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
697                 dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
698                 ret = -EINVAL;
699                 goto exit;
700         }
701
702         max_chan_num = val;
703
704         /* try to check up with SCPI version from MCU */
705         while ((retry--) && (check_version != 0)) {
706                 memset(&mcu_ver, 0, sizeof(mcu_ver));
707
708                 ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
709                 if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
710                         break;
711         }
712
713         if ((retry <= 0) && (check_version != 0)) {
714                 dev_err(&pdev->dev,
715                         "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
716                         SCPI_VERSION, mcu_ver.scpi_ver, ret);
717                 ret = -EIO;
718                 goto exit;
719         }
720
721         dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
722                  mcu_ver.scpi_ver, val);
723         dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
724
725         return 0;
726 exit:
727         the_scpi_device = NULL;
728         return ret;
729 }
730
731 static struct platform_driver mbox_scpi_driver = {
732         .probe  = mobx_scpi_probe,
733         .driver = {
734                 .name = "mbox-scpi",
735                 .of_match_table = of_match_ptr(mobx_scpi_of_match),
736         },
737 };
738
739 static int __init rockchip_mbox_scpi_init(void)
740 {
741         return platform_driver_register(&mbox_scpi_driver);
742 }
743 subsys_initcall(rockchip_mbox_scpi_init);