First Support on Ginger and OMAP TI
[linux-ginger.git] / drivers / staging / dream / qdsp5 / adsp.c
blobd096456688dac18f3d4e9d51dc96f4f15d88c501
1 /* arch/arm/mach-msm/qdsp5/adsp.c
3 * Register/Interrupt access for userspace aDSP library.
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 * Author: Iliyan Malchev <ibm@android.com>
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
20 /* TODO:
21 * - move shareable rpc code outside of adsp.c
22 * - general solution for virt->phys patchup
23 * - queue IDs should be relative to modules
24 * - disallow access to non-associated queues
27 #include <linux/clk.h>
28 #include <linux/delay.h>
29 #include <linux/interrupt.h>
30 #include <linux/kernel.h>
31 #include <linux/kthread.h>
32 #include <linux/module.h>
33 #include <linux/uaccess.h>
34 #include <linux/wait.h>
35 #include <linux/wakelock.h>
37 static struct wake_lock adsp_wake_lock;
38 static inline void prevent_suspend(void)
40 wake_lock(&adsp_wake_lock);
42 static inline void allow_suspend(void)
44 wake_unlock(&adsp_wake_lock);
47 #include <linux/io.h>
48 #include <mach/msm_iomap.h>
49 #include "adsp.h"
51 #define INT_ADSP INT_ADSP_A9_A11
53 static struct adsp_info adsp_info;
54 static struct msm_rpc_endpoint *rpc_cb_server_client;
55 static struct msm_adsp_module *adsp_modules;
56 static int adsp_open_count;
57 static DEFINE_MUTEX(adsp_open_lock);
59 /* protect interactions with the ADSP command/message queue */
60 static spinlock_t adsp_cmd_lock;
62 static uint32_t current_image = -1;
64 void adsp_set_image(struct adsp_info *info, uint32_t image)
66 current_image = image;
70 * Checks whether the module_id is available in the
71 * module_entries table.If module_id is available returns `0`.
72 * If module_id is not available returns `-ENXIO`.
74 #if CONFIG_MSM_AMSS_VERSION >= 6350
75 static int32_t adsp_validate_module(uint32_t module_id)
77 uint32_t *ptr;
78 uint32_t module_index;
79 uint32_t num_mod_entries;
81 ptr = adsp_info.init_info_ptr->module_entries;
82 num_mod_entries = adsp_info.init_info_ptr->module_table_size;
84 for (module_index = 0; module_index < num_mod_entries; module_index++)
85 if (module_id == ptr[module_index])
86 return 0;
88 return -ENXIO;
90 #else
91 static inline int32_t adsp_validate_module(uint32_t module_id) { return 0; }
92 #endif
94 uint32_t adsp_get_module(struct adsp_info *info, uint32_t task)
96 BUG_ON(current_image == -1UL);
97 return info->task_to_module[current_image][task];
100 uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id)
102 BUG_ON(current_image == -1UL);
103 return info->queue_offset[current_image][queue_id];
106 static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module,
107 struct msm_adsp_module *adsp_module)
109 int rc;
110 struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
111 struct rpc_reply_hdr *rpc_rsp;
113 msm_rpc_setup_req(&rpc_req.hdr,
114 RPC_ADSP_RTOS_ATOM_PROG,
115 msm_rpc_get_vers(adsp_module->rpc_client),
116 RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
118 rpc_req.gotit = cpu_to_be32(1);
119 rpc_req.cmd = cpu_to_be32(cmd);
120 rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
121 rpc_req.module = cpu_to_be32(module);
122 rc = msm_rpc_write(adsp_module->rpc_client, &rpc_req, sizeof(rpc_req));
123 if (rc < 0) {
124 pr_err("adsp: could not send RPC request: %d\n", rc);
125 return rc;
128 rc = msm_rpc_read(adsp_module->rpc_client,
129 (void **)&rpc_rsp, -1, (5*HZ));
130 if (rc < 0) {
131 pr_err("adsp: error receiving RPC reply: %d (%d)\n",
132 rc, -ERESTARTSYS);
133 return rc;
136 if (be32_to_cpu(rpc_rsp->reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) {
137 pr_err("adsp: RPC call was denied!\n");
138 kfree(rpc_rsp);
139 return -EPERM;
142 if (be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat) !=
143 RPC_ACCEPTSTAT_SUCCESS) {
144 pr_err("adsp error: RPC call was not successful (%d)\n",
145 be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat));
146 kfree(rpc_rsp);
147 return -EINVAL;
150 kfree(rpc_rsp);
151 return 0;
154 #if CONFIG_MSM_AMSS_VERSION >= 6350
155 static int get_module_index(uint32_t id)
157 int mod_idx;
158 for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++)
159 if (adsp_info.module[mod_idx].id == id)
160 return mod_idx;
162 return -ENXIO;
164 #endif
166 static struct msm_adsp_module *find_adsp_module_by_id(
167 struct adsp_info *info, uint32_t id)
169 if (id > info->max_module_id) {
170 return NULL;
171 } else {
172 #if CONFIG_MSM_AMSS_VERSION >= 6350
173 id = get_module_index(id);
174 if (id < 0)
175 return NULL;
176 #endif
177 return info->id_to_module[id];
181 static struct msm_adsp_module *find_adsp_module_by_name(
182 struct adsp_info *info, const char *name)
184 unsigned n;
185 for (n = 0; n < info->module_count; n++)
186 if (!strcmp(name, adsp_modules[n].name))
187 return adsp_modules + n;
188 return NULL;
191 static int adsp_rpc_init(struct msm_adsp_module *adsp_module)
193 /* remove the original connect once compatible support is complete */
194 adsp_module->rpc_client = msm_rpc_connect(
195 RPC_ADSP_RTOS_ATOM_PROG,
196 RPC_ADSP_RTOS_ATOM_VERS,
197 MSM_RPC_UNINTERRUPTIBLE);
199 if (IS_ERR(adsp_module->rpc_client)) {
200 int rc = PTR_ERR(adsp_module->rpc_client);
201 adsp_module->rpc_client = 0;
202 pr_err("adsp: could not open rpc client: %d\n", rc);
203 return rc;
206 return 0;
209 #if CONFIG_MSM_AMSS_VERSION >= 6350
211 * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get
212 * queue offsets and module entries (init info) as part of the event.
214 static void msm_get_init_info(void)
216 int rc;
217 struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
219 adsp_info.init_info_rpc_client = msm_rpc_connect(
220 RPC_ADSP_RTOS_ATOM_PROG,
221 RPC_ADSP_RTOS_ATOM_VERS,
222 MSM_RPC_UNINTERRUPTIBLE);
223 if (IS_ERR(adsp_info.init_info_rpc_client)) {
224 rc = PTR_ERR(adsp_info.init_info_rpc_client);
225 adsp_info.init_info_rpc_client = 0;
226 pr_err("adsp: could not open rpc client: %d\n", rc);
227 return;
230 msm_rpc_setup_req(&rpc_req.hdr,
231 RPC_ADSP_RTOS_ATOM_PROG,
232 msm_rpc_get_vers(adsp_info.init_info_rpc_client),
233 RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
235 rpc_req.gotit = cpu_to_be32(1);
236 rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO);
237 rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
238 rpc_req.module = 0;
240 rc = msm_rpc_write(adsp_info.init_info_rpc_client,
241 &rpc_req, sizeof(rpc_req));
242 if (rc < 0)
243 pr_err("adsp: could not send RPC request: %d\n", rc);
245 #endif
247 int msm_adsp_get(const char *name, struct msm_adsp_module **out,
248 struct msm_adsp_ops *ops, void *driver_data)
250 struct msm_adsp_module *module;
251 int rc = 0;
253 #if CONFIG_MSM_AMSS_VERSION >= 6350
254 static uint32_t init_info_cmd_sent;
255 if (!init_info_cmd_sent) {
256 msm_get_init_info();
257 init_waitqueue_head(&adsp_info.init_info_wait);
258 rc = wait_event_timeout(adsp_info.init_info_wait,
259 adsp_info.init_info_state == ADSP_STATE_INIT_INFO,
260 5 * HZ);
261 if (!rc) {
262 pr_info("adsp: INIT_INFO failed\n");
263 return -ETIMEDOUT;
265 init_info_cmd_sent++;
267 #endif
269 module = find_adsp_module_by_name(&adsp_info, name);
270 if (!module)
271 return -ENODEV;
273 mutex_lock(&module->lock);
274 pr_info("adsp: opening module %s\n", module->name);
275 if (module->open_count++ == 0 && module->clk)
276 clk_enable(module->clk);
278 mutex_lock(&adsp_open_lock);
279 if (adsp_open_count++ == 0) {
280 enable_irq(INT_ADSP);
281 prevent_suspend();
283 mutex_unlock(&adsp_open_lock);
285 if (module->ops) {
286 rc = -EBUSY;
287 goto done;
290 rc = adsp_rpc_init(module);
291 if (rc)
292 goto done;
294 module->ops = ops;
295 module->driver_data = driver_data;
296 *out = module;
297 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP,
298 module->id, module);
299 if (rc) {
300 module->ops = NULL;
301 module->driver_data = NULL;
302 *out = NULL;
303 pr_err("adsp: REGISTER_APP failed\n");
304 goto done;
307 pr_info("adsp: module %s has been registered\n", module->name);
309 done:
310 mutex_lock(&adsp_open_lock);
311 if (rc && --adsp_open_count == 0) {
312 disable_irq(INT_ADSP);
313 allow_suspend();
315 if (rc && --module->open_count == 0 && module->clk)
316 clk_disable(module->clk);
317 mutex_unlock(&adsp_open_lock);
318 mutex_unlock(&module->lock);
319 return rc;
321 EXPORT_SYMBOL(msm_adsp_get);
323 static int msm_adsp_disable_locked(struct msm_adsp_module *module);
325 void msm_adsp_put(struct msm_adsp_module *module)
327 unsigned long flags;
329 mutex_lock(&module->lock);
330 if (--module->open_count == 0 && module->clk)
331 clk_disable(module->clk);
332 if (module->ops) {
333 pr_info("adsp: closing module %s\n", module->name);
335 /* lock to ensure a dsp event cannot be delivered
336 * during or after removal of the ops and driver_data
338 spin_lock_irqsave(&adsp_cmd_lock, flags);
339 module->ops = NULL;
340 module->driver_data = NULL;
341 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
343 if (module->state != ADSP_STATE_DISABLED) {
344 pr_info("adsp: disabling module %s\n", module->name);
345 msm_adsp_disable_locked(module);
348 msm_rpc_close(module->rpc_client);
349 module->rpc_client = 0;
350 if (--adsp_open_count == 0) {
351 disable_irq(INT_ADSP);
352 allow_suspend();
353 pr_info("adsp: disable interrupt\n");
355 } else {
356 pr_info("adsp: module %s is already closed\n", module->name);
358 mutex_unlock(&module->lock);
360 EXPORT_SYMBOL(msm_adsp_put);
362 /* this should be common code with rpc_servers.c */
363 static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client,
364 uint32_t xid, uint32_t accept_status)
366 int rc = 0;
367 uint8_t reply_buf[sizeof(struct rpc_reply_hdr)];
368 struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf;
370 reply->xid = cpu_to_be32(xid);
371 reply->type = cpu_to_be32(1); /* reply */
372 reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
374 reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status);
375 reply->data.acc_hdr.verf_flavor = 0;
376 reply->data.acc_hdr.verf_length = 0;
378 rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf));
379 if (rc < 0)
380 pr_err("adsp: could not write RPC response: %d\n", rc);
381 return rc;
384 int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
385 void *cmd_buf, size_t cmd_size)
387 uint32_t ctrl_word;
388 uint32_t dsp_q_addr;
389 uint32_t dsp_addr;
390 uint32_t cmd_id = 0;
391 int cnt = 0;
392 int ret_status = 0;
393 unsigned long flags;
394 struct adsp_info *info = module->info;
396 spin_lock_irqsave(&adsp_cmd_lock, flags);
398 if (module->state != ADSP_STATE_ENABLED) {
399 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
400 pr_err("adsp: module %s not enabled before write\n",
401 module->name);
402 return -ENODEV;
404 if (adsp_validate_module(module->id)) {
405 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
406 pr_info("adsp: module id validation failed %s %d\n",
407 module->name, module->id);
408 return -ENXIO;
410 dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr);
411 dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M;
413 /* Poll until the ADSP is ready to accept a command.
414 * Wait for 100us, return error if it's not responding.
415 * If this returns an error, we need to disable ALL modules and
416 * then retry.
418 while (((ctrl_word = readl(info->write_ctrl)) &
419 ADSP_RTOS_WRITE_CTRL_WORD_READY_M) !=
420 ADSP_RTOS_WRITE_CTRL_WORD_READY_V) {
421 if (cnt > 100) {
422 pr_err("adsp: timeout waiting for DSP write ready\n");
423 ret_status = -EIO;
424 goto fail;
426 pr_warning("adsp: waiting for DSP write ready\n");
427 udelay(1);
428 cnt++;
431 /* Set the mutex bits */
432 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
433 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
435 /* Clear the command bits */
436 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
438 /* Set the queue address bits */
439 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
440 ctrl_word |= dsp_q_addr;
442 writel(ctrl_word, info->write_ctrl);
444 /* Generate an interrupt to the DSP. This notifies the DSP that
445 * we are about to send a command on this particular queue. The
446 * DSP will in response change its state.
448 writel(1, info->send_irq);
450 /* Poll until the adsp responds to the interrupt; this does not
451 * generate an interrupt from the adsp. This should happen within
452 * 5ms.
454 cnt = 0;
455 while ((readl(info->write_ctrl) &
456 ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) ==
457 ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) {
458 if (cnt > 5000) {
459 pr_err("adsp: timeout waiting for adsp ack\n");
460 ret_status = -EIO;
461 goto fail;
463 udelay(1);
464 cnt++;
467 /* Read the ctrl word */
468 ctrl_word = readl(info->write_ctrl);
470 if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) !=
471 ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) {
472 ret_status = -EAGAIN;
473 goto fail;
476 /* Ctrl word status bits were 00, no error in the ctrl word */
478 /* Get the DSP buffer address */
479 dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) +
480 (uint32_t)MSM_AD5_BASE;
482 if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
483 uint16_t *buf_ptr = (uint16_t *) cmd_buf;
484 uint16_t *dsp_addr16 = (uint16_t *)dsp_addr;
485 cmd_size /= sizeof(uint16_t);
487 /* Save the command ID */
488 cmd_id = (uint32_t) buf_ptr[0];
490 /* Copy the command to DSP memory */
491 cmd_size++;
492 while (--cmd_size)
493 *dsp_addr16++ = *buf_ptr++;
494 } else {
495 uint32_t *buf_ptr = (uint32_t *) cmd_buf;
496 uint32_t *dsp_addr32 = (uint32_t *)dsp_addr;
497 cmd_size /= sizeof(uint32_t);
499 /* Save the command ID */
500 cmd_id = buf_ptr[0];
502 cmd_size++;
503 while (--cmd_size)
504 *dsp_addr32++ = *buf_ptr++;
507 /* Set the mutex bits */
508 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
509 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
511 /* Set the command bits to write done */
512 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
513 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V;
515 /* Set the queue address bits */
516 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
517 ctrl_word |= dsp_q_addr;
519 writel(ctrl_word, info->write_ctrl);
521 /* Generate an interrupt to the DSP. It does not respond with
522 * an interrupt, and we do not need to wait for it to
523 * acknowledge, because it will hold the mutex lock until it's
524 * ready to receive more commands again.
526 writel(1, info->send_irq);
528 module->num_commands++;
530 fail:
531 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
532 return ret_status;
534 EXPORT_SYMBOL(msm_adsp_write);
536 int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
537 void *cmd_buf, size_t cmd_size)
539 int rc, retries = 0;
540 do {
541 rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, cmd_size);
542 if (rc == -EAGAIN)
543 udelay(10);
544 } while(rc == -EAGAIN && retries++ < 100);
545 if (retries > 50)
546 pr_warning("adsp: %s command took %d attempts: rc %d\n",
547 module->name, retries, rc);
548 return rc;
551 #ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
552 static void *modem_event_addr;
553 #if CONFIG_MSM_AMSS_VERSION >= 6350
554 static void read_modem_event(void *buf, size_t len)
556 uint32_t *dptr = buf;
557 struct rpc_adsp_rtos_modem_to_app_args_t *sptr;
558 struct adsp_rtos_mp_mtoa_type *pkt_ptr;
560 sptr = modem_event_addr;
561 pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
563 dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event);
564 dptr[1] = be32_to_cpu(pkt_ptr->module);
565 dptr[2] = be32_to_cpu(pkt_ptr->image);
567 #else
568 static void read_modem_event(void *buf, size_t len)
570 uint32_t *dptr = buf;
571 struct rpc_adsp_rtos_modem_to_app_args_t *sptr =
572 modem_event_addr;
573 dptr[0] = be32_to_cpu(sptr->event);
574 dptr[1] = be32_to_cpu(sptr->module);
575 dptr[2] = be32_to_cpu(sptr->image);
577 #endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
578 #endif /* CONFIG_MSM_ADSP_REPORT_EVENTS */
580 static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req)
582 struct rpc_adsp_rtos_modem_to_app_args_t *args =
583 (struct rpc_adsp_rtos_modem_to_app_args_t *)req;
584 uint32_t event;
585 uint32_t proc_id;
586 uint32_t module_id;
587 uint32_t image;
588 struct msm_adsp_module *module;
589 #if CONFIG_MSM_AMSS_VERSION >= 6350
590 struct adsp_rtos_mp_mtoa_type *pkt_ptr =
591 &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
593 event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event);
594 proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id);
595 module_id = be32_to_cpu(pkt_ptr->module);
596 image = be32_to_cpu(pkt_ptr->image);
598 if (be32_to_cpu(args->mtoa_pkt.desc_field) == RPC_ADSP_RTOS_INIT_INFO) {
599 struct queue_to_offset_type *qptr;
600 struct queue_to_offset_type *qtbl;
601 uint32_t *mptr;
602 uint32_t *mtbl;
603 uint32_t q_idx;
604 uint32_t num_entries;
605 uint32_t entries_per_image;
606 struct adsp_rtos_mp_mtoa_init_info_type *iptr;
607 struct adsp_rtos_mp_mtoa_init_info_type *sptr;
608 int32_t i_no, e_idx;
610 pr_info("adsp:INIT_INFO Event\n");
611 sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.
612 mp_mtoa_init_packet;
614 iptr = adsp_info.init_info_ptr;
615 iptr->image_count = be32_to_cpu(sptr->image_count);
616 iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets);
617 num_entries = iptr->num_queue_offsets;
618 qptr = &sptr->queue_offsets_tbl[0][0];
619 for (i_no = 0; i_no < iptr->image_count; i_no++) {
620 qtbl = &iptr->queue_offsets_tbl[i_no][0];
621 for (e_idx = 0; e_idx < num_entries; e_idx++) {
622 qtbl[e_idx].offset = be32_to_cpu(qptr->offset);
623 qtbl[e_idx].queue = be32_to_cpu(qptr->queue);
624 q_idx = be32_to_cpu(qptr->queue);
625 iptr->queue_offsets[i_no][q_idx] =
626 qtbl[e_idx].offset;
627 qptr++;
631 num_entries = be32_to_cpu(sptr->num_task_module_entries);
632 iptr->num_task_module_entries = num_entries;
633 entries_per_image = num_entries / iptr->image_count;
634 mptr = &sptr->task_to_module_tbl[0][0];
635 for (i_no = 0; i_no < iptr->image_count; i_no++) {
636 mtbl = &iptr->task_to_module_tbl[i_no][0];
637 for (e_idx = 0; e_idx < entries_per_image; e_idx++) {
638 mtbl[e_idx] = be32_to_cpu(*mptr);
639 mptr++;
643 iptr->module_table_size = be32_to_cpu(sptr->module_table_size);
644 mptr = &sptr->module_entries[0];
645 for (i_no = 0; i_no < iptr->module_table_size; i_no++)
646 iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]);
647 adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
648 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
649 RPC_ACCEPTSTAT_SUCCESS);
650 wake_up(&adsp_info.init_info_wait);
652 return;
654 #else
655 event = be32_to_cpu(args->event);
656 proc_id = be32_to_cpu(args->proc_id);
657 module_id = be32_to_cpu(args->module);
658 image = be32_to_cpu(args->image);
659 #endif
661 pr_info("adsp: rpc event=%d, proc_id=%d, module=%d, image=%d\n",
662 event, proc_id, module_id, image);
664 module = find_adsp_module_by_id(&adsp_info, module_id);
665 if (!module) {
666 pr_err("adsp: module %d is not supported!\n", module_id);
667 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
668 RPC_ACCEPTSTAT_GARBAGE_ARGS);
669 return;
672 mutex_lock(&module->lock);
673 switch (event) {
674 case RPC_ADSP_RTOS_MOD_READY:
675 pr_info("adsp: module %s: READY\n", module->name);
676 module->state = ADSP_STATE_ENABLED;
677 wake_up(&module->state_wait);
678 adsp_set_image(module->info, image);
679 break;
680 case RPC_ADSP_RTOS_MOD_DISABLE:
681 pr_info("adsp: module %s: DISABLED\n", module->name);
682 module->state = ADSP_STATE_DISABLED;
683 wake_up(&module->state_wait);
684 break;
685 case RPC_ADSP_RTOS_SERVICE_RESET:
686 pr_info("adsp: module %s: SERVICE_RESET\n", module->name);
687 module->state = ADSP_STATE_DISABLED;
688 wake_up(&module->state_wait);
689 break;
690 case RPC_ADSP_RTOS_CMD_SUCCESS:
691 pr_info("adsp: module %s: CMD_SUCCESS\n", module->name);
692 break;
693 case RPC_ADSP_RTOS_CMD_FAIL:
694 pr_info("adsp: module %s: CMD_FAIL\n", module->name);
695 break;
696 #if CONFIG_MSM_AMSS_VERSION >= 6350
697 case RPC_ADSP_RTOS_DISABLE_FAIL:
698 pr_info("adsp: module %s: DISABLE_FAIL\n", module->name);
699 break;
700 #endif
701 default:
702 pr_info("adsp: unknown event %d\n", event);
703 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
704 RPC_ACCEPTSTAT_GARBAGE_ARGS);
705 mutex_unlock(&module->lock);
706 return;
708 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
709 RPC_ACCEPTSTAT_SUCCESS);
710 mutex_unlock(&module->lock);
711 #ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
712 modem_event_addr = (uint32_t *)req;
713 module->ops->event(module->driver_data, EVENT_MSG_ID,
714 EVENT_LEN, read_modem_event);
715 #endif
718 static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req)
720 switch (req->procedure) {
721 case RPC_ADSP_RTOS_MTOA_NULL_PROC:
722 rpc_send_accepted_void_reply(rpc_cb_server_client,
723 req->xid,
724 RPC_ACCEPTSTAT_SUCCESS);
725 break;
726 case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
727 handle_adsp_rtos_mtoa_app(req);
728 break;
729 default:
730 pr_err("adsp: unknowned proc %d\n", req->procedure);
731 rpc_send_accepted_void_reply(
732 rpc_cb_server_client, req->xid,
733 RPC_ACCEPTSTAT_PROC_UNAVAIL);
734 break;
736 return 0;
739 /* this should be common code with rpc_servers.c */
740 static int adsp_rpc_thread(void *data)
742 void *buffer;
743 struct rpc_request_hdr *req;
744 int rc;
746 do {
747 rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1);
748 if (rc < 0) {
749 pr_err("adsp: could not read rpc: %d\n", rc);
750 break;
752 req = (struct rpc_request_hdr *)buffer;
754 req->type = be32_to_cpu(req->type);
755 req->xid = be32_to_cpu(req->xid);
756 req->rpc_vers = be32_to_cpu(req->rpc_vers);
757 req->prog = be32_to_cpu(req->prog);
758 req->vers = be32_to_cpu(req->vers);
759 req->procedure = be32_to_cpu(req->procedure);
761 if (req->type != 0)
762 goto bad_rpc;
763 if (req->rpc_vers != 2)
764 goto bad_rpc;
765 if (req->prog != RPC_ADSP_RTOS_MTOA_PROG)
766 goto bad_rpc;
767 if (req->vers != RPC_ADSP_RTOS_MTOA_VERS)
768 goto bad_rpc;
770 handle_adsp_rtos_mtoa(req);
771 kfree(buffer);
772 continue;
774 bad_rpc:
775 pr_err("adsp: bogus rpc from modem\n");
776 kfree(buffer);
777 } while (1);
779 do_exit(0);
782 static size_t read_event_size;
783 static void *read_event_addr;
785 static void read_event_16(void *buf, size_t len)
787 uint16_t *dst = buf;
788 uint16_t *src = read_event_addr;
789 len /= 2;
790 if (len > read_event_size)
791 len = read_event_size;
792 while (len--)
793 *dst++ = *src++;
796 static void read_event_32(void *buf, size_t len)
798 uint32_t *dst = buf;
799 uint32_t *src = read_event_addr;
800 len /= 2;
801 if (len > read_event_size)
802 len = read_event_size;
803 while (len--)
804 *dst++ = *src++;
807 static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(
808 struct adsp_info *info, void *dsp_addr)
810 struct msm_adsp_module *module;
811 unsigned rtos_task_id;
812 unsigned msg_id;
813 unsigned msg_length;
814 void (*func)(void *, size_t);
816 if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
817 uint32_t *dsp_addr32 = dsp_addr;
818 uint32_t tmp = *dsp_addr32++;
819 rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
820 msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M);
821 read_event_size = tmp >> 16;
822 read_event_addr = dsp_addr32;
823 msg_length = read_event_size * sizeof(uint32_t);
824 func = read_event_32;
825 } else {
826 uint16_t *dsp_addr16 = dsp_addr;
827 uint16_t tmp = *dsp_addr16++;
828 rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
829 msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M;
830 read_event_size = *dsp_addr16++;
831 read_event_addr = dsp_addr16;
832 msg_length = read_event_size * sizeof(uint16_t);
833 func = read_event_16;
836 if (rtos_task_id > info->max_task_id) {
837 pr_err("adsp: bogus task id %d\n", rtos_task_id);
838 return 0;
840 module = find_adsp_module_by_id(info,
841 adsp_get_module(info, rtos_task_id));
843 if (!module) {
844 pr_err("adsp: no module for task id %d\n", rtos_task_id);
845 return 0;
848 module->num_events++;
850 if (!module->ops) {
851 pr_err("adsp: module %s is not open\n", module->name);
852 return 0;
855 module->ops->event(module->driver_data, msg_id, msg_length, func);
856 return 0;
859 static int adsp_get_event(struct adsp_info *info)
861 uint32_t ctrl_word;
862 uint32_t ready;
863 void *dsp_addr;
864 uint32_t cmd_type;
865 int cnt;
866 unsigned long flags;
867 int rc = 0;
869 spin_lock_irqsave(&adsp_cmd_lock, flags);
871 /* Whenever the DSP has a message, it updates this control word
872 * and generates an interrupt. When we receive the interrupt, we
873 * read this register to find out what ADSP task the command is
874 * comming from.
876 * The ADSP should *always* be ready on the first call, but the
877 * irq handler calls us in a loop (to handle back-to-back command
878 * processing), so we give the DSP some time to return to the
879 * ready state. The DSP will not issue another IRQ for events
880 * pending between the first IRQ and the event queue being drained,
881 * unfortunately.
884 for (cnt = 0; cnt < 10; cnt++) {
885 ctrl_word = readl(info->read_ctrl);
887 if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) ==
888 ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V)
889 goto ready;
891 udelay(10);
893 pr_warning("adsp: not ready after 100uS\n");
894 rc = -EBUSY;
895 goto done;
897 ready:
898 /* Here we check to see if there are pending messages. If there are
899 * none, we siply return -EAGAIN to indicate that there are no more
900 * messages pending.
902 ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M;
903 if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) &&
904 (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) {
905 rc = -EAGAIN;
906 goto done;
909 /* DSP says that there are messages waiting for the host to read */
911 /* Get the Command Type */
912 cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M;
914 /* Get the DSP buffer address */
915 dsp_addr = (void *)((ctrl_word &
916 ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) +
917 (uint32_t)MSM_AD5_BASE);
919 /* We can only handle Task-to-Host messages */
920 if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) {
921 pr_err("adsp: unknown dsp cmd_type %d\n", cmd_type);
922 rc = -EIO;
923 goto done;
926 adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr);
928 ctrl_word = readl(info->read_ctrl);
929 ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M;
931 /* Write ctrl word to the DSP */
932 writel(ctrl_word, info->read_ctrl);
934 /* Generate an interrupt to the DSP */
935 writel(1, info->send_irq);
937 done:
938 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
939 return rc;
942 static irqreturn_t adsp_irq_handler(int irq, void *data)
944 struct adsp_info *info = &adsp_info;
945 int cnt = 0;
946 for (cnt = 0; cnt < 10; cnt++)
947 if (adsp_get_event(info) < 0)
948 break;
949 if (cnt > info->event_backlog_max)
950 info->event_backlog_max = cnt;
951 info->events_received += cnt;
952 if (cnt == 10)
953 pr_err("adsp: too many (%d) events for single irq!\n", cnt);
954 return IRQ_HANDLED;
957 int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate)
959 if (module->clk && clk_rate)
960 return clk_set_rate(module->clk, clk_rate);
962 return -EINVAL;
965 int msm_adsp_enable(struct msm_adsp_module *module)
967 int rc = 0;
969 pr_info("msm_adsp_enable() '%s'state[%d] id[%d]\n",
970 module->name, module->state, module->id);
972 mutex_lock(&module->lock);
973 switch (module->state) {
974 case ADSP_STATE_DISABLED:
975 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE,
976 module->id, module);
977 if (rc)
978 break;
979 module->state = ADSP_STATE_ENABLING;
980 mutex_unlock(&module->lock);
981 rc = wait_event_timeout(module->state_wait,
982 module->state != ADSP_STATE_ENABLING,
983 1 * HZ);
984 mutex_lock(&module->lock);
985 if (module->state == ADSP_STATE_ENABLED) {
986 rc = 0;
987 } else {
988 pr_err("adsp: module '%s' enable timed out\n",
989 module->name);
990 rc = -ETIMEDOUT;
992 break;
993 case ADSP_STATE_ENABLING:
994 pr_warning("adsp: module '%s' enable in progress\n",
995 module->name);
996 break;
997 case ADSP_STATE_ENABLED:
998 pr_warning("adsp: module '%s' already enabled\n",
999 module->name);
1000 break;
1001 case ADSP_STATE_DISABLING:
1002 pr_err("adsp: module '%s' disable in progress\n",
1003 module->name);
1004 rc = -EBUSY;
1005 break;
1007 mutex_unlock(&module->lock);
1008 return rc;
1010 EXPORT_SYMBOL(msm_adsp_enable);
1012 static int msm_adsp_disable_locked(struct msm_adsp_module *module)
1014 int rc = 0;
1016 switch (module->state) {
1017 case ADSP_STATE_DISABLED:
1018 pr_warning("adsp: module '%s' already disabled\n",
1019 module->name);
1020 break;
1021 case ADSP_STATE_ENABLING:
1022 case ADSP_STATE_ENABLED:
1023 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE,
1024 module->id, module);
1025 module->state = ADSP_STATE_DISABLED;
1027 return rc;
1030 int msm_adsp_disable(struct msm_adsp_module *module)
1032 int rc;
1033 pr_info("msm_adsp_disable() '%s'\n", module->name);
1034 mutex_lock(&module->lock);
1035 rc = msm_adsp_disable_locked(module);
1036 mutex_unlock(&module->lock);
1037 return rc;
1039 EXPORT_SYMBOL(msm_adsp_disable);
1041 static int msm_adsp_probe(struct platform_device *pdev)
1043 unsigned count;
1044 int rc, i;
1045 int max_module_id;
1047 pr_info("adsp: probe\n");
1049 wake_lock_init(&adsp_wake_lock, WAKE_LOCK_SUSPEND, "adsp");
1050 #if CONFIG_MSM_AMSS_VERSION >= 6350
1051 adsp_info.init_info_ptr = kzalloc(
1052 (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
1053 if (!adsp_info.init_info_ptr)
1054 return -ENOMEM;
1055 #endif
1057 rc = adsp_init_info(&adsp_info);
1058 if (rc)
1059 return rc;
1060 adsp_info.send_irq += (uint32_t) MSM_AD5_BASE;
1061 adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE;
1062 adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE;
1063 count = adsp_info.module_count;
1065 #if CONFIG_MSM_AMSS_VERSION >= 6350
1066 max_module_id = count;
1067 #else
1068 max_module_id = adsp_info.max_module_id + 1;
1069 #endif
1071 adsp_modules = kzalloc(
1072 sizeof(struct msm_adsp_module) * count +
1073 sizeof(void *) * max_module_id, GFP_KERNEL);
1074 if (!adsp_modules)
1075 return -ENOMEM;
1077 adsp_info.id_to_module = (void *) (adsp_modules + count);
1079 spin_lock_init(&adsp_cmd_lock);
1081 rc = request_irq(INT_ADSP, adsp_irq_handler, IRQF_TRIGGER_RISING,
1082 "adsp", 0);
1083 if (rc < 0)
1084 goto fail_request_irq;
1085 disable_irq(INT_ADSP);
1087 rpc_cb_server_client = msm_rpc_open();
1088 if (IS_ERR(rpc_cb_server_client)) {
1089 rpc_cb_server_client = NULL;
1090 rc = PTR_ERR(rpc_cb_server_client);
1091 pr_err("adsp: could not create rpc server (%d)\n", rc);
1092 goto fail_rpc_open;
1095 rc = msm_rpc_register_server(rpc_cb_server_client,
1096 RPC_ADSP_RTOS_MTOA_PROG,
1097 RPC_ADSP_RTOS_MTOA_VERS);
1098 if (rc) {
1099 pr_err("adsp: could not register callback server (%d)\n", rc);
1100 goto fail_rpc_register;
1103 /* start the kernel thread to process the callbacks */
1104 kthread_run(adsp_rpc_thread, NULL, "kadspd");
1106 for (i = 0; i < count; i++) {
1107 struct msm_adsp_module *mod = adsp_modules + i;
1108 mutex_init(&mod->lock);
1109 init_waitqueue_head(&mod->state_wait);
1110 mod->info = &adsp_info;
1111 mod->name = adsp_info.module[i].name;
1112 mod->id = adsp_info.module[i].id;
1113 if (adsp_info.module[i].clk_name)
1114 mod->clk = clk_get(NULL, adsp_info.module[i].clk_name);
1115 else
1116 mod->clk = NULL;
1117 if (mod->clk && adsp_info.module[i].clk_rate)
1118 clk_set_rate(mod->clk, adsp_info.module[i].clk_rate);
1119 mod->verify_cmd = adsp_info.module[i].verify_cmd;
1120 mod->patch_event = adsp_info.module[i].patch_event;
1121 INIT_HLIST_HEAD(&mod->pmem_regions);
1122 mod->pdev.name = adsp_info.module[i].pdev_name;
1123 mod->pdev.id = -1;
1124 #if CONFIG_MSM_AMSS_VERSION >= 6350
1125 adsp_info.id_to_module[i] = mod;
1126 #else
1127 adsp_info.id_to_module[mod->id] = mod;
1128 #endif
1129 platform_device_register(&mod->pdev);
1132 msm_adsp_publish_cdevs(adsp_modules, count);
1134 return 0;
1136 fail_rpc_register:
1137 msm_rpc_close(rpc_cb_server_client);
1138 rpc_cb_server_client = NULL;
1139 fail_rpc_open:
1140 enable_irq(INT_ADSP);
1141 free_irq(INT_ADSP, 0);
1142 fail_request_irq:
1143 kfree(adsp_modules);
1144 #if CONFIG_MSM_AMSS_VERSION >= 6350
1145 kfree(adsp_info.init_info_ptr);
1146 #endif
1147 return rc;
1150 static struct platform_driver msm_adsp_driver = {
1151 .probe = msm_adsp_probe,
1152 .driver = {
1153 .name = MSM_ADSP_DRIVER_NAME,
1154 .owner = THIS_MODULE,
1158 static int __init adsp_init(void)
1160 return platform_driver_register(&msm_adsp_driver);
1163 device_initcall(adsp_init);