Revert "media: camera config changes"
[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/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 <linux/nvmap.h>
44
45 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
46 #include "../avp/headavp.h"
47 #endif
48 #include "nvavp_os.h"
49
50 #define TEGRA_NVAVP_NAME                        "nvavp"
51
52 #define NVAVP_PUSHBUFFER_SIZE                   4096
53
54 #define NVAVP_PUSHBUFFER_MIN_UPDATE_SPACE       (sizeof(u32) * 3)
55
56 #define TEGRA_NVAVP_RESET_VECTOR_ADDR   \
57                 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x200)
58
59 #define FLOW_CTRL_HALT_COP_EVENTS       IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + 0x4)
60 #define FLOW_MODE_STOP                  (0x2 << 29)
61 #define FLOW_MODE_NONE                  0x0
62
63 #define NVAVP_OS_INBOX                  IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x10)
64 #define NVAVP_OS_OUTBOX                 IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x20)
65
66 #define NVAVP_INBOX_VALID               (1 << 29)
67
68 /* AVP behavior params */
69 #define NVAVP_OS_IDLE_TIMEOUT           100 /* milli-seconds */
70
71 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
72 /* Two control channels: Audio and Video channels */
73 #define NVAVP_NUM_CHANNELS              2
74
75 #define NVAVP_AUDIO_CHANNEL             1
76
77 #define IS_AUDIO_CHANNEL_ID(channel_id) (channel_id == NVAVP_AUDIO_CHANNEL ? 1: 0)
78 #else
79 #define NVAVP_NUM_CHANNELS              1
80 #endif
81
82 /* Channel ID 0 represents the Video channel control area */
83 #define NVAVP_VIDEO_CHANNEL             0
84 /* Channel ID 1 represents the Audio channel control area */
85
86 #define IS_VIDEO_CHANNEL_ID(channel_id) (channel_id == NVAVP_VIDEO_CHANNEL ? 1: 0)
87
88
89 struct nvavp_channel {
90         struct mutex                    pushbuffer_lock;
91         struct nvmap_handle_ref         *pushbuf_handle;
92         unsigned long                   pushbuf_phys;
93         u8                              *pushbuf_data;
94         u32                             pushbuf_index;
95         u32                             pushbuf_fence;
96         struct nv_e276_control          *os_control;
97 };
98
99 struct nvavp_info {
100         u32                             clk_enabled;
101         struct clk                      *bsev_clk;
102         struct clk                      *vde_clk;
103         struct clk                      *cop_clk;
104 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
105         struct clk                      *bsea_clk;
106         struct clk                      *vcp_clk;
107 #endif
108
109         /* used for dvfs */
110         struct clk                      *sclk;
111         struct clk                      *emc_clk;
112         unsigned long                   sclk_rate;
113         unsigned long                   emc_clk_rate;
114
115         int                             mbox_from_avp_pend_irq;
116
117         struct mutex                    open_lock;
118         int                             refcount;
119         int                             video_initialized;
120 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
121         int                             audio_initialized;
122         struct work_struct              app_notify_work;
123 #endif
124         struct work_struct              clock_disable_work;
125
126         /* os information */
127         struct nvavp_os_info            os_info;
128
129         /* ucode information */
130         struct nvavp_ucode_info         ucode_info;
131
132         /* client for driver allocations, persistent */
133         struct nvmap_client             *nvmap;
134
135         bool                            pending;
136
137         struct nvavp_channel            channel_info[NVAVP_NUM_CHANNELS];
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         u32 clk_reqs;
157         int channel_id;
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         channel_info = nvavp_get_channel_info(nvavp, NVAVP_VIDEO_CHANNEL);
299
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         if (IS_VIDEO_CHANNEL_ID(channel_id)) {
625                 mutex_lock(&nvavp->open_lock);
626                 if (!nvavp->pending) {
627                         nvavp_clks_enable(nvavp);
628                         nvavp->pending = true;
629                 }
630                 mutex_unlock(&nvavp->open_lock);
631         }
632
633         /* update put pointer */
634         channel_info->pushbuf_index = (channel_info->pushbuf_index + wordcount)&
635                                         (NVAVP_PUSHBUFFER_SIZE - 1);
636
637         writel(channel_info->pushbuf_index, &control->put);
638         wmb();
639
640         /* wake up avp */
641
642         if (IS_VIDEO_CHANNEL_ID(channel_id)) {
643                 pr_debug("Wake up Video Channel\n");
644                 writel(0xA0000001, NVAVP_OS_OUTBOX);
645         }
646         else {
647 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
648                 if (IS_AUDIO_CHANNEL_ID(channel_id)) {
649                         pr_debug("Wake up Audio Channel\n");
650                         writel(0xA0000002, NVAVP_OS_OUTBOX);
651                 }
652 #endif
653         }
654         /* Fill out fence struct */
655         if (syncpt) {
656                 syncpt->id = nvavp->syncpt_id;
657                 syncpt->value = value;
658         }
659
660         mutex_unlock(&channel_info->pushbuffer_lock);
661
662         return 0;
663 }
664
665 static void nvavp_unload_ucode(struct nvavp_info *nvavp)
666 {
667         nvmap_unpin(nvavp->nvmap, nvavp->ucode_info.handle);
668         nvmap_munmap(nvavp->ucode_info.handle, nvavp->ucode_info.data);
669         nvmap_free(nvavp->nvmap, nvavp->ucode_info.handle);
670         kfree(nvavp->ucode_info.ucode_bin);
671 }
672
673 static int nvavp_load_ucode(struct nvavp_info *nvavp)
674 {
675         struct nvavp_ucode_info *ucode_info = &nvavp->ucode_info;
676         const struct firmware *nvavp_ucode_fw;
677         char fw_ucode_file[32];
678         void *ptr;
679         int ret = 0;
680
681         if (!ucode_info->ucode_bin) {
682                 sprintf(fw_ucode_file, "nvavp_vid_ucode.bin");
683
684                 ret = request_firmware(&nvavp_ucode_fw, fw_ucode_file,
685                                         nvavp->video_misc_dev.this_device);
686                 if (ret) {
687                         /* Try alternative version */
688                         sprintf(fw_ucode_file, "nvavp_vid_ucode_alt.bin");
689
690                         ret = request_firmware(&nvavp_ucode_fw,
691                                                 fw_ucode_file,
692                                                 nvavp->video_misc_dev.this_device);
693
694                         if (ret) {
695                                 dev_err(&nvavp->nvhost_dev->dev,
696                                         "cannot read ucode firmware '%s'\n",
697                                         fw_ucode_file);
698                                 goto err_req_ucode;
699                         }
700                 }
701
702                 dev_info(&nvavp->nvhost_dev->dev,
703                         "read ucode firmware from '%s' (%d bytes)\n",
704                         fw_ucode_file, nvavp_ucode_fw->size);
705
706                 ptr = (void *)nvavp_ucode_fw->data;
707
708                 if (strncmp((const char *)ptr, "NVAVPAPP", 8)) {
709                         dev_info(&nvavp->nvhost_dev->dev,
710                                 "ucode hdr string mismatch\n");
711                         ret = -EINVAL;
712                         goto err_req_ucode;
713                 }
714                 ptr += 8;
715                 ucode_info->size = nvavp_ucode_fw->size - 8;
716
717                 ucode_info->ucode_bin = kzalloc(ucode_info->size,
718                                                 GFP_KERNEL);
719                 if (!ucode_info->ucode_bin) {
720                         dev_err(&nvavp->nvhost_dev->dev,
721                                 "cannot allocate ucode bin\n");
722                         ret = -ENOMEM;
723                         goto err_ubin_alloc;
724                 }
725
726                 ucode_info->handle = nvmap_alloc(nvavp->nvmap,
727                                                 nvavp->ucode_info.size,
728                                         SZ_1M, NVMAP_HANDLE_UNCACHEABLE, 0);
729                 if (IS_ERR(ucode_info->handle)) {
730                         dev_err(&nvavp->nvhost_dev->dev,
731                                 "cannot create ucode handle\n");
732                         ret = PTR_ERR(ucode_info->handle);
733                         goto err_ucode_alloc;
734                 }
735                 ucode_info->data = (u8 *)nvmap_mmap(ucode_info->handle);
736                 if (!ucode_info->data) {
737                         dev_err(&nvavp->nvhost_dev->dev,
738                                 "cannot map ucode handle\n");
739                         ret = -ENOMEM;
740                         goto err_ucode_mmap;
741                 }
742                 ucode_info->phys = nvmap_pin(nvavp->nvmap, ucode_info->handle);
743                 if (IS_ERR((void *)ucode_info->phys)) {
744                         dev_err(&nvavp->nvhost_dev->dev,
745                                 "cannot pin ucode handle\n");
746                         ret = PTR_ERR((void *)ucode_info->phys);
747                         goto err_ucode_pin;
748                 }
749                 memcpy(ucode_info->ucode_bin, ptr, ucode_info->size);
750                 release_firmware(nvavp_ucode_fw);
751         }
752
753         memcpy(ucode_info->data, ucode_info->ucode_bin, ucode_info->size);
754         return 0;
755
756 err_ucode_pin:
757         nvmap_munmap(ucode_info->handle, ucode_info->data);
758 err_ucode_mmap:
759         nvmap_free(nvavp->nvmap, ucode_info->handle);
760 err_ucode_alloc:
761         kfree(nvavp->ucode_info.ucode_bin);
762 err_ubin_alloc:
763         release_firmware(nvavp_ucode_fw);
764 err_req_ucode:
765         return ret;
766 }
767
768 static void nvavp_unload_os(struct nvavp_info *nvavp)
769 {
770         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
771         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
772 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
773         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
774 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
775         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
776 #endif
777         kfree(nvavp->os_info.os_bin);
778 }
779
780 static int nvavp_load_os(struct nvavp_info *nvavp, char *fw_os_file)
781 {
782         struct nvavp_os_info *os_info = &nvavp->os_info;
783         const struct firmware *nvavp_os_fw;
784         void *ptr;
785         u32 size;
786         int ret = 0;
787
788         if (!os_info->os_bin) {
789                 ret = request_firmware(&nvavp_os_fw, fw_os_file,
790                                         nvavp->video_misc_dev.this_device);
791                 if (ret) {
792                         dev_err(&nvavp->nvhost_dev->dev,
793                                 "cannot read os firmware '%s'\n", fw_os_file);
794                         goto err_req_fw;
795                 }
796
797                 dev_info(&nvavp->nvhost_dev->dev,
798                         "read firmware from '%s' (%d bytes)\n",
799                         fw_os_file, nvavp_os_fw->size);
800
801                 ptr = (void *)nvavp_os_fw->data;
802
803                 if (strncmp((const char *)ptr, "NVAVP-OS", 8)) {
804                         dev_info(&nvavp->nvhost_dev->dev,
805                                 "os hdr string mismatch\n");
806                         ret = -EINVAL;
807                         goto err_os_bin;
808                 }
809
810                 ptr += 8;
811                 os_info->entry_offset = *((u32 *)ptr);
812                 ptr += sizeof(u32);
813                 os_info->control_offset = *((u32 *)ptr);
814                 ptr += sizeof(u32);
815                 os_info->debug_offset = *((u32 *)ptr);
816                 ptr += sizeof(u32);
817
818                 size = *((u32 *)ptr);    ptr += sizeof(u32);
819
820                 os_info->size = size;
821                 os_info->os_bin = kzalloc(os_info->size,
822                                                 GFP_KERNEL);
823                 if (!os_info->os_bin) {
824                         dev_err(&nvavp->nvhost_dev->dev,
825                                 "cannot allocate os bin\n");
826                         ret = -ENOMEM;
827                         goto err_os_bin;
828                 }
829
830                 memcpy(os_info->os_bin, ptr, os_info->size);
831                 memset(os_info->data + os_info->size, 0, SZ_1M - os_info->size);
832
833                 dev_info(&nvavp->nvhost_dev->dev,
834                         "entry=%08x control=%08x debug=%08x size=%d\n",
835                         os_info->entry_offset, os_info->control_offset,
836                         os_info->debug_offset, os_info->size);
837                 release_firmware(nvavp_os_fw);
838         }
839
840         memcpy(os_info->data, os_info->os_bin, os_info->size);
841         os_info->reset_addr = os_info->phys + os_info->entry_offset;
842
843         dev_info(&nvavp->nvhost_dev->dev,
844                 "AVP os at vaddr=%p paddr=%lx reset_addr=%p\n",
845                 os_info->data, (unsigned long)(os_info->phys),
846                                 (void *)os_info->reset_addr);
847         return 0;
848
849 err_os_bin:
850         release_firmware(nvavp_os_fw);
851 err_req_fw:
852         return ret;
853 }
854
855
856 static int nvavp_os_init(struct nvavp_info *nvavp)
857 {
858         char fw_os_file[32];
859         int ret = 0;
860         int video_initialized, audio_initialized = 0;
861
862         video_initialized = nvavp_get_video_init_status(nvavp);
863
864 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
865         audio_initialized = nvavp_get_audio_init_status(nvavp);
866 #endif
867         pr_debug("video_initialized(%d) audio_initialized(%d)\n",
868                 video_initialized, audio_initialized);
869
870         /* Video and Audio both are initialized */
871         if (video_initialized || audio_initialized)
872                 return ret;
873
874         /* Video or Audio both are uninitialized */
875         pr_debug("video_initialized == audio_initialized (%d)\n",
876                 nvavp->video_initialized);
877 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
878         /* paddr is any address returned from nvmap_pin */
879         /* vaddr is AVP_KERNEL_VIRT_BASE */
880         dev_info(&nvavp->nvhost_dev->dev,
881                 "using AVP MMU to relocate AVP os\n");
882         sprintf(fw_os_file, "nvavp_os.bin");
883         nvavp->os_info.reset_addr = AVP_KERNEL_VIRT_BASE;
884 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
885         /* paddr is any address behind SMMU */
886         /* vaddr is TEGRA_SMMU_BASE */
887         dev_info(&nvavp->nvhost_dev->dev,
888                 "using SMMU at %lx to load AVP kernel\n",
889                 (unsigned long)nvavp->os_info.phys);
890         BUG_ON(nvavp->os_info.phys != 0xeff00000
891                 && nvavp->os_info.phys != 0x0ff00000);
892         sprintf(fw_os_file, "nvavp_os_%08lx.bin",
893                 (unsigned long)nvavp->os_info.phys);
894         nvavp->os_info.reset_addr = nvavp->os_info.phys;
895 #else /* nvmem= carveout */
896         /* paddr is found in nvmem= carveout */
897         /* vaddr is same as paddr */
898         /* Find nvmem carveout */
899         if (!pfn_valid(__phys_to_pfn(0x8e000000))) {
900                 nvavp->os_info.phys = 0x8e000000;
901         } else if (!pfn_valid(__phys_to_pfn(0x9e000000))) {
902                 nvavp->os_info.phys = 0x9e000000;
903         } else if (!pfn_valid(__phys_to_pfn(0xbe000000))) {
904                 nvavp->os_info.phys = 0xbe000000;
905         } else {
906                 dev_err(&nvavp->nvhost_dev->dev,
907                         "cannot find nvmem= carveout to load AVP os\n");
908                 dev_err(&nvavp->nvhost_dev->dev,
909                         "check kernel command line "
910                         "to see if nvmem= is defined\n");
911                 BUG();
912         }
913         dev_info(&nvavp->nvhost_dev->dev,
914                 "using nvmem= carveout at %lx to load AVP os\n",
915                 nvavp->os_info.phys);
916         sprintf(fw_os_file, "nvavp_os_%08lx.bin", nvavp->os_info.phys);
917         nvavp->os_info.reset_addr = nvavp->os_info.phys;
918         nvavp->os_info.data = ioremap(nvavp->os_info.phys, SZ_1M);
919 #endif
920         ret = nvavp_load_os(nvavp, fw_os_file);
921         if (ret) {
922                 dev_err(&nvavp->nvhost_dev->dev,
923                         "unable to load os firmware '%s'\n", fw_os_file);
924                 goto err_exit;
925         }
926
927         ret = nvavp_pushbuffer_init(nvavp);
928         if (ret) {
929                 dev_err(&nvavp->nvhost_dev->dev,
930                         "unable to init pushbuffer\n");
931                 goto err_exit;
932         }
933         tegra_init_legacy_irq_cop();
934         enable_irq(nvavp->mbox_from_avp_pend_irq);
935 err_exit:
936         return ret;
937 }
938
939 static int nvavp_init(struct nvavp_info *nvavp, int channel_id)
940 {
941         int ret = 0;
942
943         ret = nvavp_os_init(nvavp);
944         if (ret) {
945                 dev_err(&nvavp->nvhost_dev->dev,
946                         "unable to load os firmware and allocate buffers\n");
947         }
948
949         if (IS_VIDEO_CHANNEL_ID(channel_id) &&
950                 (!nvavp_get_video_init_status(nvavp)) ) {
951                 pr_debug("nvavp_init : channel_ID (%d)\n", channel_id);
952                 ret = nvavp_load_ucode(nvavp);
953                 if (ret) {
954                         dev_err(&nvavp->nvhost_dev->dev,
955                                 "unable to load ucode\n");
956                         goto err_exit;
957                 }
958
959                 nvavp_reset_vde(nvavp);
960                 nvavp_reset_avp(nvavp, nvavp->os_info.reset_addr);
961
962                 nvavp_set_video_init_status(nvavp, 1);
963         }
964 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
965         if (IS_AUDIO_CHANNEL_ID(channel_id) &&
966                 (!nvavp_get_audio_init_status(nvavp))) {
967                 pr_debug("nvavp_init : channel_ID (%d)\n", channel_id);
968                 nvavp_reset_avp(nvavp, nvavp->os_info.reset_addr);
969                 nvavp_set_audio_init_status(nvavp, 1);
970         }
971 #endif
972
973 err_exit:
974         return ret;
975 }
976
977 static void nvavp_uninit(struct nvavp_info *nvavp)
978 {
979         int video_initialized, audio_initialized = 0;
980
981         video_initialized = nvavp_get_video_init_status(nvavp);
982
983 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
984         audio_initialized = nvavp_get_audio_init_status(nvavp);
985 #endif
986
987         pr_debug("nvavp_uninit video_initialized(%d) audio_initialized(%d)\n",
988                 video_initialized, audio_initialized);
989
990         /* Video and Audio both are uninitialized */
991         if (!video_initialized && !audio_initialized)
992                 return;
993
994         if (video_initialized) {
995                 pr_debug("nvavp_uninit nvavp->video_initialized\n");
996                 cancel_work_sync(&nvavp->clock_disable_work);
997                 nvavp_halt_vde(nvavp);
998                 nvavp_set_video_init_status(nvavp, 0);
999                 video_initialized = 0;
1000         }
1001
1002 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1003         if (audio_initialized) {
1004                 cancel_work_sync(&nvavp->app_notify_work);
1005                 nvavp_set_audio_init_status(nvavp, 0);
1006                 audio_initialized = 0;
1007         }
1008 #endif
1009
1010         /* Video and Audio both becomes uninitialized */
1011         if (video_initialized == audio_initialized) {
1012                 pr_debug("nvavp_uninit both channels unitialized\n");
1013
1014                 clk_disable(nvavp->sclk);
1015                 clk_disable(nvavp->emc_clk);
1016                 disable_irq(nvavp->mbox_from_avp_pend_irq);
1017                 nvavp_pushbuffer_deinit(nvavp);
1018                 nvavp_halt_avp(nvavp);
1019         }
1020 }
1021
1022 static int nvavp_set_clock_ioctl(struct file *filp, unsigned int cmd,
1023                                                         unsigned long arg)
1024 {
1025         struct nvavp_clientctx *clientctx = filp->private_data;
1026         struct nvavp_info *nvavp = clientctx->nvavp;
1027         struct clk *c;
1028         struct nvavp_clock_args config;
1029
1030         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1031                 return -EFAULT;
1032
1033         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d, clk_rate=%u\n",
1034                         __func__, config.id, config.rate);
1035
1036         if (config.id == NVAVP_MODULE_ID_AVP)
1037                 nvavp->sclk_rate = config.rate;
1038         else if (config.id == NVAVP_MODULE_ID_EMC)
1039                 nvavp->emc_clk_rate = config.rate;
1040
1041         c = nvavp_clk_get(nvavp, config.id);
1042         if (IS_ERR_OR_NULL(c))
1043                 return -EINVAL;
1044
1045         clk_enable(c);
1046         clk_set_rate(c, config.rate);
1047
1048         config.rate = clk_get_rate(c);
1049         clk_disable(c);
1050         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
1051                 return -EFAULT;
1052
1053         return 0;
1054 }
1055
1056 static int nvavp_get_clock_ioctl(struct file *filp, unsigned int cmd,
1057                                                         unsigned long arg)
1058 {
1059         struct nvavp_clientctx *clientctx = filp->private_data;
1060         struct nvavp_info *nvavp = clientctx->nvavp;
1061         struct clk *c;
1062         struct nvavp_clock_args config;
1063
1064         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1065                 return -EFAULT;
1066
1067         c = nvavp_clk_get(nvavp, config.id);
1068         if (IS_ERR_OR_NULL(c))
1069                 return -EINVAL;
1070
1071         clk_enable(c);
1072         config.rate = clk_get_rate(c);
1073         clk_disable(c);
1074
1075         if (copy_to_user((void __user *)arg, &config, sizeof(struct nvavp_clock_args)))
1076                 return -EFAULT;
1077
1078         return 0;
1079 }
1080
1081 static int nvavp_get_syncpointid_ioctl(struct file *filp, unsigned int cmd,
1082                                                         unsigned long arg)
1083 {
1084         struct nvavp_clientctx *clientctx = filp->private_data;
1085         struct nvavp_info *nvavp = clientctx->nvavp;
1086         u32 id = nvavp->syncpt_id;
1087
1088         if (_IOC_DIR(cmd) & _IOC_READ) {
1089                 if (copy_to_user((void __user *)arg, &id, sizeof(u32)))
1090                         return -EFAULT;
1091                 else
1092                         return 0;
1093         }
1094         return -EFAULT;
1095 }
1096
1097 static int nvavp_set_nvmapfd_ioctl(struct file *filp, unsigned int cmd,
1098                                                         unsigned long arg)
1099 {
1100         struct nvavp_clientctx *clientctx = filp->private_data;
1101         struct nvavp_set_nvmap_fd_args buf;
1102         struct nvmap_client *new_client;
1103         int fd;
1104
1105         if (_IOC_DIR(cmd) & _IOC_WRITE) {
1106                 if (copy_from_user(&buf, (void __user *)arg, _IOC_SIZE(cmd)))
1107                         return -EFAULT;
1108         }
1109
1110         fd = buf.fd;
1111         new_client = nvmap_client_get_file(fd);
1112         if (IS_ERR(new_client))
1113                 return PTR_ERR(new_client);
1114
1115         clientctx->nvmap = new_client;
1116         return 0;
1117 }
1118
1119 static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
1120                                                         unsigned long arg)
1121 {
1122         struct nvavp_clientctx *clientctx = filp->private_data;
1123         struct nvavp_info *nvavp = clientctx->nvavp;
1124         struct nvavp_pushbuffer_submit_hdr hdr;
1125         u32 *cmdbuf_data;
1126         struct nvmap_handle *cmdbuf_handle = NULL;
1127         struct nvmap_handle_ref *cmdbuf_dupe;
1128         int ret = 0, i;
1129         unsigned long phys_addr;
1130         unsigned long virt_addr;
1131         struct nvavp_pushbuffer_submit_hdr *user_hdr =
1132                         (struct nvavp_pushbuffer_submit_hdr *) arg;
1133         struct nvavp_syncpt syncpt;
1134
1135         syncpt.id = NVSYNCPT_INVALID;
1136         syncpt.value = 0;
1137
1138         if (_IOC_DIR(cmd) & _IOC_WRITE) {
1139                 if (copy_from_user(&hdr, (void __user *)arg,
1140                         sizeof(struct nvavp_pushbuffer_submit_hdr)))
1141                         return -EFAULT;
1142         }
1143
1144         if (!hdr.cmdbuf.mem)
1145                 return 0;
1146
1147         if (copy_from_user(clientctx->relocs, (void __user *)hdr.relocs,
1148                         sizeof(struct nvavp_reloc) * hdr.num_relocs)) {
1149                 return -EFAULT;
1150         }
1151
1152         cmdbuf_handle = nvmap_get_handle_id(clientctx->nvmap, hdr.cmdbuf.mem);
1153         if (cmdbuf_handle == NULL) {
1154                 dev_err(&nvavp->nvhost_dev->dev,
1155                         "invalid cmd buffer handle %08x\n", hdr.cmdbuf.mem);
1156                 return -EPERM;
1157         }
1158
1159         /* duplicate the new pushbuffer's handle into the nvavp driver's
1160          * nvmap context, to ensure that the handle won't be freed as
1161          * long as it is in-use by the fb driver */
1162         cmdbuf_dupe = nvmap_duplicate_handle_id(nvavp->nvmap, hdr.cmdbuf.mem);
1163         nvmap_handle_put(cmdbuf_handle);
1164
1165         if (IS_ERR(cmdbuf_dupe)) {
1166                 dev_err(&nvavp->nvhost_dev->dev,
1167                         "could not duplicate handle\n");
1168                 return PTR_ERR(cmdbuf_dupe);
1169         }
1170
1171         phys_addr = nvmap_pin(nvavp->nvmap, cmdbuf_dupe);
1172         if (IS_ERR((void *)phys_addr)) {
1173                 dev_err(&nvavp->nvhost_dev->dev, "could not pin handle\n");
1174                 nvmap_free(nvavp->nvmap, cmdbuf_dupe);
1175                 return PTR_ERR((void *)phys_addr);
1176         }
1177
1178         virt_addr = (unsigned long)nvmap_mmap(cmdbuf_dupe);
1179         if (!virt_addr) {
1180                 dev_err(&nvavp->nvhost_dev->dev, "cannot map cmdbuf handle\n");
1181                 ret = -ENOMEM;
1182                 goto err_cmdbuf_mmap;
1183         }
1184
1185         cmdbuf_data = (u32 *)(virt_addr + hdr.cmdbuf.offset);
1186
1187         for (i = 0; i < hdr.num_relocs; i++) {
1188                 u32 *reloc_addr, target_phys_addr;
1189
1190                 if (clientctx->relocs[i].cmdbuf_mem != hdr.cmdbuf.mem) {
1191                         dev_err(&nvavp->nvhost_dev->dev,
1192                                 "reloc info does not match target bufferID\n");
1193                         ret = -EPERM;
1194                         goto err_reloc_info;
1195                 }
1196
1197                 reloc_addr = cmdbuf_data +
1198                              (clientctx->relocs[i].cmdbuf_offset >> 2);
1199
1200                 target_phys_addr = nvmap_handle_address(clientctx->nvmap,
1201                                             clientctx->relocs[i].target);
1202                 target_phys_addr += clientctx->relocs[i].target_offset;
1203                 writel(target_phys_addr, reloc_addr);
1204         }
1205
1206         if (hdr.syncpt) {
1207                 ret = nvavp_pushbuffer_update(nvavp,
1208                                              (phys_addr + hdr.cmdbuf.offset),
1209                                               hdr.cmdbuf.words, &syncpt,
1210                                               (hdr.flags & NVAVP_UCODE_EXT),
1211                                                 clientctx->channel_id);
1212
1213                 if (copy_to_user((void __user *)user_hdr->syncpt, &syncpt,
1214                                 sizeof(struct nvavp_syncpt))) {
1215                         ret = -EFAULT;
1216                         goto err_reloc_info;
1217                 }
1218         } else {
1219                 ret = nvavp_pushbuffer_update(nvavp,
1220                                              (phys_addr + hdr.cmdbuf.offset),
1221                                               hdr.cmdbuf.words, NULL,
1222                                               (hdr.flags & NVAVP_UCODE_EXT),
1223                                                 clientctx->channel_id);
1224         }
1225
1226 err_reloc_info:
1227         nvmap_munmap(cmdbuf_dupe, (void *)virt_addr);
1228 err_cmdbuf_mmap:
1229         nvmap_unpin(nvavp->nvmap, cmdbuf_dupe);
1230         nvmap_free(nvavp->nvmap, cmdbuf_dupe);
1231         return ret;
1232 }
1233
1234 static int nvavp_wake_avp_ioctl(struct file *filp, unsigned int cmd,
1235                                                         unsigned long arg)
1236 {
1237         wmb();
1238         /* wake up avp */
1239         writel(0xA0000001, NVAVP_OS_OUTBOX);
1240         return 0;
1241 }
1242
1243 static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
1244                                                         unsigned long arg)
1245 {
1246         struct nvavp_clientctx *clientctx = filp->private_data;
1247         struct nvavp_info *nvavp = clientctx->nvavp;
1248         struct nvavp_clock_stay_on_state_args clock;
1249
1250         if (copy_from_user(&clock, (void __user *)arg,
1251                            sizeof(struct nvavp_clock_stay_on_state_args)))
1252                 return -EFAULT;
1253
1254         dev_dbg(&nvavp->nvhost_dev->dev, "%s: state=%d\n",
1255                 __func__, clock.state);
1256
1257         if (clock.state != NVAVP_CLOCK_STAY_ON_DISABLED &&
1258             clock.state !=  NVAVP_CLOCK_STAY_ON_ENABLED) {
1259                 dev_err(&nvavp->nvhost_dev->dev, "%s: invalid argument=%d\n",
1260                         __func__, clock.state);
1261                 return -EINVAL;
1262         }
1263
1264         mutex_lock(&nvavp->open_lock);
1265         if (clock.state) {
1266                 if (clientctx->clk_reqs++ == 0)
1267                         nvavp_clks_enable(nvavp);
1268         } else {
1269                 if (--clientctx->clk_reqs == 0)
1270                         nvavp_clks_disable(nvavp);
1271         }
1272         mutex_unlock(&nvavp->open_lock);
1273         return 0;
1274 }
1275
1276 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1277 static int nvavp_enable_audio_clocks(struct file *filp, unsigned int cmd,
1278                                         unsigned long arg)
1279 {
1280         struct nvavp_clientctx *clientctx = filp->private_data;
1281         struct nvavp_info *nvavp = clientctx->nvavp;
1282         struct nvavp_clock_args config;
1283
1284         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1285                 return -EFAULT;
1286
1287         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d\n",
1288                         __func__, config.id);
1289
1290         if (config.id == NVAVP_MODULE_ID_VCP)
1291                 clk_enable(nvavp->vcp_clk);
1292         else if (config.id == NVAVP_MODULE_ID_BSEA)
1293                 clk_enable(nvavp->bsea_clk);
1294
1295         return 0;
1296 }
1297
1298 static int nvavp_disable_audio_clocks(struct file *filp, unsigned int cmd,
1299                                         unsigned long arg)
1300 {
1301         struct nvavp_clientctx *clientctx = filp->private_data;
1302         struct nvavp_info *nvavp = clientctx->nvavp;
1303         struct nvavp_clock_args config;
1304
1305         if (copy_from_user(&config, (void __user *)arg, sizeof(struct nvavp_clock_args)))
1306                 return -EFAULT;
1307
1308         dev_dbg(&nvavp->nvhost_dev->dev, "%s: clk_id=%d\n",
1309                         __func__, config.id);
1310
1311         if (config.id == NVAVP_MODULE_ID_VCP)
1312                 clk_disable(nvavp->vcp_clk);
1313         else if (config.id == NVAVP_MODULE_ID_BSEA)
1314                 clk_disable(nvavp->bsea_clk);
1315
1316         return 0;
1317 }
1318 #else
1319 static int nvavp_enable_audio_clocks(struct file *filp, unsigned int cmd,
1320                                         unsigned long arg)
1321 {
1322         return 0;
1323 }
1324
1325 static int nvavp_disable_audio_clocks(struct file *filp, unsigned int cmd,
1326                                         unsigned long arg)
1327 {
1328         return 0;
1329 }
1330 #endif
1331
1332 static int tegra_nvavp_open(struct inode *inode, struct file *filp, int channel_id)
1333 {
1334         struct miscdevice *miscdev = filp->private_data;
1335         struct nvavp_info *nvavp = dev_get_drvdata(miscdev->parent);
1336         int ret = 0;
1337         struct nvavp_clientctx *clientctx;
1338
1339         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1340
1341         nonseekable_open(inode, filp);
1342
1343         clientctx = kzalloc(sizeof(*clientctx), GFP_KERNEL);
1344         if (!clientctx)
1345                 return -ENOMEM;
1346
1347         mutex_lock(&nvavp->open_lock);
1348
1349         pr_debug("tegra_nvavp_open channel_id (%d)\n", channel_id);
1350
1351         clientctx->channel_id = channel_id;
1352
1353         ret = nvavp_init(nvavp, channel_id);
1354
1355         if (!ret)
1356                 nvavp->refcount++;
1357
1358         clientctx->nvavp = nvavp;
1359
1360         filp->private_data = clientctx;
1361
1362         mutex_unlock(&nvavp->open_lock);
1363
1364         return ret;
1365 }
1366
1367 static int tegra_nvavp_video_open(struct inode *inode, struct file *filp)
1368 {
1369         pr_debug("tegra_nvavp_video_open NVAVP_VIDEO_CHANNEL\n");
1370         return tegra_nvavp_open(inode, filp, NVAVP_VIDEO_CHANNEL);
1371 }
1372
1373 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1374 static int tegra_nvavp_audio_open(struct inode *inode, struct file *filp)
1375 {
1376         pr_debug("tegra_nvavp_audio_open NVAVP_AUDIO_CHANNEL\n");
1377         return tegra_nvavp_open(inode, filp, NVAVP_AUDIO_CHANNEL);
1378 }
1379 #endif
1380
1381 static int tegra_nvavp_release(struct inode *inode, struct file *filp)
1382 {
1383         struct nvavp_clientctx *clientctx = filp->private_data;
1384         struct nvavp_info *nvavp = clientctx->nvavp;
1385         int ret = 0;
1386
1387         dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__);
1388
1389         filp->private_data = NULL;
1390
1391         mutex_lock(&nvavp->open_lock);
1392
1393         if (!nvavp->refcount) {
1394                 dev_err(&nvavp->nvhost_dev->dev,
1395                         "releasing while in invalid state\n");
1396                 ret = -EINVAL;
1397                 goto out;
1398         }
1399
1400         /* if this client had any requests, drop our clk ref */
1401         if (clientctx->clk_reqs)
1402                 nvavp_clks_disable(nvavp);
1403
1404         if (nvavp->refcount > 0)
1405                 nvavp->refcount--;
1406         if (!nvavp->refcount)
1407                 nvavp_uninit(nvavp);
1408
1409 out:
1410         nvmap_client_put(clientctx->nvmap);
1411         mutex_unlock(&nvavp->open_lock);
1412         kfree(clientctx);
1413         return ret;
1414 }
1415
1416 static long tegra_nvavp_ioctl(struct file *filp, unsigned int cmd,
1417                             unsigned long arg)
1418 {
1419         int ret = 0;
1420
1421         if (_IOC_TYPE(cmd) != NVAVP_IOCTL_MAGIC ||
1422             _IOC_NR(cmd) < NVAVP_IOCTL_MIN_NR ||
1423             _IOC_NR(cmd) > NVAVP_IOCTL_MAX_NR)
1424                 return -EFAULT;
1425
1426         switch (cmd) {
1427         case NVAVP_IOCTL_SET_NVMAP_FD:
1428                 ret = nvavp_set_nvmapfd_ioctl(filp, cmd, arg);
1429                 break;
1430         case NVAVP_IOCTL_GET_SYNCPOINT_ID:
1431                 ret = nvavp_get_syncpointid_ioctl(filp, cmd, arg);
1432                 break;
1433         case NVAVP_IOCTL_PUSH_BUFFER_SUBMIT:
1434                 ret = nvavp_pushbuffer_submit_ioctl(filp, cmd, arg);
1435                 break;
1436         case NVAVP_IOCTL_SET_CLOCK:
1437                 ret = nvavp_set_clock_ioctl(filp, cmd, arg);
1438                 break;
1439         case NVAVP_IOCTL_GET_CLOCK:
1440                 ret = nvavp_get_clock_ioctl(filp, cmd, arg);
1441                 break;
1442         case NVAVP_IOCTL_WAKE_AVP:
1443                 ret = nvavp_wake_avp_ioctl(filp, cmd, arg);
1444                 break;
1445         case NVAVP_IOCTL_FORCE_CLOCK_STAY_ON:
1446                 ret = nvavp_force_clock_stay_on_ioctl(filp, cmd, arg);
1447                 break;
1448         case NVAVP_IOCTL_ENABLE_AUDIO_CLOCKS:
1449                 ret = nvavp_enable_audio_clocks(filp, cmd, arg);
1450                 break;
1451         case NVAVP_IOCTL_DISABLE_AUDIO_CLOCKS:
1452                 ret = nvavp_disable_audio_clocks(filp, cmd, arg);
1453                 break;
1454         default:
1455                 ret = -EINVAL;
1456                 break;
1457         }
1458         return ret;
1459 }
1460
1461 static const struct file_operations tegra_video_nvavp_fops = {
1462         .owner          = THIS_MODULE,
1463         .open           = tegra_nvavp_video_open,
1464         .release        = tegra_nvavp_release,
1465         .unlocked_ioctl = tegra_nvavp_ioctl,
1466 };
1467
1468 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1469 static const struct file_operations tegra_audio_nvavp_fops = {
1470         .owner          = THIS_MODULE,
1471         .open           = tegra_nvavp_audio_open,
1472         .release        = tegra_nvavp_release,
1473         .unlocked_ioctl = tegra_nvavp_ioctl,
1474 };
1475 #endif
1476
1477 static int tegra_nvavp_probe(struct nvhost_device *ndev,
1478         struct nvhost_device_id *id_table)
1479 {
1480         struct nvavp_info *nvavp;
1481         int irq;
1482         unsigned int heap_mask;
1483         u32 iovmm_addr;
1484         int ret = 0, channel_id;
1485
1486         irq = nvhost_get_irq_byname(ndev, "mbox_from_nvavp_pending");
1487         if (irq < 0) {
1488                 dev_err(&ndev->dev, "invalid nvhost data\n");
1489                 return -EINVAL;
1490         }
1491
1492         nvavp = kzalloc(sizeof(struct nvavp_info), GFP_KERNEL);
1493         if (!nvavp) {
1494                 dev_err(&ndev->dev, "cannot allocate avp_info\n");
1495                 return -ENOMEM;
1496         }
1497
1498         memset(nvavp, 0, sizeof(*nvavp));
1499
1500         nvavp->nvmap = nvmap_create_client(nvmap_dev, "nvavp_drv");
1501         if (IS_ERR_OR_NULL(nvavp->nvmap)) {
1502                 dev_err(&ndev->dev, "cannot create nvmap client\n");
1503                 ret = PTR_ERR(nvavp->nvmap);
1504                 goto err_nvmap_create_drv_client;
1505         }
1506
1507 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
1508         heap_mask = NVMAP_HEAP_CARVEOUT_GENERIC;
1509 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
1510         heap_mask = NVMAP_HEAP_IOVMM;
1511 #else /* nvmem= carveout */
1512         heap_mask = 0;
1513 #endif
1514         switch (heap_mask) {
1515         case NVMAP_HEAP_IOVMM:
1516
1517                 iovmm_addr = 0x0ff00000;
1518
1519                 nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M,
1520                                                 L1_CACHE_BYTES,
1521                                                 NVMAP_HANDLE_UNCACHEABLE,
1522                                                 iovmm_addr);
1523                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1524                         dev_err(&ndev->dev,
1525                                 "cannot create os handle\n");
1526                         ret = PTR_ERR(nvavp->os_info.handle);
1527                         goto err_nvmap_alloc;
1528                 }
1529
1530                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1531                 if (!nvavp->os_info.data) {
1532                         dev_err(&ndev->dev,
1533                                 "cannot map os handle\n");
1534                         ret = -ENOMEM;
1535                         goto err_nvmap_mmap;
1536                 }
1537
1538                 nvavp->os_info.phys =
1539                         nvmap_pin(nvavp->nvmap, nvavp->os_info.handle);
1540                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1541                         dev_err(&ndev->dev,
1542                                 "cannot pin os handle\n");
1543                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1544                         goto err_nvmap_pin;
1545                 }
1546
1547                 dev_info(&ndev->dev,
1548                         "allocated IOVM at %lx for AVP os\n",
1549                         (unsigned long)nvavp->os_info.phys);
1550                 break;
1551         case NVMAP_HEAP_CARVEOUT_GENERIC:
1552                 nvavp->os_info.handle = nvmap_alloc(nvavp->nvmap, SZ_1M, SZ_1M,
1553                                                 NVMAP_HANDLE_UNCACHEABLE, 0);
1554                 if (IS_ERR_OR_NULL(nvavp->os_info.handle)) {
1555                         dev_err(&ndev->dev, "cannot create AVP os handle\n");
1556                         ret = PTR_ERR(nvavp->os_info.handle);
1557                         goto err_nvmap_alloc;
1558                 }
1559
1560                 nvavp->os_info.data = nvmap_mmap(nvavp->os_info.handle);
1561                 if (!nvavp->os_info.data) {
1562                         dev_err(&ndev->dev, "cannot map AVP os handle\n");
1563                         ret = -ENOMEM;
1564                         goto err_nvmap_mmap;
1565                 }
1566
1567                 nvavp->os_info.phys = nvmap_pin(nvavp->nvmap,
1568                                         nvavp->os_info.handle);
1569                 if (IS_ERR_OR_NULL((void *)nvavp->os_info.phys)) {
1570                         dev_err(&ndev->dev, "cannot pin AVP os handle\n");
1571                         ret = PTR_ERR((void *)nvavp->os_info.phys);
1572                         goto err_nvmap_pin;
1573                 }
1574
1575                 dev_info(&ndev->dev,
1576                         "allocated carveout memory at %lx for AVP os\n",
1577                         (unsigned long)nvavp->os_info.phys);
1578                 break;
1579         default:
1580                 dev_err(&ndev->dev, "invalid/non-supported heap for AVP os\n");
1581                 ret = -EINVAL;
1582                 goto err_get_syncpt;
1583         }
1584
1585         nvavp->mbox_from_avp_pend_irq = irq;
1586         mutex_init(&nvavp->open_lock);
1587
1588         for (channel_id = 0; channel_id < NVAVP_NUM_CHANNELS; channel_id++)
1589                 mutex_init(&nvavp->channel_info[channel_id].pushbuffer_lock);
1590
1591         /* TODO DO NOT USE NVAVP DEVICE */
1592         nvavp->cop_clk = clk_get(&ndev->dev, "cop");
1593         if (IS_ERR(nvavp->cop_clk)) {
1594                 dev_err(&ndev->dev, "cannot get cop clock\n");
1595                 ret = -ENOENT;
1596                 goto err_get_cop_clk;
1597         }
1598
1599         nvavp->vde_clk = clk_get(&ndev->dev, "vde");
1600         if (IS_ERR(nvavp->vde_clk)) {
1601                 dev_err(&ndev->dev, "cannot get vde clock\n");
1602                 ret = -ENOENT;
1603                 goto err_get_vde_clk;
1604         }
1605
1606         nvavp->bsev_clk = clk_get(&ndev->dev, "bsev");
1607         if (IS_ERR(nvavp->bsev_clk)) {
1608                 dev_err(&ndev->dev, "cannot get bsev clock\n");
1609                 ret = -ENOENT;
1610                 goto err_get_bsev_clk;
1611         }
1612
1613         nvavp->sclk = clk_get(&ndev->dev, "sclk");
1614         if (IS_ERR(nvavp->sclk)) {
1615                 dev_err(&ndev->dev, "cannot get avp.sclk clock\n");
1616                 ret = -ENOENT;
1617                 goto err_get_sclk;
1618         }
1619
1620         nvavp->emc_clk = clk_get(&ndev->dev, "emc");
1621         if (IS_ERR(nvavp->emc_clk)) {
1622                 dev_err(&ndev->dev, "cannot get emc clock\n");
1623                 ret = -ENOENT;
1624                 goto err_get_emc_clk;
1625         }
1626
1627 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1628         nvavp->bsea_clk = clk_get(&ndev->dev, "bsea");
1629         if (IS_ERR(nvavp->bsea_clk)) {
1630                 dev_err(&ndev->dev, "cannot get bsea clock\n");
1631                 ret = -ENOENT;
1632                 goto err_get_bsea_clk;
1633         }
1634
1635         nvavp->vcp_clk = clk_get(&ndev->dev, "vcp");
1636         if (IS_ERR(nvavp->vcp_clk)) {
1637                 dev_err(&ndev->dev, "cannot get vcp clock\n");
1638                 ret = -ENOENT;
1639                 goto err_get_vcp_clk;
1640         }
1641 #endif
1642
1643         nvavp->clk_enabled = 0;
1644         nvavp_halt_avp(nvavp);
1645
1646         INIT_WORK(&nvavp->clock_disable_work, clock_disable_handler);
1647
1648         nvavp->video_misc_dev.minor = MISC_DYNAMIC_MINOR;
1649         nvavp->video_misc_dev.name = "tegra_avpchannel";
1650         nvavp->video_misc_dev.fops = &tegra_video_nvavp_fops;
1651         nvavp->video_misc_dev.mode = S_IRWXUGO;
1652         nvavp->video_misc_dev.parent = &ndev->dev;
1653
1654         ret = misc_register(&nvavp->video_misc_dev);
1655         if (ret) {
1656                 dev_err(&ndev->dev, "unable to register misc device!\n");
1657                 goto err_misc_reg;
1658         }
1659
1660 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1661         INIT_WORK(&nvavp->app_notify_work, app_notify_handler);
1662         nvavp->audio_misc_dev.minor = MISC_DYNAMIC_MINOR;
1663         nvavp->audio_misc_dev.name = "tegra_audio_avpchannel";
1664         nvavp->audio_misc_dev.fops = &tegra_audio_nvavp_fops;
1665         nvavp->audio_misc_dev.mode = S_IRWXUGO;
1666         nvavp->audio_misc_dev.parent = &ndev->dev;
1667
1668         ret = misc_register(&nvavp->audio_misc_dev);
1669         if (ret) {
1670         dev_err(&ndev->dev, "unable to register misc device!\n");
1671                 goto err_audio_misc_reg;
1672         }
1673 #endif
1674
1675         ret = request_irq(irq, nvavp_mbox_pending_isr, 0,
1676                           TEGRA_NVAVP_NAME, nvavp);
1677         if (ret) {
1678                 dev_err(&ndev->dev, "cannot register irq handler\n");
1679                 goto err_req_irq_pend;
1680         }
1681         disable_irq(nvavp->mbox_from_avp_pend_irq);
1682
1683         nvhost_set_drvdata(ndev, nvavp);
1684         nvavp->nvhost_dev = ndev;
1685
1686         return 0;
1687
1688 err_req_irq_pend:
1689 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1690         misc_deregister(&nvavp->audio_misc_dev);
1691 err_audio_misc_reg:
1692 #endif
1693         misc_deregister(&nvavp->video_misc_dev);
1694 err_misc_reg:
1695 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1696         clk_put(nvavp->vcp_clk);
1697 err_get_vcp_clk:
1698         clk_put(nvavp->bsea_clk);
1699 err_get_bsea_clk:
1700 #endif
1701         clk_put(nvavp->emc_clk);
1702 err_get_emc_clk:
1703         clk_put(nvavp->sclk);
1704 err_get_sclk:
1705         clk_put(nvavp->bsev_clk);
1706 err_get_bsev_clk:
1707         clk_put(nvavp->vde_clk);
1708 err_get_vde_clk:
1709         clk_put(nvavp->cop_clk);
1710 err_get_cop_clk:
1711         nvmap_unpin(nvavp->nvmap, nvavp->os_info.handle);
1712 err_nvmap_pin:
1713         nvmap_munmap(nvavp->os_info.handle, nvavp->os_info.data);
1714 err_nvmap_mmap:
1715 #if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU)
1716         nvmap_free(nvavp->nvmap, nvavp->os_info.handle);
1717 #elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU)
1718         nvmap_free_iovm(nvavp->nvmap, nvavp->os_info.handle);
1719 #endif
1720 err_nvmap_alloc:
1721         nvmap_client_put(nvavp->nvmap);
1722 err_nvmap_create_drv_client:
1723 err_get_syncpt:
1724         kfree(nvavp);
1725         return ret;
1726 }
1727
1728 static int tegra_nvavp_remove(struct nvhost_device *ndev)
1729 {
1730         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1731
1732         if (!nvavp)
1733                 return 0;
1734
1735         mutex_lock(&nvavp->open_lock);
1736         if (nvavp->refcount) {
1737                 mutex_unlock(&nvavp->open_lock);
1738                 return -EBUSY;
1739         }
1740         mutex_unlock(&nvavp->open_lock);
1741
1742         nvavp_unload_ucode(nvavp);
1743         nvavp_unload_os(nvavp);
1744
1745         misc_deregister(&nvavp->video_misc_dev);
1746
1747 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1748         misc_deregister(&nvavp->audio_misc_dev);
1749         clk_put(nvavp->vcp_clk);
1750         clk_put(nvavp->bsea_clk);
1751 #endif
1752         clk_put(nvavp->bsev_clk);
1753         clk_put(nvavp->vde_clk);
1754         clk_put(nvavp->cop_clk);
1755
1756         clk_put(nvavp->emc_clk);
1757         clk_put(nvavp->sclk);
1758
1759         nvmap_client_put(nvavp->nvmap);
1760
1761         kfree(nvavp);
1762         return 0;
1763 }
1764
1765 #ifdef CONFIG_PM
1766 static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state)
1767 {
1768         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1769         int ret = 0;
1770
1771         mutex_lock(&nvavp->open_lock);
1772
1773         if (nvavp->refcount) {
1774                 if (!nvavp->clk_enabled) {
1775 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1776                         if (nvavp_check_idle(nvavp, NVAVP_AUDIO_CHANNEL))
1777                                 nvavp_uninit(nvavp);
1778                         else
1779                                 ret = -EBUSY;
1780 #else
1781                         nvavp_uninit(nvavp);
1782 #endif
1783                 }
1784                 else {
1785                         ret = -EBUSY;
1786                 }
1787         }
1788
1789         mutex_unlock(&nvavp->open_lock);
1790         return ret;
1791 }
1792
1793 static int tegra_nvavp_resume(struct nvhost_device *ndev)
1794 {
1795         struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
1796
1797         mutex_lock(&nvavp->open_lock);
1798
1799         if (nvavp->refcount) {
1800                 nvavp_init(nvavp, NVAVP_VIDEO_CHANNEL);
1801 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
1802                 nvavp_init(nvavp, NVAVP_AUDIO_CHANNEL);
1803 #endif
1804         }
1805         mutex_unlock(&nvavp->open_lock);
1806
1807         return 0;
1808 }
1809 #endif
1810
1811 static struct nvhost_driver tegra_nvavp_driver = {
1812         .driver = {
1813                 .name   = TEGRA_NVAVP_NAME,
1814                 .owner  = THIS_MODULE,
1815         },
1816         .probe          = tegra_nvavp_probe,
1817         .remove         = tegra_nvavp_remove,
1818 #ifdef CONFIG_PM
1819         .suspend        = tegra_nvavp_suspend,
1820         .resume         = tegra_nvavp_resume,
1821 #endif
1822 };
1823
1824 static int __init tegra_nvavp_init(void)
1825 {
1826         return nvhost_driver_register(&tegra_nvavp_driver);
1827 }
1828
1829 static void __exit tegra_nvavp_exit(void)
1830 {
1831         nvhost_driver_unregister(&tegra_nvavp_driver);
1832 }
1833
1834 module_init(tegra_nvavp_init);
1835 module_exit(tegra_nvavp_exit);
1836
1837 MODULE_AUTHOR("NVIDIA");
1838 MODULE_DESCRIPTION("Channel based AVP driver for Tegra");
1839 MODULE_VERSION("1.0");
1840 MODULE_LICENSE("Dual BSD/GPL");