Loading drivers/gpu/msm/adreno.h +0 −4 Original line number Diff line number Diff line Loading @@ -362,10 +362,6 @@ struct adreno_gpudev { /* GPU specific function hooks */ int (*ctxt_create)(struct adreno_device *, struct adreno_context *); int (*ctxt_save)(struct adreno_device *, struct adreno_context *); int (*ctxt_restore)(struct adreno_device *, struct adreno_context *); int (*ctxt_draw_workaround)(struct adreno_device *, struct adreno_context *); irqreturn_t (*irq_handler)(struct adreno_device *); void (*irq_control)(struct adreno_device *, int); unsigned int (*irq_pending)(struct adreno_device *); Loading drivers/gpu/msm/adreno_a2xx.c +50 −39 Original line number Diff line number Diff line Loading @@ -1398,11 +1398,56 @@ static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev, return 0; } static void a2xx_drawctxt_detach(struct adreno_context *drawctxt) { kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); } static int a2xx_drawctxt_save(struct adreno_device *adreno_dev, struct adreno_context *context); static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context); static int a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev, struct adreno_context *context); static const struct adreno_context_ops a225_preamble_ctx_ops = { .restore = adreno_context_restore, .draw_workaround = a2xx_drawctxt_draw_workaround, }; static const struct adreno_context_ops a225_legacy_ctx_ops = { .save = a2xx_drawctxt_save, .restore = a2xx_drawctxt_restore, .draw_workaround = a2xx_drawctxt_draw_workaround, .detach = a2xx_drawctxt_detach, }; static const struct adreno_context_ops a2xx_legacy_ctx_ops = { .save = a2xx_drawctxt_save, .restore = a2xx_drawctxt_restore, .detach = a2xx_drawctxt_detach, }; static int a2xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret; if (drawctxt->flags & CTXT_FLAGS_PREAMBLE && drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC) { drawctxt->ops = (adreno_is_a225(adreno_dev)) ? &a225_preamble_ctx_ops : &adreno_preamble_ctx_ops; return 0; } drawctxt->ops = (adreno_is_a225(adreno_dev)) ? &a225_legacy_ctx_ops : &a2xx_legacy_ctx_ops; /* * Allocate memory for the GPU state and the context commands. * Despite the name, this is much more then just storage for Loading Loading @@ -1510,12 +1555,6 @@ static int a2xx_drawctxt_save(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; int ret; if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED)) return 0; if (context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; if (!(context->flags & CTXT_FLAGS_PREAMBLE)) { kgsl_cffdump_syncmem(context->base.device, &context->gpustate, context->reg_save[1], Loading Loading @@ -1600,40 +1639,14 @@ static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret = 0; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } int ret; cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); ret = adreno_context_restore(adreno_dev, context); if (ret) return ret; kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); /* restore gmem. /* * restore gmem. * (note: changes shader. shader must not already be restored.) */ if (context->flags & CTXT_FLAGS_GMEM_RESTORE) { Loading Loading @@ -1692,6 +1705,7 @@ static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, } if (adreno_is_a20x(adreno_dev)) { unsigned int cmds[2]; cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1); cmds[1] = context->bin_base_offset; ret = adreno_ringbuffer_issuecmds(device, context, Loading Loading @@ -2296,9 +2310,6 @@ struct adreno_gpudev adreno_a2xx_gpudev = { .reg_offsets = &a2xx_reg_offsets, .ctxt_create = a2xx_drawctxt_create, .ctxt_save = a2xx_drawctxt_save, .ctxt_restore = a2xx_drawctxt_restore, .ctxt_draw_workaround = a2xx_drawctxt_draw_workaround, .irq_handler = a2xx_irq_handler, .irq_control = a2xx_irq_control, .irq_pending = a2xx_irq_pending, Loading drivers/gpu/msm/adreno_a3xx.c +30 −39 Original line number Diff line number Diff line Loading @@ -2345,17 +2345,40 @@ static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev, return 0; } static void a3xx_drawctxt_detach(struct adreno_context *drawctxt) { kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); } static int a3xx_drawctxt_save(struct adreno_device *adreno_dev, struct adreno_context *context); static int a3xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context); static const struct adreno_context_ops a3xx_legacy_ctx_ops = { .save = a3xx_drawctxt_save, .restore = a3xx_drawctxt_restore, .detach = a3xx_drawctxt_detach, }; static int a3xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret; /* * Allocate memory for the GPU state and the context commands. * Despite the name, this is much more then just storage for * the gpustate. This contains command space for gmem save * and texture and vertex buffer storage too * Nothing to do here if the context is using preambles and doesn't need * GMEM save/restore */ if ((drawctxt->flags & CTXT_FLAGS_PREAMBLE) && (drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) { drawctxt->ops = &adreno_preamble_ctx_ops; return 0; } drawctxt->ops = &a3xx_legacy_ctx_ops; ret = kgsl_allocate(&drawctxt->gpustate, drawctxt->base.proc_priv->pagetable, CONTEXT_SIZE); Loading Loading @@ -2391,9 +2414,6 @@ static int a3xx_drawctxt_save(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; int ret; if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED)) return 0; if (context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; Loading Loading @@ -2451,39 +2471,13 @@ static int a3xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret = 0; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } int ret; cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); /* do the common part */ ret = adreno_context_restore(adreno_dev, context); if (ret) return ret; kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); /* * Restore GMEM. (note: changes shader. * Shader must not already be restored.) Loading Loading @@ -4401,9 +4395,6 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .perfcounters = &a3xx_perfcounters, .ctxt_create = a3xx_drawctxt_create, .ctxt_save = a3xx_drawctxt_save, .ctxt_restore = a3xx_drawctxt_restore, .ctxt_draw_workaround = NULL, .rb_init = a3xx_rb_init, .perfcounter_init = a3xx_perfcounter_init, .perfcounter_close = a3xx_perfcounter_close, Loading drivers/gpu/msm/adreno_a4xx.c +0 −66 Original line number Diff line number Diff line Loading @@ -106,70 +106,6 @@ const unsigned int a4xx_registers[] = { const unsigned int a4xx_registers_count = ARRAY_SIZE(a4xx_registers) / 2; static int a4xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret = 0; struct kgsl_device *device = &adreno_dev->dev; if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) { /* This option is not supported on a4xx */ KGSL_DRV_ERR(device, "Preambles required for A4XX draw contexts\n"); ret = -EPERM; goto done; } if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) { /* This option is not supported on a4xx */ KGSL_DRV_ERR(device, "Cannot create context with gmemalloc\n"); ret = -EPERM; } done: return ret; } static int a4xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); if (ret) return ret; ret = kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); return ret; } static const struct adreno_vbif_data a420_vbif[] = { { A4XX_VBIF_ABIT_SORT, 0x0001001F }, { A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4 }, Loading Loading @@ -294,8 +230,6 @@ const struct adreno_reg_offsets a4xx_reg_offsets = { struct adreno_gpudev adreno_a4xx_gpudev = { .reg_offsets = &a4xx_reg_offsets, .ctxt_create = a4xx_drawctxt_create, .ctxt_restore = a4xx_drawctxt_restore, .rb_init = a3xx_rb_init, .irq_control = a3xx_irq_control, .irq_handler = a3xx_irq_handler, Loading drivers/gpu/msm/adreno_drawctxt.c +109 −36 Original line number Diff line number Diff line Loading @@ -458,9 +458,20 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv, drawctxt->type = (*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT; if (adreno_dev->gpudev->ctxt_create) { ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt); if (ret) goto err; } else if ((*flags & KGSL_CONTEXT_PREAMBLE) == 0 || (*flags & KGSL_CONTEXT_NO_GMEM_ALLOC) == 0) { KGSL_DEV_ERR_ONCE(device, "legacy context switch not supported\n"); ret = -EINVAL; goto err; } else { drawctxt->ops = &adreno_preamble_ctx_ops; } kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), Loading Loading @@ -510,19 +521,8 @@ int adreno_drawctxt_detach(struct kgsl_context *context) drawctxt = ADRENO_CONTEXT(context); /* deactivate context */ if (adreno_dev->drawctxt_active == drawctxt) { /* no need to save GMEM or shader, the context is * being destroyed. */ drawctxt->flags &= ~(CTXT_FLAGS_GMEM_SAVE | CTXT_FLAGS_SHADER_SAVE | CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_STATE_SHADOW); drawctxt->flags |= CTXT_FLAGS_BEING_DESTROYED; if (adreno_dev->drawctxt_active == drawctxt) adreno_drawctxt_switch(adreno_dev, NULL, 0); } mutex_lock(&drawctxt->mutex); Loading Loading @@ -568,8 +568,8 @@ int adreno_drawctxt_detach(struct kgsl_context *context) adreno_profile_process_results(device); kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); if (drawctxt->ops->detach) drawctxt->ops->detach(drawctxt); /* wake threads waiting to submit commands from this context */ wake_up_interruptible_all(&drawctxt->waiting); Loading @@ -589,6 +589,69 @@ void adreno_drawctxt_destroy(struct kgsl_context *context) kfree(drawctxt); } /** * adreno_context_restore() - generic context restore handler * @adreno_dev: the device * @context: the context * * Basic context restore handler that writes the context identifier * to the ringbuffer and issues pagetable switch commands if necessary. * May be called directly from the adreno_context_ops.restore function * pointer or as the first action in a hardware specific restore * function. */ int adreno_context_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { int ret; struct kgsl_device *device; unsigned int cmds[5]; if (adreno_dev == NULL || context == NULL) return -EINVAL; device = &adreno_dev->dev; /* write the context identifier to the ringbuffer */ cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); if (ret) return ret; return kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); } const struct adreno_context_ops adreno_preamble_ctx_ops = { .restore = adreno_context_restore, }; /** * context_save() - save old context when necessary * @drawctxt - the old context * * For legacy context switching, we need to issue save * commands unless the context is being destroyed. */ static inline int context_save(struct adreno_device *adreno_dev, struct adreno_context *context) { if (context->ops->save == NULL || kgsl_context_detached(&context->base) || context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; return context->ops->save(adreno_dev, context); } /** * adreno_drawctxt_set_bin_base_offset - set bin base offset for the context * @device - KGSL device that owns the context Loading Loading @@ -627,6 +690,12 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, int ret = 0; if (drawctxt) { /* * Handle legacy gmem / save restore flag on each IB. * Userspace sets to guard IB sequences that require * gmem to be saved and clears it at the end of the * sequence. */ if (flags & KGSL_CONTEXT_SAVE_GMEM) /* Set the flag in context so that the save is done * when this context is switched out. */ Loading @@ -638,31 +707,25 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) { if (adreno_dev->gpudev->ctxt_draw_workaround && adreno_is_a225(adreno_dev)) ret = adreno_dev->gpudev->ctxt_draw_workaround( adreno_dev, drawctxt); if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Save the old context */ if (adreno_dev->gpudev->ctxt_save) { ret = adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active); if (adreno_dev->drawctxt_active) { ret = context_save(adreno_dev, adreno_dev->drawctxt_active); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d save: %d\n", adreno_dev->drawctxt_active->base.id, ret); return ret; } } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) { kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = NULL; } Loading @@ -671,16 +734,26 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; } /* Set the new context */ ret = adreno_dev->gpudev->ctxt_restore(adreno_dev, drawctxt); ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt ? drawctxt->base.id : 0, ret); drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, KGSL_CONTEXT_INVALID); } adreno_dev->drawctxt_active = drawctxt; return 0; Loading Loading
drivers/gpu/msm/adreno.h +0 −4 Original line number Diff line number Diff line Loading @@ -362,10 +362,6 @@ struct adreno_gpudev { /* GPU specific function hooks */ int (*ctxt_create)(struct adreno_device *, struct adreno_context *); int (*ctxt_save)(struct adreno_device *, struct adreno_context *); int (*ctxt_restore)(struct adreno_device *, struct adreno_context *); int (*ctxt_draw_workaround)(struct adreno_device *, struct adreno_context *); irqreturn_t (*irq_handler)(struct adreno_device *); void (*irq_control)(struct adreno_device *, int); unsigned int (*irq_pending)(struct adreno_device *); Loading
drivers/gpu/msm/adreno_a2xx.c +50 −39 Original line number Diff line number Diff line Loading @@ -1398,11 +1398,56 @@ static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev, return 0; } static void a2xx_drawctxt_detach(struct adreno_context *drawctxt) { kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); } static int a2xx_drawctxt_save(struct adreno_device *adreno_dev, struct adreno_context *context); static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context); static int a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev, struct adreno_context *context); static const struct adreno_context_ops a225_preamble_ctx_ops = { .restore = adreno_context_restore, .draw_workaround = a2xx_drawctxt_draw_workaround, }; static const struct adreno_context_ops a225_legacy_ctx_ops = { .save = a2xx_drawctxt_save, .restore = a2xx_drawctxt_restore, .draw_workaround = a2xx_drawctxt_draw_workaround, .detach = a2xx_drawctxt_detach, }; static const struct adreno_context_ops a2xx_legacy_ctx_ops = { .save = a2xx_drawctxt_save, .restore = a2xx_drawctxt_restore, .detach = a2xx_drawctxt_detach, }; static int a2xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret; if (drawctxt->flags & CTXT_FLAGS_PREAMBLE && drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC) { drawctxt->ops = (adreno_is_a225(adreno_dev)) ? &a225_preamble_ctx_ops : &adreno_preamble_ctx_ops; return 0; } drawctxt->ops = (adreno_is_a225(adreno_dev)) ? &a225_legacy_ctx_ops : &a2xx_legacy_ctx_ops; /* * Allocate memory for the GPU state and the context commands. * Despite the name, this is much more then just storage for Loading Loading @@ -1510,12 +1555,6 @@ static int a2xx_drawctxt_save(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; int ret; if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED)) return 0; if (context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; if (!(context->flags & CTXT_FLAGS_PREAMBLE)) { kgsl_cffdump_syncmem(context->base.device, &context->gpustate, context->reg_save[1], Loading Loading @@ -1600,40 +1639,14 @@ static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret = 0; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } int ret; cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); ret = adreno_context_restore(adreno_dev, context); if (ret) return ret; kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); /* restore gmem. /* * restore gmem. * (note: changes shader. shader must not already be restored.) */ if (context->flags & CTXT_FLAGS_GMEM_RESTORE) { Loading Loading @@ -1692,6 +1705,7 @@ static int a2xx_drawctxt_restore(struct adreno_device *adreno_dev, } if (adreno_is_a20x(adreno_dev)) { unsigned int cmds[2]; cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1); cmds[1] = context->bin_base_offset; ret = adreno_ringbuffer_issuecmds(device, context, Loading Loading @@ -2296,9 +2310,6 @@ struct adreno_gpudev adreno_a2xx_gpudev = { .reg_offsets = &a2xx_reg_offsets, .ctxt_create = a2xx_drawctxt_create, .ctxt_save = a2xx_drawctxt_save, .ctxt_restore = a2xx_drawctxt_restore, .ctxt_draw_workaround = a2xx_drawctxt_draw_workaround, .irq_handler = a2xx_irq_handler, .irq_control = a2xx_irq_control, .irq_pending = a2xx_irq_pending, Loading
drivers/gpu/msm/adreno_a3xx.c +30 −39 Original line number Diff line number Diff line Loading @@ -2345,17 +2345,40 @@ static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev, return 0; } static void a3xx_drawctxt_detach(struct adreno_context *drawctxt) { kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); } static int a3xx_drawctxt_save(struct adreno_device *adreno_dev, struct adreno_context *context); static int a3xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context); static const struct adreno_context_ops a3xx_legacy_ctx_ops = { .save = a3xx_drawctxt_save, .restore = a3xx_drawctxt_restore, .detach = a3xx_drawctxt_detach, }; static int a3xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret; /* * Allocate memory for the GPU state and the context commands. * Despite the name, this is much more then just storage for * the gpustate. This contains command space for gmem save * and texture and vertex buffer storage too * Nothing to do here if the context is using preambles and doesn't need * GMEM save/restore */ if ((drawctxt->flags & CTXT_FLAGS_PREAMBLE) && (drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) { drawctxt->ops = &adreno_preamble_ctx_ops; return 0; } drawctxt->ops = &a3xx_legacy_ctx_ops; ret = kgsl_allocate(&drawctxt->gpustate, drawctxt->base.proc_priv->pagetable, CONTEXT_SIZE); Loading Loading @@ -2391,9 +2414,6 @@ static int a3xx_drawctxt_save(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; int ret; if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED)) return 0; if (context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; Loading Loading @@ -2451,39 +2471,13 @@ static int a3xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret = 0; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } int ret; cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); /* do the common part */ ret = adreno_context_restore(adreno_dev, context); if (ret) return ret; kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); /* * Restore GMEM. (note: changes shader. * Shader must not already be restored.) Loading Loading @@ -4401,9 +4395,6 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .perfcounters = &a3xx_perfcounters, .ctxt_create = a3xx_drawctxt_create, .ctxt_save = a3xx_drawctxt_save, .ctxt_restore = a3xx_drawctxt_restore, .ctxt_draw_workaround = NULL, .rb_init = a3xx_rb_init, .perfcounter_init = a3xx_perfcounter_init, .perfcounter_close = a3xx_perfcounter_close, Loading
drivers/gpu/msm/adreno_a4xx.c +0 −66 Original line number Diff line number Diff line Loading @@ -106,70 +106,6 @@ const unsigned int a4xx_registers[] = { const unsigned int a4xx_registers_count = ARRAY_SIZE(a4xx_registers) / 2; static int a4xx_drawctxt_create(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { int ret = 0; struct kgsl_device *device = &adreno_dev->dev; if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) { /* This option is not supported on a4xx */ KGSL_DRV_ERR(device, "Preambles required for A4XX draw contexts\n"); ret = -EPERM; goto done; } if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) { /* This option is not supported on a4xx */ KGSL_DRV_ERR(device, "Cannot create context with gmemalloc\n"); ret = -EPERM; } done: return ret; } static int a4xx_drawctxt_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { struct kgsl_device *device = &adreno_dev->dev; unsigned int cmds[5]; int ret; if (context == NULL) { /* No context - set the default pagetable and thats it */ unsigned int id; /* * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ id = (adreno_dev->drawctxt_active != NULL) ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID; kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, id); return 0; } cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); if (ret) return ret; ret = kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); return ret; } static const struct adreno_vbif_data a420_vbif[] = { { A4XX_VBIF_ABIT_SORT, 0x0001001F }, { A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4 }, Loading Loading @@ -294,8 +230,6 @@ const struct adreno_reg_offsets a4xx_reg_offsets = { struct adreno_gpudev adreno_a4xx_gpudev = { .reg_offsets = &a4xx_reg_offsets, .ctxt_create = a4xx_drawctxt_create, .ctxt_restore = a4xx_drawctxt_restore, .rb_init = a3xx_rb_init, .irq_control = a3xx_irq_control, .irq_handler = a3xx_irq_handler, Loading
drivers/gpu/msm/adreno_drawctxt.c +109 −36 Original line number Diff line number Diff line Loading @@ -458,9 +458,20 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv, drawctxt->type = (*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT; if (adreno_dev->gpudev->ctxt_create) { ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt); if (ret) goto err; } else if ((*flags & KGSL_CONTEXT_PREAMBLE) == 0 || (*flags & KGSL_CONTEXT_NO_GMEM_ALLOC) == 0) { KGSL_DEV_ERR_ONCE(device, "legacy context switch not supported\n"); ret = -EINVAL; goto err; } else { drawctxt->ops = &adreno_preamble_ctx_ops; } kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), Loading Loading @@ -510,19 +521,8 @@ int adreno_drawctxt_detach(struct kgsl_context *context) drawctxt = ADRENO_CONTEXT(context); /* deactivate context */ if (adreno_dev->drawctxt_active == drawctxt) { /* no need to save GMEM or shader, the context is * being destroyed. */ drawctxt->flags &= ~(CTXT_FLAGS_GMEM_SAVE | CTXT_FLAGS_SHADER_SAVE | CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_STATE_SHADOW); drawctxt->flags |= CTXT_FLAGS_BEING_DESTROYED; if (adreno_dev->drawctxt_active == drawctxt) adreno_drawctxt_switch(adreno_dev, NULL, 0); } mutex_lock(&drawctxt->mutex); Loading Loading @@ -568,8 +568,8 @@ int adreno_drawctxt_detach(struct kgsl_context *context) adreno_profile_process_results(device); kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); if (drawctxt->ops->detach) drawctxt->ops->detach(drawctxt); /* wake threads waiting to submit commands from this context */ wake_up_interruptible_all(&drawctxt->waiting); Loading @@ -589,6 +589,69 @@ void adreno_drawctxt_destroy(struct kgsl_context *context) kfree(drawctxt); } /** * adreno_context_restore() - generic context restore handler * @adreno_dev: the device * @context: the context * * Basic context restore handler that writes the context identifier * to the ringbuffer and issues pagetable switch commands if necessary. * May be called directly from the adreno_context_ops.restore function * pointer or as the first action in a hardware specific restore * function. */ int adreno_context_restore(struct adreno_device *adreno_dev, struct adreno_context *context) { int ret; struct kgsl_device *device; unsigned int cmds[5]; if (adreno_dev == NULL || context == NULL) return -EINVAL; device = &adreno_dev->dev; /* write the context identifier to the ringbuffer */ cmds[0] = cp_nop_packet(1); cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER; cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2); cmds[3] = device->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context); cmds[4] = context->base.id; ret = adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE, cmds, 5); if (ret) return ret; return kgsl_mmu_setstate(&device->mmu, context->base.proc_priv->pagetable, context->base.id); } const struct adreno_context_ops adreno_preamble_ctx_ops = { .restore = adreno_context_restore, }; /** * context_save() - save old context when necessary * @drawctxt - the old context * * For legacy context switching, we need to issue save * commands unless the context is being destroyed. */ static inline int context_save(struct adreno_device *adreno_dev, struct adreno_context *context) { if (context->ops->save == NULL || kgsl_context_detached(&context->base) || context->state == ADRENO_CONTEXT_STATE_INVALID) return 0; return context->ops->save(adreno_dev, context); } /** * adreno_drawctxt_set_bin_base_offset - set bin base offset for the context * @device - KGSL device that owns the context Loading Loading @@ -627,6 +690,12 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, int ret = 0; if (drawctxt) { /* * Handle legacy gmem / save restore flag on each IB. * Userspace sets to guard IB sequences that require * gmem to be saved and clears it at the end of the * sequence. */ if (flags & KGSL_CONTEXT_SAVE_GMEM) /* Set the flag in context so that the save is done * when this context is switched out. */ Loading @@ -638,31 +707,25 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) { if (adreno_dev->gpudev->ctxt_draw_workaround && adreno_is_a225(adreno_dev)) ret = adreno_dev->gpudev->ctxt_draw_workaround( adreno_dev, drawctxt); if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Save the old context */ if (adreno_dev->gpudev->ctxt_save) { ret = adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active); if (adreno_dev->drawctxt_active) { ret = context_save(adreno_dev, adreno_dev->drawctxt_active); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d save: %d\n", adreno_dev->drawctxt_active->base.id, ret); return ret; } } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) { kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = NULL; } Loading @@ -671,16 +734,26 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev, if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; } /* Set the new context */ ret = adreno_dev->gpudev->ctxt_restore(adreno_dev, drawctxt); ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt ? drawctxt->base.id : 0, ret); drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, KGSL_CONTEXT_INVALID); } adreno_dev->drawctxt_active = drawctxt; return 0; Loading