Loading drivers/gpu/msm/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ msm_adreno-y += \ adreno_a6xx_snapshot.o \ adreno_a4xx_preempt.o \ adreno_a5xx_preempt.o \ adreno_a6xx_preempt.o \ adreno_sysfs.o \ adreno.o \ adreno_cp_parser.o \ Loading drivers/gpu/msm/a6xx_reg.h +10 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,15 @@ #define A6XX_CP_ADDR_MODE_CNTL 0x842 #define A6XX_CP_PROTECT_CNTL 0x84F #define A6XX_CP_PROTECT_REG 0x850 #define A6XX_CP_CONTEXT_SWITCH_CNTL 0x8A0 #define A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO 0x8A1 #define A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_HI 0x8A2 #define A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_LO 0x8A3 #define A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_HI 0x8A4 #define A6XX_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_LO 0x8A5 #define A6XX_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_HI 0x8A6 #define A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_LO 0x8A7 #define A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_HI 0x8A8 #define A6XX_CP_PERFCTR_CP_SEL_0 0x8D0 #define A6XX_CP_PERFCTR_CP_SEL_1 0x8D1 #define A6XX_CP_PERFCTR_CP_SEL_2 0x8D2 Loading Loading @@ -590,6 +599,7 @@ #define A6XX_RB_PERFCTR_CMP_SEL_1 0x8E2D #define A6XX_RB_PERFCTR_CMP_SEL_2 0x8E2E #define A6XX_RB_PERFCTR_CMP_SEL_3 0x8E2F #define A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE 0x8E50 /* PC registers */ #define A6XX_PC_DBG_ECO_CNTL 0x9E00 Loading drivers/gpu/msm/adreno.h +3 −0 Original line number Diff line number Diff line Loading @@ -845,11 +845,14 @@ struct adreno_gpudev { unsigned int *cmds, struct kgsl_context *context); int (*preemption_yield_enable)(unsigned int *); unsigned int (*preemption_set_marker)(unsigned int *cmds, int start); unsigned int (*preemption_post_ibsubmit)( struct adreno_device *adreno_dev, unsigned int *cmds); int (*preemption_init)(struct adreno_device *); void (*preemption_schedule)(struct adreno_device *); int (*preemption_context_init)(struct kgsl_context *); void (*preemption_context_destroy)(struct kgsl_context *); void (*enable_64bit)(struct adreno_device *); void (*clk_set_options)(struct adreno_device *, const char *, struct clk *, bool on); Loading drivers/gpu/msm/adreno_a6xx.c +88 −5 Original line number Diff line number Diff line Loading @@ -29,9 +29,6 @@ #include "kgsl_gmu.h" #include "kgsl_trace.h" #define A6XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \ (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F)) #define MIN_HBB 13 #define A6XX_LLC_NUM_GPU_SCIDS 5 Loading Loading @@ -482,6 +479,12 @@ static void a6xx_start(struct adreno_device *adreno_dev) if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI)) kgsl_regrmw(device, A6XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); /* Enable the GMEM save/restore feature for preemption */ if (adreno_is_preemption_enabled(adreno_dev)) kgsl_regwrite(device, A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x1); a6xx_preemption_start(adreno_dev); a6xx_protect_init(adreno_dev); } Loading Loading @@ -611,6 +614,70 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev, return ret; } /* * Follow the ME_INIT sequence with a preemption yield to allow the GPU to move * to a different ringbuffer, if desired */ static int _preemption_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_context *context) { unsigned int *cmds_orig = cmds; /* Turn CP protection OFF */ *cmds++ = cp_type7_packet(CP_SET_PROTECTED_MODE, 1); *cmds++ = 0; *cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 6); *cmds++ = 1; cmds += cp_gpuaddr(adreno_dev, cmds, rb->preemption_desc.gpuaddr); *cmds++ = 2; cmds += cp_gpuaddr(adreno_dev, cmds, 0); /* Turn CP protection ON */ *cmds++ = cp_type7_packet(CP_SET_PROTECTED_MODE, 1); *cmds++ = 1; *cmds++ = cp_type7_packet(CP_CONTEXT_SWITCH_YIELD, 4); cmds += cp_gpuaddr(adreno_dev, cmds, 0x0); *cmds++ = 0; /* generate interrupt on preemption completion */ *cmds++ = 0; return cmds - cmds_orig; } static int a6xx_post_start(struct adreno_device *adreno_dev) { int ret; unsigned int *cmds, *start; struct adreno_ringbuffer *rb = adreno_dev->cur_rb; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (!adreno_is_preemption_enabled(adreno_dev)) return 0; cmds = adreno_ringbuffer_allocspace(rb, 42); if (IS_ERR(cmds)) { KGSL_DRV_ERR(device, "error allocating preemption init cmds"); return PTR_ERR(cmds); } start = cmds; cmds += _preemption_init(adreno_dev, rb, cmds, NULL); rb->_wptr = rb->_wptr - (42 - (cmds - start)); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) adreno_spin_idle_debug(adreno_dev, "hw preemption initialization failed to idle\n"); return ret; } /* * a6xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device Loading Loading @@ -651,7 +718,11 @@ static int a6xx_rb_start(struct adreno_device *adreno_dev, return ret; /* GPU comes up in secured mode, make it unsecured by default */ return adreno_set_unsecured_mode(adreno_dev, rb); ret = adreno_set_unsecured_mode(adreno_dev, rb); if (ret) return ret; return a6xx_post_start(adreno_dev); } static int _load_firmware(struct kgsl_device *device, const char *fwfile, Loading Loading @@ -2086,7 +2157,7 @@ static struct adreno_irq_funcs a6xx_irq_funcs[32] = { /* 6 - RBBM_ATB_ASYNC_OVERFLOW */ ADRENO_IRQ_CALLBACK(a6xx_err_callback), ADRENO_IRQ_CALLBACK(NULL), /* 7 - GPC_ERR */ ADRENO_IRQ_CALLBACK(NULL),/* 8 - CP_SW */ ADRENO_IRQ_CALLBACK(a6xx_preemption_callback),/* 8 - CP_SW */ ADRENO_IRQ_CALLBACK(a6xx_cp_hw_err_callback), /* 9 - CP_HW_ERROR */ ADRENO_IRQ_CALLBACK(NULL), /* 10 - CP_CCU_FLUSH_DEPTH_TS */ ADRENO_IRQ_CALLBACK(NULL), /* 11 - CP_CCU_FLUSH_COLOR_TS */ Loading Loading @@ -2580,6 +2651,11 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { ADRENO_REG_DEFINE(ADRENO_REG_CP_IB2_BUFSZ, A6XX_CP_IB2_REM_SIZE), ADRENO_REG_DEFINE(ADRENO_REG_CP_ROQ_ADDR, A6XX_CP_ROQ_DBG_ADDR), ADRENO_REG_DEFINE(ADRENO_REG_CP_ROQ_DATA, A6XX_CP_ROQ_DBG_DATA), ADRENO_REG_DEFINE(ADRENO_REG_CP_PREEMPT, A6XX_CP_CONTEXT_SWITCH_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_LO, A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO), ADRENO_REG_DEFINE(ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_HI, A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_HI), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_STATUS, A6XX_RBBM_STATUS), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_STATUS3, A6XX_RBBM_STATUS3), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_CTL, A6XX_RBBM_PERFCTR_CNTL), Loading Loading @@ -2693,4 +2769,11 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .iommu_fault_block = a6xx_iommu_fault_block, .reset = a6xx_reset, .soft_reset = a6xx_soft_reset, .preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit, .preemption_post_ibsubmit = a6xx_preemption_post_ibsubmit, .preemption_init = a6xx_preemption_init, .preemption_schedule = a6xx_preemption_schedule, .preemption_set_marker = a6xx_preemption_set_marker, .preemption_context_init = a6xx_preemption_context_init, .preemption_context_destroy = a6xx_preemption_context_destroy, }; drivers/gpu/msm/adreno_a6xx.h +84 −1 Original line number Diff line number Diff line Loading @@ -23,10 +23,93 @@ #define CP_CLUSTER_SP_PS 0x4 #define CP_CLUSTER_PS 0x5 /** * struct a6xx_cp_preemption_record - CP context record for * preemption. * @magic: (00) Value at this offset must be equal to * A6XX_CP_CTXRECORD_MAGIC_REF. * @info: (04) Type of record. Written non-zero (usually) by CP. * we must set to zero for all ringbuffers. * @errno: (08) Error code. Initialize this to A6XX_CP_CTXRECORD_ERROR_NONE. * CP will update to another value if a preemption error occurs. * @data: (12) DATA field in YIELD and SET_MARKER packets. * Written by CP when switching out. Not used on switch-in. Initialized to 0. * @cntl: (16) RB_CNTL, saved and restored by CP. We must initialize this. * @rptr: (20) RB_RPTR, saved and restored by CP. We must initialize this. * @wptr: (24) RB_WPTR, saved and restored by CP. We must initialize this. * @_pad28: (28) Reserved/padding. * @rptr_addr: (32) RB_RPTR_ADDR_LO|HI saved and restored. We must initialize. * rbase: (40) RB_BASE_LO|HI saved and restored. * counter: (48) Pointer to preemption counter. */ struct a6xx_cp_preemption_record { uint32_t magic; uint32_t info; uint32_t errno; uint32_t data; uint32_t cntl; uint32_t rptr; uint32_t wptr; uint32_t _pad28; uint64_t rptr_addr; uint64_t rbase; uint64_t counter; }; /** * struct a6xx_cp_smmu_info - CP preemption SMMU info. * @magic: (00) The value at this offset must be equal to * A6XX_CP_SMMU_INFO_MAGIC_REF. * @_pad4: (04) Reserved/padding * @ttbr0: (08) Base address of the page table for the * incoming context. * @context_idr: (16) Context Identification Register value. */ struct a6xx_cp_smmu_info { uint32_t magic; uint32_t _pad4; uint64_t ttbr0; uint32_t asid; uint32_t context_idr; }; #define A6XX_CP_SMMU_INFO_MAGIC_REF 0x3618CDA3UL #define A6XX_CP_CTXRECORD_MAGIC_REF 0xAE399D6EUL /* Size of each CP preemption record */ #define A6XX_CP_CTXRECORD_SIZE_IN_BYTES (2112 * 1024) /* Size of the preemption counter block (in bytes) */ #define A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE (16 * 4) /* Size of the user context record block (in bytes) */ #define A6XX_CP_CTXRECORD_USER_RESTORE_SIZE (192 * 1024) /* Size of the performance counter save/restore block (in bytes) */ #define A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE (4 * 1024) #define A6XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \ (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F)) /* Preemption functions */ void a6xx_preemption_trigger(struct adreno_device *adreno_dev); void a6xx_preemption_schedule(struct adreno_device *adreno_dev); void a6xx_preemption_start(struct adreno_device *adreno_dev); int a6xx_preemption_init(struct adreno_device *adreno_dev); unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, unsigned int *cmds); unsigned int a6xx_preemption_pre_ibsubmit(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_context *context); unsigned int a6xx_preemption_set_marker(unsigned int *cmds, int start); void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit); int a6xx_preemption_context_init(struct kgsl_context *context); void a6xx_preemption_context_destroy(struct kgsl_context *context); void a6xx_snapshot(struct adreno_device *adreno_dev, struct kgsl_snapshot *snapshot); void a6xx_crashdump_init(struct adreno_device *adreno_dev); #endif Loading
drivers/gpu/msm/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ msm_adreno-y += \ adreno_a6xx_snapshot.o \ adreno_a4xx_preempt.o \ adreno_a5xx_preempt.o \ adreno_a6xx_preempt.o \ adreno_sysfs.o \ adreno.o \ adreno_cp_parser.o \ Loading
drivers/gpu/msm/a6xx_reg.h +10 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,15 @@ #define A6XX_CP_ADDR_MODE_CNTL 0x842 #define A6XX_CP_PROTECT_CNTL 0x84F #define A6XX_CP_PROTECT_REG 0x850 #define A6XX_CP_CONTEXT_SWITCH_CNTL 0x8A0 #define A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO 0x8A1 #define A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_HI 0x8A2 #define A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_LO 0x8A3 #define A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_HI 0x8A4 #define A6XX_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_LO 0x8A5 #define A6XX_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_HI 0x8A6 #define A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_LO 0x8A7 #define A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_HI 0x8A8 #define A6XX_CP_PERFCTR_CP_SEL_0 0x8D0 #define A6XX_CP_PERFCTR_CP_SEL_1 0x8D1 #define A6XX_CP_PERFCTR_CP_SEL_2 0x8D2 Loading Loading @@ -590,6 +599,7 @@ #define A6XX_RB_PERFCTR_CMP_SEL_1 0x8E2D #define A6XX_RB_PERFCTR_CMP_SEL_2 0x8E2E #define A6XX_RB_PERFCTR_CMP_SEL_3 0x8E2F #define A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE 0x8E50 /* PC registers */ #define A6XX_PC_DBG_ECO_CNTL 0x9E00 Loading
drivers/gpu/msm/adreno.h +3 −0 Original line number Diff line number Diff line Loading @@ -845,11 +845,14 @@ struct adreno_gpudev { unsigned int *cmds, struct kgsl_context *context); int (*preemption_yield_enable)(unsigned int *); unsigned int (*preemption_set_marker)(unsigned int *cmds, int start); unsigned int (*preemption_post_ibsubmit)( struct adreno_device *adreno_dev, unsigned int *cmds); int (*preemption_init)(struct adreno_device *); void (*preemption_schedule)(struct adreno_device *); int (*preemption_context_init)(struct kgsl_context *); void (*preemption_context_destroy)(struct kgsl_context *); void (*enable_64bit)(struct adreno_device *); void (*clk_set_options)(struct adreno_device *, const char *, struct clk *, bool on); Loading
drivers/gpu/msm/adreno_a6xx.c +88 −5 Original line number Diff line number Diff line Loading @@ -29,9 +29,6 @@ #include "kgsl_gmu.h" #include "kgsl_trace.h" #define A6XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \ (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F)) #define MIN_HBB 13 #define A6XX_LLC_NUM_GPU_SCIDS 5 Loading Loading @@ -482,6 +479,12 @@ static void a6xx_start(struct adreno_device *adreno_dev) if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI)) kgsl_regrmw(device, A6XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); /* Enable the GMEM save/restore feature for preemption */ if (adreno_is_preemption_enabled(adreno_dev)) kgsl_regwrite(device, A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x1); a6xx_preemption_start(adreno_dev); a6xx_protect_init(adreno_dev); } Loading Loading @@ -611,6 +614,70 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev, return ret; } /* * Follow the ME_INIT sequence with a preemption yield to allow the GPU to move * to a different ringbuffer, if desired */ static int _preemption_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_context *context) { unsigned int *cmds_orig = cmds; /* Turn CP protection OFF */ *cmds++ = cp_type7_packet(CP_SET_PROTECTED_MODE, 1); *cmds++ = 0; *cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 6); *cmds++ = 1; cmds += cp_gpuaddr(adreno_dev, cmds, rb->preemption_desc.gpuaddr); *cmds++ = 2; cmds += cp_gpuaddr(adreno_dev, cmds, 0); /* Turn CP protection ON */ *cmds++ = cp_type7_packet(CP_SET_PROTECTED_MODE, 1); *cmds++ = 1; *cmds++ = cp_type7_packet(CP_CONTEXT_SWITCH_YIELD, 4); cmds += cp_gpuaddr(adreno_dev, cmds, 0x0); *cmds++ = 0; /* generate interrupt on preemption completion */ *cmds++ = 0; return cmds - cmds_orig; } static int a6xx_post_start(struct adreno_device *adreno_dev) { int ret; unsigned int *cmds, *start; struct adreno_ringbuffer *rb = adreno_dev->cur_rb; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (!adreno_is_preemption_enabled(adreno_dev)) return 0; cmds = adreno_ringbuffer_allocspace(rb, 42); if (IS_ERR(cmds)) { KGSL_DRV_ERR(device, "error allocating preemption init cmds"); return PTR_ERR(cmds); } start = cmds; cmds += _preemption_init(adreno_dev, rb, cmds, NULL); rb->_wptr = rb->_wptr - (42 - (cmds - start)); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) adreno_spin_idle_debug(adreno_dev, "hw preemption initialization failed to idle\n"); return ret; } /* * a6xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device Loading Loading @@ -651,7 +718,11 @@ static int a6xx_rb_start(struct adreno_device *adreno_dev, return ret; /* GPU comes up in secured mode, make it unsecured by default */ return adreno_set_unsecured_mode(adreno_dev, rb); ret = adreno_set_unsecured_mode(adreno_dev, rb); if (ret) return ret; return a6xx_post_start(adreno_dev); } static int _load_firmware(struct kgsl_device *device, const char *fwfile, Loading Loading @@ -2086,7 +2157,7 @@ static struct adreno_irq_funcs a6xx_irq_funcs[32] = { /* 6 - RBBM_ATB_ASYNC_OVERFLOW */ ADRENO_IRQ_CALLBACK(a6xx_err_callback), ADRENO_IRQ_CALLBACK(NULL), /* 7 - GPC_ERR */ ADRENO_IRQ_CALLBACK(NULL),/* 8 - CP_SW */ ADRENO_IRQ_CALLBACK(a6xx_preemption_callback),/* 8 - CP_SW */ ADRENO_IRQ_CALLBACK(a6xx_cp_hw_err_callback), /* 9 - CP_HW_ERROR */ ADRENO_IRQ_CALLBACK(NULL), /* 10 - CP_CCU_FLUSH_DEPTH_TS */ ADRENO_IRQ_CALLBACK(NULL), /* 11 - CP_CCU_FLUSH_COLOR_TS */ Loading Loading @@ -2580,6 +2651,11 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { ADRENO_REG_DEFINE(ADRENO_REG_CP_IB2_BUFSZ, A6XX_CP_IB2_REM_SIZE), ADRENO_REG_DEFINE(ADRENO_REG_CP_ROQ_ADDR, A6XX_CP_ROQ_DBG_ADDR), ADRENO_REG_DEFINE(ADRENO_REG_CP_ROQ_DATA, A6XX_CP_ROQ_DBG_DATA), ADRENO_REG_DEFINE(ADRENO_REG_CP_PREEMPT, A6XX_CP_CONTEXT_SWITCH_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_LO, A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO), ADRENO_REG_DEFINE(ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_HI, A6XX_CP_CONTEXT_SWITCH_SMMU_INFO_HI), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_STATUS, A6XX_RBBM_STATUS), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_STATUS3, A6XX_RBBM_STATUS3), ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_CTL, A6XX_RBBM_PERFCTR_CNTL), Loading Loading @@ -2693,4 +2769,11 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .iommu_fault_block = a6xx_iommu_fault_block, .reset = a6xx_reset, .soft_reset = a6xx_soft_reset, .preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit, .preemption_post_ibsubmit = a6xx_preemption_post_ibsubmit, .preemption_init = a6xx_preemption_init, .preemption_schedule = a6xx_preemption_schedule, .preemption_set_marker = a6xx_preemption_set_marker, .preemption_context_init = a6xx_preemption_context_init, .preemption_context_destroy = a6xx_preemption_context_destroy, };
drivers/gpu/msm/adreno_a6xx.h +84 −1 Original line number Diff line number Diff line Loading @@ -23,10 +23,93 @@ #define CP_CLUSTER_SP_PS 0x4 #define CP_CLUSTER_PS 0x5 /** * struct a6xx_cp_preemption_record - CP context record for * preemption. * @magic: (00) Value at this offset must be equal to * A6XX_CP_CTXRECORD_MAGIC_REF. * @info: (04) Type of record. Written non-zero (usually) by CP. * we must set to zero for all ringbuffers. * @errno: (08) Error code. Initialize this to A6XX_CP_CTXRECORD_ERROR_NONE. * CP will update to another value if a preemption error occurs. * @data: (12) DATA field in YIELD and SET_MARKER packets. * Written by CP when switching out. Not used on switch-in. Initialized to 0. * @cntl: (16) RB_CNTL, saved and restored by CP. We must initialize this. * @rptr: (20) RB_RPTR, saved and restored by CP. We must initialize this. * @wptr: (24) RB_WPTR, saved and restored by CP. We must initialize this. * @_pad28: (28) Reserved/padding. * @rptr_addr: (32) RB_RPTR_ADDR_LO|HI saved and restored. We must initialize. * rbase: (40) RB_BASE_LO|HI saved and restored. * counter: (48) Pointer to preemption counter. */ struct a6xx_cp_preemption_record { uint32_t magic; uint32_t info; uint32_t errno; uint32_t data; uint32_t cntl; uint32_t rptr; uint32_t wptr; uint32_t _pad28; uint64_t rptr_addr; uint64_t rbase; uint64_t counter; }; /** * struct a6xx_cp_smmu_info - CP preemption SMMU info. * @magic: (00) The value at this offset must be equal to * A6XX_CP_SMMU_INFO_MAGIC_REF. * @_pad4: (04) Reserved/padding * @ttbr0: (08) Base address of the page table for the * incoming context. * @context_idr: (16) Context Identification Register value. */ struct a6xx_cp_smmu_info { uint32_t magic; uint32_t _pad4; uint64_t ttbr0; uint32_t asid; uint32_t context_idr; }; #define A6XX_CP_SMMU_INFO_MAGIC_REF 0x3618CDA3UL #define A6XX_CP_CTXRECORD_MAGIC_REF 0xAE399D6EUL /* Size of each CP preemption record */ #define A6XX_CP_CTXRECORD_SIZE_IN_BYTES (2112 * 1024) /* Size of the preemption counter block (in bytes) */ #define A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE (16 * 4) /* Size of the user context record block (in bytes) */ #define A6XX_CP_CTXRECORD_USER_RESTORE_SIZE (192 * 1024) /* Size of the performance counter save/restore block (in bytes) */ #define A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE (4 * 1024) #define A6XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \ (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F)) /* Preemption functions */ void a6xx_preemption_trigger(struct adreno_device *adreno_dev); void a6xx_preemption_schedule(struct adreno_device *adreno_dev); void a6xx_preemption_start(struct adreno_device *adreno_dev); int a6xx_preemption_init(struct adreno_device *adreno_dev); unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, unsigned int *cmds); unsigned int a6xx_preemption_pre_ibsubmit(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_context *context); unsigned int a6xx_preemption_set_marker(unsigned int *cmds, int start); void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit); int a6xx_preemption_context_init(struct kgsl_context *context); void a6xx_preemption_context_destroy(struct kgsl_context *context); void a6xx_snapshot(struct adreno_device *adreno_dev, struct kgsl_snapshot *snapshot); void a6xx_crashdump_init(struct adreno_device *adreno_dev); #endif