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