video: tegra: host: Adjust Tegra11 3D context handler
Terje Bergstrom [Fri, 16 Mar 2012 20:06:54 +0000 (22:06 +0200)]
Context handler was refactored. This patch adjusts Tegra11 to follow
the same structure.

Change-Id: I1f2888c23bdd794f8925e4252b0a811d861ba822
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/90692
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Tested-by: Scott Williams <scwilliams@nvidia.com>

drivers/video/tegra/host/gr3d/gr3d_t114.c
drivers/video/tegra/host/gr3d/gr3d_t114.h
drivers/video/tegra/host/t114/t114.c

index fd5720b..3351d5f 100644 (file)
@@ -82,10 +82,6 @@ static const struct hwctx_reginfo ctxsave_regs_3d_global[] = {
        HWCTX_REGINFO(0xe45,    1, DIRECT),
 };
 
-/* the same context save command sequence is used for all contexts. */
-static phys_addr_t save_phys;
-static unsigned int save_size;
-
 #define SAVE_BEGIN_V1_SIZE (1 + RESTORE_BEGIN_SIZE)
 #define SAVE_DIRECT_V1_SIZE (4 + RESTORE_DIRECT_SIZE)
 #define SAVE_INDIRECT_V1_SIZE (6 + RESTORE_INDIRECT_SIZE)
@@ -106,19 +102,21 @@ struct save_info {
 
 /*** save ***/
 
-static void save_push_v1(struct nvhost_cdma *cdma,
-                       struct nvhost_hwctx *ctx)
+static void save_push_v1(struct nvhost_hwctx *nctx, struct nvhost_cdma *cdma)
 {
+       struct host1x_hwctx *ctx = to_host1x_hwctx(nctx);
+       struct host1x_hwctx_handler *p = host1x_hwctx_handler(ctx);
+
        /* wait for 3d idle */
        nvhost_cdma_push(cdma,
                        nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0, 0),
                        nvhost_opcode_imm_incr_syncpt(NV_SYNCPT_OP_DONE,
-                                       NVSYNCPT_3D));
+                                       p->syncpt));
        nvhost_cdma_push(cdma,
                        nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
                                        NV_CLASS_HOST_WAIT_SYNCPT_BASE, 1),
                        nvhost_class_host_wait_syncpt_base(NVSYNCPT_3D,
-                                                       NVWAITBASE_3D, 1));
+                                                       p->waitbase, 1));
        /* back to 3d */
        nvhost_cdma_push(cdma,
                        nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0, 0),
@@ -130,22 +128,19 @@ static void save_push_v1(struct nvhost_cdma *cdma,
        nvhost_cdma_push_gather(cdma,
                        (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE,
                        (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE,
-                       nvhost_opcode_gather(save_size),
-                       save_phys);
+                       nvhost_opcode_gather(p->save_size),
+                       p->save_phys);
 }
 
-static void __init save_begin_v1(u32 *ptr)
+static void __init save_begin_v1(struct host1x_hwctx_handler *p, u32 *ptr)
 {
        ptr[0] = nvhost_opcode_nonincr(0x905, RESTORE_BEGIN_SIZE);
-       nvhost_3dctx_restore_begin(ptr + 1);
+       nvhost_3dctx_restore_begin(p, ptr + 1);
        ptr += RESTORE_BEGIN_SIZE;
 }
 
 static void __init save_direct_v1(u32 *ptr, u32 start_reg, u32 count)
 {
-#if RESTORE_DIRECT_SIZE != 1
-#error whoops! code is optimized for RESTORE_DIRECT_SIZE == 1
-#endif
        ptr[0] = nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0x905, 1);
        nvhost_3dctx_restore_direct(ptr + 1, start_reg, count);
        ptr += RESTORE_DIRECT_SIZE;
@@ -173,33 +168,30 @@ static void __init save_indirect_v1(u32 *ptr, u32 offset_reg, u32 offset,
        ptr[5] = nvhost_opcode_nonincr(NV_CLASS_HOST_INDDATA, count);
 }
 
-static void __init save_end_v1(u32 *ptr)
+static void __init save_end_v1(struct host1x_hwctx_handler *p, u32 *ptr)
 {
-#if RESTORE_END_SIZE != 1
-#error whoops! code is optimized for RESTORE_END_SIZE == 1
-#endif
        /* write end of restore buffer */
        ptr[0] = nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0x905, 1);
-       nvhost_3dctx_restore_end(ptr + 1);
+       nvhost_3dctx_restore_end(p, ptr + 1);
        ptr += RESTORE_END_SIZE;
        /* op_done syncpt incr to flush FDC */
-       ptr[1] = nvhost_opcode_imm_incr_syncpt(NV_SYNCPT_OP_DONE, NVSYNCPT_3D);
+       ptr[1] = nvhost_opcode_imm_incr_syncpt(NV_SYNCPT_OP_DONE, p->syncpt);
        /* host wait for that syncpt incr, and advance the wait base */
        ptr[2] = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
                        NV_CLASS_HOST_WAIT_SYNCPT_BASE,
                        nvhost_mask2(
                                NV_CLASS_HOST_WAIT_SYNCPT_BASE,
                                NV_CLASS_HOST_INCR_SYNCPT_BASE));
