Merge tag 'v4.4-rc5'
[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 #define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id,         \
211                                 _cmd, _tx_buf, _tx_size, _rx_buf)       \
212 do {                                                                    \
213         struct rockchip_mbox_msg *pdata = &mbox_buf;                    \
214         pdata->cmd = _cmd;                                              \
215         pdata->tx_buf = _tx_buf;                                        \
216         pdata->tx_size = _tx_size;                                      \
217         pdata->rx_buf = &_rx_buf;                                       \
218         pdata->rx_size = sizeof(_rx_buf);                               \
219         scpi_buf.client_id = _client_id;                                \
220         scpi_buf.data = pdata;                                          \
221         scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS;              \
222 } while (0)
223
224 static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
225 {
226         struct rockchip_mbox_msg *data;
227         int index;
228
229         if (!scpi_buf || !scpi_buf->data)
230                 return -EINVAL;
231
232         index = scpi_alloc_mbox_chan();
233         if (index < 0)
234                 return -EBUSY;
235
236         data = scpi_buf->data;
237         data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
238                                   data->tx_size);
239         data->cl_data = scpi_buf;
240
241         return send_scpi_cmd(scpi_buf, index);
242 }
243
244 unsigned long scpi_clk_get_val(u16 clk_id)
245 {
246         struct scpi_data_buf sdata;
247         struct rockchip_mbox_msg mdata;
248         struct __packed {
249                 u32 status;
250                 u32 clk_rate;
251         } buf;
252
253         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
254                         SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
255         if (scpi_execute_cmd(&sdata))
256                 return 0;
257
258         return buf.clk_rate;
259 }
260 EXPORT_SYMBOL_GPL(scpi_clk_get_val);
261
262 int scpi_clk_set_val(u16 clk_id, unsigned long rate)
263 {
264         struct scpi_data_buf sdata;
265         struct rockchip_mbox_msg mdata;
266         int stat;
267         struct __packed {
268                 u32 clk_rate;
269                 u16 clk_id;
270         } buf;
271
272         buf.clk_rate = (u32)rate;
273         buf.clk_id = clk_id;
274
275         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
276                         SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
277         return scpi_execute_cmd(&sdata);
278 }
279 EXPORT_SYMBOL_GPL(scpi_clk_set_val);
280
281 struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
282 {
283         struct scpi_data_buf sdata;
284         struct rockchip_mbox_msg mdata;
285         struct __packed {
286                 u32 status;
287                 u32 header;
288                 struct scpi_opp_entry opp[MAX_DVFS_OPPS];
289         } buf;
290         struct scpi_opp *opps;
291         size_t opps_sz;
292         int count, ret;
293
294         if (domain >= MAX_DVFS_DOMAINS)
295                 return ERR_PTR(-EINVAL);
296
297         if (scpi_opps[domain])  /* data already populated */
298                 return scpi_opps[domain];
299
300         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
301                         SCPI_CMD_GET_DVFS_INFO, domain, buf);
302         ret = scpi_execute_cmd(&sdata);
303         if (ret)
304                 return ERR_PTR(ret);
305
306         opps = kmalloc(sizeof(*opps), GFP_KERNEL);
307         if (!opps)
308                 return ERR_PTR(-ENOMEM);
309
310         count = DVFS_OPP_COUNT(buf.header);
311         opps_sz = count * sizeof(*(opps->opp));
312
313         opps->count = count;
314         opps->latency = DVFS_LATENCY(buf.header);
315         opps->opp = kmalloc(opps_sz, GFP_KERNEL);
316         if (!opps->opp) {
317                 kfree(opps);
318                 return ERR_PTR(-ENOMEM);
319         }
320
321         memcpy(opps->opp, &buf.opp[0], opps_sz);
322         scpi_opps[domain] = opps;
323
324         return opps;
325 }
326 EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
327
328 int scpi_dvfs_get_idx(u8 domain)
329 {
330         struct scpi_data_buf sdata;
331         struct rockchip_mbox_msg mdata;
332         struct __packed {
333                 u32 status;
334                 u8 dvfs_idx;
335         } buf;
336         int ret;
337
338         if (domain >= MAX_DVFS_DOMAINS)
339                 return -EINVAL;
340
341         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
342                         SCPI_CMD_GET_DVFS, domain, buf);
343         ret = scpi_execute_cmd(&sdata);
344
345         if (!ret)
346                 ret = buf.dvfs_idx;
347         return ret;
348 }
349 EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
350
351 int scpi_dvfs_set_idx(u8 domain, u8 idx)
352 {
353         struct scpi_data_buf sdata;
354         struct rockchip_mbox_msg mdata;
355         struct __packed {
356                 u8 dvfs_domain;
357                 u8 dvfs_idx;
358         } buf;
359         int stat;
360
361         buf.dvfs_idx = idx;
362         buf.dvfs_domain = domain;
363
364         if (domain >= MAX_DVFS_DOMAINS)
365                 return -EINVAL;
366
367         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
368                         SCPI_CMD_SET_DVFS, buf, stat);
369         return scpi_execute_cmd(&sdata);
370 }
371 EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
372
373 int scpi_get_sensor(char *name)
374 {
375         struct scpi_data_buf sdata;
376         struct rockchip_mbox_msg mdata;
377         struct __packed {
378                 u32 status;
379                 u16 sensors;
380         } cap_buf;
381         struct __packed {
382                 u32 status;
383                 u16 sensor;
384                 u8 class;
385                 u8 trigger;
386                 char name[20];
387         } info_buf;
388         int ret;
389         u16 sensor_id;
390
391         /* This should be handled by a generic macro */
392         do {
393                 struct rockchip_mbox_msg *pdata = &mdata;
394
395                 pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
396                 pdata->tx_size = 0;
397                 pdata->rx_buf = &cap_buf;
398                 pdata->rx_size = sizeof(cap_buf);
399                 sdata.client_id = SCPI_CL_THERMAL;
400                 sdata.data = pdata;
401         } while (0);
402
403         ret = scpi_execute_cmd(&sdata);
404         if (ret)
405                 goto out;
406
407         ret = -ENODEV;
408         for (sensor_id = 0; sensor_id < cap_buf.sensors; sensor_id++) {
409                 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
410                                 SCPI_CMD_SENSOR_INFO, sensor_id, info_buf);
411                 ret = scpi_execute_cmd(&sdata);
412                 if (ret)
413                         break;
414
415                 if (!strcmp(name, info_buf.name)) {
416                         ret = sensor_id;
417                         break;
418                 }
419         }
420 out:
421         return ret;
422 }
423 EXPORT_SYMBOL_GPL(scpi_get_sensor);
424
425 int scpi_get_sensor_value(u16 sensor, u32 *val)
426 {
427         struct scpi_data_buf sdata;
428         struct rockchip_mbox_msg mdata;
429         struct __packed {
430                 u32 status;
431                 u32 val;
432         } buf;
433         int ret;
434
435         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
436                         sensor, buf);
437
438         ret = scpi_execute_cmd(&sdata);
439         if (ret)
440                 *val = buf.val;
441
442         return ret;
443 }
444 EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
445
446 static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
447 {
448         int ret;
449         struct scpi_data_buf sdata;
450         struct rockchip_mbox_msg mdata;
451         struct __packed {
452                 u32 status;
453                 struct scpi_mcu_ver version;
454         } buf;
455
456         memset(&buf, 0, sizeof(buf));
457         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
458                         old, buf);
459
460         ret = scpi_execute_cmd(&sdata);
461         if (ret) {
462                 pr_err("get scpi version from MCU failed, ret=%d\n", ret);
463                 goto OUT;
464         }
465
466         memcpy(ver, &(buf.version), sizeof(*ver));
467
468 OUT:
469         return ret;
470 }
471
472 int scpi_sys_set_mcu_state_suspend(void)
473 {
474         struct scpi_data_buf sdata;
475         struct rockchip_mbox_msg mdata;
476         struct __packed1 {
477                 u32 status;
478         } tx_buf;
479         struct __packed2 {
480                 u32 status;
481         } rx_buf;
482
483         tx_buf.status = 0;
484         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
485                         SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
486         return scpi_execute_cmd(&sdata);
487 }
488 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
489
490 int scpi_sys_set_mcu_state_resume(void)
491 {
492         struct scpi_data_buf sdata;
493         struct rockchip_mbox_msg mdata;
494         struct __packed1 {
495                 u32 status;
496         } tx_buf;
497         struct __packed2 {
498                 u32 status;
499         } rx_buf;
500
501         tx_buf.status = 0;
502
503         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
504                         SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
505         return scpi_execute_cmd(&sdata);
506 }
507 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
508
509 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
510 {
511         struct scpi_data_buf sdata;
512         struct rockchip_mbox_msg mdata;
513         struct __packed1 {
514                 u32 dram_speed_bin;
515                 u32 freq;
516                 u32 lcdc_type;
517                 u32 addr_mcu_el3;
518         } tx_buf;
519         struct __packed2 {
520                 u32 status;
521         } rx_buf;
522
523         tx_buf.dram_speed_bin = (u32)dram_speed_bin;
524         tx_buf.freq = (u32)freq;
525         tx_buf.lcdc_type = (u32)lcdc_type;
526         tx_buf.addr_mcu_el3 = addr_mcu_el3;
527         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
528                         SCPI_DDR_INIT, tx_buf, rx_buf);
529         return scpi_execute_cmd(&sdata);
530 }
531 EXPORT_SYMBOL_GPL(scpi_ddr_init);
532
533 int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
534 {
535         struct scpi_data_buf sdata;
536         struct rockchip_mbox_msg mdata;
537         struct __packed1 {
538                 u32 clk_rate;
539                 u32 lcdc_type;
540         } tx_buf;
541         struct __packed2 {
542                 u32 status;
543         } rx_buf;
544
545         tx_buf.clk_rate = (u32)rate;
546         tx_buf.lcdc_type = (u32)lcdc_type;
547         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
548                         SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
549         return scpi_execute_cmd(&sdata);
550 }
551 EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
552
553 int scpi_ddr_send_timing(u32 *p, u32 size)
554 {
555         struct scpi_data_buf sdata;
556         struct rockchip_mbox_msg mdata;
557         struct __packed2 {
558                 u32 status;
559         } rx_buf;
560         SCPI_SETUP_DBUF_BY_SIZE(sdata, mdata, SCPI_CL_DDR,
561                                 SCPI_DDR_SEND_TIMING, p, size, rx_buf);
562         return scpi_execute_cmd(&sdata);
563 }
564 EXPORT_SYMBOL_GPL(scpi_ddr_send_timing);
565
566 int scpi_ddr_round_rate(u32 m_hz)
567 {
568         struct scpi_data_buf sdata;
569         struct rockchip_mbox_msg mdata;
570         struct __packed1 {
571                 u32 clk_rate;
572         } tx_buf;
573         struct __packed2 {
574                 u32 status;
575                 u32 round_rate;
576         } rx_buf;
577
578         tx_buf.clk_rate = (u32)m_hz;
579
580         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
581                         SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
582         if (scpi_execute_cmd(&sdata))
583                 return 0;
584
585         return rx_buf.round_rate;
586 }
587 EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
588
589 int scpi_ddr_set_auto_self_refresh(u32 en)
590 {
591         struct scpi_data_buf sdata;
592         struct rockchip_mbox_msg mdata;
593         struct __packed1 {
594                 u32 enable;
595         } tx_buf;
596         struct __packed2 {
597                 u32 status;
598         } rx_buf;
599
600         tx_buf.enable = (u32)en;
601
602         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
603                         SCPI_DDR_AUTO_SELF_REFRESH, tx_buf, rx_buf);
604         return scpi_execute_cmd(&sdata);
605 }
606 EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
607
608 int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,
609                            struct ddr_bw_info *ddr_bw_ch1)
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                 struct ddr_bw_info ddr_bw_ch0;
619                 struct ddr_bw_info ddr_bw_ch1;
620         } rx_buf;
621
622         tx_buf.status = 0;
623
624         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
625                         SCPI_DDR_BANDWIDTH_GET, tx_buf, rx_buf);
626         if (scpi_execute_cmd(&sdata))
627                 return 0;
628
629         memcpy(ddr_bw_ch0, &(rx_buf.ddr_bw_ch0), sizeof(rx_buf.ddr_bw_ch0));
630         memcpy(ddr_bw_ch1, &(rx_buf.ddr_bw_ch1), sizeof(rx_buf.ddr_bw_ch1));
631
632         return 0;
633 }
634 EXPORT_SYMBOL_GPL(scpi_ddr_bandwidth_get);
635
636 int scpi_ddr_get_clk_rate(void)
637 {
638         struct scpi_data_buf sdata;
639         struct rockchip_mbox_msg mdata;
640         struct __packed1 {
641                 u32 status;
642         } tx_buf;
643         struct __packed2 {
644                 u32 status;
645                 u32 clk_rate;
646         } rx_buf;
647
648         tx_buf.status = 0;
649         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
650                         SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
651         if (scpi_execute_cmd(&sdata))
652                 return 0;
653
654         return rx_buf.clk_rate;
655 }
656 EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
657
658 int scpi_thermal_get_temperature(void)
659 {
660         int ret;
661         struct scpi_data_buf sdata;
662         struct rockchip_mbox_msg mdata;
663         struct __packed1 {
664                 u32 status;
665         } tx_buf;
666
667         struct __packed2 {
668                 u32 status;
669                 u32 tsadc_data;
670         } rx_buf;
671
672         tx_buf.status = 0;
673         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
674                         SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
675
676         ret = scpi_execute_cmd(&sdata);
677         if (ret) {
678                 pr_err("get temperature from MCU failed, ret=%d\n", ret);
679                 return ret;
680         }
681
682         return rx_buf.tsadc_data;
683 }
684 EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
685
686 int scpi_thermal_set_clk_cycle(u32 cycle)
687 {
688         struct scpi_data_buf sdata;
689         struct rockchip_mbox_msg mdata;
690         struct __packed1 {
691                 u32 clk_cycle;
692         } tx_buf;
693
694         struct __packed2 {
695                 u32 status;
696         } rx_buf;
697
698         tx_buf.clk_cycle = cycle;
699         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
700                         SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
701
702         return scpi_execute_cmd(&sdata);
703 }
704 EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
705
706 static struct of_device_id mobx_scpi_of_match[] = {
707         { .compatible = "rockchip,mbox-scpi"},
708         { },
709 };
710 MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
711
712 static int mobx_scpi_probe(struct platform_device *pdev)
713 {
714         int ret = 0;
715         int retry = 3;
716         int val = 0;
717         struct scpi_mcu_ver mcu_ver;
718         int check_version = 1; /*0: not check version, 1: check version*/
719
720         the_scpi_device = &pdev->dev;
721
722         /* try to get mboxes chan nums from DT */
723         if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
724                 dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
725                 ret = -EINVAL;
726                 goto exit;
727         }
728
729         max_chan_num = val;
730
731         /* try to check up with SCPI version from MCU */
732         while ((retry--) && (check_version != 0)) {
733                 memset(&mcu_ver, 0, sizeof(mcu_ver));
734
735                 ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
736                 if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
737                         break;
738         }
739
740         if ((retry <= 0) && (check_version != 0)) {
741                 dev_err(&pdev->dev,
742                         "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
743                         SCPI_VERSION, mcu_ver.scpi_ver, ret);
744                 ret = -EIO;
745                 goto exit;
746         }
747
748         dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
749                  mcu_ver.scpi_ver, val);
750         dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
751
752         return 0;
753 exit:
754         the_scpi_device = NULL;
755         return ret;
756 }
757
758 static struct platform_driver mbox_scpi_driver = {
759         .probe  = mobx_scpi_probe,
760         .driver = {
761                 .name = "mbox-scpi",
762                 .of_match_table = of_match_ptr(mobx_scpi_of_match),
763         },
764 };
765
766 static int __init rockchip_mbox_scpi_init(void)
767 {
768         return platform_driver_register(&mbox_scpi_driver);
769 }
770 subsys_initcall(rockchip_mbox_scpi_init);