Merge commit 'main-jb-2012.08.03-B4' into t114-0806
[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) 2012, NVIDIA CORPORATION.  All rights reserved.
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/module.h>
27 #include <linux/mutex.h>
28 #include <linux/nvhost.h>
29 #include <linux/platform_device.h>
30 #include <linux/rbtree.h>
31 #include <linux/seq_file.h>
32 #include <linux/slab.h>
33 #include <linux/string.h>
34 #include <linux/tegra_nvavp.h>
35 #include <linux/types.h>
36 #include <linux/vmalloc.h>
37 #include <linux/workqueue.h>
38
39 #include <mach/clk.h>
40 #include <mach/hardware.h>
41 #include <mach/io.h>
42 #include <mach/iomap.h>
43 #include <mach/legacy_irq.h>
44 #include <linux/nvmap.h>
45
46 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
47 #include "../avp/headavp.h"
48 #endif
49 #include "nvavp_os.h"
50
51 #define TEGRA_NVAVP_NAME                        "nvavp"
52
53 #define NVAVP_PUSHBUFFER_SIZE                   4096
54
55 #define NVAVP_PUSHBUFFER_MIN_UPDATE_SPACE       (sizeof(u32) * 3)
56
57 #define TEGRA_NVAVP_RESET_VECTOR_ADDR   \
58                 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x200)
59
60 #define FLOW_CTRL_HALT_COP_EVENTS       IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + 0x4)
61 #define FLOW_MODE_STOP                  (0x2 << 29)
62 #define FLOW_MODE_NONE                  0x0
63
64 #define NVAVP_OS_INBOX                  IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x10)
65 #define NVAVP_OS_OUTBOX                 IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x20)
66
67 #define NVAVP_INBOX_VALID               (1 << 29)
68
69 /* AVP behavior params */
70 #define NVAVP_OS_IDLE_TIMEOUT           100 /* milli-seconds */
71
72 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
73 /* Two control channels: Audio and Video channels */
74 #define NVAVP_NUM_CHANNELS              2
75
76 #define NVAVP_AUDIO_CHANNEL             1
77
78 #define IS_AUDIO_CHANNEL_ID(channel_id) (channel_id == NVAVP_AUDIO_CHANNEL ? 1: 0)
79 #else
80 #define NVAVP_NUM_CHANNELS              1
81 #endif
82
83 /* Channel ID 0 represents the Video channel control area */
84 #define NVAVP_VIDEO_CHANNEL             0
85 /* Channel ID 1 represents the Audio channel control area */
86
87 #define IS_VIDEO_CHANNEL_ID(channel_id) (channel_id == NVAVP_VIDEO_CHANNEL ? 1: 0)
88
89
90 struct nvavp_channel {
91         struct mutex                    pushbuffer_lock;
92         struct nvmap_handle_ref         *pushbuf_handle;
93         unsigned long                   pushbuf_phys;
94         u8                              *pushbuf_data;
95         u32                             pushbuf_index;
96         u32                             pushbuf_fence;
97         struct nv_e276_control          *os_control;
98 };
99
100 struct nvavp_info {
101         u32                             clk_enabled;
102         struct clk                      *bsev_clk;
103         struct clk                      *vde_clk;
104         struct clk                      *cop_clk;
105 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
106         struct clk                      *bsea_clk;
107         struct clk                      *vcp_clk;
108 #endif
109
110         /* used for dvfs */
111         struct clk                      *sclk;
112         struct clk                      *emc_clk;
113         unsigned long                   sclk_rate;
114         unsigned long                   emc_clk_rate;
115
116         int                             mbox_from_avp_pend_irq;
117
118         struct mutex                    open_lock;
119         int                             refcount;
120         int                             video_initialized;
121 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
122         int                             audio_initialized;
123         struct work_struct              app_notify_work;
124 #endif
125         struct work_struct              clock_disable_work;
126
127         /* os information */
128         struct nvavp_os_info            os_info;
129
130         /* ucode information */
131         struct nvavp_ucode_info         ucode_info;
132
133         /* client for driver allocations, persistent */
134         struct nvmap_client             *nvmap;
135
136         struct nvavp_channel            channel_info[NVAVP_NUM_CHANNELS];
137         bool                            pending;
138
139         u32                             syncpt_id;
140         u32                             syncpt_value;
141
142         struct nvhost_device            *nvhost_dev;
143         struct miscdevice               video_misc_dev;
144 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
145         struct miscdevice               audio_misc_dev;
146 #endif
147 };
148
149 struct nvavp_clientctx {
150         struct nvmap_client *nvmap;
151         struct nvavp_pushbuffer_submit_hdr submit_hdr;
152         struct nvavp_reloc relocs[NVAVP_MAX_RELOCATION_COUNT];
153         struct nvmap_handle_ref *gather_mem;
154         int num_relocs;
155         struct nvavp_info *nvavp;
156         int channel_id;
157         u32 clk_reqs;
158 };
159
160 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
161 static int nvavp_get_audio_init_status(struct nvavp_info *nvavp)
162 {
163         return nvavp->audio_initialized;
164 }
165
166 static void nvavp_set_audio_init_status(struct nvavp_info *nvavp, int status)
167 {
168         nvavp->audio_initialized = status;
169 }
170 #endif
171
172 static void nvavp_set_video_init_status(struct nvavp_info *nvavp, int status)
173 {
174         nvavp->video_initialized = status;
175 }
176
177 static int nvavp_get_video_init_status(struct nvavp_info *nvavp)
178 {
179         return nvavp->video_initialized;
180 }
181
182 static struct nvavp_channel *nvavp_get_channel_info(struct nvavp_info *nvavp, int channel_id)
183 {
184         return &nvavp->channel_info[channel_id];
185 }
186
187 static void nvavp_set_channel_control_area(struct nvavp_info *nvavp, int channel_id)
188 {
189         struct nv_e276_control *control;
190         struct nvavp_os_info *os = &nvavp->os_info;
191         u32 temp;
192         void *ptr;
193         struct nvavp_channel *channel_info;
194
195         ptr = os->data + os->control_offset + (sizeof(struct nv_e276_control) * channel_id);
196
197         channel_info = nvavp_get_channel_info(nvavp, channel_id);
198         channel_info->os_control = (struct nv_e276_control *)ptr;
199
200         control = channel_info->os_control;
201
202         /* init get and put pointers */
203         writel(0x0, &control->put);
204         writel(0x0, &control->get);
205
206         pr_debug("nvavp_set_channel_control_area for channel_id (%d):\
207                 control->put (0x%08x) control->get (0x%08x)\n",
208                 channel_id, (u32) &control->put, (u32) &control->get);
209
210         /* enable avp VDE clock control and disable iram clock gating */
211         writel(0x0, &control->idle_clk_enable);
212         writel(0x0, &control->iram_clk_gating);
213
214         /* enable avp idle timeout interrupt */
215         writel(0x1, &control->idle_notify_enable);
216         writel(NVAVP_OS_IDLE_TIMEOUT, &control->idle_notify_delay);
217
218         /* init dma start and end pointers */
219         writel(channel_info->pushbuf_phys, &control->dma_start);
220         writel((channel_info->pushbuf_phys + NVAVP_PUSHBUFFER_SIZE),
221                                                 &control->dma_end);
222
223         writel(0x00, &channel_info->pushbuf_index);
224         temp = NVAVP_PUSHBUFFER_SIZE - NVAVP_PUSHBUFFER_MIN_UPDATE_SPACE;
225         writel(temp, &channel_info->pushbuf_fence);
226 }
227
228 static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
229 {
230         if (!nvavp)
231                 return NULL;
232
233         if (id == NVAVP_MODULE_ID_AVP)
234                 return nvavp->sclk;
235         if (id == NVAVP_MODULE_ID_VDE)
236                 return nvavp->vde_clk;
237         if (id == NVAVP_MODULE_ID_EMC)
238                 return nvavp->emc_clk;
239
240         return NULL;
241 }
242
243 static void nvavp_clks_enable(struct nvavp_info *nvavp)
244 {
245         if (nvavp->clk_enabled++ == 0) {
246                 nvhost_module_busy_ext(nvhost_get_parent(nvavp->nvhost_dev));
247                 clk_enable(nvavp->bsev_clk);
248                 clk_enable(nvavp->vde_clk);
249                 clk_set_rate(nvavp->emc_clk, nvavp->emc_clk_rate);
250                 clk_set_rate(nvavp->sclk, nvavp->sclk_rate);
251                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting sclk to %lu\n",
252                                 __func__, nvavp->sclk_rate);
253                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting emc_clk to %lu\n",
254                                 __func__, nvavp->emc_clk_rate);
255         }
256 }
257
258 static void nvavp_clks_disable(struct nvavp_info *nvavp)
259 {
260         if (--nvavp->clk_enabled == 0) {
261                 clk_disable(nvavp->bsev_clk);
262                 clk_disable(nvavp->vde_clk);
263                 clk_set_rate(nvavp->emc_clk, 0);
264                 clk_set_rate(nvavp->sclk, 0);
265                 nvhost_module_idle_ext(nvhost_get_parent(nvavp->nvhost_dev));
266                 dev_dbg(&nvavp->nvhost_dev->dev, "%s: resetting emc_clk "
267                                 "and sclk\n", __func__);
268         }
269 }
270
271 static u32 nvavp_check_idle(struct nvavp_info *nvavp, int channel_id)
272 {
273         struct nvavp_channel *channel_info = nvavp_get_channel_info(nvavp, channel_id);
274         struct nv_e276_control *control = channel_info->os_control;
275
276         return (control->put == control->get) ? 1 : 0;
277 }
278
279 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
280 static void app_notify_handler(struct work_struct *work)
281 {
282         struct nvavp_info *nvavp;
283
284         nvavp = container_of(work, struct nvavp_info,
285                             app_notify_work);
286
287         kobject_uevent(&nvavp->nvhost_dev->dev.kobj, KOBJ_CHANGE);
288 }
289 #endif
290
291 static void clock_disable_handler(struct work_struct *work)
292 {
293         struct nvavp_info *nvavp;
294         struct nvavp_channel *channel_info;
295
296         nvavp = container_of(work, struct nvavp_info,
297                             clock_disable_work);
298
299         channel_info = nvavp_get_channel_info(nvavp, NVAVP_VIDEO_CHANNEL);
300         mutex_lock(&channel_info->pushbuffer_lock);
301         mutex_lock(&nvavp->open_lock);
302         if (nvavp_check_idle(nvavp, NVAVP_VIDEO_CHANNEL) && nvavp->pending) {
303                 nvavp->pending = false;
304                 nvavp_clks_disable(nvavp);
305         }
306         mutex_unlock(&nvavp->open_lock);
307         mutex_unlock(&channel_info->pushbuffer_lock);
308 }
309
310 static int nvavp_service(struct nvavp_info *nvavp)
311 {
312         struct nvavp_os_info *os = &nvavp->os_info;
313         u8 *debug_print;
314         u32 inbox;
315
316         inbox = readl(NVAVP_OS_INBOX);
317         if (!(inbox & NVAVP_INBOX_VALID))
318                 inbox = 0x00000000;
319
320         if (inbox & NVE276_OS_INTERRUPT_VIDEO_IDLE)
321                 schedule_work(&nvavp->clock_disable_work);
322
323 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
324         if (inbox & NVE276_OS_INTERRUPT_AUDIO_IDLE)
325                 pr_debug("nvavp_service NVE276_OS_INTERRUPT_AUDIO_IDLE\n");
326 #endif
327         if (inbox & NVE276_OS_INTERRUPT_DEBUG_STRING) {
328                 /* Should only occur with debug AVP OS builds */
329                 debug_print = os->data;
330                 debug_print += os->debug_offset;
331                 dev_info(&nvavp->nvhost_dev->dev, "%s\n", debug_print);
332         }
333         if (inbox & (NVE276_OS_INTERRUPT_SEMAPHORE_AWAKEN |
334                      NVE276_OS_INTERRUPT_EXECUTE_AWAKEN)) {
335                 dev_info(&nvavp->nvhost_dev->dev,
336                         "AVP awaken event (0x%x)\n", inbox);
337         }
338         if (inbox & NVE276_OS_INTERRUPT_AVP_FATAL_ERROR) {
339                 dev_err(&nvavp->nvhost_dev->dev,
340                         "fatal AVP error (0x%08X)\n", inbox);
341         }
342         if (inbox & NVE276_OS_INTERRUPT_AVP_BREAKPOINT)
343                 dev_err(&nvavp->nvhost_dev->dev, "AVP breakpoint hit\n");
344         if (inbox & NVE276_OS_INTERRUPT_TIMEOUT)
345                 dev_err(&nvavp->nvhost_dev->dev, "AVP timeout\n");
346         writel(inbox & NVAVP_INBOX_VALID, NVAVP_OS_INBOX);
347
348 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
349         if (inbox & NVE276_OS_INTERRUPT_APP_NOTIFY) {
350                 pr_debug("nvavp_service NVE276_OS_INTERRUPT_APP_NOTIFY\n");
351                 schedule_work(&nvavp->app_notify_work);
352         }
353 #endif
354
355         return 0;
356 }
357
358 static irqreturn_t nvavp_mbox_pending_isr(int irq, void *data)
359 {
360         struct nvavp_info *nvavp = data;
361
362         nvavp_service(nvavp);
363
364         return IRQ_HANDLED;
365 }
366
367 static void nvavp_halt_avp(struct nvavp_info *nvavp)
368 {
369         /* ensure the AVP is halted */
370         writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS);
371         tegra_periph_reset_assert(nvavp->cop_clk);
372
373         writel(0, NVAVP_OS_OUTBOX);
374         writel(0, NVAVP_OS_INBOX);
375 }
376
377 static int nvavp_reset_avp(struct nvavp_info *nvavp, unsigned long reset_addr)
378 {
379 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
380         unsigned long stub_code_phys = virt_to_phys(_tegra_avp_boot_stub);
381         dma_addr_t stub_data_phys;
382
383         _tegra_avp_boot_stub_data.map_phys_addr = avp->kernel_phys;
384         _tegra_avp_boot_stub_data.jump_addr = reset_addr;
385         wmb();
386         stub_data_phys = dma_map_single(NULL, &_tegra_avp_boot_stub_data,
387                                         sizeof(_tegra_avp_boot_stub_data),
388                                         DMA_TO_DEVICE);
389         rmb();
390         reset_addr = (unsigned long)stub_data_phys;
391 #endif
392         writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS);
393
394         writel(reset_addr, TEGRA_NVAVP_RESET_VECTOR_ADDR);
395
396         clk_enable(nvavp->sclk);
397         clk_enable(nvavp->emc_clk);
398
399         /* If sclk_rate and emc_clk is not set by user space,
400          * max clock in dvfs table will be used to get best performance.
401          */
402         nvavp->sclk_rate = ULONG_MAX;
403         nvavp->emc_clk_rate = ULONG_MAX;
404
405         tegra_periph_reset_assert(nvavp->cop_clk);
406         udelay(2);
407         tegra_periph_reset_deassert(nvavp->cop_clk);
408
409         writel(FLOW_MODE_NONE, FLOW_CTRL_HALT_COP_EVENTS);
410
411 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
412         dma_unmap_single(NULL, stub_data_phys,
413                          sizeof(_tegra_avp_boot_stub_data),
414                          DMA_TO_DEVICE);
415 #endif
416         return 0;
417 }
418
419 static void nvavp_halt_vde(struct nvavp_info *nvavp)
420 {
421         if (nvavp->clk_enabled && !nvavp->pending)
422                 BUG();
423
424         if (nvavp->pending) {
425                 nvavp_clks_disable(nvavp);
426                 nvavp->pending = false;
427         }
428
429         tegra_periph_reset_assert(nvavp->bsev_clk);
430         tegra_periph_reset_assert(nvavp->vde_clk);
431 }
432
433 static int nvavp_reset_vde(struct nvavp_info *nvavp)
434 {
435         if (nvavp->clk_enabled)
436                 BUG();
437
438         nvavp_clks_enable(nvavp);
439
440         tegra_periph_reset_assert(nvavp->bsev_clk);
441         udelay(2);
442         tegra_periph_reset_deassert(nvavp->bsev_clk);
443
444         tegra_periph_reset_assert(nvavp->vde_clk);
445         udelay(2);
446         tegra_periph_reset_deassert(nvavp->vde_clk);
447
448         /*
449          * VDE clock is set to max freq by default.
450          * VDE clock can be set to different freq if needed
451          * through ioctl.
452          */
453         clk_set_rate(nvavp->vde_clk, ULONG_MAX);
454
455         nvavp_clks_disable(nvavp);
456
457         return 0;
458 }
459
460 static int nvavp_pushbuffer_alloc(struct nvavp_info *nvavp, int channel_id)
461 {
462         int ret = 0;
463
464         struct nvavp_channel *channel_info = nvavp_get_channel_info(
465                                                         nvavp, channel_id);
466
467         channel_info->pushbuf_handle = nvmap_alloc(nvavp->nvmap,
468                                                 NVAVP_PUSHBUFFER_SIZE,
469                                                 SZ_1M, NVMAP_HANDLE_UNCACHEABLE,
470                                                 0);
471         if (IS_ERR(channel_info->pushbuf_handle)) {
472                 dev_err(&nvavp->nvhost_dev->dev,
473                         "cannot create pushbuffer handle\n");
474                 ret = PTR_ERR(channel_info->pushbuf_handle);
475                 goto err_pushbuf_alloc;
476         }
477         channel_info->pushbuf_data = (u8 *)nvmap_mmap(
478                                                 channel_info->pushbuf_handle);
479
480         if (!channel_info->pushbuf_data) {
481                 dev_err(&nvavp->nvhost_dev->dev,
482                         "cannot map pushbuffer handle\n");
483                 ret = -ENOMEM;
484                 goto err_pushbuf_mmap;
485         }
486         channel_info->pushbuf_phys = nvmap_pin(nvavp->nvmap,
487                                         channel_info->pushbuf_handle);
488         if (IS_ERR((void *)channel_info->pushbuf_phys)) {
489                 dev_err(&nvavp->nvhost_dev->dev,
490                         "cannot pin pushbuffer handle\n");
491                 ret = PTR_ERR((void *)channel_info->pushbuf_phys);
492                 goto err_pushbuf_pin;
493         }
494
495         memset(channel_info->pushbuf_data, 0, NVAVP_PUSHBUFFER_SIZE);
496
497         return 0;
498
499 err_pushbuf_pin:
500         nvmap_munmap(channel_info->pushbuf_handle, channel_info->pushbuf_data);
501 err_pushbuf_mmap:
502         nvmap_free(nvavp->nvmap, channel_info->pushbuf_handle);
503 err_pushbuf_alloc:
504         return ret;
505 }
506
507 static void nvavp_pushbuffer_free(struct nvavp_info *nvavp)
508 {
509         int channel_id;
510
511         for (channel_id = 0; channel_id < NVAVP_NUM_CHANNELS; channel_id++) {
512                 if (nvavp->channel_info[channel_id].pushbuf_data) {
513                         nvmap_unpin(nvavp->nvmap,
514                                 nvavp->channel_info[channel_id].pushbuf_handle);
515                         nvmap_munmap(
516                                 nvavp->channel_info[channel_id].pushbuf_handle,
517                                 nvavp->channel_info[channel_id].pushbuf_data);
518                         nvmap_free(nvavp->nvmap,
519                                 nvavp->channel_info[channel_id].pushbuf_handle);
520                 }
521         }
522 }
523
524
525 static int nvavp_pushbuffer_init(struct nvavp_info *nvavp)
526 {
527         int ret, channel_id;
528
529         for (channel_id = 0; channel_id < NVAVP_NUM_CHANNELS; channel_id++) {
530                 ret = nvavp_pushbuffer_alloc(nvavp, channel_id);
531                 if (ret) {
532                         dev_err(&nvavp->nvhost_dev->dev,
533                                 "unable to alloc pushbuffer\n");
534                         return ret;
535                 }
536                 nvavp_set_channel_control_area(nvavp, channel_id);
537                 if (IS_VIDEO_CHANNEL_ID(channel_id)) {
538                         nvavp->syncpt_id = NVSYNCPT_AVP_0;
539                         nvavp->syncpt_value = nvhost_syncpt_read_ext(
540                                 nvavp->nvhost_dev, nvavp->syncpt_id);
541                 }
542
543         }
544         return 0;
545 }
546
547 static void nvavp_pushbuffer_deinit(struct nvavp_info *nvavp)
548 {
549         nvavp_pushbuffer_free(nvavp);
550 }
551
552 static int nvavp_pushbuffer_update(struct nvavp_info *nvavp, u32 phys_addr,
553                         u32 gather_count, struct nvavp_syncpt *syncpt,
554                         u32 ext_ucode_flag, int channel_id)
555 {
556         struct nvavp_channel  *channel_info;
557         struct nv_e276_control *control;
558         u32 gather_cmd, setucode_cmd, sync = 0;
559         u32 wordcount = 0;
560         u32 index, value = -1;
561
562         channel_info = nvavp_get_channel_info(nvavp, channel_id);
563
564         control = channel_info->os_control;
565         pr_debug("nvavp_pushbuffer_update for channel_id (%d):\
566                 control->put (0x%x) control->get (0x%x)\n",
567                 channel_id, (u32) &control->put, (u32) &control->get);
568
569         mutex_lock(&channel_info->pushbuffer_lock);
570
571         /* check for pushbuffer wrapping */
572         if (channel_info->pushbuf_index >= channel_info->pushbuf_fence)
573                 channel_info->pushbuf_index = 0;
574
575         if (!ext_ucode_flag) {
576                 setucode_cmd =
577                         NVE26E_CH_OPCODE_INCR(NVE276_SET_MICROCODE_A, 3);
578
579                 index = wordcount + channel_info->pushbuf_index;
580                 writel(setucode_cmd, (channel_info->pushbuf_data + index));
581                 wordcount += sizeof(u32);
582
583                 index = wordcount + channel_info->pushbuf_index;
584                 writel(0, (channel_info->pushbuf_data + index));
585                 wordcount += sizeof(u32);
586
587                 index = wordcount + channel_info->pushbuf_index;
588                 writel(nvavp->ucode_info.phys,
589                         (channel_info->pushbuf_data + index));
590                 wordcount += sizeof(u32);
591
592                 index = wordcount + channel_info->pushbuf_index;
593                 writel(nvavp->ucode_info.size,
594                         (channel_info->pushbuf_data + index));
595                 wordcount += sizeof(u32);
596         }
597
598         gather_cmd = NVE26E_CH_OPCODE_GATHER(0, 0, 0, gather_count);
599
600         if (syncpt) {
601                 value = ++nvavp->syncpt_value;
602                 /* XXX: NvSchedValueWrappingComparison */
603                 sync = NVE26E_CH_OPCODE_IMM(NVE26E_HOST1X_INCR_SYNCPT,
604                         (NVE26E_HOST1X_INCR_SYNCPT_COND_OP_DONE << 8) |
605                         (nvavp->syncpt_id & 0xFF));
606         }
607
608         /* write commands out */
609         index = wordcount + channel_info->pushbuf_index;
610         writel(gather_cmd, (channel_info->pushbuf_data + index));
611         wordcount += sizeof(u32);
612
613         index = wordcount + channel_info->pushbuf_index;
614         writel(phys_addr, (channel_info->pushbuf_data + index));
615         wordcount += sizeof(u32);
616
617         if (syncpt) {
618                 index = wordcount + channel_info->pushbuf_index;
619                 writel(sync, (channel_info->pushbuf_data + index));
620                 wordcount += sizeof(u32);
621         }
622
623         /* enable clocks to VDE/BSEV */
624         mutex_lock(&nvavp->open_lock);
625         if (!nvavp->pending && IS_VIDEO_CHANNEL_ID(channel_id)) {
626                 nvavp_clks_enable(nvavp);
627                 nvavp->pending = true;
628         }
629         mutex_unlock(&nvavp->open_lock);
630
631         /* update put pointer */
632         channel_info->pushbuf_index = (channel_info->pushbuf_index + wordcount)&
633                                         (NVAVP_PUSHBUFFER_SIZE - 1);
634
635         writel(channel_info->pushbuf_index, &control->put);
636         wmb();
637
638         /* wake up avp */
639
640         if (IS_VIDEO_CHANNEL_ID(channel_id)) {
641                 pr_debug("Wake up Video Channel\n");
642                 writel(0xA0000001, NVAVP_OS_OUTBOX);
643         }
644         else {
645 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
646                 if (IS_AUDIO_CHANNEL_ID(channel_id)) {
647                         pr_debug("Wake up Audio Channel\n");
648                         writel(0xA0000002, NVAVP_OS_OUTBOX);
649                 }
650 #endif
651         }
652         /* Fill out fence struct */
653         if (syncpt) {
654                 syncpt->id = nvavp->syncpt_id;
655                 syncpt->value = value;
656         }
657
658         mutex_unlock(&channel_info->pushbuffer_lock);
659
660         return 0;
661 }
662
663 static void nvavp_unload_ucode(struct nvavp_info *nvavp)
664 {
665         nvmap_unpin(nvavp->nvmap, nvavp->ucode_info.handle);
666         nvmap_munmap(nvavp->ucode_info.handle, nvavp->ucode_info.data);
667         nvmap_free(nvavp->nvmap, nvavp->ucode_info.handle);
668         kfree(nvavp->ucode_info.ucode_bin);
669 }
670
671 static int nvavp_load_ucode(struct nvavp_info *nvavp)
672 {
673         struct nvavp_ucode_info *ucode_info = &nvavp->ucode_info;
674         const struct firmware *nvavp_ucode_fw;
675         char fw_ucode_file[32];
676         void *ptr;
677         int ret = 0;
678
679         if (!ucode_info->ucode_bin) {
680                 sprintf(fw_ucode_file, "nvavp_vid_ucode.bin");
681
682                 ret = request_firmware(&nvavp_ucode_fw, fw_ucode_file,
683                                         nvavp->video_misc_dev.this_device);
684                 if (ret) {
685                         /* Try alternative version */
686                         sprintf(fw_ucode_file, "nvavp_vid_ucode_alt.bin");
687
688                         ret = request_firmware(&nvavp_ucode_fw,
689                                                 fw_ucode_file,
690                                                 nvavp->video_misc_dev.this_device);
691
692                         if (ret) {
693                                 dev_err(&nvavp->nvhost_dev->dev,
694                                         "cannot read ucode firmware '%s'\n",
695                                         fw_ucode_file);
696                                 goto err_req_ucode;
697                         }
698                 }
699
700                 dev_info(&nvavp->nvhost_dev->dev,
701                         "read ucode firmware from '%s' (%d bytes)\n",
702                         fw_ucode_file, nvavp_ucode_fw->size);
703
704                 ptr = (void *)nvavp_ucode_fw->data;
705
706                 if (strncmp((const char *)ptr, "NVAVPAPP", 8)) {
707                         dev_info(&nvavp->nvhost_dev->dev,
708                                 "ucode hdr string mismatch\n");
709                         ret = -EINVAL;
710                         goto err_req_ucode;
711                 }
712                 ptr += 8;
713                 ucode_info->size = nvavp_ucode_fw->size - 8;
714
715                 ucode_info->ucode_bin = kzalloc(ucode_info->size,
716                                                 GFP_KERNEL);
717                 if (!ucode_info->ucode_bin) {
718                         dev_err(&nvavp->nvhost_dev->dev,
719                                 "cannot allocate ucode bin\n");
720                         ret = -ENOMEM;
721                         goto err_ubin_alloc;
722                 }
723
724                 ucode_info->handle = nvmap_alloc(nvavp->nvmap,
725                                                 nvavp->ucode_info.size,
726                                         SZ_1M, NVMAP_HANDLE_UNCACHEABLE, 0);
727                 if (IS_ERR(ucode_info->handle)) {
728                         dev_err(&nvavp->nvhost_dev->dev,
729                                 "cannot create ucode handle\n");
730                         ret = PTR_ERR(ucode_info->handle);
731                         goto err_ucode_alloc;
732                 }
733                 ucode_info->data = (u8 *)nvmap_mmap(ucode_info->handle);
734                 if (!ucode_info->data) {
735                         dev_err(&nvavp->nvhost_dev->dev,
736                                 "cannot map ucode handle\n");
737                         ret = -ENOMEM;
738                         goto err_ucode_mmap;
739                 }
740                 ucode_info->phys = nvmap_pin(nvavp->nvmap, ucode_info->handle);
741                 if (IS_ERR((void *)ucode_info->phys)) {
742                         dev_err(&nvavp->nvhost_dev->dev,
743                                 "cannot pin ucode handle\n");
744                         ret = PTR_ERR((void *)ucode_info->phys);
745                         goto err_ucode_pin;
746                 }
747                 memcpy(ucode_info->ucode_bin, ptr, ucode_info->size);
748                 release_firmware(nvavp_ucode_fw);
749         }
750
751         memcpy(ucode_info->data, ucode_info->ucode_bin, ucode_info->size);
752         return 0;
753
754 err_ucode_pin:
755         nvmap_munmap(ucode_info->handle, ucode_info->data);
756 err_ucode_mmap:
757         nvmap_free(nvavp->nvmap, ucode_info->handle);
758 err_ucode_alloc:
759         kfree(nvavp->ucode_info.ucode_bin);
760 err_ubin_alloc:
761         release_firmware(nvavp_ucode_fw);
762 err_req_ucode:
763         return ret;
764 }
765
766 static void nvavp_unload_os(struct nvavp_info *nvavp)
767 {
768         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
769         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
770 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
771         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
772 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
773         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
774 #endif
775         kfree(nvavp->os_info.os_bin);
776 }
777
778 static int nvavp_load_os(struct nvavp_info *nvavp, char *fw_os_file)
779 {
780         struct nvavp_os_info *os_info = &nvavp->os_info;
781         const struct firmware *nvavp_os_fw;
782         void *ptr;
783         u32 size;
784         int ret = 0;
785
786         if (!os_info->os_bin) {
787                 ret = request_firmware(&nvavp_os_fw, fw_os_file,
788                                         nvavp->video_misc_dev.this_device);
789                 if (ret) {
790                         dev_err(&nvavp->nvhost_dev->dev,
791                                 "cannot read os firmware '%s'\n", fw_os_file);
792                         goto err_req_fw;
793                 }
794
795                 dev_info(&nvavp->nvhost_dev->dev,
796                         "read firmware from '%s' (%d bytes)\n",
797                         fw_os_file, nvavp_os_fw->size);
798
799                 ptr = (void *)nvavp_os_fw->data;
800
801                 if (strncmp((const char *)ptr, "NVAVP-OS", 8)) {
802                         dev_info(&nvavp->nvhost_dev->dev,
803                                 "os hdr string mismatch\n");
804                         ret = -EINVAL;
805                         goto err_os_bin;
806                 }
807
808                 ptr += 8;
809                 os_info->entry_offset = *((u32 *)ptr);
810                 ptr += sizeof(u32);
811                 os_info->control_offset = *((u32 *)ptr);
812                 ptr += sizeof(u32);
813                 os_info->debug_offset = *((u32 *)ptr);
814                 ptr += sizeof(u32);
815
816                 size = *((u32 *)ptr);    ptr += sizeof(u32);
817
818                 os_info->size = size;
819                 os_info->os_bin = kzalloc(os_info->size,
820                                                 GFP_KERNEL);
821                 if (!os_info->os_bin) {
822                         dev_err(&nvavp->nvhost_dev->dev,
823                                 "cannot allocate os bin\n");
824                         ret = -ENOMEM;
825                         goto err_os_bin;
826                 }
827
828                 memcpy(os_info->os_bin, ptr, os_info->size);
829                 memset(os_info->data + os_info->size, 0, SZ_1M - os_info->size);
830
831                 dev_info(&nvavp->nvhost_dev->dev,
832                         "entry=%08x control=%08x debug=%08x size=%d\n",
833                         os_info->entry_offset, os_info->control_offset,
834                         os_info->debug_offset, os_info->size);
835                 release_firmware(nvavp_os_fw);
836         }
837
838         memcpy(os_info->data, os_info->os_bin, os_info->size);
839         os_info->reset_addr = os_info->phys + os_info->entry_offset;
840
841         dev_info(&nvavp->nvhost_dev->dev,
842                 "AVP os at vaddr=%p paddr=%lx reset_addr=%p\n",
843                 os_info->data, (unsigned long)(os_info->phys),
844                                 (void *)os_info->reset_addr);
845         return 0;
846
847 err_os_bin:
848         release_firmware(nvavp_os_fw);
849 err_req_fw:
850         return ret;
851 }
852
853
854 static int nvavp_os_init(struct nvavp_info *nvavp)
855 {
856         char fw_os_file[32];
857         int ret = 0;
858         int video_initialized, audio_initialized = 0;
859
860         video_initialized = nvavp_get_video_init_status(nvavp);
861
862 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
863         audio_initialized = nvavp_get_audio_init_status(nvavp);
864 #endif
865         pr_debug("video_initialized(%d) audio_initialized(%d)\n",
866                 video_initialized, audio_initialized);
867
868         /* Video and Audio both are initialized */
869         if (video_initialized || audio_initialized)
870                 return ret;
871
872         /* Video or Audio both are uninitialized */
873         pr_debug("video_initialized == audio_initialized (%d)\n",
874                 nvavp->video_initialized);
875 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
876         /* paddr is any address returned from nvmap_pin */
877         /* vaddr is AVP_KERNEL_VIRT_BASE */
878         dev_info(&nvavp->nvhost_dev->dev,
879                 "using AVP MMU to relocate AVP os\n");
880         sprintf(fw_os_file, "nvavp_os.bin");
881         nvavp->os_info.reset_addr = AVP_KERNEL_VIRT_BASE;
882 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
883         /* paddr is any address behind SMMU */
884         /* vaddr is TEGRA_SMMU_BASE */
885         dev_info(&nvavp->nvhost_dev->dev,
886                 "using SMMU at %lx to load AVP kernel\n",
887                 (unsigned long)nvavp->os_info.phys);
888         BUG_ON(nvavp->os_info.phys != 0xeff00000
889                 && nvavp->os_info.phys != 0x0ff00000);
890         sprintf(fw_os_file, "nvavp_os_%08lx.bin",
891                 (unsigned long)nvavp->os_info.phys);
892         nvavp->os_info.reset_addr = nvavp->os_info.phys;
893 #else /* nvmem= carveout */
894         /* paddr is found in nvmem= carveout */
895         /* vaddr is same as paddr */
896         /* Find nvmem carveout */
897         if (!pfn_valid(__phys_to_pfn(0x8e000000))) {
898                 nvavp->os_info.phys = 0x8e000000;
899         } else if (!pfn_valid(__phys_to_pfn(0x9e000000))) {
900                 nvavp->os_info.phys = 0x9e000000;
901         } else if (!pfn_valid(__phys_to_pfn(0xbe000000))) {
902                 nvavp->os_info.phys = 0xbe000000;
903         } else {
904                 dev_err(&nvavp->nvhost_dev->dev,
905                         "cannot find nvmem= carveout to load AVP os\n");
906                 dev_err(&nvavp->nvhost_dev->dev,
907                         "check kernel command line "
908                         "to see if nvmem= is defined\n");
909                 BUG();
910         }
911         dev_info(&nvavp->nvhost_dev->dev,
912                 "using nvmem= carveout at %lx to load AVP os\n",
913                 nvavp->os_info.phys);
914         sprintf(fw_os_file, "nvavp_os_%08lx.bin", nvavp->os_info.phys);
915         nvavp->os_info.reset_addr = nvavp->os_info.phys;
916         nvavp->os_info.data = ioremap(nvavp->os_info.phys, SZ_1M);
917 #endif
918         ret = nvavp_load_os(nvavp, fw_os_file);
919         if (ret) {
920                 dev_err(&nvavp->nvhost_dev->dev,
921                         "unable to load os firmware '%s'\n", fw_os_file);
922                 goto err_exit;
923         }
924
925         ret = nvavp_pushbuffer_init(nvavp);
926         if (ret) {
927                 dev_err(&nvavp->nvhost_dev->dev,
928                         "unable to init pushbuffer\n");
929                 goto err_exit;
930         }
931         tegra_init_legacy_irq_cop();
932         enable_irq(nvavp->mbox_from_avp_pend_irq);
933 err_exit:
934         return ret;
935 }
936
937 static int nvavp_init(struct nvavp_info *nvavp, int channel_id)
938 {
939         int ret = 0;
940
941         ret = nvavp_os_init(nvavp);
942         if (ret) {
943                 dev_err(&nvavp->nvhost_dev->dev,
944                         "unable to load os firmware and allocate buffers\n");
945         }
946
947         if (IS_VIDEO_CHANNEL_ID(channel_id) &&
948                 (!nvavp_get_video_init_status(nvavp)) ) {
949                 pr_debug("nvavp_init : channel_ID (%d)\n", channel_id);
950                 ret = nvavp_load_ucode(nvavp);
951                 if (ret) {
952                         dev_err(&nvavp->nvhost_dev->dev,
953                                 "unable to load ucode\n");
954                         goto err_exit;
955                 }
956
957                 nvavp_reset_vde(nvavp);
958                 nvavp_reset_avp(nvavp, nvavp->os_info.reset_addr);
959
960                 nvavp_set_video_init_status(nvavp, 1);
961         }
962 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
963         if (IS_AUDIO_CHANNEL_ID(channel_id) &&
964                 (!nvavp_get_audio_init_status(nvavp))) {
965                 pr_debug("nvavp_init : channel_ID (%d)\n", channel_id);
966                 nvavp_reset_avp(nvavp, nvavp->os_info.reset_addr);
967                 nvavp_set_audio_init_status(nvavp, 1);
968         }
969 #endif
970
971 err_exit:
972         return ret;
973 }
974
975 static void nvavp_uninit(struct nvavp_info *nvavp)
976 {
977         int video_initialized, audio_initialized = 0;
978
979         video_initialized = nvavp_get_video_init_status(nvavp);
980
981 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
982         audio_initialized = nvavp_get_audio_init_status(nvavp);
983 #endif
984
985         pr_debug("nvavp_uninit video_initialized(%d) audio_initialized(%d)\n",
986                 video_initialized, audio_initialized);
987
988         /* Video and Audio both are uninitialized */
989         if (!video_initialized && !audio_initialized)
990                 return;
991
992         if (video_initialized) {
993                 pr_debug("nvavp_uninit nvavp->video_initialized\n");
994                 cancel_work_sync(&nvavp->clock_disable_work);
995                 nvavp_halt_vde(nvavp);
996                 nvavp_set_video_init_status(nvavp, 0);
997                 video_initialized = 0;
998         }
999
1000 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1001         if (audio_initialized) {
1002                 cancel_work_sync(&nvavp->app_notify_work);
1003                 nvavp_set_audio_init_status(nvavp, 0);
1004                 audio_initialized = 0;
1005         }
1006 #endif
1007
1008         /* Video and Audio both becomes uninitialized */
1009         if (video_initialized == audio_initialized) {
1010                 pr_debug("nvavp_uninit both channels unitialized\n");
1011
1012                 clk_disable(nvavp->sclk);
1013                 clk_disable(nvavp->emc_clk);
1014                 disable_irq(nvavp->mbox_from_avp_pend_irq);
1015                 nvavp_pushbuffer_deinit(nvavp);
1016                 nvavp_halt_avp(nvavp);
1017         }
1018 }
1019
1020 static int nvavp_set_clock_ioctl(struct file *filp, unsigned int cmd,
1021                                                         unsigned long arg)
1022 {
1023         struct nvavp_clientctx *clientctx = filp->private_data;
1024         struct nvavp_info *nvavp = clientctx->nvavp;
1025         struct clk *c;
1026         struct nvavp_clock_args config;
1027
1028         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1029                 return -EFAULT;
1030
1031         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d, clk_rate=%u\n",
1032                         __func__, config.id, config.rate);
1033
1034         if (config.id == NVAVP_MODULE_ID_AVP)
1035                 nvavp->sclk_rate = config.rate;
1036         else if (config.id == NVAVP_MODULE_ID_EMC)
1037                 nvavp->emc_clk_rate = config.rate;
1038
1039         c = nvavp_clk_get(nvavp, config.id);
1040         if (IS_ERR_OR_NULL(c))
1041                 return -EINVAL;
1042
1043         clk_enable(c);
1044         clk_set_rate(c, config.rate);
1045
1046         config.rate = clk_get_rate(c);
1047         clk_disable(c);
1048         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
1049                 return -EFAULT;
1050
1051         return 0;
1052 }
1053
1054 static int nvavp_get_clock_ioctl(struct file *filp, unsigned int cmd,
1055                                                         unsigned long arg)
1056 {
1057         struct nvavp_clientctx *clientctx = filp->private_data;
1058         struct nvavp_info *nvavp = clientctx->nvavp;
1059         struct clk *c;
1060         struct nvavp_clock_args config;
1061
1062         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1063                 return -EFAULT;
1064
1065         c = nvavp_clk_get(nvavp, config.id);
1066         if (IS_ERR_OR_NULL(c))
1067                 return -EINVAL;
1068
1069         clk_enable(c);
1070         config.rate = clk_get_rate(c);
1071         clk_disable(c);
1072
1073         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
1074                 return -EFAULT;
1075
1076         return 0;
1077 }
1078
1079 static int nvavp_get_syncpointid_ioctl(struct file *filp, unsigned int cmd,
1080                                                         unsigned long arg)
1081 {
1082         struct nvavp_clientctx *clientctx = filp->private_data;
1083         struct nvavp_info *nvavp = clientctx->nvavp;
1084         u32 id = nvavp->syncpt_id;
1085
1086         if (_IOC_DIR(cmd) & _IOC_READ) {
1087                 if (copy_to_user((void __user *)arg, &id, sizeof(u32)))
1088                         return -EFAULT;
1089                 else
1090                         return 0;
1091         }
1092         return -EFAULT;
1093 }
1094
1095 static int nvavp_set_nvmapfd_ioctl(struct file *filp, unsigned int cmd,
1096                                                         unsigned long arg)
1097 {
1098         struct nvavp_clientctx *clientctx = filp->private_data;
1099         struct nvavp_set_nvmap_fd_args buf;
1100         struct nvmap_client *new_client;
1101         int fd;
1102
1103         if (_IOC_DIR(cmd) & _IOC_WRITE) {
1104                 if (copy_from_user(&buf, (void __user *)arg, _IOC_SIZE(cmd)))
1105                         return -EFAULT;
1106         }
1107
1108         fd = buf.fd;
1109         new_client = nvmap_client_get_file(fd);
1110         if (IS_ERR(new_client))
1111                 return PTR_ERR(new_client);
1112
1113         clientctx->nvmap = new_client;
1114         return 0;
1115 }
1116
1117 static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
1118                                                         unsigned long arg)
1119 {
1120         struct nvavp_clientctx *clientctx = filp->private_data;
1121         struct nvavp_info *nvavp = clientctx->nvavp;
1122         struct nvavp_pushbuffer_submit_hdr hdr;
1123         u32 *cmdbuf_data;
1124         struct nvmap_handle *cmdbuf_handle = NULL;
1125         struct nvmap_handle_ref *cmdbuf_dupe;
1126         int ret = 0, i;
1127         unsigned long phys_addr;
1128         unsigned long virt_addr;
1129         struct nvavp_pushbuffer_submit_hdr *user_hdr =
1130                         (struct nvavp_pushbuffer_submit_hdr *) arg;
1131         struct nvavp_syncpt syncpt;
1132
1133         syncpt.id = NVSYNCPT_INVALID;
1134         syncpt.value = 0;
1135
1136         if (_IOC_DIR(cmd) & _IOC_WRITE) {
1137                 if (copy_from_user(&hdr, (void __user *)arg,
1138                         sizeof(struct nvavp_pushbuffer_submit_hdr)))
1139                         return -EFAULT;
1140         }
1141
1142         if (!hdr.cmdbuf.mem)
1143                 return 0;
1144
1145         if (copy_from_user(clientctx->relocs, (void __user *)hdr.relocs,
1146                         sizeof(struct nvavp_reloc) * hdr.num_relocs)) {
1147                 return -EFAULT;
1148         }
1149
1150         cmdbuf_handle = nvmap_get_handle_id(clientctx->nvmap, hdr.cmdbuf.mem);
1151         if (cmdbuf_handle == NULL) {
1152                 dev_err(&nvavp->nvhost_dev->dev,
1153                         "invalid cmd buffer handle %08x\n", hdr.cmdbuf.mem);
1154                 return -EPERM;
1155         }
1156
1157         /* duplicate the new pushbuffer's handle into the nvavp driver's
1158          * nvmap context, to ensure that the handle won't be freed as
1159          * long as it is in-use by the fb driver */
1160         cmdbuf_dupe = nvmap_duplicate_handle_id(nvavp->nvmap, hdr.cmdbuf.mem);
1161         nvmap_handle_put(cmdbuf_handle);
1162
1163         if (IS_ERR(cmdbuf_dupe)) {
1164                 dev_err(&nvavp->nvhost_dev->dev,
1165                         "could not duplicate handle\n");
1166                 return PTR_ERR(cmdbuf_dupe);
1167         }
1168
1169         phys_addr = nvmap_pin(nvavp->nvmap, cmdbuf_dupe);
1170         if (IS_ERR((void *)phys_addr)) {
1171                 dev_err(&nvavp->nvhost_dev->dev, "could not pin handle\n");
1172                 nvmap_free(nvavp->nvmap, cmdbuf_dupe);
1173                 return PTR_ERR((void *)phys_addr);
1174         }
1175
1176         virt_addr = (unsigned long)nvmap_mmap(cmdbuf_dupe);
1177         if (!virt_addr) {
1178                 dev_err(&nvavp->nvhost_dev->dev, "cannot map cmdbuf handle\n");
1179                 ret = -ENOMEM;
1180                 goto err_cmdbuf_mmap;
1181         }
1182
1183         cmdbuf_data = (u32 *)(virt_addr + hdr.cmdbuf.offset);
1184
1185         for (i = 0; i < hdr.num_relocs; i++) {
1186                 u32 *reloc_addr, target_phys_addr;
1187
1188                 if (clientctx->relocs[i].cmdbuf_mem != hdr.cmdbuf.mem) {
1189                         dev_err(&nvavp->nvhost_dev->dev,
1190                                 "reloc info does not match target bufferID\n");
1191                         ret = -EPERM;
1192                         goto err_reloc_info;
1193                 }
1194
1195                 reloc_addr = cmdbuf_data +
1196                              (clientctx->relocs[i].cmdbuf_offset >> 2);
1197
1198                 target_phys_addr = nvmap_handle_address(clientctx->nvmap,
1199                                             clientctx->relocs[i].target);
1200                 target_phys_addr += clientctx->relocs[i].target_offset;
1201                 writel(target_phys_addr, reloc_addr);
1202         }
1203
1204         if (hdr.syncpt) {
1205                 ret = nvavp_pushbuffer_update(nvavp,
1206                                              (phys_addr + hdr.cmdbuf.offset),
1207                                               hdr.cmdbuf.words, &syncpt,
1208                                               (hdr.flags & NVAVP_UCODE_EXT),
1209                                                 clientctx->channel_id);
1210
1211                 if (copy_to_user((void __user *)user_hdr->syncpt, &syncpt,
1212                                 sizeof(struct nvavp_syncpt))) {
1213                         ret = -EFAULT;
1214                         goto err_reloc_info;
1215                 }
1216         } else {
1217                 ret = nvavp_pushbuffer_update(nvavp,
1218                                              (phys_addr + hdr.cmdbuf.offset),
1219                                               hdr.cmdbuf.words, NULL,
1220                                               (hdr.flags & NVAVP_UCODE_EXT),
1221                                                 clientctx->channel_id);
1222         }
1223
1224 err_reloc_info:
1225         nvmap_munmap(cmdbuf_dupe, (void *)virt_addr);
1226 err_cmdbuf_mmap:
1227         nvmap_unpin(nvavp->nvmap, cmdbuf_dupe);
1228         nvmap_free(nvavp->nvmap, cmdbuf_dupe);
1229         return ret;
1230 }
1231
1232 static int nvavp_wake_avp_ioctl(struct file *filp, unsigned int cmd,
1233                                                         unsigned long arg)
1234 {
1235         wmb();
1236         /* wake up avp */
1237         writel(0xA0000001, NVAVP_OS_OUTBOX);
1238         return 0;
1239 }
1240
1241 static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
1242                                                         unsigned long arg)
1243 {
1244         struct nvavp_clientctx *clientctx = filp->private_data;
1245         struct nvavp_info *nvavp = clientctx->nvavp;
1246         struct nvavp_clock_stay_on_state_args clock;
1247
1248         if (copy_from_user(&clock, (void __user *)arg,
1249                            sizeof(struct nvavp_clock_stay_on_state_args)))
1250                 return -EFAULT;
1251
1252         dev_dbg(&nvavp->nvhost_dev->dev, "%s: state=%d\n",
1253                 __func__, clock.state);
1254
1255         if (clock.state != NVAVP_CLOCK_STAY_ON_DISABLED &&
1256                    clock.state !=  NVAVP_CLOCK_STAY_ON_ENABLED) {
1257                 dev_err(&nvavp->nvhost_dev->dev, "%s: invalid argument=%d\n",
1258                         __func__, clock.state);
1259                 return -EINVAL;
1260         }
1261
1262         mutex_lock(&nvavp->open_lock);
1263         if (clock.state) {
1264                 if (clientctx->clk_reqs++ == 0)
1265                         nvavp_clks_enable(nvavp);
1266         } else {
1267                 if (--clientctx->clk_reqs == 0)
1268                         nvavp_clks_disable(nvavp);
1269         }
1270         mutex_unlock(&nvavp->open_lock);
1271         return 0;
1272 }
1273
1274 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1275 static int nvavp_enable_audio_clocks(struct file *filp, unsigned int cmd,
1276                                         unsigned long arg)
1277 {
1278         struct nvavp_clientctx *clientctx = filp->private_data;
1279         struct nvavp_info *nvavp = clientctx->nvavp;
1280         struct nvavp_clock_args config;
1281
1282         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1283                 return -EFAULT;
1284
1285         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d\n",
1286                         __func__, config.id);
1287
1288         if (config.id == NVAVP_MODULE_ID_VCP)
1289                 clk_enable(nvavp->vcp_clk);
1290         else if (config.id == NVAVP_MODULE_ID_BSEA)
1291                 clk_enable(nvavp->bsea_clk);
1292
1293         return 0;
1294 }
1295
1296 static int nvavp_disable_audio_clocks(struct file *filp, unsigned int cmd,
1297                                         unsigned long arg)
1298 {
1299         struct nvavp_clientctx *clientctx = filp->private_data;
1300         struct nvavp_info *nvavp = clientctx->nvavp;
1301         struct nvavp_clock_args config;
1302
1303         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1304                 return -EFAULT;
1305
1306         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d\n",
1307                         __func__, config.id);
1308
1309         if (config.id == NVAVP_MODULE_ID_VCP)
1310                 clk_disable(nvavp->vcp_clk);
1311         else if (config.id == NVAVP_MODULE_ID_BSEA)
1312                 clk_disable(nvavp->bsea_clk);
1313
1314         return 0;
1315 }
1316 #else
1317 static int nvavp_enable_audio_clocks(struct file *filp, unsigned int cmd,
1318                                         unsigned long arg)
1319 {
1320         return 0;
1321 }
1322
1323 static int nvavp_disable_audio_clocks(struct file *filp, unsigned int cmd,
1324                                         unsigned long arg)
1325 {
1326         return 0;
1327 }
1328 #endif
1329
1330 static int tegra_nvavp_open(struct inode *inode, struct file *filp, int channel_id)
1331 {
1332         struct miscdevice *miscdev = filp->private_data;
1333         struct nvavp_info *nvavp = dev_get_drvdata(miscdev->parent);
1334         int ret = 0;
1335         struct nvavp_clientctx *clientctx;
1336
1337         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1338
1339         nonseekable_open(inode, filp);
1340
1341         clientctx = kzalloc(sizeof(*clientctx), GFP_KERNEL);
1342         if (!clientctx)
1343                 return -ENOMEM;
1344
1345         mutex_lock(&nvavp->open_lock);
1346
1347         pr_debug("tegra_nvavp_open channel_id (%d)\n", channel_id);
1348
1349         clientctx->channel_id = channel_id;
1350
1351         ret = nvavp_init(nvavp, channel_id);
1352
1353         if (!ret)
1354                 nvavp->refcount++;
1355
1356         clientctx->nvmap = nvavp->nvmap;
1357         clientctx->nvavp = nvavp;
1358
1359         filp->private_data = clientctx;
1360
1361         mutex_unlock(&nvavp->open_lock);
1362
1363         return ret;
1364 }
1365
1366 static int tegra_nvavp_video_open(struct inode *inode, struct file *filp)
1367 {
1368         pr_debug("tegra_nvavp_video_open NVAVP_VIDEO_CHANNEL\n");
1369         return tegra_nvavp_open(inode, filp, NVAVP_VIDEO_CHANNEL);
1370 }
1371
1372 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1373 static int tegra_nvavp_audio_open(struct inode *inode, struct file *filp)
1374 {
1375         pr_debug("tegra_nvavp_audio_open NVAVP_AUDIO_CHANNEL\n");
1376         return tegra_nvavp_open(inode, filp, NVAVP_AUDIO_CHANNEL);
1377 }
1378 #endif
1379
1380 static int tegra_nvavp_release(struct inode *inode, struct file *filp)
1381 {
1382         struct nvavp_clientctx *clientctx = filp->private_data;
1383         struct nvavp_info *nvavp = clientctx->nvavp;
1384         int ret = 0;
1385
1386         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1387
1388         filp->private_data = NULL;
1389
1390         mutex_lock(&nvavp->open_lock);
1391
1392         if (!nvavp->refcount) {
1393                 dev_err(&nvavp->nvhost_dev->dev,
1394                         "releasing while in invalid state\n");
1395                 ret = -EINVAL;
1396                 goto out;
1397         }
1398
1399         /* if this client had any requests, drop our clk ref */
1400         if (clientctx->clk_reqs)
1401                 nvavp_clks_disable(nvavp);
1402
1403         if (nvavp->refcount > 0)
1404                 nvavp->refcount--;
1405         if (!nvavp->refcount)
1406                 nvavp_uninit(nvavp);
1407
1408 out:
1409         nvmap_client_put(clientctx->nvmap);
1410         mutex_unlock(&nvavp->open_lock);
1411         kfree(clientctx);
1412         return ret;
1413 }
1414
1415 static long tegra_nvavp_ioctl(struct file *filp, unsigned int cmd,
1416                             unsigned long arg)
1417 {
1418         int ret = 0;
1419
1420         if (_IOC_TYPE(cmd) != NVAVP_IOCTL_MAGIC ||
1421             _IOC_NR(cmd) < NVAVP_IOCTL_MIN_NR ||
1422             _IOC_NR(cmd) > NVAVP_IOCTL_MAX_NR)
1423                 return -EFAULT;
1424
1425         switch (cmd) {
1426         case NVAVP_IOCTL_SET_NVMAP_FD:
1427                 ret = nvavp_set_nvmapfd_ioctl(filp, cmd, arg);
1428                 break;
1429         case NVAVP_IOCTL_GET_SYNCPOINT_ID:
1430                 ret = nvavp_get_syncpointid_ioctl(filp, cmd, arg);
1431                 break;
1432         case NVAVP_IOCTL_PUSH_BUFFER_SUBMIT:
1433                 ret = nvavp_pushbuffer_submit_ioctl(filp, cmd, arg);
1434                 break;
1435         case NVAVP_IOCTL_SET_CLOCK:
1436                 ret = nvavp_set_clock_ioctl(filp, cmd, arg);
1437                 break;
1438         case NVAVP_IOCTL_GET_CLOCK:
1439                 ret = nvavp_get_clock_ioctl(filp, cmd, arg);
1440                 break;
1441         case NVAVP_IOCTL_WAKE_AVP:
1442                 ret = nvavp_wake_avp_ioctl(filp, cmd, arg);
1443                 break;
1444         case NVAVP_IOCTL_FORCE_CLOCK_STAY_ON:
1445                 ret = nvavp_force_clock_stay_on_ioctl(filp, cmd, arg);
1446                 break;
1447         case NVAVP_IOCTL_ENABLE_AUDIO_CLOCKS:
1448                 ret = nvavp_enable_audio_clocks(filp, cmd, arg);
1449                 break;
1450         case NVAVP_IOCTL_DISABLE_AUDIO_CLOCKS:
1451                 ret = nvavp_disable_audio_clocks(filp, cmd, arg);
1452                 break;
1453         default:
1454                 ret = -EINVAL;
1455                 break;
1456         }
1457         return ret;
1458 }
1459
1460 static const struct file_operations tegra_video_nvavp_fops = {
1461         .owner          = THIS_MODULE,
1462         .open           = tegra_nvavp_video_open,
1463         .release        = tegra_nvavp_release,
1464         .unlocked_ioctl = tegra_nvavp_ioctl,
1465 };
1466
1467 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1468 static const struct file_operations tegra_audio_nvavp_fops = {
1469         .owner          = THIS_MODULE,
1470         .open           = tegra_nvavp_audio_open,
1471         .release        = tegra_nvavp_release,
1472         .unlocked_ioctl = tegra_nvavp_ioctl,
1473 };
1474 #endif
1475
1476 static int tegra_nvavp_probe(struct nvhost_device *ndev,
1477         struct nvhost_device_id *id_table)
1478 {
1479         struct nvavp_info *nvavp;
1480         int irq;
1481         unsigned int heap_mask;
1482         u32 iovmm_addr;
1483         int ret = 0, channel_id;
1484
1485         irq = nvhost_get_irq_byname(ndev, "mbox_from_nvavp_pending");
1486         if (irq < 0) {
1487                 dev_err(&ndev->dev, "invalid nvhost data\n");
1488                 return -EINVAL;
1489         }
1490
1491         nvavp = kzalloc(sizeof(struct nvavp_info), GFP_KERNEL);
1492         if (!nvavp) {
1493                 dev_err(&ndev->dev, "cannot allocate avp_info\n");
1494                 return -ENOMEM;
1495         }
1496
1497         memset(nvavp, 0, sizeof(*nvavp));
1498
1499         nvavp->nvmap = nvmap_create_client(nvmap_dev, "nvavp_drv");
1500         if (IS_ERR_OR_NULL(nvavp->nvmap)) {
1501                 dev_err(&ndev->dev, "cannot create nvmap client\n");
1502                 ret = PTR_ERR(nvavp->nvmap);
1503                 goto err_nvmap_create_drv_client;
1504         }
1505
1506 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
1507         heap_mask = NVMAP_HEAP_CARVEOUT_GENERIC;
1508 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
1509         heap_mask = NVMAP_HEAP_IOVMM;
1510 #else /* nvmem= carveout */
1511         heap_mask = 0;
1512 #endif
1513         switch (heap_mask) {
1514         case NVMAP_HEAP_IOVMM:
1515
1516                 iovmm_addr = 0x0ff00000;
1517
1518                 nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M,
1519                                                 L1_CACHE_BYTES,
1520                                                 NVMAP_HANDLE_UNCACHEABLE,
1521                                                 iovmm_addr);
1522                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1523                         dev_err(&ndev->dev,
1524                                 "cannot create os handle\n");
1525                         ret = PTR_ERR(nvavp->os_info.handle);
1526                         goto err_nvmap_alloc;
1527                 }
1528
1529                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1530                 if (!nvavp->os_info.data) {
1531                         dev_err(&ndev->dev,
1532                                 "cannot map os handle\n");
1533                         ret = -ENOMEM;
1534                         goto err_nvmap_mmap;
1535                 }
1536
1537                 nvavp->os_info.phys =
1538                         nvmap_pin(nvavp->nvmap, nvavp->os_info.handle);
1539                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1540                         dev_err(&ndev->dev,
1541                                 "cannot pin os handle\n");
1542                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1543                         goto err_nvmap_pin;
1544                 }
1545
1546                 dev_info(&ndev->dev,
1547                         "allocated IOVM at %lx for AVP os\n",
1548                         (unsigned long)nvavp->os_info.phys);
1549                 break;
1550         case NVMAP_HEAP_CARVEOUT_GENERIC:
1551                 nvavp->os_info.handle = nvmap_alloc(nvavp->nvmap, SZ_1M, SZ_1M,
1552                                                 NVMAP_HANDLE_UNCACHEABLE, 0);
1553                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1554                         dev_err(&ndev->dev, "cannot create AVP os handle\n");
1555                         ret = PTR_ERR(nvavp->os_info.handle);
1556                         goto err_nvmap_alloc;
1557                 }
1558
1559                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1560                 if (!nvavp->os_info.data) {
1561                         dev_err(&ndev->dev, "cannot map AVP os handle\n");
1562                         ret = -ENOMEM;
1563                         goto err_nvmap_mmap;
1564                 }
1565
1566                 nvavp->os_info.phys = nvmap_pin(nvavp->nvmap,
1567                                         nvavp->os_info.handle);
1568                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1569                         dev_err(&ndev->dev, "cannot pin AVP os handle\n");
1570                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1571                         goto err_nvmap_pin;
1572                 }
1573
1574                 dev_info(&ndev->dev,
1575                         "allocated carveout memory at %lx for AVP os\n",
1576                         (unsigned long)nvavp->os_info.phys);
1577                 break;
1578         default:
1579                 dev_err(&ndev->dev, "invalid/non-supported heap for AVP os\n");
1580                 ret = -EINVAL;
1581                 goto err_get_syncpt;
1582         }
1583
1584         nvavp->mbox_from_avp_pend_irq = irq;
1585         mutex_init(&nvavp->open_lock);
1586
1587         for (channel_id = 0; channel_id < NVAVP_NUM_CHANNELS; channel_id++)
1588                 mutex_init(&nvavp->channel_info[channel_id].pushbuffer_lock);
1589
1590         /* TODO DO NOT USE NVAVP DEVICE */
1591         nvavp->cop_clk = clk_get(&ndev->dev, "cop");
1592         if (IS_ERR(nvavp->cop_clk)) {
1593                 dev_err(&ndev->dev, "cannot get cop clock\n");
1594                 ret = -ENOENT;
1595                 goto err_get_cop_clk;
1596         }
1597
1598         nvavp->vde_clk = clk_get(&ndev->dev, "vde");
1599         if (IS_ERR(nvavp->vde_clk)) {
1600                 dev_err(&ndev->dev, "cannot get vde clock\n");
1601                 ret = -ENOENT;
1602                 goto err_get_vde_clk;
1603         }
1604
1605         nvavp->bsev_clk = clk_get(&ndev->dev, "bsev");
1606         if (IS_ERR(nvavp->bsev_clk)) {
1607                 dev_err(&ndev->dev, "cannot get bsev clock\n");
1608                 ret = -ENOENT;
1609                 goto err_get_bsev_clk;
1610         }
1611
1612         nvavp->sclk = clk_get(&ndev->dev, "sclk");
1613         if (IS_ERR(nvavp->sclk)) {
1614                 dev_err(&ndev->dev, "cannot get avp.sclk clock\n");
1615                 ret = -ENOENT;
1616                 goto err_get_sclk;
1617         }
1618
1619         nvavp->emc_clk = clk_get(&ndev->dev, "emc");
1620         if (IS_ERR(nvavp->emc_clk)) {
1621                 dev_err(&ndev->dev, "cannot get emc clock\n");
1622                 ret = -ENOENT;
1623                 goto err_get_emc_clk;
1624         }
1625
1626 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1627         nvavp->bsea_clk = clk_get(&ndev->dev, "bsea");
1628         if (IS_ERR(nvavp->bsea_clk)) {
1629                 dev_err(&ndev->dev, "cannot get bsea clock\n");
1630                 ret = -ENOENT;
1631                 goto err_get_bsea_clk;
1632         }
1633
1634         nvavp->vcp_clk = clk_get(&ndev->dev, "vcp");
1635         if (IS_ERR(nvavp->vcp_clk)) {
1636                 dev_err(&ndev->dev, "cannot get vcp clock\n");
1637                 ret = -ENOENT;
1638                 goto err_get_vcp_clk;
1639         }
1640 #endif
1641
1642         nvavp->clk_enabled = 0;
1643         nvavp_halt_avp(nvavp);
1644
1645         INIT_WORK(&nvavp->clock_disable_work, clock_disable_handler);
1646
1647         nvavp->video_misc_dev.minor = MISC_DYNAMIC_MINOR;
1648         nvavp->video_misc_dev.name = "tegra_avpchannel";
1649         nvavp->video_misc_dev.fops = &tegra_video_nvavp_fops;
1650         nvavp->video_misc_dev.mode = S_IRWXUGO;
1651         nvavp->video_misc_dev.parent = &ndev->dev;
1652
1653         ret = misc_register(&nvavp->video_misc_dev);
1654         if (ret) {
1655                 dev_err(&ndev->dev, "unable to register misc device!\n");
1656                 goto err_misc_reg;
1657         }
1658
1659 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1660         INIT_WORK(&nvavp->app_notify_work, app_notify_handler);
1661         nvavp->audio_misc_dev.minor = MISC_DYNAMIC_MINOR;
1662         nvavp->audio_misc_dev.name = "tegra_audio_avpchannel";
1663         nvavp->audio_misc_dev.fops = &tegra_audio_nvavp_fops;
1664         nvavp->audio_misc_dev.mode = S_IRWXUGO;
1665         nvavp->audio_misc_dev.parent = &ndev->dev;
1666
1667         ret = misc_register(&nvavp->audio_misc_dev);
1668         if (ret) {
1669         dev_err(&ndev->dev, "unable to register misc device!\n");
1670                 goto err_audio_misc_reg;
1671         }
1672 #endif
1673
1674         ret = request_irq(irq, nvavp_mbox_pending_isr, 0,
1675                           TEGRA_NVAVP_NAME, nvavp);
1676         if (ret) {
1677                 dev_err(&ndev->dev, "cannot register irq handler\n");
1678                 goto err_req_irq_pend;
1679         }
1680         disable_irq(nvavp->mbox_from_avp_pend_irq);
1681
1682         nvhost_set_drvdata(ndev, nvavp);
1683         nvavp->nvhost_dev = ndev;
1684
1685         return 0;
1686
1687 err_req_irq_pend:
1688 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1689         misc_deregister(&nvavp->audio_misc_dev);
1690 err_audio_misc_reg:
1691 #endif
1692         misc_deregister(&nvavp->video_misc_dev);
1693 err_misc_reg:
1694 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1695         clk_put(nvavp->vcp_clk);
1696 err_get_vcp_clk:
1697         clk_put(nvavp->bsea_clk);
1698 err_get_bsea_clk:
1699 #endif
1700         clk_put(nvavp->emc_clk);
1701 err_get_emc_clk:
1702         clk_put(nvavp->sclk);
1703 err_get_sclk:
1704         clk_put(nvavp->bsev_clk);
1705 err_get_bsev_clk:
1706         clk_put(nvavp->vde_clk);
1707 err_get_vde_clk:
1708         clk_put(nvavp->cop_clk);
1709 err_get_cop_clk:
1710         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
1711 err_nvmap_pin:
1712         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
1713 err_nvmap_mmap:
1714 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
1715         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
1716 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
1717         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
1718 #endif
1719 err_nvmap_alloc:
1720         nvmap_client_put(nvavp->nvmap);
1721 err_nvmap_create_drv_client:
1722 err_get_syncpt:
1723         kfree(nvavp);
1724         return ret;
1725 }
1726
1727 static int tegra_nvavp_remove(struct nvhost_device *ndev)
1728 {
1729         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1730
1731         if (!nvavp)
1732                 return 0;
1733
1734         mutex_lock(&nvavp->open_lock);
1735         if (nvavp->refcount) {
1736                 mutex_unlock(&nvavp->open_lock);
1737                 return -EBUSY;
1738         }
1739         mutex_unlock(&nvavp->open_lock);
1740
1741         nvavp_unload_ucode(nvavp);
1742         nvavp_unload_os(nvavp);
1743
1744         misc_deregister(&nvavp->video_misc_dev);
1745
1746 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1747         misc_deregister(&nvavp->audio_misc_dev);
1748         clk_put(nvavp->vcp_clk);
1749         clk_put(nvavp->bsea_clk);
1750 #endif
1751         clk_put(nvavp->bsev_clk);
1752         clk_put(nvavp->vde_clk);
1753         clk_put(nvavp->cop_clk);
1754
1755         clk_put(nvavp->emc_clk);
1756         clk_put(nvavp->sclk);
1757
1758         nvmap_client_put(nvavp->nvmap);
1759
1760         kfree(nvavp);
1761         return 0;
1762 }
1763
1764 #ifdef CONFIG_PM
1765 static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state)
1766 {
1767         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1768         int ret = 0;
1769
1770         mutex_lock(&nvavp->open_lock);
1771
1772         if (nvavp->refcount) {
1773                 if (!nvavp->clk_enabled) {
1774 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1775                         if (nvavp_check_idle(nvavp, NVAVP_AUDIO_CHANNEL))
1776                                 nvavp_uninit(nvavp);
1777                         else
1778                                 ret = -EBUSY;
1779 #else
1780                         nvavp_uninit(nvavp);
1781 #endif
1782                 }
1783                 else {
1784                         ret = -EBUSY;
1785                 }
1786         }
1787
1788         mutex_unlock(&nvavp->open_lock);
1789         return ret;
1790 }
1791
1792 static int tegra_nvavp_resume(struct nvhost_device *ndev)
1793 {
1794         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1795
1796         mutex_lock(&nvavp->open_lock);
1797
1798         if (nvavp->refcount) {
1799                 nvavp_init(nvavp, NVAVP_VIDEO_CHANNEL);
1800 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1801                 nvavp_init(nvavp, NVAVP_AUDIO_CHANNEL);
1802 #endif
1803         }
1804         mutex_unlock(&nvavp->open_lock);
1805
1806         return 0;
1807 }
1808 #endif
1809
1810 static struct nvhost_driver tegra_nvavp_driver = {
1811         .driver = {
1812                 .name   = TEGRA_NVAVP_NAME,
1813                 .owner  = THIS_MODULE,
1814         },
1815         .probe          = tegra_nvavp_probe,
1816         .remove         = tegra_nvavp_remove,
1817 #ifdef CONFIG_PM
1818         .suspend        = tegra_nvavp_suspend,
1819         .resume         = tegra_nvavp_resume,
1820 #endif
1821 };
1822
1823 static int __init tegra_nvavp_init(void)
1824 {
1825         return nvhost_driver_register(&tegra_nvavp_driver);
1826 }
1827
1828 static void __exit tegra_nvavp_exit(void)
1829 {
1830         nvhost_driver_unregister(&tegra_nvavp_driver);
1831 }
1832
1833 module_init(tegra_nvavp_init);
1834 module_exit(tegra_nvavp_exit);
1835
1836 MODULE_AUTHOR("NVIDIA");
1837 MODULE_DESCRIPTION("Channel based AVP driver for Tegra");
1838 MODULE_VERSION("1.0");
1839 MODULE_LICENSE("Dual BSD/GPL");