Merge tag 'lsk-v4.4-17.03-android' of git://git.linaro.org/kernel/linux-linaro-stable.git
[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/slab.h>
28 #include <linux/rockchip/scpi.h>
29 #include <linux/rockchip/rk3368-mailbox.h>
30
31 #define SCPI_VERSION            0x01000002      /* version: 1.0.0.2 */
32
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
44
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)
49
50 static int max_chan_num = 0;
51 static DECLARE_BITMAP(bm_mbox_chans, 4);
52 static DEFINE_MUTEX(scpi_mtx);
53
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 */
67         SCPI_ERR_MAX
68 };
69
70 enum scpi_client_id {
71         SCPI_CL_NONE,
72         SCPI_CL_CLOCKS,
73         SCPI_CL_DVFS,
74         SCPI_CL_POWER,
75         SCPI_CL_THERMAL,
76         SCPI_CL_DDR,
77         SCPI_CL_SYS,
78         SCPI_MAX,
79 };
80
81 enum scpi_ddr_cmd {
82         SCPI_DDR_INIT,
83         SCPI_DDR_SET_FREQ,
84         SCPI_DDR_ROUND_RATE,
85         SCPI_DDR_AUTO_SELF_REFRESH,
86         SCPI_DDR_BANDWIDTH_GET,
87         SCPI_DDR_GET_FREQ,
88         SCPI_DDR_SEND_TIMING,
89 };
90
91 enum scpi_sys_cmd {
92         SCPI_SYS_GET_VERSION,
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,
97 };
98
99 enum scpi_std_cmd {
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,
132         SCPI_CMD_COUNT
133 };
134
135 enum scpi_thermal_cmd {
136         SCPI_THERMAL_GET_TSADC_DATA,
137         SCPI_THERMAL_SET_TSADC_CYCLE,
138         SCPI_THERMAL_COUNT
139 };
140
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,
145         SCPI_CMD_SET_DVFS,
146         SCPI_CMD_GET_DVFS,
147         SCPI_CMD_SET_RTC,
148         SCPI_CMD_GET_RTC,
149         SCPI_CMD_SET_CLOCK_INDEX,
150         SCPI_CMD_SET_CLOCK_VALUE,
151         SCPI_CMD_GET_CLOCK_VALUE,
152         SCPI_CMD_SET_PSU,
153         SCPI_CMD_GET_PSU,
154         SCPI_CMD_SENSOR_CFG_PERIODIC,
155         SCPI_CMD_SENSOR_CFG_BOUNDS,
156 };
157
158 struct scpi_data_buf {
159         int client_id;
160         struct rk3368_mbox_msg *data;
161         struct completion complete;
162         int timeout_ms;
163 };
164
165 struct scpi_mcu_ver {
166         u32  scpi_ver;
167         char mcu_ver[16];
168 };
169
170 static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
171
172 static struct device *the_scpi_device;
173
174 static int scpi_linux_errmap[SCPI_ERR_MAX] = {
175         0, -EINVAL, -ENOEXEC, -EMSGSIZE,
176         -EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
177         -ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
178 };
179
180 static inline int scpi_to_linux_errno(int errno)
181 {
182         if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
183                 return scpi_linux_errmap[errno];
184         return -EIO;
185 }
186
187 static bool __maybe_unused high_priority_chan_supported(int cmd)
188 {
189         int idx;
190
191         for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
192                 if (cmd == high_priority_cmds[idx])
193                         return true;
194         return false;
195 }
196
197 static int scpi_alloc_mbox_chan(void)
198 {
199         int index;
200
201         mutex_lock(&scpi_mtx);
202
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);
207                 return -EBUSY;
208         }
209
210         set_bit(index, bm_mbox_chans);
211
212         mutex_unlock(&scpi_mtx);
213         return index;
214 }
215
216 static void scpi_free_mbox_chan(int chan)
217 {
218         int index = chan;
219
220         mutex_lock(&scpi_mtx);
221
222         if (index < max_chan_num && index >= 0)
223                 clear_bit(index, bm_mbox_chans);
224
225         mutex_unlock(&scpi_mtx);
226 }
227
228 static void scpi_rx_callback(struct mbox_client *cl, void *msg)
229 {
230         struct rk3368_mbox_msg *data = (struct rk3368_mbox_msg *)msg;
231         struct scpi_data_buf *scpi_buf = data->cl_data;
232
233         complete(&scpi_buf->complete);
234 }
235
236 static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
237 {
238         struct mbox_chan *chan;
239         struct mbox_client cl;
240         struct rk3368_mbox_msg *data = scpi_buf->data;
241         u32 status;
242         int ret;
243         int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
244
245         if (!the_scpi_device) {
246                 pr_err("Scpi initializes unsuccessfully\n");
247                 return -EIO;
248         }
249
250         cl.dev = the_scpi_device;
251         cl.rx_callback = scpi_rx_callback;
252         cl.tx_done = NULL;
253         cl.tx_prepare = NULL;
254         cl.tx_block = false;
255         cl.knows_txdone = false;
256
257         chan = mbox_request_channel(&cl, index);
258         if (IS_ERR(chan)) {
259                 scpi_free_mbox_chan(index);
260                 return PTR_ERR(chan);
261         }
262
263         init_completion(&scpi_buf->complete);
264         if (mbox_send_message(chan, (void *)data) < 0) {
265                 status = SCPI_ERR_TIMEOUT;
266                 goto free_channel;
267         }
268
269         ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
270         if (ret == 0) {
271                 status = SCPI_ERR_TIMEOUT;
272                 goto free_channel;
273         }
274         status = *(u32 *)(data->rx_buf); /* read first word */
275
276 free_channel:
277         mbox_free_channel(chan);
278         scpi_free_mbox_chan(index);
279
280         return scpi_to_linux_errno(status);
281 }
282
283 #define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
284                         _cmd, _tx_buf, _rx_buf) \
285 do {                                            \
286         struct rk3368_mbox_msg *pdata = &mbox_buf;      \
287         pdata->cmd = _cmd;                      \
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; \
295 } while (0)
296
297 #define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id,         \
298                                 _cmd, _tx_buf, _tx_size, _rx_buf)       \
299 do {                                                                    \
300         struct rk3368_mbox_msg *pdata = &mbox_buf;                      \
301         pdata->cmd = _cmd;                                              \
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;              \
309 } while (0)
310
311 static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
312 {
313         struct rk3368_mbox_msg *data;
314         int index;
315
316         if (!scpi_buf || !scpi_buf->data)
317                 return -EINVAL;
318
319         index = scpi_alloc_mbox_chan();
320         if (index < 0)
321                 return -EBUSY;
322
323         data = scpi_buf->data;
324         data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
325                                   data->tx_size);
326         data->cl_data = scpi_buf;
327
328         return send_scpi_cmd(scpi_buf, index);
329 }
330
331 unsigned long scpi_clk_get_val(u16 clk_id)
332 {
333         struct scpi_data_buf sdata;
334         struct rk3368_mbox_msg mdata;
335         struct __packed {
336                 u32 status;
337                 u32 clk_rate;
338         } buf;
339
340         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
341                         SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
342         if (scpi_execute_cmd(&sdata))
343                 return 0;
344
345         return buf.clk_rate;
346 }
347 EXPORT_SYMBOL_GPL(scpi_clk_get_val);
348
349 int scpi_clk_set_val(u16 clk_id, unsigned long rate)
350 {
351         struct scpi_data_buf sdata;
352         struct rk3368_mbox_msg mdata;
353         int stat;
354         struct __packed {
355                 u32 clk_rate;
356                 u16 clk_id;
357         } buf;
358
359         buf.clk_rate = (u32)rate;
360         buf.clk_id = clk_id;
361
362         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
363                         SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
364         return scpi_execute_cmd(&sdata);
365 }
366 EXPORT_SYMBOL_GPL(scpi_clk_set_val);
367
368 struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
369 {
370         struct scpi_data_buf sdata;
371         struct rk3368_mbox_msg mdata;
372         struct __packed {
373                 u32 status;
374                 u32 header;
375                 struct scpi_opp_entry opp[MAX_DVFS_OPPS];
376         } buf;
377         struct scpi_opp *opps;
378         size_t opps_sz;
379         int count, ret;
380
381         if (domain >= MAX_DVFS_DOMAINS)
382                 return ERR_PTR(-EINVAL);
383
384         if (scpi_opps[domain])  /* data already populated */
385                 return scpi_opps[domain];
386
387         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
388                         SCPI_CMD_GET_DVFS_INFO, domain, buf);
389         ret = scpi_execute_cmd(&sdata);
390         if (ret)
391                 return ERR_PTR(ret);
392
393         opps = kmalloc(sizeof(*opps), GFP_KERNEL);
394         if (!opps)
395                 return ERR_PTR(-ENOMEM);
396
397         count = DVFS_OPP_COUNT(buf.header);
398         opps_sz = count * sizeof(*(opps->opp));
399
400         opps->count = count;
401         opps->latency = DVFS_LATENCY(buf.header);
402         opps->opp = kmalloc(opps_sz, GFP_KERNEL);
403         if (!opps->opp) {
404                 kfree(opps);
405                 return ERR_PTR(-ENOMEM);
406         }
407
408         memcpy(opps->opp, &buf.opp[0], opps_sz);
409         scpi_opps[domain] = opps;
410
411         return opps;
412 }
413 EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
414
415 int scpi_dvfs_get_idx(u8 domain)
416 {
417         struct scpi_data_buf sdata;
418         struct rk3368_mbox_msg mdata;
419         struct __packed {
420                 u32 status;
421                 u8 dvfs_idx;
422         } buf;
423         int ret;
424
425         if (domain >= MAX_DVFS_DOMAINS)
426                 return -EINVAL;
427
428         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
429                         SCPI_CMD_GET_DVFS, domain, buf);
430         ret = scpi_execute_cmd(&sdata);
431
432         if (!ret)
433                 ret = buf.dvfs_idx;
434         return ret;
435 }
436 EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
437
438 int scpi_dvfs_set_idx(u8 domain, u8 idx)
439 {
440         struct scpi_data_buf sdata;
441         struct rk3368_mbox_msg mdata;
442         struct __packed {
443                 u8 dvfs_domain;
444                 u8 dvfs_idx;
445         } buf;
446         int stat;
447
448         buf.dvfs_idx = idx;
449         buf.dvfs_domain = domain;
450
451         if (domain >= MAX_DVFS_DOMAINS)
452                 return -EINVAL;
453
454         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
455                         SCPI_CMD_SET_DVFS, buf, stat);
456         return scpi_execute_cmd(&sdata);
457 }
458 EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
459
460 int scpi_get_sensor(char *name)
461 {
462         struct scpi_data_buf sdata;
463         struct rk3368_mbox_msg mdata;
464         struct __packed {
465                 u32 status;
466                 u16 sensors;
467         } cap_buf;
468         struct __packed {
469                 u32 status;
470                 u16 sensor;
471                 u8 class;
472                 u8 trigger;
473                 char name[20];
474         } info_buf;
475         int ret;
476         u16 sensor_id;
477
478         /* This should be handled by a generic macro */
479         do {
480                 struct rk3368_mbox_msg *pdata = &mdata;
481
482                 pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
483                 pdata->tx_size = 0;
484                 pdata->rx_buf = &cap_buf;
485                 pdata->rx_size = sizeof(cap_buf);
486                 sdata.client_id = SCPI_CL_THERMAL;
487                 sdata.data = pdata;
488         } while (0);
489
490         ret = scpi_execute_cmd(&sdata);
491         if (ret)
492                 goto out;
493
494         ret = -ENODEV;
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);
499                 if (ret)
500                         break;
501
502                 if (!strcmp(name, info_buf.name)) {
503                         ret = sensor_id;
504                         break;
505                 }
506         }
507 out:
508         return ret;
509 }
510 EXPORT_SYMBOL_GPL(scpi_get_sensor);
511
512 int scpi_get_sensor_value(u16 sensor, u32 *val)
513 {
514         struct scpi_data_buf sdata;
515         struct rk3368_mbox_msg mdata;
516         struct __packed {
517                 u32 status;
518                 u32 val;
519         } buf;
520         int ret;
521
522         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
523                         sensor, buf);
524
525         ret = scpi_execute_cmd(&sdata);
526         if (ret)
527                 *val = buf.val;
528
529         return ret;
530 }
531 EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
532
533 static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
534 {
535         int ret;
536         struct scpi_data_buf sdata;
537         struct rk3368_mbox_msg mdata;
538         struct __packed {
539                 u32 status;
540                 struct scpi_mcu_ver version;
541         } buf;
542
543         memset(&buf, 0, sizeof(buf));
544         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
545                         old, buf);
546
547         ret = scpi_execute_cmd(&sdata);
548         if (ret) {
549                 pr_err("get scpi version from MCU failed, ret=%d\n", ret);
550                 goto OUT;
551         }
552
553         memcpy(ver, &(buf.version), sizeof(*ver));
554
555 OUT:
556         return ret;
557 }
558
559 int scpi_sys_set_mcu_state_suspend(void)
560 {
561         struct scpi_data_buf sdata;
562         struct rk3368_mbox_msg mdata;
563         struct __packed1 {
564                 u32 status;
565         } tx_buf;
566         struct __packed2 {
567                 u32 status;
568         } rx_buf;
569
570         tx_buf.status = 0;
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);
574 }
575 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
576
577 int scpi_sys_set_mcu_state_resume(void)
578 {
579         struct scpi_data_buf sdata;
580         struct rk3368_mbox_msg mdata;
581         struct __packed1 {
582                 u32 status;
583         } tx_buf;
584         struct __packed2 {
585                 u32 status;
586         } rx_buf;
587
588         tx_buf.status = 0;
589
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);
593 }
594 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
595
596 int scpi_sys_set_jtagmux_on_off(u32 en)
597 {
598         int ret;
599         struct scpi_data_buf sdata;
600         struct rk3368_mbox_msg mdata;
601         struct __packed1 {
602                 u32 enable;
603         } tx_buf;
604
605         struct __packed2 {
606                 u32 status;
607         } rx_buf;
608
609         tx_buf.enable = en;
610         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
611                         SCPI_SYS_SET_JTAGMUX_ON_OFF, tx_buf, rx_buf);
612
613         ret = scpi_execute_cmd(&sdata);
614         if (ret)
615                 pr_err("set jtagmux on-off failed, ret=%d\n", ret);
616         else
617                 ret = rx_buf.status;
618
619         return ret;
620 }
621 EXPORT_SYMBOL_GPL(scpi_sys_set_jtagmux_on_off);
622
623 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
624 {
625         struct scpi_data_buf sdata;
626         struct rk3368_mbox_msg mdata;
627         struct __packed1 {
628                 u32 dram_speed_bin;
629                 u32 freq;
630                 u32 lcdc_type;
631                 u32 addr_mcu_el3;
632         } tx_buf;
633         struct __packed2 {
634                 u32 status;
635         } rx_buf;
636
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);
644 }
645 EXPORT_SYMBOL_GPL(scpi_ddr_init);
646
647 int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
648 {
649         struct scpi_data_buf sdata;
650         struct rk3368_mbox_msg mdata;
651         struct __packed1 {
652                 u32 clk_rate;
653                 u32 lcdc_type;
654         } tx_buf;
655         struct __packed2 {
656                 u32 status;
657         } rx_buf;
658
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);
664 }
665 EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
666
667 int scpi_ddr_send_timing(u32 *p, u32 size)
668 {
669         struct scpi_data_buf sdata;
670         struct rk3368_mbox_msg mdata;
671         struct __packed2 {
672                 u32 status;
673         } rx_buf;
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);
677 }
678 EXPORT_SYMBOL_GPL(scpi_ddr_send_timing);
679
680 int scpi_ddr_round_rate(u32 m_hz)
681 {
682         struct scpi_data_buf sdata;
683         struct rk3368_mbox_msg mdata;
684         struct __packed1 {
685                 u32 clk_rate;
686         } tx_buf;
687         struct __packed2 {
688                 u32 status;
689                 u32 round_rate;
690         } rx_buf;
691
692         tx_buf.clk_rate = (u32)m_hz;
693
694         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
695                         SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
696         if (scpi_execute_cmd(&sdata))
697                 return 0;
698
699         return rx_buf.round_rate;
700 }
701 EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
702
703 int scpi_ddr_set_auto_self_refresh(u32 en)
704 {
705         struct scpi_data_buf sdata;
706         struct rk3368_mbox_msg mdata;
707         struct __packed1 {
708                 u32 enable;
709         } tx_buf;
710         struct __packed2 {
711                 u32 status;
712         } rx_buf;
713
714         tx_buf.enable = (u32)en;
715
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);
719 }
720 EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
721
722 int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,
723                            struct ddr_bw_info *ddr_bw_ch1)
724 {
725         struct scpi_data_buf sdata;
726         struct rk3368_mbox_msg mdata;
727         struct __packed1 {
728                 u32 status;
729         } tx_buf;
730         struct __packed2 {
731                 u32 status;
732                 struct ddr_bw_info ddr_bw_ch0;
733                 struct ddr_bw_info ddr_bw_ch1;
734         } rx_buf;
735
736         tx_buf.status = 0;
737
738         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
739                         SCPI_DDR_BANDWIDTH_GET, tx_buf, rx_buf);
740         if (scpi_execute_cmd(&sdata))
741                 return 0;
742
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));
745
746         return 0;
747 }
748 EXPORT_SYMBOL_GPL(scpi_ddr_bandwidth_get);
749
750 int scpi_ddr_get_clk_rate(void)
751 {
752         struct scpi_data_buf sdata;
753         struct rk3368_mbox_msg mdata;
754         struct __packed1 {
755                 u32 status;
756         } tx_buf;
757         struct __packed2 {
758                 u32 status;
759                 u32 clk_rate;
760         } rx_buf;
761
762         tx_buf.status = 0;
763         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
764                         SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
765         if (scpi_execute_cmd(&sdata))
766                 return 0;
767
768         return rx_buf.clk_rate;
769 }
770 EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
771
772 int scpi_thermal_get_temperature(void)
773 {
774         int ret;
775         struct scpi_data_buf sdata;
776         struct rk3368_mbox_msg mdata;
777         struct __packed1 {
778                 u32 status;
779         } tx_buf;
780
781         struct __packed2 {
782                 u32 status;
783                 u32 tsadc_data;
784         } rx_buf;
785
786         tx_buf.status = 0;
787         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
788                         SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
789
790         ret = scpi_execute_cmd(&sdata);
791         if (ret) {
792                 pr_err("get temperature from MCU failed, ret=%d\n", ret);
793                 return ret;
794         }
795
796         return rx_buf.tsadc_data;
797 }
798 EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
799
800 int scpi_thermal_set_clk_cycle(u32 cycle)
801 {
802         struct scpi_data_buf sdata;
803         struct rk3368_mbox_msg mdata;
804         struct __packed1 {
805                 u32 clk_cycle;
806         } tx_buf;
807
808         struct __packed2 {
809                 u32 status;
810         } rx_buf;
811
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);
815
816         return scpi_execute_cmd(&sdata);
817 }
818 EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
819
820 static struct of_device_id mobx_scpi_of_match[] = {
821         { .compatible = "rockchip,rk3368-scpi-legacy"},
822         { },
823 };
824 MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
825
826 static int mobx_scpi_probe(struct platform_device *pdev)
827 {
828         int ret = 0;
829         int retry = 3;
830         int val = 0;
831         struct scpi_mcu_ver mcu_ver;
832         int check_version = 1; /*0: not check version, 1: check version*/
833
834         the_scpi_device = &pdev->dev;
835
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");
839                 ret = -EINVAL;
840                 goto exit;
841         }
842
843         max_chan_num = val;
844
845         /* try to check up with SCPI version from MCU */
846         while ((retry--) && (check_version != 0)) {
847                 memset(&mcu_ver, 0, sizeof(mcu_ver));
848
849                 ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
850                 if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
851                         break;
852         }
853
854         if ((retry <= 0) && (check_version != 0)) {
855                 dev_err(&pdev->dev,
856                         "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
857                         SCPI_VERSION, mcu_ver.scpi_ver, ret);
858                 ret = -EIO;
859                 goto exit;
860         }
861
862         dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
863                  SCPI_VERSION, val);
864
865         if (check_version)
866                 dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
867
868         return 0;
869 exit:
870         the_scpi_device = NULL;
871         return ret;
872 }
873
874 static struct platform_driver mbox_scpi_driver = {
875         .probe  = mobx_scpi_probe,
876         .driver = {
877                 .name = "mbox-scpi",
878                 .of_match_table = of_match_ptr(mobx_scpi_of_match),
879         },
880 };
881
882 static int __init rockchip_mbox_scpi_init(void)
883 {
884         return platform_driver_register(&mbox_scpi_driver);
885 }
886 subsys_initcall(rockchip_mbox_scpi_init);