video: tegra: host: add DT support
[linux-2.6.git] / drivers / video / tegra / host / mpe / mpe.c
1 /*
2  * drivers/video/tegra/host/mpe/mpe.c
3  *
4  * Tegra Graphics Host MPE
5  *
6  * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/slab.h>
22 #include <linux/export.h>
23 #include <linux/resource.h>
24 #include <linux/module.h>
25 #include <linux/scatterlist.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/of.h>
28 #include <linux/of_device.h>
29 #include <linux/of_platform.h>
30
31 #include <mach/iomap.h>
32 #include <mach/hardware.h>
33
34 #include "nvhost_hwctx.h"
35 #include "nvhost_channel.h"
36 #include "dev.h"
37 #include "host1x/host1x01_hardware.h"
38 #include "host1x/host1x_hwctx.h"
39 #include "t20/t20.h"
40 #include "t30/t30.h"
41 #include "t114/t114.h"
42 #include "chip_support.h"
43 #include "nvhost_memmgr.h"
44 #include "class_ids.h"
45 #include "nvhost_job.h"
46 #include "nvhost_acm.h"
47 #include "mpe.h"
48
49 #include "bus_client.h"
50
51 enum {
52         HWCTX_REGINFO_NORMAL = 0,
53         HWCTX_REGINFO_STASH,
54         HWCTX_REGINFO_CALCULATE,
55         HWCTX_REGINFO_WRITEBACK
56 };
57
58 const struct hwctx_reginfo ctxsave_regs_mpe[] = {
59         HWCTX_REGINFO(0x124,  1, STASH),
60         HWCTX_REGINFO(0x123,  1, STASH),
61         HWCTX_REGINFO(0x103,  1, STASH),
62         HWCTX_REGINFO(0x074,  1, STASH),
63         HWCTX_REGINFO(0x021,  1, NORMAL),
64         HWCTX_REGINFO(0x020,  1, STASH),
65         HWCTX_REGINFO(0x024,  2, NORMAL),
66         HWCTX_REGINFO(0x0e6,  1, NORMAL),
67         HWCTX_REGINFO(0x3fc,  1, NORMAL),
68         HWCTX_REGINFO(0x3d0,  1, NORMAL),
69         HWCTX_REGINFO(0x3d4,  1, NORMAL),
70         HWCTX_REGINFO(0x013,  1, NORMAL),
71         HWCTX_REGINFO(0x022,  1, NORMAL),
72         HWCTX_REGINFO(0x030,  4, NORMAL),
73         HWCTX_REGINFO(0x023,  1, NORMAL),
74         HWCTX_REGINFO(0x070,  1, NORMAL),
75         HWCTX_REGINFO(0x0a0,  9, NORMAL),
76         HWCTX_REGINFO(0x071,  1, NORMAL),
77         HWCTX_REGINFO(0x100,  4, NORMAL),
78         HWCTX_REGINFO(0x104,  2, NORMAL),
79         HWCTX_REGINFO(0x108,  9, NORMAL),
80         HWCTX_REGINFO(0x112,  2, NORMAL),
81         HWCTX_REGINFO(0x114,  1, STASH),
82         HWCTX_REGINFO(0x014,  1, NORMAL),
83         HWCTX_REGINFO(0x072,  1, NORMAL),
84         HWCTX_REGINFO(0x200,  1, NORMAL),
85         HWCTX_REGINFO(0x0d1,  1, NORMAL),
86         HWCTX_REGINFO(0x0d0,  1, NORMAL),
87         HWCTX_REGINFO(0x0c0,  1, NORMAL),
88         HWCTX_REGINFO(0x0c3,  2, NORMAL),
89         HWCTX_REGINFO(0x0d2,  1, NORMAL),
90         HWCTX_REGINFO(0x0d8,  1, NORMAL),
91         HWCTX_REGINFO(0x0e0,  2, NORMAL),
92         HWCTX_REGINFO(0x07f,  2, NORMAL),
93         HWCTX_REGINFO(0x084,  8, NORMAL),
94         HWCTX_REGINFO(0x0d3,  1, NORMAL),
95         HWCTX_REGINFO(0x040, 13, NORMAL),
96         HWCTX_REGINFO(0x050,  6, NORMAL),
97         HWCTX_REGINFO(0x058,  1, NORMAL),
98         HWCTX_REGINFO(0x057,  1, NORMAL),
99         HWCTX_REGINFO(0x111,  1, NORMAL),
100         HWCTX_REGINFO(0x130,  3, NORMAL),
101         HWCTX_REGINFO(0x201,  1, NORMAL),
102         HWCTX_REGINFO(0x068,  2, NORMAL),
103         HWCTX_REGINFO(0x08c,  1, NORMAL),
104         HWCTX_REGINFO(0x0cf,  1, NORMAL),
105         HWCTX_REGINFO(0x082,  2, NORMAL),
106         HWCTX_REGINFO(0x075,  1, NORMAL),
107         HWCTX_REGINFO(0x0e8,  1, NORMAL),
108         HWCTX_REGINFO(0x056,  1, NORMAL),
109         HWCTX_REGINFO(0x057,  1, NORMAL),
110         HWCTX_REGINFO(0x073,  1, CALCULATE),
111         HWCTX_REGINFO(0x074,  1, NORMAL),
112         HWCTX_REGINFO(0x075,  1, NORMAL),
113         HWCTX_REGINFO(0x076,  1, STASH),
114         HWCTX_REGINFO(0x11a,  9, NORMAL),
115         HWCTX_REGINFO(0x123,  1, NORMAL),
116         HWCTX_REGINFO(0x124,  1, NORMAL),
117         HWCTX_REGINFO(0x12a,  5, NORMAL),
118         HWCTX_REGINFO(0x12f,  1, STASH),
119         HWCTX_REGINFO(0x125,  2, NORMAL),
120         HWCTX_REGINFO(0x034,  1, NORMAL),
121         HWCTX_REGINFO(0x133,  2, NORMAL),
122         HWCTX_REGINFO(0x127,  1, NORMAL),
123         HWCTX_REGINFO(0x106,  1, WRITEBACK),
124         HWCTX_REGINFO(0x107,  1, WRITEBACK)
125 };
126
127 #define NR_STASHES 8
128 #define NR_WRITEBACKS 2
129
130 #define RC_RAM_LOAD_CMD 0x115
131 #define RC_RAM_LOAD_DATA 0x116
132 #define RC_RAM_READ_CMD 0x128
133 #define RC_RAM_READ_DATA 0x129
134 #define RC_RAM_SIZE 692
135
136 #define IRFR_RAM_LOAD_CMD 0xc5
137 #define IRFR_RAM_LOAD_DATA 0xc6
138 #define IRFR_RAM_READ_CMD 0xcd
139 #define IRFR_RAM_READ_DATA 0xce
140 #define IRFR_RAM_SIZE 408
141
142 struct mpe_save_info {
143         u32 in[NR_STASHES];
144         u32 out[NR_WRITEBACKS];
145         unsigned in_pos;
146         unsigned out_pos;
147         u32 h264_mode;
148 };
149
150 /*** restore ***/
151
152 static unsigned int restore_size;
153
154 static void restore_begin(struct host1x_hwctx_handler *h, u32 *ptr)
155 {
156         /* set class to host */
157         ptr[0] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
158                                         host1x_uclass_incr_syncpt_base_r(), 1);
159         /* increment sync point base */
160         ptr[1] = nvhost_class_host_incr_syncpt_base(h->waitbase, 1);
161         /* set class to MPE */
162         ptr[2] = nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID, 0, 0);
163 }
164 #define RESTORE_BEGIN_SIZE 3
165
166 static void restore_ram(u32 *ptr, unsigned words,
167                         unsigned cmd_reg, unsigned data_reg)
168 {
169         ptr[0] = nvhost_opcode_imm(cmd_reg, words);
170         ptr[1] = nvhost_opcode_nonincr(data_reg, words);
171 }
172 #define RESTORE_RAM_SIZE 2
173
174 static void restore_end(struct host1x_hwctx_handler *h, u32 *ptr)
175 {
176         /* syncpt increment to track restore gather. */
177         ptr[0] = nvhost_opcode_imm_incr_syncpt(
178                         host1x_uclass_incr_syncpt_cond_op_done_v(),
179                         h->syncpt);
180 }
181 #define RESTORE_END_SIZE 1
182
183 static u32 *setup_restore_regs(u32 *ptr,
184                         const struct hwctx_reginfo *regs,
185                         unsigned int nr_regs)
186 {
187         const struct hwctx_reginfo *rend = regs + nr_regs;
188
189         for ( ; regs != rend; ++regs) {
190                 u32 offset = regs->offset;
191                 u32 count = regs->count;
192                 *ptr++ = nvhost_opcode_incr(offset, count);
193                 ptr += count;
194         }
195         return ptr;
196 }
197
198 static u32 *setup_restore_ram(u32 *ptr, unsigned words,
199                         unsigned cmd_reg, unsigned data_reg)
200 {
201         restore_ram(ptr, words, cmd_reg, data_reg);
202         return ptr + (RESTORE_RAM_SIZE + words);
203 }
204
205 static void setup_restore(struct host1x_hwctx_handler *h, u32 *ptr)
206 {
207         restore_begin(h, ptr);
208         ptr += RESTORE_BEGIN_SIZE;
209
210         ptr = setup_restore_regs(ptr, ctxsave_regs_mpe,
211                                 ARRAY_SIZE(ctxsave_regs_mpe));
212
213         ptr = setup_restore_ram(ptr, RC_RAM_SIZE,
214                         RC_RAM_LOAD_CMD, RC_RAM_LOAD_DATA);
215
216         ptr = setup_restore_ram(ptr, IRFR_RAM_SIZE,
217                         IRFR_RAM_LOAD_CMD, IRFR_RAM_LOAD_DATA);
218
219         restore_end(h, ptr);
220
221         wmb();
222 }
223
224 /*** save ***/
225
226 struct save_info {
227         u32 *ptr;
228         unsigned int save_count;
229         unsigned int restore_count;
230 };
231
232 static void save_begin(struct host1x_hwctx_handler *h, u32 *ptr)
233 {
234         /* MPE: when done, increment syncpt to base+1 */
235         ptr[0] = nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID, 0, 0);
236         ptr[1] = nvhost_opcode_imm_incr_syncpt(
237                         host1x_uclass_incr_syncpt_cond_op_done_v(), h->syncpt);
238         /* host: wait for syncpt base+1 */
239         ptr[2] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
240                                         host1x_uclass_wait_syncpt_base_r(), 1);
241         ptr[3] = nvhost_class_host_wait_syncpt_base(h->syncpt, h->waitbase, 1);
242         /* host: signal context read thread to start reading */
243         ptr[4] = nvhost_opcode_imm_incr_syncpt(
244                         host1x_uclass_incr_syncpt_cond_immediate_v(),
245                         h->syncpt);
246 }
247 #define SAVE_BEGIN_SIZE 5
248
249 static void save_direct(u32 *ptr, u32 start_reg, u32 count)
250 {
251         ptr[0] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
252                                         host1x_uclass_indoff_r(), 1);
253         ptr[1] = nvhost_class_host_indoff_reg_read(
254                         host1x_uclass_indoff_indmodid_mpe_v(),
255                         start_reg, true);
256         ptr[2] = nvhost_opcode_nonincr(host1x_uclass_inddata_r(), count);
257 }
258 #define SAVE_DIRECT_SIZE 3
259
260 static void save_set_ram_cmd(u32 *ptr, u32 cmd_reg, u32 count)
261 {
262         ptr[0] = nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID,
263                                         cmd_reg, 1);
264         ptr[1] = count;
265 }
266 #define SAVE_SET_RAM_CMD_SIZE 2
267
268 static void save_read_ram_data_nasty(u32 *ptr, u32 data_reg)
269 {
270         ptr[0] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
271                                         host1x_uclass_indoff_r(), 1);
272         ptr[1] = nvhost_class_host_indoff_reg_read(
273                         host1x_uclass_indoff_indmodid_mpe_v(),
274                         data_reg, false);
275         ptr[2] = nvhost_opcode_imm(host1x_uclass_inddata_r(), 0);
276         /* write junk data to avoid 'cached problem with register memory' */
277         ptr[3] = nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID,
278                                         data_reg, 1);
279         ptr[4] = 0x99;
280 }
281 #define SAVE_READ_RAM_DATA_NASTY_SIZE 5
282
283 static void save_end(struct host1x_hwctx_handler *h, u32 *ptr)
284 {
285         /* Wait for context read service to finish (cpu incr 3) */
286         ptr[0] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
287                                         host1x_uclass_wait_syncpt_base_r(), 1);
288         ptr[1] = nvhost_class_host_wait_syncpt_base(h->syncpt, h->waitbase, 3);
289         /* Advance syncpoint base */
290         ptr[2] = nvhost_opcode_nonincr(host1x_uclass_incr_syncpt_base_r(), 1);
291         ptr[3] = nvhost_class_host_incr_syncpt_base(h->waitbase, 3);
292         /* set class back to the unit */
293         ptr[4] = nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID, 0, 0);
294 }
295 #define SAVE_END_SIZE 5
296
297 static void setup_save_regs(struct save_info *info,
298                         const struct hwctx_reginfo *regs,
299                         unsigned int nr_regs)
300 {
301         const struct hwctx_reginfo *rend = regs + nr_regs;
302         u32 *ptr = info->ptr;
303         unsigned int save_count = info->save_count;
304         unsigned int restore_count = info->restore_count;
305
306         for ( ; regs != rend; ++regs) {
307                 u32 offset = regs->offset;
308                 u32 count = regs->count;
309                 if (regs->type != HWCTX_REGINFO_WRITEBACK) {
310                         if (ptr) {
311                                 save_direct(ptr, offset, count);
312                                 ptr += SAVE_DIRECT_SIZE;
313                                 memset(ptr, 0, count * 4);
314                                 ptr += count;
315                         }
316                         save_count += (SAVE_DIRECT_SIZE + count);
317                 }
318                 restore_count += (1 + count);
319         }
320
321         info->ptr = ptr;
322         info->save_count = save_count;
323         info->restore_count = restore_count;
324 }
325
326 static void setup_save_ram_nasty(struct save_info *info, unsigned words,
327                                         unsigned cmd_reg, unsigned data_reg)
328 {
329         u32 *ptr = info->ptr;
330         unsigned int save_count = info->save_count;
331         unsigned int restore_count = info->restore_count;
332         unsigned i;
333
334         if (ptr) {
335                 save_set_ram_cmd(ptr, cmd_reg, words);
336                 ptr += SAVE_SET_RAM_CMD_SIZE;
337                 for (i = words; i; --i) {
338                         save_read_ram_data_nasty(ptr, data_reg);
339                         ptr += SAVE_READ_RAM_DATA_NASTY_SIZE;
340                 }
341         }
342
343         save_count += SAVE_SET_RAM_CMD_SIZE;
344         save_count += words * SAVE_READ_RAM_DATA_NASTY_SIZE;
345         restore_count += (RESTORE_RAM_SIZE + words);
346
347         info->ptr = ptr;
348         info->save_count = save_count;
349         info->restore_count = restore_count;
350 }
351
352 static void setup_save(struct host1x_hwctx_handler *h, u32 *ptr)
353 {
354         struct save_info info = {
355                 ptr,
356                 SAVE_BEGIN_SIZE,
357                 RESTORE_BEGIN_SIZE
358         };
359
360         if (info.ptr) {
361                 save_begin(h, info.ptr);
362                 info.ptr += SAVE_BEGIN_SIZE;
363         }
364
365         setup_save_regs(&info, ctxsave_regs_mpe,
366                         ARRAY_SIZE(ctxsave_regs_mpe));
367
368         setup_save_ram_nasty(&info, RC_RAM_SIZE,
369                         RC_RAM_READ_CMD, RC_RAM_READ_DATA);
370
371         setup_save_ram_nasty(&info, IRFR_RAM_SIZE,
372                         IRFR_RAM_READ_CMD, IRFR_RAM_READ_DATA);
373
374         if (info.ptr) {
375                 save_end(h, info.ptr);
376                 info.ptr += SAVE_END_SIZE;
377         }
378
379         wmb();
380
381         h->save_size = info.save_count + SAVE_END_SIZE;
382         restore_size = info.restore_count + RESTORE_END_SIZE;
383 }
384
385 static u32 calculate_mpe(u32 word, struct mpe_save_info *msi)
386 {
387         u32 buffer_full_read = msi->in[0] & 0x01ffffff;
388         u32 byte_len = msi->in[1];
389         u32 drain = (msi->in[2] >> 2) & 0x007fffff;
390         u32 rep_frame = msi->in[3] & 0x0000ffff;
391         u32 h264_mode = (msi->in[4] >> 11) & 1;
392         int new_buffer_full;
393
394         if (h264_mode)
395                 byte_len >>= 3;
396         new_buffer_full = buffer_full_read + byte_len - (drain * 4);
397         msi->out[0] = max(0, new_buffer_full);
398         msi->out[1] = rep_frame;
399         if (rep_frame == 0)
400                 word &= 0xffff0000;
401         return word;
402 }
403
404 static u32 *save_regs(u32 *ptr, unsigned int *pending,
405                 struct nvhost_channel *channel,
406                 const struct hwctx_reginfo *regs,
407                 unsigned int nr_regs,
408                 struct mpe_save_info *msi)
409 {
410         const struct hwctx_reginfo *rend = regs + nr_regs;
411
412         for ( ; regs != rend; ++regs) {
413                 u32 count = regs->count;
414                 ++ptr; /* restore incr */
415                 if (regs->type == HWCTX_REGINFO_NORMAL) {
416                         nvhost_channel_drain_read_fifo(channel,
417                                                 ptr, count, pending);
418                         ptr += count;
419                 } else {
420                         u32 word;
421                         if (regs->type == HWCTX_REGINFO_WRITEBACK) {
422                                 BUG_ON(msi->out_pos >= NR_WRITEBACKS);
423                                 word = msi->out[msi->out_pos++];
424                         } else {
425                                 nvhost_channel_drain_read_fifo(channel,
426                                                 &word, 1, pending);
427                                 if (regs->type == HWCTX_REGINFO_STASH) {
428                                         BUG_ON(msi->in_pos >= NR_STASHES);
429                                         msi->in[msi->in_pos++] = word;
430                                 } else {
431                                         word = calculate_mpe(word, msi);
432                                 }
433                         }
434                         *ptr++ = word;
435                 }
436         }
437         return ptr;
438 }
439
440 static u32 *save_ram(u32 *ptr, unsigned int *pending,
441                 struct nvhost_channel *channel,
442                 unsigned words, unsigned cmd_reg, unsigned data_reg)
443 {
444         int err = 0;
445         ptr += RESTORE_RAM_SIZE;
446         err = nvhost_channel_drain_read_fifo(channel, ptr, words, pending);
447         WARN_ON(err);
448         return ptr + words;
449 }
450
451 /*** ctxmpe ***/
452
453 static struct nvhost_hwctx *ctxmpe_alloc(struct nvhost_hwctx_handler *h,
454                 struct nvhost_channel *ch)
455 {
456         struct mem_mgr *memmgr = nvhost_get_host(ch->dev)->memmgr;
457         struct host1x_hwctx_handler *p = to_host1x_hwctx_handler(h);
458         struct host1x_hwctx *ctx;
459
460         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
461         if (!ctx)
462                 return NULL;
463
464         ctx->restore = mem_op().alloc(memmgr, restore_size * 4, 32,
465                                 mem_mgr_flag_write_combine);
466         if (IS_ERR_OR_NULL(ctx->restore))
467                 goto fail_alloc;
468
469         ctx->restore_virt = mem_op().mmap(ctx->restore);
470         if (IS_ERR_OR_NULL(ctx->restore_virt))
471                 goto fail_mmap;
472
473         ctx->restore_sgt = mem_op().pin(memmgr, ctx->restore);
474         if (IS_ERR_OR_NULL(ctx->restore_sgt))
475                 goto fail_pin;
476         ctx->restore_phys = sg_dma_address(ctx->restore_sgt->sgl);
477
478         kref_init(&ctx->hwctx.ref);
479         ctx->hwctx.h = &p->h;
480         ctx->hwctx.channel = ch;
481         ctx->hwctx.valid = false;
482         ctx->save_incrs = 3;
483         ctx->save_thresh = 2;
484         ctx->save_slots = p->save_slots;
485         ctx->restore_size = restore_size;
486         ctx->restore_incrs = 1;
487
488         setup_restore(p, ctx->restore_virt);
489
490         return &ctx->hwctx;
491
492 fail_pin:
493         mem_op().munmap(ctx->restore, ctx->restore_virt);
494 fail_mmap:
495         mem_op().put(memmgr, ctx->restore);
496 fail_alloc:
497         kfree(ctx);
498         return NULL;
499 }
500
501 static void ctxmpe_get(struct nvhost_hwctx *ctx)
502 {
503         kref_get(&ctx->ref);
504 }
505
506 static void ctxmpe_free(struct kref *ref)
507 {
508         struct nvhost_hwctx *nctx = container_of(ref, struct nvhost_hwctx, ref);
509         struct host1x_hwctx *ctx = to_host1x_hwctx(nctx);
510         struct mem_mgr *memmgr = nvhost_get_host(nctx->channel->dev)->memmgr;
511
512         if (ctx->restore_virt)
513                 mem_op().munmap(ctx->restore, ctx->restore_virt);
514         mem_op().unpin(memmgr, ctx->restore, ctx->restore_sgt);
515         mem_op().put(memmgr, ctx->restore);
516         kfree(ctx);
517 }
518
519 static void ctxmpe_put(struct nvhost_hwctx *ctx)
520 {
521         kref_put(&ctx->ref, ctxmpe_free);
522 }
523
524 static void ctxmpe_save_push(struct nvhost_hwctx *nctx,
525                 struct nvhost_cdma *cdma)
526 {
527         struct host1x_hwctx *ctx = to_host1x_hwctx(nctx);
528         struct host1x_hwctx_handler *h = host1x_hwctx_handler(ctx);
529         nvhost_cdma_push_gather(cdma,
530                         nvhost_get_host(nctx->channel->dev)->memmgr,
531                         h->save_buf,
532                         0,
533                         nvhost_opcode_gather(h->save_size),
534                         h->save_phys);
535 }
536
537 static void ctxmpe_save_service(struct nvhost_hwctx *nctx)
538 {
539         struct host1x_hwctx *ctx = to_host1x_hwctx(nctx);
540         struct host1x_hwctx_handler *h = host1x_hwctx_handler(ctx);
541
542         u32 *ptr = (u32 *)ctx->restore_virt + RESTORE_BEGIN_SIZE;
543         unsigned int pending = 0;
544         struct mpe_save_info msi;
545
546         msi.in_pos = 0;
547         msi.out_pos = 0;
548
549         ptr = save_regs(ptr, &pending, nctx->channel,
550                         ctxsave_regs_mpe, ARRAY_SIZE(ctxsave_regs_mpe), &msi);
551
552         ptr = save_ram(ptr, &pending, nctx->channel,
553                 RC_RAM_SIZE, RC_RAM_READ_CMD, RC_RAM_READ_DATA);
554
555         ptr = save_ram(ptr, &pending, nctx->channel,
556                 IRFR_RAM_SIZE, IRFR_RAM_READ_CMD, IRFR_RAM_READ_DATA);
557
558         wmb();
559         nvhost_syncpt_cpu_incr(&nvhost_get_host(nctx->channel->dev)->syncpt,
560                         h->syncpt);
561 }
562
563 struct nvhost_hwctx_handler *nvhost_mpe_ctxhandler_init(u32 syncpt,
564         u32 waitbase, struct nvhost_channel *ch)
565 {
566         struct mem_mgr *memmgr;
567         u32 *save_ptr;
568         struct host1x_hwctx_handler *p;
569
570         p = kmalloc(sizeof(*p), GFP_KERNEL);
571         if (!p)
572                 return NULL;
573
574         memmgr = nvhost_get_host(ch->dev)->memmgr;
575
576         p->syncpt = syncpt;
577         p->waitbase = waitbase;
578
579         setup_save(p, NULL);
580
581         p->save_buf = mem_op().alloc(memmgr, p->save_size * 4, 32,
582                                 mem_mgr_flag_write_combine);
583         if (IS_ERR_OR_NULL(p->save_buf))
584                 goto fail_alloc;
585
586         save_ptr = mem_op().mmap(p->save_buf);
587         if (IS_ERR_OR_NULL(save_ptr))
588                 goto fail_mmap;
589
590         p->save_sgt = mem_op().pin(memmgr, p->save_buf);
591         if (IS_ERR_OR_NULL(p->save_sgt))
592                 goto fail_pin;
593         p->save_phys = sg_dma_address(p->save_sgt->sgl);
594
595         setup_save(p, save_ptr);
596
597         mem_op().munmap(p->save_buf, save_ptr);
598
599         p->save_slots = 1;
600         p->h.alloc = ctxmpe_alloc;
601         p->h.save_push = ctxmpe_save_push;
602         p->h.save_service = ctxmpe_save_service;
603         p->h.get = ctxmpe_get;
604         p->h.put = ctxmpe_put;
605
606         return &p->h;
607
608 fail_pin:
609         mem_op().munmap(p->save_buf, save_ptr);
610 fail_mmap:
611         mem_op().put(memmgr, p->save_buf);
612 fail_alloc:
613         kfree(p);
614         return NULL;
615 }
616
617 int nvhost_mpe_prepare_power_off(struct platform_device *dev)
618 {
619         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
620         return nvhost_channel_save_context(pdata->channel);
621 }
622
623 static struct of_device_id tegra_mpe_of_match[] __devinitdata = {
624         { .compatible = "nvidia,tegra20-mpe",
625                 .data = (struct nvhost_device_data *)&t20_mpe_info },
626         { .compatible = "nvidia,tegra30-mpe",
627                 .data = (struct nvhost_device_data *)&t30_mpe_info },
628         { },
629 };
630 static int __devinit mpe_probe(struct platform_device *dev)
631 {
632         int err = 0;
633         struct nvhost_device_data *pdata = NULL;
634
635         if (dev->dev.of_node) {
636                 const struct of_device_id *match;
637
638                 match = of_match_device(tegra_mpe_of_match, &dev->dev);
639                 if (match)
640                         pdata = (struct nvhost_device_data *)match->data;
641         } else
642                 pdata = (struct nvhost_device_data *)dev->dev.platform_data;
643
644         WARN_ON(!pdata);
645         if (!pdata) {
646                 dev_info(&dev->dev, "no platform data\n");
647                 return -ENODATA;
648         }
649
650         pdata->pdev = dev;
651         platform_set_drvdata(dev, pdata);
652
653         err = nvhost_client_device_get_resources(dev);
654         if (err)
655                 return err;
656
657         err = nvhost_client_device_init(dev);
658         if (err)
659                 return err;
660
661         pm_runtime_use_autosuspend(&dev->dev);
662         pm_runtime_set_autosuspend_delay(&dev->dev, 100);
663         pm_runtime_enable(&dev->dev);
664
665         return 0;
666 }
667
668 static int __exit mpe_remove(struct platform_device *dev)
669 {
670         /* Add clean-up */
671         return 0;
672 }
673
674 #ifdef CONFIG_PM
675 static int mpe_suspend(struct platform_device *dev, pm_message_t state)
676 {
677         return nvhost_client_device_suspend(dev);
678 }
679
680 static int mpe_resume(struct platform_device *dev)
681 {
682         dev_info(&dev->dev, "resuming\n");
683         return 0;
684 }
685 #endif
686
687 static struct platform_driver mpe_driver = {
688         .probe = mpe_probe,
689         .remove = __exit_p(mpe_remove),
690 #ifdef CONFIG_PM
691         .suspend = mpe_suspend,
692         .resume = mpe_resume,
693 #endif
694         .driver = {
695                 .owner = THIS_MODULE,
696                 .name = "mpe",
697 #ifdef CONFIG_OF
698                 .of_match_table = tegra_mpe_of_match,
699 #endif
700         },
701 };
702
703 static int __init mpe_init(void)
704 {
705         return platform_driver_register(&mpe_driver);
706 }
707
708 static void __exit mpe_exit(void)
709 {
710         platform_driver_unregister(&mpe_driver);
711 }
712
713 module_init(mpe_init);
714 module_exit(mpe_exit);
715
716 int nvhost_mpe_read_reg(struct platform_device *dev,
717         struct nvhost_channel *channel,
718         struct nvhost_hwctx *hwctx,
719         u32 offset,
720         u32 *value)
721 {
722         struct host1x_hwctx *hwctx_to_save = NULL;
723         struct nvhost_hwctx_handler *h = hwctx->h;
724         struct host1x_hwctx_handler *p = to_host1x_hwctx_handler(h);
725         bool need_restore = false;
726         u32 syncpt_incrs = 4;
727         unsigned int pending = 0;
728         DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
729         void *ref;
730         void *ctx_waiter, *read_waiter, *completed_waiter;
731         struct nvhost_job *job;
732         u32 syncval;
733         int err;
734
735         if (hwctx && hwctx->has_timedout)
736                 return -ETIMEDOUT;
737
738         ctx_waiter = nvhost_intr_alloc_waiter();
739         read_waiter = nvhost_intr_alloc_waiter();
740         completed_waiter = nvhost_intr_alloc_waiter();
741         if (!ctx_waiter || !read_waiter || !completed_waiter) {
742                 err = -ENOMEM;
743                 goto done;
744         }
745
746         job = nvhost_job_alloc(channel, hwctx, 0, 0, 0,
747                         nvhost_get_host(dev)->memmgr);
748         if (!job) {
749                 err = -ENOMEM;
750                 goto done;
751         }
752
753         /* keep module powered */
754         nvhost_module_busy(dev);
755
756         /* get submit lock */
757         err = mutex_lock_interruptible(&channel->submitlock);
758         if (err) {
759                 nvhost_module_idle(dev);
760                 return err;
761         }
762
763         /* context switch */
764         if (channel->cur_ctx != hwctx) {
765                 hwctx_to_save = channel->cur_ctx ?
766                         to_host1x_hwctx(channel->cur_ctx) : NULL;
767                 if (hwctx_to_save) {
768                         syncpt_incrs += hwctx_to_save->save_incrs;
769                         hwctx_to_save->hwctx.valid = true;
770                         nvhost_job_get_hwctx(job, &hwctx_to_save->hwctx);
771                 }
772                 channel->cur_ctx = hwctx;
773                 if (channel->cur_ctx && channel->cur_ctx->valid) {
774                         need_restore = true;
775                         syncpt_incrs += to_host1x_hwctx(channel->cur_ctx)
776                                 ->restore_incrs;
777                 }
778         }
779
780         syncval = nvhost_syncpt_incr_max(&nvhost_get_host(dev)->syncpt,
781                 p->syncpt, syncpt_incrs);
782
783         job->syncpt_id = p->syncpt;
784         job->syncpt_incrs = syncpt_incrs;
785         job->syncpt_end = syncval;
786
787         /* begin a CDMA submit */
788         nvhost_cdma_begin(&channel->cdma, job);
789
790         /* push save buffer (pre-gather setup depends on unit) */
791         if (hwctx_to_save)
792                 h->save_push(&hwctx_to_save->hwctx, &channel->cdma);
793
794         /* gather restore buffer */
795         if (need_restore)
796                 nvhost_cdma_push(&channel->cdma,
797                         nvhost_opcode_gather(to_host1x_hwctx(channel->cur_ctx)
798                                 ->restore_size),
799                         to_host1x_hwctx(channel->cur_ctx)->restore_phys);
800
801         /* Switch to MPE - wait for it to complete what it was doing */
802         nvhost_cdma_push(&channel->cdma,
803                 nvhost_opcode_setclass(NV_VIDEO_ENCODE_MPEG_CLASS_ID, 0, 0),
804                 nvhost_opcode_imm_incr_syncpt(
805                         host1x_uclass_incr_syncpt_cond_op_done_v(),
806                         p->syncpt));
807         nvhost_cdma_push(&channel->cdma,
808                 nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
809                         host1x_uclass_wait_syncpt_base_r(), 1),
810                 nvhost_class_host_wait_syncpt_base(p->syncpt,
811                         p->waitbase, 1));
812         /*  Tell MPE to send register value to FIFO */
813         nvhost_cdma_push(&channel->cdma,
814                 nvhost_opcode_nonincr(host1x_uclass_indoff_r(), 1),
815                 nvhost_class_host_indoff_reg_read(
816                         host1x_uclass_indoff_indmodid_mpe_v(),
817                         offset, false));
818         nvhost_cdma_push(&channel->cdma,
819                 nvhost_opcode_imm(host1x_uclass_inddata_r(), 0),
820                 NVHOST_OPCODE_NOOP);
821         /*  Increment syncpt to indicate that FIFO can be read */
822         nvhost_cdma_push(&channel->cdma,
823                 nvhost_opcode_imm_incr_syncpt(
824                         host1x_uclass_incr_syncpt_cond_immediate_v(),
825                         p->syncpt),
826                 NVHOST_OPCODE_NOOP);
827         /*  Wait for value to be read from FIFO */
828         nvhost_cdma_push(&channel->cdma,
829                 nvhost_opcode_nonincr(host1x_uclass_wait_syncpt_base_r(), 1),
830                 nvhost_class_host_wait_syncpt_base(p->syncpt,
831                         p->waitbase, 3));
832         /*  Indicate submit complete */
833         nvhost_cdma_push(&channel->cdma,
834                 nvhost_opcode_nonincr(host1x_uclass_incr_syncpt_base_r(), 1),
835                 nvhost_class_host_incr_syncpt_base(p->waitbase, 4));
836         nvhost_cdma_push(&channel->cdma,
837                 NVHOST_OPCODE_NOOP,
838                 nvhost_opcode_imm_incr_syncpt(
839                         host1x_uclass_incr_syncpt_cond_immediate_v(),
840                         p->syncpt));
841
842         /* end CDMA submit  */
843         nvhost_cdma_end(&channel->cdma, job);
844         nvhost_job_put(job);
845         job = NULL;
846
847         /*
848          * schedule a context save interrupt (to drain the host FIFO
849          * if necessary, and to release the restore buffer)
850          */
851         if (hwctx_to_save) {
852                 err = nvhost_intr_add_action(
853                         &nvhost_get_host(dev)->intr,
854                         p->syncpt,
855                         syncval - syncpt_incrs
856                                 + hwctx_to_save->save_incrs
857                                 - 1,
858                         NVHOST_INTR_ACTION_CTXSAVE, hwctx_to_save,
859                         ctx_waiter,
860                         NULL);
861                 ctx_waiter = NULL;
862                 WARN(err, "Failed to set context save interrupt");
863         }
864
865         /* Wait for FIFO to be ready */
866         err = nvhost_intr_add_action(&nvhost_get_host(dev)->intr,
867                         p->syncpt, syncval - 2,
868                         NVHOST_INTR_ACTION_WAKEUP, &wq,
869                         read_waiter,
870                         &ref);
871         read_waiter = NULL;
872         WARN(err, "Failed to set wakeup interrupt");
873         wait_event(wq,
874                 nvhost_syncpt_is_expired(&nvhost_get_host(dev)->syncpt,
875                                 p->syncpt, syncval - 2));
876         nvhost_intr_put_ref(&nvhost_get_host(dev)->intr, p->syncpt,
877                         ref);
878
879         /* Read the register value from FIFO */
880         err = nvhost_channel_drain_read_fifo(channel, value, 1, &pending);
881
882         /* Indicate we've read the value */
883         nvhost_syncpt_cpu_incr(&nvhost_get_host(dev)->syncpt,
884                         p->syncpt);
885
886         /* Schedule a submit complete interrupt */
887         err = nvhost_intr_add_action(&nvhost_get_host(dev)->intr,
888                         p->syncpt, syncval,
889                         NVHOST_INTR_ACTION_SUBMIT_COMPLETE, channel,
890                         completed_waiter, NULL);
891         completed_waiter = NULL;
892         WARN(err, "Failed to set submit complete interrupt");
893
894         mutex_unlock(&channel->submitlock);
895
896 done:
897         kfree(ctx_waiter);
898         kfree(read_waiter);
899         kfree(completed_waiter);
900         return err;
901 }