Loading drivers/gpu/msm/adreno.c +5 −38 Original line number Diff line number Diff line Loading @@ -949,7 +949,7 @@ static int adreno_probe(struct platform_device *pdev) if (!ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) device->mmu.secured = false; status = adreno_ringbuffer_init(adreno_dev, nopreempt); status = adreno_ringbuffer_probe(adreno_dev, nopreempt); if (status) goto out; Loading Loading @@ -1136,15 +1136,6 @@ static int adreno_init(struct kgsl_device *device) /* Power down the device */ kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT); /* * Enable the power on shader corruption fix * This is only applicable for 28nm targets */ if (adreno_is_a3xx(adreno_dev)) adreno_a3xx_pwron_fixup_init(adreno_dev); else if ((adreno_is_a405(adreno_dev)) || (adreno_is_a420(adreno_dev))) adreno_a4xx_pwron_fixup_init(adreno_dev); if (gpudev->init != NULL) gpudev->init(adreno_dev); Loading @@ -1167,16 +1158,6 @@ static int adreno_init(struct kgsl_device *device) } } /* Adjust snapshot section sizes according to core */ if ((adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))) { gpudev->snapshot_data->sect_sizes->cp_pfp = A320_SNAPSHOT_CP_STATE_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->roq = A320_SNAPSHOT_ROQ_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->cp_merciu = A320_SNAPSHOT_CP_MERCIU_SECTION_SIZE; } /* * Allocate a small chunk of memory for precise cmdbatch profiling for * those targets that have the always on timer Loading Loading @@ -1462,12 +1443,6 @@ static int _adreno_start(struct adreno_device *adreno_dev) if (status) goto error_mmu_off; if (gpudev->hw_init) { status = gpudev->hw_init(adreno_dev); if (status) goto error_mmu_off; } /* Start the dispatcher */ adreno_dispatcher_start(device); Loading Loading @@ -2125,19 +2100,11 @@ static int adreno_soft_reset(struct kgsl_device *device) ret = adreno_ringbuffer_start(adreno_dev, ADRENO_START_WARM); else ret = adreno_ringbuffer_start(adreno_dev, ADRENO_START_COLD); if (ret) goto done; if (gpudev->hw_init) ret = gpudev->hw_init(adreno_dev); if (ret) goto done; if (ret == 0) { device->reset_counter++; /* device is back online */ set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv); } done: return ret; } Loading drivers/gpu/msm/adreno.h +1 −6 Original line number Diff line number Diff line Loading @@ -701,10 +701,8 @@ struct adreno_gpudev { void (*platform_setup)(struct adreno_device *); void (*init)(struct adreno_device *); void (*remove)(struct adreno_device *); int (*rb_init)(struct adreno_device *, struct adreno_ringbuffer *); int (*hw_init)(struct adreno_device *); int (*rb_start)(struct adreno_device *, unsigned int start_type); int (*microcode_read)(struct adreno_device *); int (*microcode_load)(struct adreno_device *, unsigned int start_type); void (*perfcounter_init)(struct adreno_device *); void (*perfcounter_close)(struct adreno_device *); void (*start)(struct adreno_device *); Loading Loading @@ -849,9 +847,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch); int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev); int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev); int adreno_coresight_init(struct adreno_device *adreno_dev); void adreno_coresight_start(struct adreno_device *adreno_dev); Loading drivers/gpu/msm/adreno_a3xx.c +58 −13 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "adreno_trace.h" #include "adreno_pm4types.h" #include "adreno_perfcounter.h" #include "adreno_snapshot.h" /* * Define registers for a3xx that contain addresses used by the Loading Loading @@ -151,7 +152,7 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = { }; /** * adreno_a3xx_pwron_fixup_init() - Initalize a special command buffer to run a * _a3xx_pwron_fixup() - Initialize a special command buffer to run a * post-power collapse shader workaround * @adreno_dev: Pointer to a adreno_device struct * Loading @@ -161,7 +162,7 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = { * * Returns: 0 on success or negative on error */ int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev) static int _a3xx_pwron_fixup(struct adreno_device *adreno_dev) { unsigned int *cmds; int count = ARRAY_SIZE(_a3xx_pwron_fixup_fs_instructions); Loading Loading @@ -605,15 +606,7 @@ static void a3xx_platform_setup(struct adreno_device *adreno_dev) } } /* * a3xx_rb_init() - Initialize ringbuffer * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, common function shared between * a3xx devices */ static int a3xx_rb_init(struct adreno_device *adreno_dev, static int a3xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading Loading @@ -659,6 +652,58 @@ static int a3xx_rb_init(struct adreno_device *adreno_dev, return ret; } static int a3xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a3xx_microcode_load(adreno_dev, start_type); if (ret == 0) { /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a3xx_send_me_init(adreno_dev, rb); } return ret; } /* * a3xx_init() - Initialize gpu specific data * @adreno_dev: Pointer to adreno device */ static void a3xx_init(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); _a3xx_pwron_fixup(adreno_dev); /* Adjust snapshot section sizes according to core */ if ((adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))) { gpudev->snapshot_data->sect_sizes->cp_pfp = A320_SNAPSHOT_CP_STATE_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->roq = A320_SNAPSHOT_ROQ_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->cp_merciu = A320_SNAPSHOT_CP_MERCIU_SECTION_SIZE; } } /* * a3xx_err_callback() - Call back for a3xx error interrupts * @adreno_dev: Pointer to device Loading Loading @@ -1817,9 +1862,9 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .num_prio_levels = 1, .vbif_xin_halt_ctrl0_mask = A3XX_VBIF_XIN_HALT_CTRL0_MASK, .platform_setup = a3xx_platform_setup, .rb_init = a3xx_rb_init, .rb_start = a3xx_rb_start, .init = a3xx_init, .microcode_read = a3xx_microcode_read, .microcode_load = a3xx_microcode_load, .perfcounter_init = a3xx_perfcounter_init, .perfcounter_close = a3xx_perfcounter_close, .start = a3xx_start, Loading drivers/gpu/msm/adreno_a4xx.c +53 −19 Original line number Diff line number Diff line Loading @@ -1439,7 +1439,7 @@ static const unsigned int _a4xx_pwron_fixup_fs_instructions[] = { }; /** * adreno_a4xx_pwron_fixup_init() - Initalize a special command buffer to run a * _a4xx_pwron_fixup() - Initialize a special command buffer to run a * post-power collapse shader workaround * @adreno_dev: Pointer to a adreno_device struct * Loading @@ -1449,7 +1449,7 @@ static const unsigned int _a4xx_pwron_fixup_fs_instructions[] = { * * Returns: 0 on success or negative on error */ int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev) static int _a4xx_pwron_fixup(struct adreno_device *adreno_dev) { unsigned int *cmds; unsigned int count = ARRAY_SIZE(_a4xx_pwron_fixup_fs_instructions); Loading Loading @@ -1560,23 +1560,17 @@ int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev) return 0; } static int a4xx_hw_init(struct adreno_device *adreno_dev) { a4xx_enable_pc(adreno_dev); a4xx_enable_ppd(adreno_dev); return 0; } /* * a4xx_rb_init() - Initialize ringbuffer * a4xx_init() - Initialize gpu specific data * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, common function shared between * a4xx devices */ static int a4xx_rb_init(struct adreno_device *adreno_dev, static void a4xx_init(struct adreno_device *adreno_dev) { if ((adreno_is_a405(adreno_dev)) || (adreno_is_a420(adreno_dev))) _a4xx_pwron_fixup(adreno_dev); } static int a4xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading Loading @@ -1631,6 +1625,47 @@ static int a4xx_rb_init(struct adreno_device *adreno_dev, return ret; } /* * a4xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device * @start_type: Warm or cold start */ static int a4xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a3xx_microcode_load(adreno_dev, start_type); if (ret) return ret; /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a4xx_send_me_init(adreno_dev, rb); if (ret == 0) { a4xx_enable_pc(adreno_dev); a4xx_enable_ppd(adreno_dev); } return ret; } static ADRENO_CORESIGHT_ATTR(cfg_debbus_ctrlt, &a4xx_coresight_registers[0]); static ADRENO_CORESIGHT_ATTR(cfg_debbus_sela, &a4xx_coresight_registers[1]); static ADRENO_CORESIGHT_ATTR(cfg_debbus_selb, &a4xx_coresight_registers[2]); Loading Loading @@ -2238,10 +2273,9 @@ struct adreno_gpudev adreno_a4xx_gpudev = { .perfcounter_init = a4xx_perfcounter_init, .perfcounter_close = a4xx_perfcounter_close, .rb_init = a4xx_rb_init, .hw_init = a4xx_hw_init, .rb_start = a4xx_rb_start, .init = a4xx_init, .microcode_read = a3xx_microcode_read, .microcode_load = a3xx_microcode_load, .coresight = &a4xx_coresight, .start = a4xx_start, .snapshot = a4xx_snapshot, Loading drivers/gpu/msm/adreno_a5xx.c +178 −137 Original line number Diff line number Diff line Loading @@ -88,6 +88,33 @@ static int a5xx_gpmu_init(struct adreno_device *adreno_dev); #define A530_QFPROM_RAW_PTE_ROW0_MSB 0x134 #define A530_QFPROM_RAW_PTE_ROW2_MSB 0x144 /* Print some key registers if a spin-for-idle times out */ static void spin_idle_debug(struct kgsl_device *device, const char *str) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int rptr, wptr; unsigned int status, status3, intstatus; unsigned int hwfault; dev_err(device->dev, str); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr); kgsl_regread(device, A5XX_RBBM_STATUS, &status); kgsl_regread(device, A5XX_RBBM_STATUS3, &status3); kgsl_regread(device, A5XX_RBBM_INT_0_STATUS, &intstatus); kgsl_regread(device, A5XX_CP_HW_FAULT, &hwfault); dev_err(device->dev, " rb=%X/%X rbbm_status=%8.8X/%8.8X int_0_status=%8.8X\n", rptr, wptr, status, status3, intstatus); dev_err(device->dev, " hwfault=%8.8X\n", hwfault); kgsl_device_snapshot(device, NULL); } static void a530_efuse_leakage(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); Loading Loading @@ -916,6 +943,7 @@ static int _gpmu_send_init_cmds(struct adreno_device *adreno_dev) struct adreno_ringbuffer *rb = adreno_dev->cur_rb; uint32_t *cmds; uint32_t size = adreno_dev->gpmu_cmds_size; int ret; if (size == 0 || adreno_dev->gpmu_cmds == NULL) return -EINVAL; Loading @@ -928,7 +956,13 @@ static int _gpmu_send_init_cmds(struct adreno_device *adreno_dev) /* Copy to the RB the predefined fw sequence cmds */ memcpy(cmds, adreno_dev->gpmu_cmds, size << 2); return adreno_ringbuffer_submit_spin(rb, NULL, 2000); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) spin_idle_debug(&adreno_dev->dev, "gpmu initialization failed to idle\n"); return ret; } /* Loading @@ -948,10 +982,8 @@ static int a5xx_gpmu_start(struct adreno_device *adreno_dev) return 0; ret = _gpmu_send_init_cmds(adreno_dev); if (ret) { KGSL_CORE_ERR("Failed to program the GPMU: %d\n", ret); if (ret) return ret; } if (adreno_is_a530(adreno_dev)) { /* GPMU clock gating setup */ Loading Loading @@ -2309,28 +2341,6 @@ static int _preemption_init( return cmds - cmds_orig; } /* Print some key registers if a spin-for-idle times out */ static void spin_idle_debug(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int rptr, wptr; unsigned int status, status3, intstatus; unsigned int hwfault; adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr); kgsl_regread(device, A5XX_RBBM_STATUS, &status); kgsl_regread(device, A5XX_RBBM_STATUS3, &status3); kgsl_regread(device, A5XX_RBBM_INT_0_STATUS, &intstatus); kgsl_regread(device, A5XX_CP_HW_FAULT, &hwfault); dev_err(device->dev, " rb=%X/%X rbbm_status=%8.8X/%8.8X int_0_status=%8.8X\n", rptr, wptr, status, status3, intstatus); dev_err(device->dev, " hwfault=%8.8X\n", hwfault); } static int a5xx_post_start(struct adreno_device *adreno_dev) { int ret; Loading Loading @@ -2364,19 +2374,13 @@ static int a5xx_post_start(struct adreno_device *adreno_dev) rb->wptr = rb->wptr - (42 - (cmds - start)); if (cmds == start) return 0; ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "hw initialization failed to idle\n"); KGSL_DRV_ERR(device, "hw initialization failed to idle\n"); kgsl_device_snapshot(device, NULL); return ret; } return 0; } static int a5xx_gpmu_init(struct adreno_device *adreno_dev) { Loading @@ -2402,23 +2406,6 @@ static int a5xx_gpmu_init(struct adreno_device *adreno_dev) return 0; } /* * a5xx_hw_init() - Initialize GPU HW using PM4 cmds * @adreno_dev: Pointer to adreno device * * Submit PM4 commands for HW initialization, */ static int a5xx_hw_init(struct adreno_device *adreno_dev) { int ret = a5xx_gpmu_init(adreno_dev); if (!ret) ret = a5xx_post_start(adreno_dev); return ret; } static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { Loading @@ -2434,17 +2421,71 @@ static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev, cmds += cp_secure_mode(adreno_dev, cmds, 0); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "Switch to unsecure failed to idle\n"); dev_err(device->dev, "Switch to unsecure failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); return ret; } /* * a5xx_microcode_load() - Load microcode * @adreno_dev: Pointer to adreno device */ static int a5xx_microcode_load(struct adreno_device *adreno_dev) { void *ptr; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); uint64_t gpuaddr; gpuaddr = adreno_dev->pm4.gpuaddr; kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_HI, upper_32_bits(gpuaddr)); gpuaddr = adreno_dev->pfp.gpuaddr; kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_HI, upper_32_bits(gpuaddr)); /* * Resume call to write the zap shader base address into the * appropriate register, * skip if retention is supported for the CPZ register */ if (zap_ucode_loaded && !(ADRENO_FEATURE(adreno_dev, ADRENO_CPZ_RETENTION))) { int ret; struct scm_desc desc = {0}; desc.args[0] = 0; desc.args[1] = 13; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, 0xA), &desc); if (ret) { pr_err("SCM resume call failed with error %d\n", ret); return ret; } } /* Load the zap shader firmware through PIL if its available */ if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) { ptr = subsystem_get(adreno_dev->gpucore->zap_name); /* Return error if the zap shader cannot be loaded */ if (IS_ERR_OR_NULL(ptr)) return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr); zap_ucode_loaded = 1; } return 0; } static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev) { switch (ADRENO_GPUREV(adreno_dev)) { Loading Loading @@ -2550,26 +2591,21 @@ static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev, *cmds++ = crit_pkts_dwords; ret = adreno_ringbuffer_submit_spin(rb, NULL, 20); if (ret != 0) { struct kgsl_device *device = &adreno_dev->dev; dev_err(device->dev, if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "Critical packet submission failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); } return ret; } /* * a5xx_rb_init() - Initialize ringbuffer * a5xx_send_me_init() - Initialize ringbuffer * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, */ static int a5xx_rb_init(struct adreno_device *adreno_dev, static int a5xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading @@ -2586,14 +2622,18 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev, _set_ordinals(adreno_dev, cmds, 8); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "CP initialization failed to idle\n"); dev_err(device->dev, "CP initialization failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); return ret; } static int a5xx_set_unsecured_mode(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { int ret = 0; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CRITICAL_PACKETS)) { ret = a5xx_critical_packet_submit(adreno_dev, rb); if (ret) Loading @@ -2603,10 +2643,73 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev, /* GPU comes up in secured mode, make it unsecured by default */ if (ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) ret = a5xx_switch_to_unsecure_mode(adreno_dev, rb); else kgsl_regwrite(&adreno_dev->dev, A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); return ret; } /* * a5xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device * @start_type: Warm or cold start */ static int a5xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a5xx_microcode_load(adreno_dev); if (ret) return ret; /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a5xx_send_me_init(adreno_dev, rb); if (ret) return ret; /* GPU comes up in secured mode, make it unsecured by default */ ret = a5xx_set_unsecured_mode(adreno_dev, rb); if (ret) return ret; /* Set up LM before initializing the GPMU */ a5xx_lm_init(adreno_dev); /* Enable SPTP based power collapse before enabling GPMU */ a5xx_enable_pc(adreno_dev); /* Program the GPMU */ ret = a5xx_gpmu_start(adreno_dev); if (ret) return ret; /* Enable limits management */ a5xx_lm_enable(adreno_dev); a5xx_post_start(adreno_dev); return 0; } static int _load_firmware(struct kgsl_device *device, const char *fwfile, struct kgsl_memdesc *ucode, size_t *ucode_size, unsigned int *ucode_version) Loading Loading @@ -2667,66 +2770,6 @@ static int a5xx_microcode_read(struct adreno_device *adreno_dev) return ret; } /* * a5xx_microcode_load() - Load microcode * @adreno_dev: Pointer to adreno device * @start_type: type of device start cold/warm */ static int a5xx_microcode_load(struct adreno_device *adreno_dev, unsigned int start_type) { void *ptr; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); uint64_t gpuaddr; gpuaddr = adreno_dev->pm4.gpuaddr; kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_HI, upper_32_bits(gpuaddr)); gpuaddr = adreno_dev->pfp.gpuaddr; kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_HI, upper_32_bits(gpuaddr)); /* * Resume call to write the zap shader base address into the * appropriate register, * skip if retention is supported for the CPZ register */ if (zap_ucode_loaded && !(ADRENO_FEATURE(adreno_dev, ADRENO_CPZ_RETENTION))) { int ret; struct scm_desc desc = {0}; desc.args[0] = 0; desc.args[1] = 13; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, 0xA), &desc); if (ret) { pr_err("SCM resume call failed with error %d\n", ret); return ret; } } /* Load the zap shader firmware through PIL if its available */ if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) { ptr = subsystem_get(adreno_dev->gpucore->zap_name); /* Return error if the zap shader cannot be loaded */ if (IS_ERR_OR_NULL(ptr)) return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr); zap_ucode_loaded = 1; } return 0; } static struct adreno_perfcount_register a5xx_perfcounters_cp[] = { { KGSL_PERFCOUNTER_NOT_USED, 0, 0, A5XX_RBBM_PERFCTR_CP_0_LO, A5XX_RBBM_PERFCTR_CP_0_HI, 0, A5XX_CP_PERFCTR_CP_SEL_0 }, Loading Loading @@ -4124,10 +4167,8 @@ struct adreno_gpudev adreno_a5xx_gpudev = { .platform_setup = a5xx_platform_setup, .init = a5xx_init, .remove = a5xx_remove, .rb_init = a5xx_rb_init, .hw_init = a5xx_hw_init, .rb_start = a5xx_rb_start, .microcode_read = a5xx_microcode_read, .microcode_load = a5xx_microcode_load, .perfcounters = &a5xx_perfcounters, .vbif_xin_halt_ctrl0_mask = A5XX_VBIF_XIN_HALT_CTRL0_MASK, .is_sptp_idle = a5xx_is_sptp_idle, Loading Loading
drivers/gpu/msm/adreno.c +5 −38 Original line number Diff line number Diff line Loading @@ -949,7 +949,7 @@ static int adreno_probe(struct platform_device *pdev) if (!ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) device->mmu.secured = false; status = adreno_ringbuffer_init(adreno_dev, nopreempt); status = adreno_ringbuffer_probe(adreno_dev, nopreempt); if (status) goto out; Loading Loading @@ -1136,15 +1136,6 @@ static int adreno_init(struct kgsl_device *device) /* Power down the device */ kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT); /* * Enable the power on shader corruption fix * This is only applicable for 28nm targets */ if (adreno_is_a3xx(adreno_dev)) adreno_a3xx_pwron_fixup_init(adreno_dev); else if ((adreno_is_a405(adreno_dev)) || (adreno_is_a420(adreno_dev))) adreno_a4xx_pwron_fixup_init(adreno_dev); if (gpudev->init != NULL) gpudev->init(adreno_dev); Loading @@ -1167,16 +1158,6 @@ static int adreno_init(struct kgsl_device *device) } } /* Adjust snapshot section sizes according to core */ if ((adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))) { gpudev->snapshot_data->sect_sizes->cp_pfp = A320_SNAPSHOT_CP_STATE_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->roq = A320_SNAPSHOT_ROQ_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->cp_merciu = A320_SNAPSHOT_CP_MERCIU_SECTION_SIZE; } /* * Allocate a small chunk of memory for precise cmdbatch profiling for * those targets that have the always on timer Loading Loading @@ -1462,12 +1443,6 @@ static int _adreno_start(struct adreno_device *adreno_dev) if (status) goto error_mmu_off; if (gpudev->hw_init) { status = gpudev->hw_init(adreno_dev); if (status) goto error_mmu_off; } /* Start the dispatcher */ adreno_dispatcher_start(device); Loading Loading @@ -2125,19 +2100,11 @@ static int adreno_soft_reset(struct kgsl_device *device) ret = adreno_ringbuffer_start(adreno_dev, ADRENO_START_WARM); else ret = adreno_ringbuffer_start(adreno_dev, ADRENO_START_COLD); if (ret) goto done; if (gpudev->hw_init) ret = gpudev->hw_init(adreno_dev); if (ret) goto done; if (ret == 0) { device->reset_counter++; /* device is back online */ set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv); } done: return ret; } Loading
drivers/gpu/msm/adreno.h +1 −6 Original line number Diff line number Diff line Loading @@ -701,10 +701,8 @@ struct adreno_gpudev { void (*platform_setup)(struct adreno_device *); void (*init)(struct adreno_device *); void (*remove)(struct adreno_device *); int (*rb_init)(struct adreno_device *, struct adreno_ringbuffer *); int (*hw_init)(struct adreno_device *); int (*rb_start)(struct adreno_device *, unsigned int start_type); int (*microcode_read)(struct adreno_device *); int (*microcode_load)(struct adreno_device *, unsigned int start_type); void (*perfcounter_init)(struct adreno_device *); void (*perfcounter_close)(struct adreno_device *); void (*start)(struct adreno_device *); Loading Loading @@ -849,9 +847,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch); int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev); int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev); int adreno_coresight_init(struct adreno_device *adreno_dev); void adreno_coresight_start(struct adreno_device *adreno_dev); Loading
drivers/gpu/msm/adreno_a3xx.c +58 −13 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "adreno_trace.h" #include "adreno_pm4types.h" #include "adreno_perfcounter.h" #include "adreno_snapshot.h" /* * Define registers for a3xx that contain addresses used by the Loading Loading @@ -151,7 +152,7 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = { }; /** * adreno_a3xx_pwron_fixup_init() - Initalize a special command buffer to run a * _a3xx_pwron_fixup() - Initialize a special command buffer to run a * post-power collapse shader workaround * @adreno_dev: Pointer to a adreno_device struct * Loading @@ -161,7 +162,7 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = { * * Returns: 0 on success or negative on error */ int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev) static int _a3xx_pwron_fixup(struct adreno_device *adreno_dev) { unsigned int *cmds; int count = ARRAY_SIZE(_a3xx_pwron_fixup_fs_instructions); Loading Loading @@ -605,15 +606,7 @@ static void a3xx_platform_setup(struct adreno_device *adreno_dev) } } /* * a3xx_rb_init() - Initialize ringbuffer * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, common function shared between * a3xx devices */ static int a3xx_rb_init(struct adreno_device *adreno_dev, static int a3xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading Loading @@ -659,6 +652,58 @@ static int a3xx_rb_init(struct adreno_device *adreno_dev, return ret; } static int a3xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a3xx_microcode_load(adreno_dev, start_type); if (ret == 0) { /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a3xx_send_me_init(adreno_dev, rb); } return ret; } /* * a3xx_init() - Initialize gpu specific data * @adreno_dev: Pointer to adreno device */ static void a3xx_init(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); _a3xx_pwron_fixup(adreno_dev); /* Adjust snapshot section sizes according to core */ if ((adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev))) { gpudev->snapshot_data->sect_sizes->cp_pfp = A320_SNAPSHOT_CP_STATE_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->roq = A320_SNAPSHOT_ROQ_SECTION_SIZE; gpudev->snapshot_data->sect_sizes->cp_merciu = A320_SNAPSHOT_CP_MERCIU_SECTION_SIZE; } } /* * a3xx_err_callback() - Call back for a3xx error interrupts * @adreno_dev: Pointer to device Loading Loading @@ -1817,9 +1862,9 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .num_prio_levels = 1, .vbif_xin_halt_ctrl0_mask = A3XX_VBIF_XIN_HALT_CTRL0_MASK, .platform_setup = a3xx_platform_setup, .rb_init = a3xx_rb_init, .rb_start = a3xx_rb_start, .init = a3xx_init, .microcode_read = a3xx_microcode_read, .microcode_load = a3xx_microcode_load, .perfcounter_init = a3xx_perfcounter_init, .perfcounter_close = a3xx_perfcounter_close, .start = a3xx_start, Loading
drivers/gpu/msm/adreno_a4xx.c +53 −19 Original line number Diff line number Diff line Loading @@ -1439,7 +1439,7 @@ static const unsigned int _a4xx_pwron_fixup_fs_instructions[] = { }; /** * adreno_a4xx_pwron_fixup_init() - Initalize a special command buffer to run a * _a4xx_pwron_fixup() - Initialize a special command buffer to run a * post-power collapse shader workaround * @adreno_dev: Pointer to a adreno_device struct * Loading @@ -1449,7 +1449,7 @@ static const unsigned int _a4xx_pwron_fixup_fs_instructions[] = { * * Returns: 0 on success or negative on error */ int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev) static int _a4xx_pwron_fixup(struct adreno_device *adreno_dev) { unsigned int *cmds; unsigned int count = ARRAY_SIZE(_a4xx_pwron_fixup_fs_instructions); Loading Loading @@ -1560,23 +1560,17 @@ int adreno_a4xx_pwron_fixup_init(struct adreno_device *adreno_dev) return 0; } static int a4xx_hw_init(struct adreno_device *adreno_dev) { a4xx_enable_pc(adreno_dev); a4xx_enable_ppd(adreno_dev); return 0; } /* * a4xx_rb_init() - Initialize ringbuffer * a4xx_init() - Initialize gpu specific data * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, common function shared between * a4xx devices */ static int a4xx_rb_init(struct adreno_device *adreno_dev, static void a4xx_init(struct adreno_device *adreno_dev) { if ((adreno_is_a405(adreno_dev)) || (adreno_is_a420(adreno_dev))) _a4xx_pwron_fixup(adreno_dev); } static int a4xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading Loading @@ -1631,6 +1625,47 @@ static int a4xx_rb_init(struct adreno_device *adreno_dev, return ret; } /* * a4xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device * @start_type: Warm or cold start */ static int a4xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a3xx_microcode_load(adreno_dev, start_type); if (ret) return ret; /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a4xx_send_me_init(adreno_dev, rb); if (ret == 0) { a4xx_enable_pc(adreno_dev); a4xx_enable_ppd(adreno_dev); } return ret; } static ADRENO_CORESIGHT_ATTR(cfg_debbus_ctrlt, &a4xx_coresight_registers[0]); static ADRENO_CORESIGHT_ATTR(cfg_debbus_sela, &a4xx_coresight_registers[1]); static ADRENO_CORESIGHT_ATTR(cfg_debbus_selb, &a4xx_coresight_registers[2]); Loading Loading @@ -2238,10 +2273,9 @@ struct adreno_gpudev adreno_a4xx_gpudev = { .perfcounter_init = a4xx_perfcounter_init, .perfcounter_close = a4xx_perfcounter_close, .rb_init = a4xx_rb_init, .hw_init = a4xx_hw_init, .rb_start = a4xx_rb_start, .init = a4xx_init, .microcode_read = a3xx_microcode_read, .microcode_load = a3xx_microcode_load, .coresight = &a4xx_coresight, .start = a4xx_start, .snapshot = a4xx_snapshot, Loading
drivers/gpu/msm/adreno_a5xx.c +178 −137 Original line number Diff line number Diff line Loading @@ -88,6 +88,33 @@ static int a5xx_gpmu_init(struct adreno_device *adreno_dev); #define A530_QFPROM_RAW_PTE_ROW0_MSB 0x134 #define A530_QFPROM_RAW_PTE_ROW2_MSB 0x144 /* Print some key registers if a spin-for-idle times out */ static void spin_idle_debug(struct kgsl_device *device, const char *str) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int rptr, wptr; unsigned int status, status3, intstatus; unsigned int hwfault; dev_err(device->dev, str); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr); kgsl_regread(device, A5XX_RBBM_STATUS, &status); kgsl_regread(device, A5XX_RBBM_STATUS3, &status3); kgsl_regread(device, A5XX_RBBM_INT_0_STATUS, &intstatus); kgsl_regread(device, A5XX_CP_HW_FAULT, &hwfault); dev_err(device->dev, " rb=%X/%X rbbm_status=%8.8X/%8.8X int_0_status=%8.8X\n", rptr, wptr, status, status3, intstatus); dev_err(device->dev, " hwfault=%8.8X\n", hwfault); kgsl_device_snapshot(device, NULL); } static void a530_efuse_leakage(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); Loading Loading @@ -916,6 +943,7 @@ static int _gpmu_send_init_cmds(struct adreno_device *adreno_dev) struct adreno_ringbuffer *rb = adreno_dev->cur_rb; uint32_t *cmds; uint32_t size = adreno_dev->gpmu_cmds_size; int ret; if (size == 0 || adreno_dev->gpmu_cmds == NULL) return -EINVAL; Loading @@ -928,7 +956,13 @@ static int _gpmu_send_init_cmds(struct adreno_device *adreno_dev) /* Copy to the RB the predefined fw sequence cmds */ memcpy(cmds, adreno_dev->gpmu_cmds, size << 2); return adreno_ringbuffer_submit_spin(rb, NULL, 2000); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) spin_idle_debug(&adreno_dev->dev, "gpmu initialization failed to idle\n"); return ret; } /* Loading @@ -948,10 +982,8 @@ static int a5xx_gpmu_start(struct adreno_device *adreno_dev) return 0; ret = _gpmu_send_init_cmds(adreno_dev); if (ret) { KGSL_CORE_ERR("Failed to program the GPMU: %d\n", ret); if (ret) return ret; } if (adreno_is_a530(adreno_dev)) { /* GPMU clock gating setup */ Loading Loading @@ -2309,28 +2341,6 @@ static int _preemption_init( return cmds - cmds_orig; } /* Print some key registers if a spin-for-idle times out */ static void spin_idle_debug(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int rptr, wptr; unsigned int status, status3, intstatus; unsigned int hwfault; adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr); adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr); kgsl_regread(device, A5XX_RBBM_STATUS, &status); kgsl_regread(device, A5XX_RBBM_STATUS3, &status3); kgsl_regread(device, A5XX_RBBM_INT_0_STATUS, &intstatus); kgsl_regread(device, A5XX_CP_HW_FAULT, &hwfault); dev_err(device->dev, " rb=%X/%X rbbm_status=%8.8X/%8.8X int_0_status=%8.8X\n", rptr, wptr, status, status3, intstatus); dev_err(device->dev, " hwfault=%8.8X\n", hwfault); } static int a5xx_post_start(struct adreno_device *adreno_dev) { int ret; Loading Loading @@ -2364,19 +2374,13 @@ static int a5xx_post_start(struct adreno_device *adreno_dev) rb->wptr = rb->wptr - (42 - (cmds - start)); if (cmds == start) return 0; ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "hw initialization failed to idle\n"); KGSL_DRV_ERR(device, "hw initialization failed to idle\n"); kgsl_device_snapshot(device, NULL); return ret; } return 0; } static int a5xx_gpmu_init(struct adreno_device *adreno_dev) { Loading @@ -2402,23 +2406,6 @@ static int a5xx_gpmu_init(struct adreno_device *adreno_dev) return 0; } /* * a5xx_hw_init() - Initialize GPU HW using PM4 cmds * @adreno_dev: Pointer to adreno device * * Submit PM4 commands for HW initialization, */ static int a5xx_hw_init(struct adreno_device *adreno_dev) { int ret = a5xx_gpmu_init(adreno_dev); if (!ret) ret = a5xx_post_start(adreno_dev); return ret; } static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { Loading @@ -2434,17 +2421,71 @@ static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev, cmds += cp_secure_mode(adreno_dev, cmds, 0); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "Switch to unsecure failed to idle\n"); dev_err(device->dev, "Switch to unsecure failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); return ret; } /* * a5xx_microcode_load() - Load microcode * @adreno_dev: Pointer to adreno device */ static int a5xx_microcode_load(struct adreno_device *adreno_dev) { void *ptr; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); uint64_t gpuaddr; gpuaddr = adreno_dev->pm4.gpuaddr; kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_HI, upper_32_bits(gpuaddr)); gpuaddr = adreno_dev->pfp.gpuaddr; kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_HI, upper_32_bits(gpuaddr)); /* * Resume call to write the zap shader base address into the * appropriate register, * skip if retention is supported for the CPZ register */ if (zap_ucode_loaded && !(ADRENO_FEATURE(adreno_dev, ADRENO_CPZ_RETENTION))) { int ret; struct scm_desc desc = {0}; desc.args[0] = 0; desc.args[1] = 13; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, 0xA), &desc); if (ret) { pr_err("SCM resume call failed with error %d\n", ret); return ret; } } /* Load the zap shader firmware through PIL if its available */ if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) { ptr = subsystem_get(adreno_dev->gpucore->zap_name); /* Return error if the zap shader cannot be loaded */ if (IS_ERR_OR_NULL(ptr)) return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr); zap_ucode_loaded = 1; } return 0; } static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev) { switch (ADRENO_GPUREV(adreno_dev)) { Loading Loading @@ -2550,26 +2591,21 @@ static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev, *cmds++ = crit_pkts_dwords; ret = adreno_ringbuffer_submit_spin(rb, NULL, 20); if (ret != 0) { struct kgsl_device *device = &adreno_dev->dev; dev_err(device->dev, if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "Critical packet submission failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); } return ret; } /* * a5xx_rb_init() - Initialize ringbuffer * a5xx_send_me_init() - Initialize ringbuffer * @adreno_dev: Pointer to adreno device * @rb: Pointer to the ringbuffer of device * * Submit commands for ME initialization, */ static int a5xx_rb_init(struct adreno_device *adreno_dev, static int a5xx_send_me_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { unsigned int *cmds; Loading @@ -2586,14 +2622,18 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev, _set_ordinals(adreno_dev, cmds, 8); ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret != 0) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "CP initialization failed to idle\n"); dev_err(device->dev, "CP initialization failed to idle\n"); spin_idle_debug(device); kgsl_device_snapshot(device, NULL); return ret; } static int a5xx_set_unsecured_mode(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { int ret = 0; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CRITICAL_PACKETS)) { ret = a5xx_critical_packet_submit(adreno_dev, rb); if (ret) Loading @@ -2603,10 +2643,73 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev, /* GPU comes up in secured mode, make it unsecured by default */ if (ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) ret = a5xx_switch_to_unsecure_mode(adreno_dev, rb); else kgsl_regwrite(&adreno_dev->dev, A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); return ret; } /* * a5xx_rb_start() - Start the ringbuffer * @adreno_dev: Pointer to adreno device * @start_type: Warm or cold start */ static int a5xx_rb_start(struct adreno_device *adreno_dev, unsigned int start_type) { struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev); int ret; /* * The size of the ringbuffer in the hardware is the log2 * representation of the size in quadwords (sizedwords / 2). * Also disable the host RPTR shadow register as it might be unreliable * in certain circumstances. */ adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL, (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F) | (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); ret = a5xx_microcode_load(adreno_dev); if (ret) return ret; /* clear ME_HALT to start micro engine */ adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0); ret = a5xx_send_me_init(adreno_dev, rb); if (ret) return ret; /* GPU comes up in secured mode, make it unsecured by default */ ret = a5xx_set_unsecured_mode(adreno_dev, rb); if (ret) return ret; /* Set up LM before initializing the GPMU */ a5xx_lm_init(adreno_dev); /* Enable SPTP based power collapse before enabling GPMU */ a5xx_enable_pc(adreno_dev); /* Program the GPMU */ ret = a5xx_gpmu_start(adreno_dev); if (ret) return ret; /* Enable limits management */ a5xx_lm_enable(adreno_dev); a5xx_post_start(adreno_dev); return 0; } static int _load_firmware(struct kgsl_device *device, const char *fwfile, struct kgsl_memdesc *ucode, size_t *ucode_size, unsigned int *ucode_version) Loading Loading @@ -2667,66 +2770,6 @@ static int a5xx_microcode_read(struct adreno_device *adreno_dev) return ret; } /* * a5xx_microcode_load() - Load microcode * @adreno_dev: Pointer to adreno device * @start_type: type of device start cold/warm */ static int a5xx_microcode_load(struct adreno_device *adreno_dev, unsigned int start_type) { void *ptr; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); uint64_t gpuaddr; gpuaddr = adreno_dev->pm4.gpuaddr; kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_HI, upper_32_bits(gpuaddr)); gpuaddr = adreno_dev->pfp.gpuaddr; kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_HI, upper_32_bits(gpuaddr)); /* * Resume call to write the zap shader base address into the * appropriate register, * skip if retention is supported for the CPZ register */ if (zap_ucode_loaded && !(ADRENO_FEATURE(adreno_dev, ADRENO_CPZ_RETENTION))) { int ret; struct scm_desc desc = {0}; desc.args[0] = 0; desc.args[1] = 13; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, 0xA), &desc); if (ret) { pr_err("SCM resume call failed with error %d\n", ret); return ret; } } /* Load the zap shader firmware through PIL if its available */ if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) { ptr = subsystem_get(adreno_dev->gpucore->zap_name); /* Return error if the zap shader cannot be loaded */ if (IS_ERR_OR_NULL(ptr)) return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr); zap_ucode_loaded = 1; } return 0; } static struct adreno_perfcount_register a5xx_perfcounters_cp[] = { { KGSL_PERFCOUNTER_NOT_USED, 0, 0, A5XX_RBBM_PERFCTR_CP_0_LO, A5XX_RBBM_PERFCTR_CP_0_HI, 0, A5XX_CP_PERFCTR_CP_SEL_0 }, Loading Loading @@ -4124,10 +4167,8 @@ struct adreno_gpudev adreno_a5xx_gpudev = { .platform_setup = a5xx_platform_setup, .init = a5xx_init, .remove = a5xx_remove, .rb_init = a5xx_rb_init, .hw_init = a5xx_hw_init, .rb_start = a5xx_rb_start, .microcode_read = a5xx_microcode_read, .microcode_load = a5xx_microcode_load, .perfcounters = &a5xx_perfcounters, .vbif_xin_halt_ctrl0_mask = A5XX_VBIF_XIN_HALT_CTRL0_MASK, .is_sptp_idle = a5xx_is_sptp_idle, Loading