-       ptr[3] = nvhost_class_host_wait_syncpt_base(NVSYNCPT_3D,
-                               NVWAITBASE_3D, nvhost_3dctx_save_incrs - 1);
-       ptr[4] = nvhost_class_host_incr_syncpt_base(NVWAITBASE_3D,
-                       nvhost_3dctx_save_incrs);
+       ptr[3] = nvhost_class_host_wait_syncpt_base(p->syncpt,
+                       p->waitbase, p->save_incrs - 1);
+       ptr[4] = nvhost_class_host_incr_syncpt_base(p->waitbase,
+                       p->save_incrs);
        /* set class back to 3d */
        ptr[5] = nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0, 0);
        /* send reg reads back to host */
        ptr[6] = nvhost_opcode_imm(0xe40, 0);
        /* final syncpt increment to release waiters */
-       ptr[7] = nvhost_opcode_imm(0, NVSYNCPT_3D);
+       ptr[7] = nvhost_opcode_imm(0, p->syncpt);
 }
 
 static void __init setup_save_regs(struct save_info *info,
@@ -260,7 +252,7 @@ static void __init setup_save_regs(struct save_info *info,
        info->restore_count = restore_count;
 }
 
-static void __init setup_save(u32 *ptr)
+static void __init setup_save(struct host1x_hwctx_handler *p, u32 *ptr)
 {
        struct save_info info = {
                ptr,
@@ -271,7 +263,7 @@ static void __init setup_save(u32 *ptr)
        };
 
        if (info.ptr) {
-               save_begin_v1(info.ptr);
+               save_begin_v1(p, info.ptr);
                info.ptr += SAVE_BEGIN_V1_SIZE;
        }
 
@@ -281,63 +273,77 @@ static void __init setup_save(u32 *ptr)
                        ARRAY_SIZE(ctxsave_regs_3d_global));
 
        if (info.ptr) {
-               save_end_v1(info.ptr);
+               save_end_v1(p, info.ptr);
                info.ptr += SAVE_END_V1_SIZE;
        }
 
        wmb();
 
-       save_size = info.save_count + SAVE_END_V1_SIZE;
-       nvhost_3dctx_restore_size = info.restore_count + RESTORE_END_SIZE;
-       nvhost_3dctx_save_incrs = info.save_incrs;
-       nvhost_3dctx_save_thresh = nvhost_3dctx_save_incrs;
-       nvhost_3dctx_restore_incrs = info.restore_incrs;
+       p->save_size = info.save_count + SAVE_END_V1_SIZE;
+       p->restore_size = info.restore_count + RESTORE_END_SIZE;
+       p->save_incrs = info.save_incrs;
+       p->save_thresh = p->save_incrs;
+       p->restore_incrs = info.restore_incrs;
 }
 
 /*** ctx3d ***/
 
-static struct nvhost_hwctx *ctx3d_alloc_v1(struct nvhost_channel *ch)
+static struct nvhost_hwctx *ctx3d_alloc_v1(struct nvhost_hwctx_handler *h,
+               struct nvhost_channel *ch)
 {
-       return nvhost_3dctx_alloc_common(ch, false);
+       struct host1x_hwctx_handler *p = to_host1x_hwctx_handler(h);
+       struct host1x_hwctx *ctx = nvhost_3dctx_alloc_common(p, ch, false);
+
+       if (ctx)
+               return &ctx->hwctx;
+       else
+               return NULL;
 }
 
