video: tegra: host: Move device data to nvhost_device
[linux-2.6.git] / drivers / media / video / tegra / nvavp / nvavp_dev.c
1 /*
2  * drivers/media/video/tegra/nvavp/nvavp_dev.c
3  *
4  * Copyright (C) 2011 NVIDIA Corp.
5  *
6  * This file is licensed under the terms of the GNU General Public License
7  * version 2. This program is licensed "as is" without any warranty of any
8  * kind, whether express or implied.
9  */
10
11 #include <linux/uaccess.h>
12 #include <linux/clk.h>
13 #include <linux/completion.h>
14 #include <linux/delay.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/err.h>
17 #include <linux/firmware.h>
18 #include <linux/fs.h>
19 #include <linux/interrupt.h>
20 #include <linux/io.h>
21 #include <linux/ioctl.h>
22 #include <linux/irq.h>
23 #include <linux/kref.h>
24 #include <linux/list.h>
25 #include <linux/miscdevice.h>
26 #include <linux/mutex.h>
27 #include <linux/nvhost.h>
28 #include <linux/platform_device.h>
29 #include <linux/rbtree.h>
30 #include <linux/seq_file.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/tegra_nvavp.h>
34 #include <linux/types.h>
35 #include <linux/vmalloc.h>
36 #include <linux/workqueue.h>
37
38 #include <mach/clk.h>
39 #include <mach/hardware.h>
40 #include <mach/io.h>
41 #include <mach/iomap.h>
42 #include <mach/legacy_irq.h>
43 #include <mach/nvmap.h>
44
45 #include "../../../../video/tegra/nvmap/nvmap.h"
46 #include "../../../../video/tegra/host/host1x/host1x_syncpt.h"
47 #include "../../../../video/tegra/host/dev.h"
48 #include "../../../../video/tegra/host/nvhost_acm.h"
49
50 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
51 #include "../avp/headavp.h"
52 #endif
53 #include "nvavp_os.h"
54
55 #define TEGRA_NVAVP_NAME                        "nvavp"
56
57 #define NVAVP_PUSHBUFFER_SIZE                   4096
58
59 #define NVAVP_PUSHBUFFER_MIN_UPDATE_SPACE       (sizeof(u32) * 3)
60
61 #define TEGRA_NVAVP_RESET_VECTOR_ADDR   \
62                 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x200)
63
64 #define FLOW_CTRL_HALT_COP_EVENTS       IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + 0x4)
65 #define FLOW_MODE_STOP                  (0x2 << 29)
66 #define FLOW_MODE_NONE                  0x0
67
68 #define NVAVP_OS_INBOX                  IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x10)
69 #define NVAVP_OS_OUTBOX                 IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x20)
70
71 #define NVAVP_INBOX_VALID               (1 << 29)
72
73 /* AVP behavior params */
74 #define NVAVP_OS_IDLE_TIMEOUT           100 /* milli-seconds */
75
76 struct nvavp_info {
77         u32                             clk_enabled;
78         struct clk                      *bsev_clk;
79         struct clk                      *vde_clk;
80         struct clk                      *cop_clk;
81
82         /* used for dvfs */
83         struct clk                      *sclk;
84         struct clk                      *emc_clk;
85         unsigned long                   sclk_rate;
86         unsigned long                   emc_clk_rate;
87
88         int                             mbox_from_avp_pend_irq;
89
90         struct mutex                    open_lock;
91         int                             refcount;
92
93         struct work_struct              clock_disable_work;
94
95         /* os information */
96         struct nvavp_os_info            os_info;
97
98         /* ucode information */
99         struct nvavp_ucode_info         ucode_info;
100
101         /* client for driver allocations, persistent */
102         struct nvmap_client             *nvmap;
103
104         struct mutex                    pushbuffer_lock;
105         struct nvmap_handle_ref         *pushbuf_handle;
106         unsigned long                   pushbuf_phys;
107         u8                              *pushbuf_data;
108         u32                             pushbuf_index;
109         u32                             pushbuf_fence;
110
111         struct nv_e276_control          *os_control;
112
113         struct nvhost_syncpt            *nvhost_syncpt;
114         u32                             syncpt_id;
115         u32                             syncpt_value;
116
117         struct nvhost_device            *nvhost_dev;
118         struct miscdevice               misc_dev;
119 };
120
121 struct nvavp_clientctx {
122         struct nvmap_client *nvmap;
123         struct nvavp_pushbuffer_submit_hdr submit_hdr;
124         struct nvavp_reloc relocs[NVAVP_MAX_RELOCATION_COUNT];
125         struct nvmap_handle_ref *gather_mem;
126         int num_relocs;
127         struct nvavp_info *nvavp;
128 };
129
130 static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
131 {
132         if (!nvavp)
133                 return NULL;
134
135         if (id == NVAVP_MODULE_ID_AVP)
136                 return nvavp->sclk;
137         if (id == NVAVP_MODULE_ID_VDE)
138                 return nvavp->vde_clk;
139         if (id == NVAVP_MODULE_ID_EMC)
140                 return nvavp->emc_clk;
141
142         return NULL;
143 }
144
145 static void nvavp_clk_ctrl(struct nvavp_info *nvavp, u32 clk_en)
146 {
147         if (clk_en && !nvavp->clk_enabled) {
148                 clk_enable(nvavp->bsev_clk);
149                 clk_enable(nvavp->vde_clk);
150                 clk_set_rate(nvavp->emc_clk, nvavp->emc_clk_rate);
151                 clk_set_rate(nvavp->sclk, nvavp->sclk_rate);
152                 nvavp->clk_enabled = 1;
153                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting sclk to %lu\n",
154                                 __func__, nvavp->sclk_rate);
155                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting emc_clk to %lu\n",
156                                 __func__, nvavp->emc_clk_rate);
157         } else if (!clk_en && nvavp->clk_enabled) {
158                 clk_disable(nvavp->bsev_clk);
159                 clk_disable(nvavp->vde_clk);
160                 clk_set_rate(nvavp->emc_clk, 0);
161                 clk_set_rate(nvavp->sclk, 0);
162                 nvavp->clk_enabled = 0;
163                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: resetting emc_clk "
164                                 "and sclk\n", __func__);
165         }
166 }
167
168 static u32 nvavp_check_idle(struct nvavp_info *nvavp)
169 {
170         struct nv_e276_control *control = nvavp->os_control;
171         return (control->put == control->get) ? 1 : 0;
172 }
173
174 static void clock_disable_handler(struct work_struct *work)
175 {
176         struct nvavp_info *nvavp;
177
178         nvavp = container_of(work, struct nvavp_info,
179                             clock_disable_work);
180
181         mutex_lock(&nvavp->pushbuffer_lock);
182         nvavp_clk_ctrl(nvavp, !nvavp_check_idle(nvavp));
183         mutex_unlock(&nvavp->pushbuffer_lock);
184 }
185
186 static int nvavp_service(struct nvavp_info *nvavp)
187 {
188         struct nvavp_os_info *os = &nvavp->os_info;
189         u8 *debug_print;
190         u32 inbox;
191
192         inbox = readl(NVAVP_OS_INBOX);
193         if (!(inbox & NVAVP_INBOX_VALID))
194                 inbox = 0x00000000;
195
196         writel(0x00000000, NVAVP_OS_INBOX);
197
198         if (inbox & NVE276_OS_INTERRUPT_VIDEO_IDLE)
199                 schedule_work(&nvavp->clock_disable_work);
200
201         if (inbox & NVE276_OS_INTERRUPT_DEBUG_STRING) {
202                 /* Should only occur with debug AVP OS builds */
203                 debug_print = os->data;
204                 debug_print += os->debug_offset;
205                 dev_info(&nvavp->nvhost_dev->dev, "%s\n", debug_print);
206         }
207         if (inbox & (NVE276_OS_INTERRUPT_SEMAPHORE_AWAKEN |
208                      NVE276_OS_INTERRUPT_EXECUTE_AWAKEN)) {
209                 dev_info(&nvavp->nvhost_dev->dev,
210                         "AVP awaken event (0x%x)\n", inbox);
211         }
212         if (inbox & NVE276_OS_INTERRUPT_AVP_FATAL_ERROR) {
213                 dev_err(&nvavp->nvhost_dev->dev,
214                         "fatal AVP error (0x%08X)\n", inbox);
215         }
216         if (inbox & NVE276_OS_INTERRUPT_AVP_BREAKPOINT)
217                 dev_err(&nvavp->nvhost_dev->dev, "AVP breakpoint hit\n");
218         if (inbox & NVE276_OS_INTERRUPT_TIMEOUT)
219                 dev_err(&nvavp->nvhost_dev->dev, "AVP timeout\n");
220
221         return 0;
222 }
223
224 static irqreturn_t nvavp_mbox_pending_isr(int irq, void *data)
225 {
226         struct nvavp_info *nvavp = data;
227
228         nvavp_service(nvavp);
229
230         return IRQ_HANDLED;
231 }
232
233 static void nvavp_halt_avp(struct nvavp_info *nvavp)
234 {
235         /* ensure the AVP is halted */
236         writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS);
237         tegra_periph_reset_assert(nvavp->cop_clk);
238
239         writel(0, NVAVP_OS_OUTBOX);
240         writel(0, NVAVP_OS_INBOX);
241 }
242
243 static int nvavp_reset_avp(struct nvavp_info *nvavp, unsigned long reset_addr)
244 {
245 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
246         unsigned long stub_code_phys = virt_to_phys(_tegra_avp_boot_stub);
247         dma_addr_t stub_data_phys;
248
249         _tegra_avp_boot_stub_data.map_phys_addr = avp->kernel_phys;
250         _tegra_avp_boot_stub_data.jump_addr = reset_addr;
251         wmb();
252         stub_data_phys = dma_map_single(NULL, &_tegra_avp_boot_stub_data,
253                                         sizeof(_tegra_avp_boot_stub_data),
254                                         DMA_TO_DEVICE);
255         rmb();
256         reset_addr = (unsigned long)stub_data_phys;
257 #endif
258         writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS);
259
260         writel(reset_addr, TEGRA_NVAVP_RESET_VECTOR_ADDR);
261
262         clk_enable(nvavp->sclk);
263         clk_enable(nvavp->emc_clk);
264
265         /* If sclk_rate and emc_clk is not set by user space,
266          * max clock in dvfs table will be used to get best performance.
267          */
268         nvavp->sclk_rate = ULONG_MAX;
269         nvavp->emc_clk_rate = ULONG_MAX;
270
271         tegra_periph_reset_assert(nvavp->cop_clk);
272         udelay(2);
273         tegra_periph_reset_deassert(nvavp->cop_clk);
274
275         writel(FLOW_MODE_NONE, FLOW_CTRL_HALT_COP_EVENTS);
276
277 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
278         dma_unmap_single(NULL, stub_data_phys,
279                          sizeof(_tegra_avp_boot_stub_data),
280                          DMA_TO_DEVICE);
281 #endif
282         return 0;
283 }
284
285 static void nvavp_halt_vde(struct nvavp_info *nvavp)
286 {
287         if (nvavp->clk_enabled) {
288                 tegra_periph_reset_assert(nvavp->bsev_clk);
289                 clk_disable(nvavp->bsev_clk);
290                 tegra_periph_reset_assert(nvavp->vde_clk);
291                 clk_disable(nvavp->vde_clk);
292                 nvavp->clk_enabled = 0;
293         }
294 }
295
296 static int nvavp_reset_vde(struct nvavp_info *nvavp)
297 {
298         clk_enable(nvavp->bsev_clk);
299         tegra_periph_reset_assert(nvavp->bsev_clk);
300         udelay(2);
301         tegra_periph_reset_deassert(nvavp->bsev_clk);
302
303         clk_enable(nvavp->vde_clk);
304         tegra_periph_reset_assert(nvavp->vde_clk);
305         udelay(2);
306         tegra_periph_reset_deassert(nvavp->vde_clk);
307
308         /*
309          * VDE clock is set to max freq by default.
310          * VDE clock can be set to different freq if needed
311          * through ioctl.
312          */
313         clk_set_rate(nvavp->vde_clk, ULONG_MAX);
314
315         nvavp->clk_enabled = 1;
316         return 0;
317 }
318
319 static int nvavp_pushbuffer_alloc(struct nvavp_info *nvavp)
320 {
321         int ret = 0;
322
323         nvavp->pushbuf_handle = nvmap_alloc(nvavp->nvmap, NVAVP_PUSHBUFFER_SIZE,
324                                 SZ_1M, NVMAP_HANDLE_UNCACHEABLE);
325         if (IS_ERR(nvavp->pushbuf_handle)) {
326                 dev_err(&nvavp->nvhost_dev->dev,
327                         "cannot create pushbuffer handle\n");
328                 ret = PTR_ERR(nvavp->pushbuf_handle);
329                 goto err_pushbuf_alloc;
330         }
331         nvavp->pushbuf_data = (u8 *)nvmap_mmap(nvavp->pushbuf_handle);
332         if (!nvavp->pushbuf_data) {
333                 dev_err(&nvavp->nvhost_dev->dev,
334                         "cannot map pushbuffer handle\n");
335                 ret = -ENOMEM;
336                 goto err_pushbuf_mmap;
337         }
338         nvavp->pushbuf_phys = nvmap_pin(nvavp->nvmap, nvavp->pushbuf_handle);
339         if (IS_ERR((void *)nvavp->pushbuf_phys)) {
340                 dev_err(&nvavp->nvhost_dev->dev,
341                         "cannot pin pushbuffer handle\n");
342                 ret = PTR_ERR((void *)nvavp->pushbuf_phys);
343                 goto err_pushbuf_pin;
344         }
345
346         memset(nvavp->pushbuf_data, 0, NVAVP_PUSHBUFFER_SIZE);
347
348         return 0;
349
350 err_pushbuf_pin:
351         nvmap_munmap(nvavp->pushbuf_handle, nvavp->pushbuf_data);
352 err_pushbuf_mmap:
353         nvmap_free(nvavp->nvmap, nvavp->pushbuf_handle);
354 err_pushbuf_alloc:
355         return ret;
356 }
357
358 static void nvavp_pushbuffer_free(struct nvavp_info *nvavp)
359 {
360         nvmap_unpin(nvavp->nvmap, nvavp->pushbuf_handle);
361         nvmap_munmap(nvavp->pushbuf_handle, nvavp->pushbuf_data);
362         nvmap_free(nvavp->nvmap, nvavp->pushbuf_handle);
363 }
364
365 static int nvavp_pushbuffer_init(struct nvavp_info *nvavp)
366 {
367         void *ptr;
368         struct nvavp_os_info *os = &nvavp->os_info;
369         struct nv_e276_control *control;
370         u32 temp;
371         int ret;
372
373         ret = nvavp_pushbuffer_alloc(nvavp);
374         if (ret) {
375                 dev_err(&nvavp->nvhost_dev->dev,
376                         "unable to alloc pushbuffer\n");
377                 return ret;
378         }
379
380         ptr = os->data;
381         ptr += os->control_offset;
382         nvavp->os_control = (struct nv_e276_control *)ptr;
383
384         control = nvavp->os_control;
385         memset(control, 0, sizeof(struct nvavp_os_info));
386
387         /* init get and put pointers */
388         writel(0x0, &control->put);
389         writel(0x0, &control->get);
390
391         /* enable avp VDE clock control and disable iram clock gating */
392         writel(0x0, &control->idle_clk_enable);
393         writel(0x0, &control->iram_clk_gating);
394
395         /* enable avp idle timeout interrupt */
396         writel(0x1, &control->idle_notify_enable);
397         writel(NVAVP_OS_IDLE_TIMEOUT, &control->idle_notify_delay);
398
399         /* init dma start and end pointers */
400         writel(nvavp->pushbuf_phys, &control->dma_start);
401         writel((nvavp->pushbuf_phys + NVAVP_PUSHBUFFER_SIZE),
402                                         &control->dma_end);
403
404         writel(0x00, &nvavp->pushbuf_index);
405         temp = NVAVP_PUSHBUFFER_SIZE - NVAVP_PUSHBUFFER_MIN_UPDATE_SPACE;
406         writel(temp, &nvavp->pushbuf_fence);
407
408         nvavp->syncpt_id = NVSYNCPT_AVP_0;
409         nvavp->syncpt_value = nvhost_syncpt_read(nvavp->nvhost_syncpt,
410                                                  nvavp->syncpt_id);
411
412         return 0;
413 }
414
415 static void nvavp_pushbuffer_deinit(struct nvavp_info *nvavp)
416 {
417         nvavp_pushbuffer_free(nvavp);
418 }
419
420 static int nvavp_pushbuffer_update(struct nvavp_info *nvavp, u32 phys_addr,
421                         u32 gather_count, struct nvavp_syncpt *syncpt,
422                         u32 ext_ucode_flag)
423 {
424         struct nv_e276_control *control = nvavp->os_control;
425         u32 gather_cmd, setucode_cmd, sync = 0;
426         u32 wordcount = 0;
427         u32 index, value = -1;
428
429         mutex_lock(&nvavp->pushbuffer_lock);
430
431         /* check for pushbuffer wrapping */
432         if (nvavp->pushbuf_index >= nvavp->pushbuf_fence)
433                 nvavp->pushbuf_index = 0;
434
435         if (!ext_ucode_flag) {
436                 setucode_cmd =
437                         NVE26E_CH_OPCODE_INCR(NVE276_SET_MICROCODE_A, 3);
438
439                 index = wordcount + nvavp->pushbuf_index;
440                 writel(setucode_cmd, (nvavp->pushbuf_data + index));
441                 wordcount += sizeof(u32);
442
443                 index = wordcount + nvavp->pushbuf_index;
444                 writel(0, (nvavp->pushbuf_data + index));
445                 wordcount += sizeof(u32);
446
447                 index = wordcount + nvavp->pushbuf_index;
448                 writel(nvavp->ucode_info.phys, (nvavp->pushbuf_data + index));
449                 wordcount += sizeof(u32);
450
451                 index = wordcount + nvavp->pushbuf_index;
452                 writel(nvavp->ucode_info.size, (nvavp->pushbuf_data + index));
453                 wordcount += sizeof(u32);
454         }
455
456         gather_cmd = NVE26E_CH_OPCODE_GATHER(0, 0, 0, gather_count);
457
458         if (syncpt) {
459                 value = ++nvavp->syncpt_value;
460                 /* XXX: NvSchedValueWrappingComparison */
461                 sync = NVE26E_CH_OPCODE_IMM(NVE26E_HOST1X_INCR_SYNCPT,
462                         (NVE26E_HOST1X_INCR_SYNCPT_COND_OP_DONE << 8) |
463                         (nvavp->syncpt_id & 0xFF));
464         }
465
466         /* write commands out */
467         index = wordcount + nvavp->pushbuf_index;
468         writel(gather_cmd, (nvavp->pushbuf_data + index));
469         wordcount += sizeof(u32);
470
471         index = wordcount + nvavp->pushbuf_index;
472         writel(phys_addr, (nvavp->pushbuf_data + index));
473         wordcount += sizeof(u32);
474
475         if (syncpt) {
476                 index = wordcount + nvavp->pushbuf_index;
477                 writel(sync, (nvavp->pushbuf_data + index));
478                 wordcount += sizeof(u32);
479         }
480
481         /* enable clocks to VDE/BSEV */
482         nvavp_clk_ctrl(nvavp, 1);
483
484         /* update put pointer */
485         nvavp->pushbuf_index = (nvavp->pushbuf_index + wordcount) &
486                                         (NVAVP_PUSHBUFFER_SIZE - 1);
487         writel(nvavp->pushbuf_index, &control->put);
488         wmb();
489
490         /* wake up avp */
491         writel(0xA0000001, NVAVP_OS_OUTBOX);
492
493         /* Fill out fence struct */
494         if (syncpt) {
495                 syncpt->id = nvavp->syncpt_id;
496                 syncpt->value = value;
497         }
498
499         mutex_unlock(&nvavp->pushbuffer_lock);
500
501         return 0;
502 }
503
504 static void nvavp_unload_ucode(struct nvavp_info *nvavp)
505 {
506         nvmap_unpin(nvavp->nvmap, nvavp->ucode_info.handle);
507         nvmap_munmap(nvavp->ucode_info.handle, nvavp->ucode_info.data);
508         nvmap_free(nvavp->nvmap, nvavp->ucode_info.handle);
509         kfree(nvavp->ucode_info.ucode_bin);
510 }
511
512 static int nvavp_load_ucode(struct nvavp_info *nvavp)
513 {
514         struct nvavp_ucode_info *ucode_info = &nvavp->ucode_info;
515         const struct firmware *nvavp_ucode_fw;
516         char fw_ucode_file[32];
517         void *ptr;
518         int ret = 0;
519
520         if (!ucode_info->ucode_bin) {
521                 sprintf(fw_ucode_file, "nvavp_vid_ucode.bin");
522
523                 ret = request_firmware(&nvavp_ucode_fw, fw_ucode_file,
524                                         nvavp->misc_dev.this_device);
525                 if (ret) {
526                         /* Try alternative version */
527                         sprintf(fw_ucode_file, "nvavp_vid_ucode_alt.bin");
528
529                         ret = request_firmware(&nvavp_ucode_fw,
530                                                 fw_ucode_file,
531                                                 nvavp->misc_dev.this_device);
532
533                         if (ret) {
534                                 dev_err(&nvavp->nvhost_dev->dev,
535                                         "cannot read ucode firmware '%s'\n",
536                                         fw_ucode_file);
537                                 goto err_req_ucode;
538                         }
539                 }
540
541                 dev_info(&nvavp->nvhost_dev->dev,
542                         "read ucode firmware from '%s' (%d bytes)\n",
543                         fw_ucode_file, nvavp_ucode_fw->size);
544
545                 ptr = (void *)nvavp_ucode_fw->data;
546
547                 if (strncmp((const char *)ptr, "NVAVPAPP", 8)) {
548                         dev_info(&nvavp->nvhost_dev->dev,
549                                 "ucode hdr string mismatch\n");
550                         ret = -EINVAL;
551                         goto err_req_ucode;
552                 }
553                 ptr += 8;
554                 ucode_info->size = nvavp_ucode_fw->size - 8;
555
556                 ucode_info->ucode_bin = kzalloc(ucode_info->size,
557                                                 GFP_KERNEL);
558                 if (!ucode_info->ucode_bin) {
559                         dev_err(&nvavp->nvhost_dev->dev,
560                                 "cannot allocate ucode bin\n");
561                         ret = -ENOMEM;
562                         goto err_ubin_alloc;
563                 }
564
565                 ucode_info->handle = nvmap_alloc(nvavp->nvmap,
566                                                 nvavp->ucode_info.size,
567                                         SZ_1M, NVMAP_HANDLE_UNCACHEABLE);
568                 if (IS_ERR(ucode_info->handle)) {
569                         dev_err(&nvavp->nvhost_dev->dev,
570                                 "cannot create ucode handle\n");
571                         ret = PTR_ERR(ucode_info->handle);
572                         goto err_ucode_alloc;
573                 }
574                 ucode_info->data = (u8 *)nvmap_mmap(ucode_info->handle);
575                 if (!ucode_info->data) {
576                         dev_err(&nvavp->nvhost_dev->dev,
577                                 "cannot map ucode handle\n");
578                         ret = -ENOMEM;
579                         goto err_ucode_mmap;
580                 }
581                 ucode_info->phys = nvmap_pin(nvavp->nvmap, ucode_info->handle);
582                 if (IS_ERR((void *)ucode_info->phys)) {
583                         dev_err(&nvavp->nvhost_dev->dev,
584                                 "cannot pin ucode handle\n");
585                         ret = PTR_ERR((void *)ucode_info->phys);
586                         goto err_ucode_pin;
587                 }
588                 memcpy(ucode_info->ucode_bin, ptr, ucode_info->size);
589                 release_firmware(nvavp_ucode_fw);
590         }
591
592         memcpy(ucode_info->data, ucode_info->ucode_bin, ucode_info->size);
593         return 0;
594
595 err_ucode_pin:
596         nvmap_munmap(ucode_info->handle, ucode_info->data);
597 err_ucode_mmap:
598         nvmap_free(nvavp->nvmap, ucode_info->handle);
599 err_ucode_alloc:
600         kfree(nvavp->ucode_info.ucode_bin);
601 err_ubin_alloc:
602         release_firmware(nvavp_ucode_fw);
603 err_req_ucode:
604         return ret;
605 }
606
607 static void nvavp_unload_os(struct nvavp_info *nvavp)
608 {
609         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
610         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
611 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
612         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
613 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
614         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
615 #endif
616         kfree(nvavp->os_info.os_bin);
617 }
618
619 static int nvavp_load_os(struct nvavp_info *nvavp, char *fw_os_file)
620 {
621         struct nvavp_os_info *os_info = &nvavp->os_info;
622         const struct firmware *nvavp_os_fw;
623         void *ptr;
624         u32 size;
625         int ret = 0;
626
627         if (!os_info->os_bin) {
628                 ret = request_firmware(&nvavp_os_fw, fw_os_file,
629                                         nvavp->misc_dev.this_device);
630                 if (ret) {
631                         dev_err(&nvavp->nvhost_dev->dev,
632                                 "cannot read os firmware '%s'\n", fw_os_file);
633                         goto err_req_fw;
634                 }
635
636                 dev_info(&nvavp->nvhost_dev->dev,
637                         "read firmware from '%s' (%d bytes)\n",
638                         fw_os_file, nvavp_os_fw->size);
639
640                 ptr = (void *)nvavp_os_fw->data;
641
642                 if (strncmp((const char *)ptr, "NVAVP-OS", 8)) {
643                         dev_info(&nvavp->nvhost_dev->dev,
644                                 "os hdr string mismatch\n");
645                         ret = -EINVAL;
646                         goto err_os_bin;
647                 }
648
649                 ptr += 8;
650                 os_info->entry_offset = *((u32 *)ptr);
651                 ptr += sizeof(u32);
652                 os_info->control_offset = *((u32 *)ptr);
653                 ptr += sizeof(u32);
654                 os_info->debug_offset = *((u32 *)ptr);
655                 ptr += sizeof(u32);
656
657                 size = *((u32 *)ptr);    ptr += sizeof(u32);
658
659                 os_info->size = size;
660                 os_info->os_bin = kzalloc(os_info->size,
661                                                 GFP_KERNEL);
662                 if (!os_info->os_bin) {
663                         dev_err(&nvavp->nvhost_dev->dev,
664                                 "cannot allocate os bin\n");
665                         ret = -ENOMEM;
666                         goto err_os_bin;
667                 }
668
669                 memcpy(os_info->os_bin, ptr, os_info->size);
670                 memset(os_info->data + os_info->size, 0, SZ_1M - os_info->size);
671
672                 dev_info(&nvavp->nvhost_dev->dev,
673                         "entry=%08x control=%08x debug=%08x size=%d\n",
674                         os_info->entry_offset, os_info->control_offset,
675                         os_info->debug_offset, os_info->size);
676                 release_firmware(nvavp_os_fw);
677         }
678
679         memcpy(os_info->data, os_info->os_bin, os_info->size);
680         os_info->reset_addr = os_info->phys + os_info->entry_offset;
681
682         dev_info(&nvavp->nvhost_dev->dev,
683                 "AVP os at vaddr=%p paddr=%lx reset_addr=%p\n",
684                 os_info->data, (unsigned long)(os_info->phys),
685                                 (void *)os_info->reset_addr);
686         return 0;
687
688 err_os_bin:
689         release_firmware(nvavp_os_fw);
690 err_req_fw:
691         return ret;
692 }
693
694 static int nvavp_init(struct nvavp_info *nvavp)
695 {
696         char fw_os_file[32];
697         int ret = 0;
698
699 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
700         /* paddr is any address returned from nvmap_pin */
701         /* vaddr is AVP_KERNEL_VIRT_BASE */
702         dev_info(&nvavp->nvhost_dev->dev,
703                 "using AVP MMU to relocate AVP os\n");
704         sprintf(fw_os_file, "nvavp_os.bin");
705         nvavp->os_info.reset_addr = AVP_KERNEL_VIRT_BASE;
706 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
707         /* paddr is any address behind SMMU */
708         /* vaddr is TEGRA_SMMU_BASE */
709         dev_info(&nvavp->nvhost_dev->dev,
710                 "using SMMU at %lx to load AVP kernel\n",
711                 (unsigned long)nvavp->os_info.phys);
712         BUG_ON(nvavp->os_info.phys != 0xeff00000
713                 && nvavp->os_info.phys != 0x0ff00000);
714         sprintf(fw_os_file, "nvavp_os_%08lx.bin",
715                 (unsigned long)nvavp->os_info.phys);
716         nvavp->os_info.reset_addr = nvavp->os_info.phys;
717 #else /* nvmem= carveout */
718         /* paddr is found in nvmem= carveout */
719         /* vaddr is same as paddr */
720         /* Find nvmem carveout */
721         if (!pfn_valid(__phys_to_pfn(0x8e000000))) {
722                 nvavp->os_info->phys = 0x8e000000;
723         } else if (!pfn_valid(__phys_to_pfn(0x9e000000))) {
724                 nvavp->os_info.phys = 0x9e000000;
725         } else if (!pfn_valid(__phys_to_pfn(0xbe000000))) {
726                 nvavp->os_info.phys = 0xbe000000;
727         } else {
728                 dev_err(&nvavp->nvhost_dev->dev,
729                         "cannot find nvmem= carveout to load AVP os\n");
730                 dev_err(&nvavp->nvhost_dev->dev,
731                         "check kernel command line "
732                         "to see if nvmem= is defined\n");
733                 BUG();
734         }
735         dev_info(&nvavp->nvhost_dev->dev,
736                 "using nvmem= carveout at %lx to load AVP os\n",
737                 nvavp->os_info.phys);
738         sprintf(fw_os_file, "nvavp_os_%08lx.bin", nvavp->os_info.phys);
739         nvavp->os_info.reset_addr = nvavp->os_info.phys;
740         nvavp->os_info.data = ioremap(nvavp->os_info.phys, SZ_1M);
741 #endif
742
743         ret = nvavp_load_os(nvavp, fw_os_file);
744         if (ret) {
745                 dev_err(&nvavp->nvhost_dev->dev,
746                         "unable to load os firmware '%s'\n", fw_os_file);
747                 goto err_exit;
748         }
749
750         ret = nvavp_pushbuffer_init(nvavp);
751         if (ret) {
752                 dev_err(&nvavp->nvhost_dev->dev,
753                         "unable to init pushbuffer\n");
754                 goto err_exit;
755         }
756
757         ret = nvavp_load_ucode(nvavp);
758         if (ret) {
759                 dev_err(&nvavp->nvhost_dev->dev,
760                         "unable to load ucode\n");
761                 goto err_exit;
762         }
763
764         tegra_init_legacy_irq_cop();
765
766         nvavp_reset_vde(nvavp);
767         nvavp_reset_avp(nvavp, nvavp->os_info.reset_addr);
768         enable_irq(nvavp->mbox_from_avp_pend_irq);
769
770 err_exit:
771         return ret;
772 }
773
774 static void nvavp_uninit(struct nvavp_info *nvavp)
775 {
776         disable_irq(nvavp->mbox_from_avp_pend_irq);
777
778         cancel_work_sync(&nvavp->clock_disable_work);
779
780         nvavp_pushbuffer_deinit(nvavp);
781
782         nvavp_halt_vde(nvavp);
783         nvavp_halt_avp(nvavp);
784
785         clk_disable(nvavp->sclk);
786         clk_disable(nvavp->emc_clk);
787 }
788
789 static int nvavp_set_clock_ioctl(struct file *filp, unsigned int cmd,
790                                                         unsigned long arg)
791 {
792         struct nvavp_clientctx *clientctx = filp->private_data;
793         struct nvavp_info *nvavp = clientctx->nvavp;
794         struct clk *c;
795         struct nvavp_clock_args config;
796
797         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
798                 return -EFAULT;
799
800         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d, clk_rate=%lu\n",
801                         __func__, config.id, config.rate);
802
803         if (config.id == NVAVP_MODULE_ID_AVP)
804                 nvavp->sclk_rate = config.rate;
805         else if (config.id == NVAVP_MODULE_ID_EMC)
806                 nvavp->emc_clk_rate = config.rate;
807
808         c = nvavp_clk_get(nvavp, config.id);
809         if (IS_ERR_OR_NULL(c))
810                 return -EINVAL;
811
812         clk_enable(c);
813         clk_set_rate(c, config.rate);
814
815         config.rate = clk_get_rate(c);
816         clk_disable(c);
817         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
818                 return -EFAULT;
819
820         return 0;
821 }
822
823 static int nvavp_get_clock_ioctl(struct file *filp, unsigned int cmd,
824                                                         unsigned long arg)
825 {
826         struct nvavp_clientctx *clientctx = filp->private_data;
827         struct nvavp_info *nvavp = clientctx->nvavp;
828         struct clk *c;
829         struct nvavp_clock_args config;
830
831         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
832                 return -EFAULT;
833
834         c = nvavp_clk_get(nvavp, config.id);
835         if (IS_ERR_OR_NULL(c))
836                 return -EINVAL;
837
838         clk_enable(c);
839         config.rate = clk_get_rate(c);
840         clk_disable(c);
841
842         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
843                 return -EFAULT;
844
845         return 0;
846 }
847
848 static int nvavp_get_syncpointid_ioctl(struct file *filp, unsigned int cmd,
849                                                         unsigned long arg)
850 {
851         struct nvavp_clientctx *clientctx = filp->private_data;
852         struct nvavp_info *nvavp = clientctx->nvavp;
853         u32 id = nvavp->syncpt_id;
854
855         if (_IOC_DIR(cmd) & _IOC_READ) {
856                 if (copy_to_user((void __user *)arg, &id, sizeof(u32)))
857                         return -EFAULT;
858                 else
859                         return 0;
860         }
861         return -EFAULT;
862 }
863
864 static int nvavp_set_nvmapfd_ioctl(struct file *filp, unsigned int cmd,
865                                                         unsigned long arg)
866 {
867         struct nvavp_clientctx *clientctx = filp->private_data;
868         struct nvavp_set_nvmap_fd_args buf;
869         struct nvmap_client *new_client;
870         int fd;
871
872         if (_IOC_DIR(cmd) & _IOC_WRITE) {
873                 if (copy_from_user(&buf, (void __user *)arg, _IOC_SIZE(cmd)))
874                         return -EFAULT;
875         }
876
877         fd = buf.fd;
878         new_client = nvmap_client_get_file(fd);
879         if (IS_ERR(new_client))
880                 return PTR_ERR(new_client);
881
882         clientctx->nvmap = new_client;
883         return 0;
884 }
885
886 static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
887                                                         unsigned long arg)
888 {
889         struct nvavp_clientctx *clientctx = filp->private_data;
890         struct nvavp_info *nvavp = clientctx->nvavp;
891         struct nvavp_pushbuffer_submit_hdr hdr;
892         u32 *cmdbuf_data;
893         struct nvmap_handle *cmdbuf_handle = NULL;
894         struct nvmap_handle_ref *cmdbuf_dupe;
895         int ret = 0, i;
896         unsigned long phys_addr;
897         unsigned long virt_addr;
898         struct nvavp_pushbuffer_submit_hdr *user_hdr =
899                         (struct nvavp_pushbuffer_submit_hdr *) arg;
900         struct nvavp_syncpt syncpt;
901
902         syncpt.id = NVSYNCPT_INVALID;
903         syncpt.value = 0;
904
905         if (_IOC_DIR(cmd) & _IOC_WRITE) {
906                 if (copy_from_user(&hdr, (void __user *)arg,
907                         sizeof(struct nvavp_pushbuffer_submit_hdr)))
908                         return -EFAULT;
909         }
910
911         if (!hdr.cmdbuf.mem)
912                 return 0;
913
914         if (copy_from_user(clientctx->relocs, (void __user *)hdr.relocs,
915                         sizeof(struct nvavp_reloc) * hdr.num_relocs)) {
916                 return -EFAULT;
917         }
918
919         cmdbuf_handle = nvmap_get_handle_id(clientctx->nvmap, hdr.cmdbuf.mem);
920         if (cmdbuf_handle == NULL) {
921                 dev_err(&nvavp->nvhost_dev->dev,
922                         "invalid cmd buffer handle %08x\n", hdr.cmdbuf.mem);
923                 return -EPERM;
924         }
925
926         /* duplicate the new pushbuffer's handle into the nvavp driver's
927          * nvmap context, to ensure that the handle won't be freed as
928          * long as it is in-use by the fb driver */
929         cmdbuf_dupe = nvmap_duplicate_handle_id(nvavp->nvmap, hdr.cmdbuf.mem);
930         nvmap_handle_put(cmdbuf_handle);
931
932         if (IS_ERR(cmdbuf_dupe)) {
933                 dev_err(&nvavp->nvhost_dev->dev,
934                         "could not duplicate handle\n");
935                 return PTR_ERR(cmdbuf_dupe);
936         }
937
938         phys_addr = nvmap_pin(nvavp->nvmap, cmdbuf_dupe);
939         if (IS_ERR((void *)phys_addr)) {
940                 dev_err(&nvavp->nvhost_dev->dev, "could not pin handle\n");
941                 nvmap_free(nvavp->nvmap, cmdbuf_dupe);
942                 return PTR_ERR((void *)phys_addr);
943         }
944
945         virt_addr = (unsigned long)nvmap_mmap(cmdbuf_dupe);
946         if (!virt_addr) {
947                 dev_err(&nvavp->nvhost_dev->dev, "cannot map cmdbuf handle\n");
948                 ret = -ENOMEM;
949                 goto err_cmdbuf_mmap;
950         }
951
952         cmdbuf_data = (u32 *)(virt_addr + hdr.cmdbuf.offset);
953
954         for (i = 0; i < hdr.num_relocs; i++) {
955                 u32 *reloc_addr, target_phys_addr;
956
957                 if (clientctx->relocs[i].cmdbuf_mem != hdr.cmdbuf.mem) {
958                         dev_err(&nvavp->nvhost_dev->dev,
959                                 "reloc info does not match target bufferID\n");
960                         ret = -EPERM;
961                         goto err_reloc_info;
962                 }
963
964                 reloc_addr = cmdbuf_data +
965                              (clientctx->relocs[i].cmdbuf_offset >> 2);
966
967                 target_phys_addr = nvmap_handle_address(clientctx->nvmap,
968                                             clientctx->relocs[i].target);
969                 target_phys_addr += clientctx->relocs[i].target_offset;
970                 writel(target_phys_addr, reloc_addr);
971         }
972
973         if (hdr.syncpt) {
974                 ret = nvavp_pushbuffer_update(nvavp,
975                                              (phys_addr + hdr.cmdbuf.offset),
976                                               hdr.cmdbuf.words, &syncpt,
977                                               (hdr.flags & NVAVP_UCODE_EXT));
978
979                 if (copy_to_user((void __user *)user_hdr->syncpt, &syncpt,
980                                 sizeof(struct nvavp_syncpt))) {
981                         ret = -EFAULT;
982                         goto err_reloc_info;
983                 }
984         } else {
985                 ret = nvavp_pushbuffer_update(nvavp,
986                                              (phys_addr + hdr.cmdbuf.offset),
987                                               hdr.cmdbuf.words, NULL,
988                                               (hdr.flags & NVAVP_UCODE_EXT));
989         }
990
991 err_reloc_info:
992         nvmap_munmap(cmdbuf_dupe, (void *)virt_addr);
993 err_cmdbuf_mmap:
994         nvmap_unpin(nvavp->nvmap, cmdbuf_dupe);
995         nvmap_free(nvavp->nvmap, cmdbuf_dupe);
996         return ret;
997 }
998
999 static int tegra_nvavp_open(struct inode *inode, struct file *filp)
1000 {
1001         struct miscdevice *miscdev = filp->private_data;
1002         struct nvavp_info *nvavp = dev_get_drvdata(miscdev->parent);
1003         int ret = 0;
1004         struct nvavp_clientctx *clientctx;
1005
1006         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1007
1008         nonseekable_open(inode, filp);
1009
1010         clientctx = kzalloc(sizeof(*clientctx), GFP_KERNEL);
1011         if (!clientctx)
1012                 return -ENOMEM;
1013
1014         mutex_lock(&nvavp->open_lock);
1015
1016         if (!nvavp->refcount)
1017                 ret = nvavp_init(nvavp);
1018
1019         if (!ret)
1020                 nvavp->refcount++;
1021
1022         clientctx->nvmap = nvavp->nvmap;
1023         clientctx->nvavp = nvavp;
1024
1025         filp->private_data = clientctx;
1026
1027         nvhost_module_busy(nvavp->nvhost_dev->host->dev);
1028         mutex_unlock(&nvavp->open_lock);
1029
1030         return ret;
1031 }
1032
1033 static int tegra_nvavp_release(struct inode *inode, struct file *filp)
1034 {
1035         struct nvavp_clientctx *clientctx = filp->private_data;
1036         struct nvavp_info *nvavp = clientctx->nvavp;
1037         int ret = 0;
1038
1039         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1040
1041         filp->private_data = NULL;
1042         nvhost_module_idle(nvavp->nvhost_dev->host->dev);
1043
1044         mutex_lock(&nvavp->open_lock);
1045
1046         if (!nvavp->refcount) {
1047                 dev_err(&nvavp->nvhost_dev->dev,
1048                         "releasing while in invalid state\n");
1049                 ret = -EINVAL;
1050                 goto out;
1051         }
1052
1053         if (nvavp->refcount > 0)
1054                 nvavp->refcount--;
1055         if (!nvavp->refcount)
1056                 nvavp_uninit(nvavp);
1057
1058 out:
1059         mutex_unlock(&nvavp->open_lock);
1060         kfree(clientctx);
1061         return ret;
1062 }
1063
1064 static long tegra_nvavp_ioctl(struct file *filp, unsigned int cmd,
1065                             unsigned long arg)
1066 {
1067         int ret = 0;
1068
1069         if (_IOC_TYPE(cmd) != NVAVP_IOCTL_MAGIC ||
1070             _IOC_NR(cmd) < NVAVP_IOCTL_MIN_NR ||
1071             _IOC_NR(cmd) > NVAVP_IOCTL_MAX_NR)
1072                 return -EFAULT;
1073
1074         switch (cmd) {
1075         case NVAVP_IOCTL_SET_NVMAP_FD:
1076                 ret = nvavp_set_nvmapfd_ioctl(filp, cmd, arg);
1077                 break;
1078         case NVAVP_IOCTL_GET_SYNCPOINT_ID:
1079                 ret = nvavp_get_syncpointid_ioctl(filp, cmd, arg);
1080                 break;
1081         case NVAVP_IOCTL_PUSH_BUFFER_SUBMIT:
1082                 ret = nvavp_pushbuffer_submit_ioctl(filp, cmd, arg);
1083                 break;
1084         case NVAVP_IOCTL_SET_CLOCK:
1085                 ret = nvavp_set_clock_ioctl(filp, cmd, arg);
1086                 break;
1087         case NVAVP_IOCTL_GET_CLOCK:
1088                 ret = nvavp_get_clock_ioctl(filp, cmd, arg);
1089                 break;
1090         default:
1091                 ret = -EINVAL;
1092                 break;
1093         }
1094         return ret;
1095 }
1096
1097 static const struct file_operations tegra_nvavp_fops = {
1098         .owner          = THIS_MODULE,
1099         .open           = tegra_nvavp_open,
1100         .release        = tegra_nvavp_release,
1101         .unlocked_ioctl = tegra_nvavp_ioctl,
1102 };
1103
1104 static int tegra_nvavp_probe(struct nvhost_device *ndev)
1105 {
1106         struct nvavp_info *nvavp;
1107         int irq;
1108         unsigned int heap_mask;
1109         u32 iovmm_addr;
1110         int ret = 0;
1111
1112         irq = nvhost_get_irq_byname(ndev, "mbox_from_nvavp_pending");
1113         if (irq < 0) {
1114                 dev_err(&ndev->dev, "invalid nvhost data\n");
1115                 return -EINVAL;
1116         }
1117
1118
1119         nvavp = kzalloc(sizeof(struct nvavp_info), GFP_KERNEL);
1120         if (!nvavp) {
1121                 dev_err(&ndev->dev, "cannot allocate avp_info\n");
1122                 return -ENOMEM;
1123         }
1124
1125         memset(nvavp, 0, sizeof(*nvavp));
1126
1127         nvavp->nvhost_syncpt = &ndev->host->syncpt;
1128         if (!nvavp->nvhost_syncpt) {
1129                 dev_err(&ndev->dev, "cannot get syncpt handle\n");
1130                 ret = -ENOENT;
1131                 goto err_get_syncpt;
1132         }
1133
1134         nvavp->nvmap = nvmap_create_client(nvmap_dev, "nvavp_drv");
1135         if (IS_ERR_OR_NULL(nvavp->nvmap)) {
1136                 dev_err(&ndev->dev, "cannot create nvmap client\n");
1137                 ret = PTR_ERR(nvavp->nvmap);
1138                 goto err_nvmap_create_drv_client;
1139         }
1140
1141 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
1142         heap_mask = NVMAP_HEAP_CARVEOUT_GENERIC;
1143 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
1144         heap_mask = NVMAP_HEAP_IOVMM;
1145 #else /* nvmem= carveout */
1146         heap_mask = 0;
1147 #endif
1148         switch (heap_mask) {
1149         case NVMAP_HEAP_IOVMM:
1150                 iovmm_addr = 0x0ff00000;
1151
1152                 /* Tegra3 A01 has different SMMU address */
1153                 if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3
1154                         && tegra_get_revision() == TEGRA_REVISION_A01) {
1155                         iovmm_addr = 0xeff00000;
1156                 }
1157
1158                 nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M,
1159                                                 L1_CACHE_BYTES,
1160                                                 NVMAP_HANDLE_UNCACHEABLE,
1161                                                 iovmm_addr);
1162                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1163                         dev_err(&ndev->dev,
1164                                 "cannot create os handle\n");
1165                         ret = PTR_ERR(nvavp->os_info.handle);
1166                         goto err_nvmap_alloc;
1167                 }
1168
1169                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1170                 if (!nvavp->os_info.data) {
1171                         dev_err(&ndev->dev,
1172                                 "cannot map os handle\n");
1173                         ret = -ENOMEM;
1174                         goto err_nvmap_mmap;
1175                 }
1176
1177                 nvavp->os_info.phys =
1178                         nvmap_pin(nvavp->nvmap, nvavp->os_info.handle);
1179                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1180                         dev_err(&ndev->dev,
1181                                 "cannot pin os handle\n");
1182                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1183                         goto err_nvmap_pin;
1184                 }
1185
1186                 dev_info(&ndev->dev,
1187                         "allocated IOVM at %lx for AVP os\n",
1188                         (unsigned long)nvavp->os_info.phys);
1189                 break;
1190         case NVMAP_HEAP_CARVEOUT_GENERIC:
1191                 nvavp->os_info.handle = nvmap_alloc(nvavp->nvmap, SZ_1M, SZ_1M,
1192                                                 NVMAP_HANDLE_UNCACHEABLE);
1193                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1194                         dev_err(&ndev->dev, "cannot create AVP os handle\n");
1195                         ret = PTR_ERR(nvavp->os_info.handle);
1196                         goto err_nvmap_alloc;
1197                 }
1198
1199                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1200                 if (!nvavp->os_info.data) {
1201                         dev_err(&ndev->dev, "cannot map AVP os handle\n");
1202                         ret = -ENOMEM;
1203                         goto err_nvmap_mmap;
1204                 }
1205
1206                 nvavp->os_info.phys = nvmap_pin(nvavp->nvmap,
1207                                         nvavp->os_info.handle);
1208                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1209                         dev_err(&ndev->dev, "cannot pin AVP os handle\n");
1210                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1211                         goto err_nvmap_pin;
1212                 }
1213
1214                 dev_info(&ndev->dev,
1215                         "allocated carveout memory at %lx for AVP os\n",
1216                         (unsigned long)nvavp->os_info.phys);
1217                 break;
1218         default:
1219                 dev_err(&ndev->dev, "invalid/non-supported heap for AVP os\n");
1220                 ret = -EINVAL;
1221                 goto err_get_syncpt;
1222         }
1223
1224         nvavp->mbox_from_avp_pend_irq = irq;
1225         mutex_init(&nvavp->open_lock);
1226         mutex_init(&nvavp->pushbuffer_lock);
1227
1228         /* TODO DO NOT USE NVAVP DEVICE */
1229         nvavp->cop_clk = clk_get(&ndev->dev, "cop");
1230         if (IS_ERR(nvavp->cop_clk)) {
1231                 dev_err(&ndev->dev, "cannot get cop clock\n");
1232                 ret = -ENOENT;
1233                 goto err_get_cop_clk;
1234         }
1235
1236         nvavp->vde_clk = clk_get(&ndev->dev, "vde");
1237         if (IS_ERR(nvavp->vde_clk)) {
1238                 dev_err(&ndev->dev, "cannot get vde clock\n");
1239                 ret = -ENOENT;
1240                 goto err_get_vde_clk;
1241         }
1242
1243         nvavp->bsev_clk = clk_get(&ndev->dev, "bsev");
1244         if (IS_ERR(nvavp->bsev_clk)) {
1245                 dev_err(&ndev->dev, "cannot get bsev clock\n");
1246                 ret = -ENOENT;
1247                 goto err_get_bsev_clk;
1248         }
1249
1250         nvavp->sclk = clk_get(&ndev->dev, "sclk");
1251         if (IS_ERR(nvavp->sclk)) {
1252                 dev_err(&ndev->dev, "cannot get avp.sclk clock\n");
1253                 ret = -ENOENT;
1254                 goto err_get_sclk;
1255         }
1256
1257         nvavp->emc_clk = clk_get(&ndev->dev, "emc");
1258         if (IS_ERR(nvavp->emc_clk)) {
1259                 dev_err(&ndev->dev, "cannot get emc clock\n");
1260                 ret = -ENOENT;
1261                 goto err_get_emc_clk;
1262         }
1263
1264         nvavp->clk_enabled = 0;
1265         nvavp_halt_avp(nvavp);
1266
1267         INIT_WORK(&nvavp->clock_disable_work, clock_disable_handler);
1268
1269         nvavp->misc_dev.minor = MISC_DYNAMIC_MINOR;
1270         nvavp->misc_dev.name = "tegra_avpchannel";
1271         nvavp->misc_dev.fops = &tegra_nvavp_fops;
1272         nvavp->misc_dev.mode = S_IRWXUGO;
1273         nvavp->misc_dev.parent = &ndev->dev;
1274
1275         ret = misc_register(&nvavp->misc_dev);
1276         if (ret) {
1277                 dev_err(&ndev->dev, "unable to register misc device!\n");
1278                 goto err_misc_reg;
1279         }
1280
1281         ret = request_irq(irq, nvavp_mbox_pending_isr, 0,
1282                           TEGRA_NVAVP_NAME, nvavp);
1283         if (ret) {
1284                 dev_err(&ndev->dev, "cannot register irq handler\n");
1285                 goto err_req_irq_pend;
1286         }
1287         disable_irq(nvavp->mbox_from_avp_pend_irq);
1288
1289         nvhost_set_drvdata(ndev, nvavp);
1290         nvavp->nvhost_dev = ndev;
1291
1292         return 0;
1293
1294 err_req_irq_pend:
1295         misc_deregister(&nvavp->misc_dev);
1296 err_misc_reg:
1297         clk_put(nvavp->emc_clk);
1298 err_get_emc_clk:
1299         clk_put(nvavp->sclk);
1300 err_get_sclk:
1301         clk_put(nvavp->bsev_clk);
1302 err_get_bsev_clk:
1303         clk_put(nvavp->vde_clk);
1304 err_get_vde_clk:
1305         clk_put(nvavp->cop_clk);
1306 err_get_cop_clk:
1307         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
1308 err_nvmap_pin:
1309         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
1310 err_nvmap_mmap:
1311 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
1312         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
1313 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
1314         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
1315 #endif
1316 err_nvmap_alloc:
1317         nvmap_client_put(nvavp->nvmap);
1318 err_nvmap_create_drv_client:
1319 err_get_syncpt:
1320         kfree(nvavp);
1321         return ret;
1322 }
1323
1324 static int tegra_nvavp_remove(struct nvhost_device *ndev)
1325 {
1326         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1327
1328         if (!nvavp)
1329                 return 0;
1330
1331         mutex_lock(&nvavp->open_lock);
1332         if (nvavp->refcount) {
1333                 mutex_unlock(&nvavp->open_lock);
1334                 return -EBUSY;
1335         }
1336         mutex_unlock(&nvavp->open_lock);
1337
1338         nvavp_unload_ucode(nvavp);
1339         nvavp_unload_os(nvavp);
1340
1341         misc_deregister(&nvavp->misc_dev);
1342
1343         clk_put(nvavp->bsev_clk);
1344         clk_put(nvavp->vde_clk);
1345         clk_put(nvavp->cop_clk);
1346
1347         clk_put(nvavp->emc_clk);
1348         clk_put(nvavp->sclk);
1349
1350         nvmap_client_put(nvavp->nvmap);
1351
1352         kfree(nvavp);
1353         return 0;
1354 }
1355
1356 #ifdef CONFIG_PM
1357 static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state)
1358 {
1359         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1360
1361         if (nvavp->refcount)
1362                 nvhost_module_idle(ndev);
1363         return 0;
1364 }
1365
1366 static int tegra_nvavp_resume(struct nvhost_device *ndev)
1367 {
1368         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1369
1370         if (nvavp->refcount)
1371                 nvhost_module_busy(ndev);
1372         return 0;
1373 }
1374 #endif
1375
1376 static struct nvhost_driver tegra_nvavp_driver = {
1377         .driver = {
1378                 .name   = TEGRA_NVAVP_NAME,
1379                 .owner  = THIS_MODULE,
1380         },
1381         .probe          = tegra_nvavp_probe,
1382         .remove         = tegra_nvavp_remove,
1383 #ifdef CONFIG_PM
1384         .suspend        = tegra_nvavp_suspend,
1385         .resume         = tegra_nvavp_resume,
1386 #endif
1387 };
1388
1389 static int __init tegra_nvavp_init(void)
1390 {
1391         return nvhost_driver_register(&tegra_nvavp_driver);
1392 }
1393
1394 static void __exit tegra_nvavp_exit(void)
1395 {
1396         nvhost_driver_unregister(&tegra_nvavp_driver);
1397 }
1398
1399 module_init(tegra_nvavp_init);
1400 module_exit(tegra_nvavp_exit);
1401
1402 MODULE_AUTHOR("NVIDIA");
1403 MODULE_DESCRIPTION("Channel based AVP driver for Tegra");
1404 MODULE_VERSION("1.0");
1405 MODULE_LICENSE("Dual BSD/GPL");