Loading drivers/gpu/msm/adreno.h +3 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,8 @@ struct adreno_gpu_core { * @profile_buffer: Memdesc holding the drawobj profiling buffer * @profile_index: Index to store the start/stop ticks in the profiling * buffer * @pwrup_reglist: Memdesc holding the power up register list * which is used by CP during preemption and IFPC * @sp_local_gpuaddr: Base GPU virtual address for SP local memory * @sp_pvt_gpuaddr: Base GPU virtual address for SP private memory * @lm_fw: The LM firmware handle Loading Loading @@ -453,6 +455,7 @@ struct adreno_device { struct kgsl_memdesc profile_buffer; unsigned int profile_index; struct kgsl_memdesc pwrup_reglist; uint64_t sp_local_gpuaddr; uint64_t sp_pvt_gpuaddr; const struct firmware *lm_fw; Loading drivers/gpu/msm/adreno_a6xx.c +90 −4 Original line number Diff line number Diff line Loading @@ -210,6 +210,40 @@ static struct a6xx_protected_regs { { 0xA630, 0x0, 1 }, }; static struct reg_list_pair { uint32_t offset; uint32_t val; } a6xx_pwrup_reglist[] = { { A6XX_VSC_ADDR_MODE_CNTL, 0x0 }, { A6XX_GRAS_ADDR_MODE_CNTL, 0x0 }, { A6XX_RB_ADDR_MODE_CNTL, 0x0 }, { A6XX_PC_ADDR_MODE_CNTL, 0x0 }, { A6XX_HLSQ_ADDR_MODE_CNTL, 0x0 }, { A6XX_VFD_ADDR_MODE_CNTL, 0x0 }, { A6XX_VPC_ADDR_MODE_CNTL, 0x0 }, { A6XX_UCHE_ADDR_MODE_CNTL, 0x0 }, { A6XX_SP_ADDR_MODE_CNTL, 0x0 }, { A6XX_TPL1_ADDR_MODE_CNTL, 0x0 }, { A6XX_UCHE_WRITE_RANGE_MAX_LO, 0x0 }, { A6XX_UCHE_WRITE_RANGE_MAX_HI, 0x0 }, { A6XX_UCHE_TRAP_BASE_LO, 0x0 }, { A6XX_UCHE_TRAP_BASE_HI, 0x0 }, { A6XX_UCHE_WRITE_THRU_BASE_LO, 0x0 }, { A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MIN_LO, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MAX_LO, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MAX_HI, 0x0 }, { A6XX_UCHE_FILTER_CNTL, 0x0 }, { A6XX_UCHE_CACHE_WAYS, 0x0 }, { A6XX_UCHE_MODE_CNTL, 0x0 }, { A6XX_RB_NC_MODE_CNTL, 0x0 }, { A6XX_TPL1_NC_MODE_CNTL, 0x0 }, { A6XX_SP_NC_MODE_CNTL, 0x0 }, { A6XX_PC_DBG_ECO_CNTL, 0x0 }, { A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x0 }, }; static void a6xx_platform_setup(struct adreno_device *adreno_dev) { uint64_t addr; Loading @@ -233,6 +267,21 @@ static void _update_always_on_regs(struct adreno_device *adreno_dev) A6XX_CP_ALWAYS_ON_COUNTER_HI; } static void a6xx_pwrup_reglist_init(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (kgsl_allocate_global(device, &adreno_dev->pwrup_reglist, PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED, "powerup_register_list")) { adreno_dev->pwrup_reglist.gpuaddr = 0; return; } kgsl_sharedmem_set(device, &adreno_dev->pwrup_reglist, 0, 0, PAGE_SIZE); } static void a6xx_init(struct adreno_device *adreno_dev) { a6xx_crashdump_init(adreno_dev); Loading @@ -243,6 +292,8 @@ static void a6xx_init(struct adreno_device *adreno_dev) */ if (!kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev))) _update_always_on_regs(adreno_dev); a6xx_pwrup_reglist_init(adreno_dev); } /** Loading Loading @@ -375,6 +426,22 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev) return adreno_dev->lm_limit; } static void a6xx_patch_pwrup_reglist(struct adreno_device *adreno_dev) { uint32_t i; /* Set up the register values */ for (i = 0; i < ARRAY_SIZE(a6xx_pwrup_reglist); i++) { struct reg_list_pair *r = &a6xx_pwrup_reglist[i]; kgsl_regread(KGSL_DEVICE(adreno_dev), r->offset, &r->val); } /* Copy Preemption register/data pairs */ memcpy(adreno_dev->pwrup_reglist.hostptr, &a6xx_pwrup_reglist, sizeof(a6xx_pwrup_reglist)); } /* * a6xx_start() - Device start * @adreno_dev: Pointer to adreno device Loading @@ -386,6 +453,7 @@ static void a6xx_start(struct adreno_device *adreno_dev) struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int bit, mal, mode, glbl_inv; unsigned int amsbc = 0; static bool patch_reglist; /* runtime adjust callbacks based on feature sets */ if (!kgsl_gmu_isenabled(device)) Loading Loading @@ -503,6 +571,11 @@ static void a6xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x1); if (!patch_reglist && (adreno_dev->pwrup_reglist.gpuaddr != 0)) { a6xx_patch_pwrup_reglist(adreno_dev); patch_reglist = true; } a6xx_preemption_start(adreno_dev); a6xx_protect_init(adreno_dev); } Loading Loading @@ -570,12 +643,16 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev) */ #define CP_INIT_OPERATION_MODE_MASK BIT(6) /* Register initialization list */ #define CP_INIT_REGISTER_INIT_LIST BIT(7) #define CP_INIT_MASK (CP_INIT_MAX_CONTEXT | \ CP_INIT_ERROR_DETECTION_CONTROL | \ CP_INIT_HEADER_DUMP | \ CP_INIT_DEFAULT_RESET_STATE | \ CP_INIT_UCODE_WORKAROUND_MASK | \ CP_INIT_OPERATION_MODE_MASK) CP_INIT_OPERATION_MODE_MASK | \ CP_INIT_REGISTER_INIT_LIST) static void _set_ordinals(struct adreno_device *adreno_dev, unsigned int *cmds, unsigned int count) Loading Loading @@ -611,6 +688,15 @@ static void _set_ordinals(struct adreno_device *adreno_dev, if (CP_INIT_MASK & CP_INIT_OPERATION_MODE_MASK) *cmds++ = 0x00000002; if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST) { uint64_t gpuaddr = adreno_dev->pwrup_reglist.gpuaddr; *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); /* Size is in dwords */ *cmds++ = sizeof(a6xx_pwrup_reglist) >> 2; } /* Pad rest of the cmds with 0's */ while ((unsigned int)(cmds - start) < count) *cmds++ = 0x0; Loading @@ -629,13 +715,13 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev, unsigned int *cmds; int ret; cmds = adreno_ringbuffer_allocspace(rb, 9); cmds = adreno_ringbuffer_allocspace(rb, 12); if (IS_ERR(cmds)) return PTR_ERR(cmds); *cmds++ = cp_type7_packet(CP_ME_INIT, 8); *cmds++ = cp_type7_packet(CP_ME_INIT, 11); _set_ordinals(adreno_dev, cmds, 8); _set_ordinals(adreno_dev, cmds, 11); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) Loading Loading
drivers/gpu/msm/adreno.h +3 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,8 @@ struct adreno_gpu_core { * @profile_buffer: Memdesc holding the drawobj profiling buffer * @profile_index: Index to store the start/stop ticks in the profiling * buffer * @pwrup_reglist: Memdesc holding the power up register list * which is used by CP during preemption and IFPC * @sp_local_gpuaddr: Base GPU virtual address for SP local memory * @sp_pvt_gpuaddr: Base GPU virtual address for SP private memory * @lm_fw: The LM firmware handle Loading Loading @@ -453,6 +455,7 @@ struct adreno_device { struct kgsl_memdesc profile_buffer; unsigned int profile_index; struct kgsl_memdesc pwrup_reglist; uint64_t sp_local_gpuaddr; uint64_t sp_pvt_gpuaddr; const struct firmware *lm_fw; Loading
drivers/gpu/msm/adreno_a6xx.c +90 −4 Original line number Diff line number Diff line Loading @@ -210,6 +210,40 @@ static struct a6xx_protected_regs { { 0xA630, 0x0, 1 }, }; static struct reg_list_pair { uint32_t offset; uint32_t val; } a6xx_pwrup_reglist[] = { { A6XX_VSC_ADDR_MODE_CNTL, 0x0 }, { A6XX_GRAS_ADDR_MODE_CNTL, 0x0 }, { A6XX_RB_ADDR_MODE_CNTL, 0x0 }, { A6XX_PC_ADDR_MODE_CNTL, 0x0 }, { A6XX_HLSQ_ADDR_MODE_CNTL, 0x0 }, { A6XX_VFD_ADDR_MODE_CNTL, 0x0 }, { A6XX_VPC_ADDR_MODE_CNTL, 0x0 }, { A6XX_UCHE_ADDR_MODE_CNTL, 0x0 }, { A6XX_SP_ADDR_MODE_CNTL, 0x0 }, { A6XX_TPL1_ADDR_MODE_CNTL, 0x0 }, { A6XX_UCHE_WRITE_RANGE_MAX_LO, 0x0 }, { A6XX_UCHE_WRITE_RANGE_MAX_HI, 0x0 }, { A6XX_UCHE_TRAP_BASE_LO, 0x0 }, { A6XX_UCHE_TRAP_BASE_HI, 0x0 }, { A6XX_UCHE_WRITE_THRU_BASE_LO, 0x0 }, { A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MIN_LO, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MAX_LO, 0x0 }, { A6XX_UCHE_GMEM_RANGE_MAX_HI, 0x0 }, { A6XX_UCHE_FILTER_CNTL, 0x0 }, { A6XX_UCHE_CACHE_WAYS, 0x0 }, { A6XX_UCHE_MODE_CNTL, 0x0 }, { A6XX_RB_NC_MODE_CNTL, 0x0 }, { A6XX_TPL1_NC_MODE_CNTL, 0x0 }, { A6XX_SP_NC_MODE_CNTL, 0x0 }, { A6XX_PC_DBG_ECO_CNTL, 0x0 }, { A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x0 }, }; static void a6xx_platform_setup(struct adreno_device *adreno_dev) { uint64_t addr; Loading @@ -233,6 +267,21 @@ static void _update_always_on_regs(struct adreno_device *adreno_dev) A6XX_CP_ALWAYS_ON_COUNTER_HI; } static void a6xx_pwrup_reglist_init(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (kgsl_allocate_global(device, &adreno_dev->pwrup_reglist, PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED, "powerup_register_list")) { adreno_dev->pwrup_reglist.gpuaddr = 0; return; } kgsl_sharedmem_set(device, &adreno_dev->pwrup_reglist, 0, 0, PAGE_SIZE); } static void a6xx_init(struct adreno_device *adreno_dev) { a6xx_crashdump_init(adreno_dev); Loading @@ -243,6 +292,8 @@ static void a6xx_init(struct adreno_device *adreno_dev) */ if (!kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev))) _update_always_on_regs(adreno_dev); a6xx_pwrup_reglist_init(adreno_dev); } /** Loading Loading @@ -375,6 +426,22 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev) return adreno_dev->lm_limit; } static void a6xx_patch_pwrup_reglist(struct adreno_device *adreno_dev) { uint32_t i; /* Set up the register values */ for (i = 0; i < ARRAY_SIZE(a6xx_pwrup_reglist); i++) { struct reg_list_pair *r = &a6xx_pwrup_reglist[i]; kgsl_regread(KGSL_DEVICE(adreno_dev), r->offset, &r->val); } /* Copy Preemption register/data pairs */ memcpy(adreno_dev->pwrup_reglist.hostptr, &a6xx_pwrup_reglist, sizeof(a6xx_pwrup_reglist)); } /* * a6xx_start() - Device start * @adreno_dev: Pointer to adreno device Loading @@ -386,6 +453,7 @@ static void a6xx_start(struct adreno_device *adreno_dev) struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int bit, mal, mode, glbl_inv; unsigned int amsbc = 0; static bool patch_reglist; /* runtime adjust callbacks based on feature sets */ if (!kgsl_gmu_isenabled(device)) Loading Loading @@ -503,6 +571,11 @@ static void a6xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x1); if (!patch_reglist && (adreno_dev->pwrup_reglist.gpuaddr != 0)) { a6xx_patch_pwrup_reglist(adreno_dev); patch_reglist = true; } a6xx_preemption_start(adreno_dev); a6xx_protect_init(adreno_dev); } Loading Loading @@ -570,12 +643,16 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev) */ #define CP_INIT_OPERATION_MODE_MASK BIT(6) /* Register initialization list */ #define CP_INIT_REGISTER_INIT_LIST BIT(7) #define CP_INIT_MASK (CP_INIT_MAX_CONTEXT | \ CP_INIT_ERROR_DETECTION_CONTROL | \ CP_INIT_HEADER_DUMP | \ CP_INIT_DEFAULT_RESET_STATE | \ CP_INIT_UCODE_WORKAROUND_MASK | \ CP_INIT_OPERATION_MODE_MASK) CP_INIT_OPERATION_MODE_MASK | \ CP_INIT_REGISTER_INIT_LIST) static void _set_ordinals(struct adreno_device *adreno_dev, unsigned int *cmds, unsigned int count) Loading Loading @@ -611,6 +688,15 @@ static void _set_ordinals(struct adreno_device *adreno_dev, if (CP_INIT_MASK & CP_INIT_OPERATION_MODE_MASK) *cmds++ = 0x00000002; if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST) { uint64_t gpuaddr = adreno_dev->pwrup_reglist.gpuaddr; *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); /* Size is in dwords */ *cmds++ = sizeof(a6xx_pwrup_reglist) >> 2; } /* Pad rest of the cmds with 0's */ while ((unsigned int)(cmds - start) < count) *cmds++ = 0x0; Loading @@ -629,13 +715,13 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev, unsigned int *cmds; int ret; cmds = adreno_ringbuffer_allocspace(rb, 9); cmds = adreno_ringbuffer_allocspace(rb, 12); if (IS_ERR(cmds)) return PTR_ERR(cmds); *cmds++ = cp_type7_packet(CP_ME_INIT, 8); *cmds++ = cp_type7_packet(CP_ME_INIT, 11); _set_ordinals(adreno_dev, cmds, 8); _set_ordinals(adreno_dev, cmds, 11); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) Loading