-int __init t114_nvhost_3dctx_handler_init(struct nvhost_hwctx_handler *h)
+struct nvhost_hwctx_handler * __init t114_nvhost_3dctx_handler_init(
+               u32 syncpt, u32 waitbase,
+               struct nvhost_channel *ch)
 {
-       struct nvhost_channel *ch;
        struct nvmap_client *nvmap;
        u32 *save_ptr;
+       struct host1x_hwctx_handler *p;
+
+       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return NULL;
 
-       ch = container_of(h, struct nvhost_channel, ctxhandler);
        nvmap = nvhost_get_host(ch->dev)->nvmap;
 
-       setup_save(NULL);
+       p->syncpt = syncpt;
+       p->waitbase = waitbase;
+
+       setup_save(p, NULL);
 
-       nvhost_3dctx_save_buf = nvmap_alloc(nvmap, save_size * 4, 32,
+       p->save_buf = nvmap_alloc(nvmap, p->save_size * 4, 32,
                                NVMAP_HANDLE_WRITE_COMBINE);
-       if (IS_ERR(nvhost_3dctx_save_buf)) {
-               int err = PTR_ERR(nvhost_3dctx_save_buf);
-               nvhost_3dctx_save_buf = NULL;
-               return err;
+       if (IS_ERR(p->save_buf)) {
+               p->save_buf = NULL;
+               return NULL;
        }
 
-       nvhost_3dctx_save_slots = 5;
+       p->save_slots = 5;
 
-       save_ptr = nvmap_mmap(nvhost_3dctx_save_buf);
+       save_ptr = nvmap_mmap(p->save_buf);
        if (!save_ptr) {
-               nvmap_free(nvmap, nvhost_3dctx_save_buf);
-               nvhost_3dctx_save_buf = NULL;
-               return -ENOMEM;
+               nvmap_free(nvmap, p->save_buf);
+               p->save_buf = NULL;
+               return NULL;
        }
 
-       save_phys = nvmap_pin(nvmap, nvhost_3dctx_save_buf);
+       p->save_phys = nvmap_pin(nvmap, p->save_buf);
 
-       setup_save(save_ptr);
+       setup_save(p, save_ptr);
 
-       h->alloc = ctx3d_alloc_v1;
-       h->save_push = save_push_v1;
-       h->save_service = NULL;
-       h->get = nvhost_3dctx_get;
-       h->put = nvhost_3dctx_put;
+       p->h.alloc = ctx3d_alloc_v1;
+       p->h.save_push = save_push_v1;
+       p->h.save_service = NULL;
+       p->h.get = nvhost_3dctx_get;
+       p->h.put = nvhost_3dctx_put;
 
-       return 0;
+       return &p->h;
 }
index 4fa69c0..9aca14b 100644 (file)
@@ -25,6 +25,8 @@
 
 struct nvhost_hwctx_handler;
 
-int t114_nvhost_3dctx_handler_init(struct nvhost_hwctx_handler *h);
+struct nvhost_hwctx_handler *t114_nvhost_3dctx_handler_init(
+               u32 syncpt, u32 base,
+               struct nvhost_channel *ch);
 
 #endif
index 6e815ad..3411292 100644 (file)
@@ -72,6 +72,7 @@ static struct nvhost_device devices[] = {
        .idle = nvhost_scale3d_notify_idle,
        .init = nvhost_scale3d_init,
        .deinit = nvhost_scale3d_deinit,
+       .alloc_hwctx_handler = t114_nvhost_3dctx_handler_init,
        .clocks = {{"gr3d", UINT_MAX},
                        {"emc", HOST_EMC_FLOOR} },
        NVHOST_MODULE_NO_POWERGATE_IDS,
@@ -152,14 +153,22 @@ static struct nvhost_device devices[] = {
        .moduleid      = NVHOST_MODULE_TSEC,
 } };
 
-static inline int t114_nvhost_hwctx_handler_init(
-       struct nvhost_hwctx_handler *h,
-       const char *module)
+static inline int t114_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
 {
-       if (strcmp(module, "gr3d") == 0)
-               return t114_nvhost_3dctx_handler_init(h);
+       int err = 0;
+       unsigned long syncpts = ch->dev->syncpts;
+       unsigned long waitbases = ch->dev->waitbases;
+       u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
+       u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
 
-       return 0;
+       if (ch->dev->alloc_hwctx_handler) {
+               ch->ctxhandler = ch->dev->alloc_hwctx_handler(syncpt,
+                               waitbase, ch);
+               if (!ch->ctxhandler)
+                       err = -ENOMEM;
+       }
+
+       return err;
 }
 
 static inline void __iomem *t114_channel_aperture(void __iomem *p, int ndx)
@@ -180,7 +189,7 @@ static int t114_channel_init(struct nvhost_channel *ch,
        nvhost_device_register(ch->dev);
        ch->aperture = t114_channel_aperture(dev->aperture, index);
 
-       return t114_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->dev->name);
+       return t114_nvhost_hwctx_handler_init(ch);
 }
 
 int nvhost_init_t114_channel_support(struct nvhost_master *host)