Loading drivers/gpu/msm/a3xx_reg.h +0 −1 Original line number Diff line number Diff line Loading @@ -883,7 +883,6 @@ #define A310_RBBM_GPR0_CTL_DEFAULT 0x000000AA /* COUNTABLE FOR SP PERFCOUNTER */ #define SP_FS_FULL_ALU_INSTRUCTIONS 0x0E #define SP_ALU_ACTIVE_CYCLES 0x1D #define SP0_ICL1_MISSES 0x1A #define SP_FS_CFLOW_INSTRUCTIONS 0x0C Loading drivers/gpu/msm/adreno.c +116 −29 Original line number Diff line number Diff line Loading @@ -94,7 +94,21 @@ static struct adreno_device device_3d0 = { adreno_input_work), }; unsigned int ft_detect_regs[FT_DETECT_REGS_COUNT]; /* Ptr to array for the current set of fault detect registers */ unsigned int *adreno_ft_regs; /* Total number of fault detect registers */ unsigned int adreno_ft_regs_num; /* Ptr to array for the current fault detect registers values */ unsigned int *adreno_ft_regs_val; /* Array of default fault detect registers */ static unsigned int adreno_ft_regs_default[] = { ADRENO_REG_RBBM_STATUS, ADRENO_REG_CP_RB_RPTR, ADRENO_REG_CP_IB1_BASE, ADRENO_REG_CP_IB1_BUFSZ, ADRENO_REG_CP_IB2_BASE, ADRENO_REG_CP_IB2_BUFSZ }; static struct workqueue_struct *adreno_wq; Loading @@ -104,6 +118,86 @@ static unsigned int _wake_nice = -7; /* Number of milliseconds to stay active active after a wake on touch */ static unsigned int _wake_timeout = 100; static int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { int ret = 0; if (*lo == 0) { ret = adreno_perfcounter_get(adreno_dev, group, countable, lo, hi, PERFCOUNTER_FLAG_KERNEL); if (ret) { struct kgsl_device *device = &adreno_dev->dev; KGSL_DRV_ERR(device, "Unable to allocate fault detect performance counter %d/%d\n", group, countable); KGSL_DRV_ERR(device, "GPU fault detect will be less reliable\n"); } } return ret; } static inline void _put_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { if (*lo != 0) adreno_perfcounter_put(adreno_dev, group, countable, PERFCOUNTER_FLAG_KERNEL); *lo = 0; *hi = 0; } /** * adreno_fault_detect_start() - Allocate performance counters * used for fast fault detection * @adreno_dev: Pointer to an adreno_device structure * * Allocate the series of performance counters that should be periodically * checked to verify that the GPU is still moving */ void adreno_fault_detect_start(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned int i, j = ARRAY_SIZE(adreno_ft_regs_default); for (i = 0; i < gpudev->ft_perf_counters_count; i++) { _get_counter(adreno_dev, gpudev->ft_perf_counters[i].counter, gpudev->ft_perf_counters[i].countable, &adreno_ft_regs[j + (i * 2)], &adreno_ft_regs[j + ((i * 2) + 1)]); } } /** * adreno_fault_detect_stop() - Release performance counters * used for fast fault detection * @adreno_dev: Pointer to an adreno_device structure * * Release the counters allocated in adreno_fault_detect_start */ void adreno_fault_detect_stop(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned int i, j = ARRAY_SIZE(adreno_ft_regs_default); for (i = 0; i < gpudev->ft_perf_counters_count; i++) { _put_counter(adreno_dev, gpudev->ft_perf_counters[i].counter, gpudev->ft_perf_counters[i].countable, &adreno_ft_regs[j + (i * 2)], &adreno_ft_regs[j + ((i * 2) + 1)]); } } /* * A workqueue callback responsible for actually turning on the GPU after a * touch event. kgsl_pwrctrl_change_state(ACTIVE) is used without any Loading Loading @@ -1269,21 +1363,20 @@ static int adreno_init(struct kgsl_device *device) adreno_dev->gpucore->sync_lock_pfp_ver) >= 0)) device->mmu.flags |= KGSL_MMU_FLAGS_IOMMU_SYNC; /* Initialize ft detection register offsets */ ft_detect_regs[0] = adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS); ft_detect_regs[1] = adreno_getreg(adreno_dev, ADRENO_REG_CP_RB_RPTR); ft_detect_regs[2] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB1_BASE); ft_detect_regs[3] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB1_BUFSZ); ft_detect_regs[4] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB2_BASE); ft_detect_regs[5] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB2_BUFSZ); for (i = 6; i < FT_DETECT_REGS_COUNT; i++) ft_detect_regs[i] = 0; adreno_ft_regs_num = (ARRAY_SIZE(adreno_ft_regs_default) + gpudev->ft_perf_counters_count*2); adreno_ft_regs = kzalloc(adreno_ft_regs_num, GFP_KERNEL); if (!adreno_ft_regs) return -ENOMEM; adreno_ft_regs_val = kzalloc(adreno_ft_regs_num, GFP_KERNEL); if (!adreno_ft_regs_val) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(adreno_ft_regs_default); i++) adreno_ft_regs[i] = adreno_getreg(adreno_dev, adreno_ft_regs_default[i]); /* turn on hang interrupt for A4XX and a330v2 by default */ if ((adreno_is_a4xx(adreno_dev)) || (adreno_is_a330v2(adreno_dev))) Loading Loading @@ -1760,15 +1853,12 @@ static ssize_t _ft_fast_hang_detect_store(struct device *dev, if (tmp != adreno_dev->fast_hang_detect) { if (adreno_dev->fast_hang_detect) { if (gpudev->fault_detect_start && !kgsl_active_count_get(&adreno_dev->dev)) { gpudev->fault_detect_start(adreno_dev); if (kgsl_active_count_get(&adreno_dev->dev)) { adreno_fault_detect_start(adreno_dev); kgsl_active_count_put(&adreno_dev->dev); } } else { if (gpudev->fault_detect_stop) gpudev->fault_detect_stop(adreno_dev); } } else adreno_fault_detect_stop(adreno_dev); } mutex_unlock(&adreno_dev->dev.mutex); Loading Loading @@ -2345,7 +2435,6 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, int status = -EINVAL; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); switch (type) { case KGSL_PROP_PWRCTRL: { Loading @@ -2365,9 +2454,8 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, device->pwrctrl.ctrl_flags = 0; adreno_dev->fast_hang_detect = 1; if (gpudev->fault_detect_start && !kgsl_active_count_get(&adreno_dev->dev)) { gpudev->fault_detect_start(adreno_dev); if (!kgsl_active_count_get(&adreno_dev->dev)) { adreno_fault_detect_start(adreno_dev); kgsl_active_count_put(&adreno_dev->dev); } Loading @@ -2377,8 +2465,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, KGSL_STATE_ACTIVE); device->pwrctrl.ctrl_flags = KGSL_PWR_ON; adreno_dev->fast_hang_detect = 0; if (gpudev->fault_detect_stop) gpudev->fault_detect_stop(adreno_dev); adreno_fault_detect_stop(adreno_dev); kgsl_pwrscale_disable(device); } Loading drivers/gpu/msm/adreno.h +14 −6 Original line number Diff line number Diff line Loading @@ -591,6 +591,8 @@ struct adreno_gpudev { * so define them in the structure and use them as variables. */ const struct adreno_reg_offsets *reg_offsets; const struct adreno_ft_perf_counters *ft_perf_counters; unsigned int ft_perf_counters_count; struct adreno_perfcounters *perfcounters; const struct adreno_invalid_countables Loading @@ -612,8 +614,6 @@ struct adreno_gpudev { void (*perfcounter_close)(struct adreno_device *); void (*perfcounter_save)(struct adreno_device *); void (*perfcounter_restore)(struct adreno_device *); void (*fault_detect_start)(struct adreno_device *); void (*fault_detect_stop)(struct adreno_device *); void (*start)(struct adreno_device *); void (*busy_cycles)(struct adreno_device *, struct adreno_busy_data *); int (*perfcounter_enable)(struct adreno_device *, unsigned int group, Loading @@ -629,8 +629,6 @@ struct adreno_gpudev { void (*regulator_disable)(struct adreno_device *); }; #define FT_DETECT_REGS_COUNT 14 struct log_field { bool show; const char *display; Loading Loading @@ -678,6 +676,15 @@ struct log_field { (_i) < (_dev)->num_ringbuffers; \ (_i)++, (_rb)++) struct adreno_ft_perf_counters { unsigned int counter; unsigned int countable; }; extern unsigned int *adreno_ft_regs; extern unsigned int adreno_ft_regs_num; extern unsigned int *adreno_ft_regs_val; extern struct adreno_gpudev adreno_a3xx_gpudev; extern struct adreno_gpudev adreno_a4xx_gpudev; Loading Loading @@ -705,8 +712,6 @@ extern const struct adreno_vbif_snapshot_registers a4xx_vbif_snapshot_registers[]; extern const unsigned int a4xx_vbif_snapshot_reg_cnt; extern unsigned int ft_detect_regs[]; int adreno_spin_idle(struct kgsl_device *device); int adreno_idle(struct kgsl_device *device); bool adreno_isidle(struct kgsl_device *device); Loading Loading @@ -788,6 +793,9 @@ int adreno_iommu_set_pt(struct adreno_ringbuffer *rb, void adreno_iommu_set_pt_generate_rb_cmds(struct adreno_ringbuffer *rb, struct kgsl_pagetable *pt); void adreno_fault_detect_start(struct adreno_device *adreno_dev); void adreno_fault_detect_stop(struct adreno_device *adreno_dev); static inline int adreno_is_a3xx(struct adreno_device *adreno_dev) { return ((ADRENO_GPUREV(adreno_dev) >= 300) && Loading drivers/gpu/msm/adreno_a3xx.c +11 −93 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/sched.h> #include <linux/msm_kgsl.h> #include "kgsl.h" #include "adreno.h" Loading Loading @@ -2074,95 +2075,12 @@ static struct adreno_perfcounters a3xx_perfcounters = { ARRAY_SIZE(a3xx_perfcounter_groups), }; static inline int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { int ret = 0; if (*lo == 0) { ret = adreno_perfcounter_get(adreno_dev, group, countable, lo, hi, PERFCOUNTER_FLAG_KERNEL); if (ret) { struct kgsl_device *device = &adreno_dev->dev; KGSL_DRV_ERR(device, "Unable to allocate fault detect performance counter %d/%d\n", group, countable); KGSL_DRV_ERR(device, "GPU fault detect will be less reliable\n"); } } return ret; } static inline void _put_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { if (*lo != 0) { adreno_perfcounter_put(adreno_dev, group, countable, PERFCOUNTER_FLAG_KERNEL); } *lo = 0; *hi = 0; } /** * a3xx_fault_detect_start() - Allocate performance counters used for fast fault * detection * @adreno_dev: Pointer to an adreno_device structure * * Allocate the series of performance counters that should be periodically * checked to verify that the GPU is still moving */ void a3xx_fault_detect_start(struct adreno_device *adreno_dev) { _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES, &ft_detect_regs[6], &ft_detect_regs[7]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES, &ft_detect_regs[8], &ft_detect_regs[9]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS, &ft_detect_regs[10], &ft_detect_regs[11]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM, &ft_detect_regs[12], &ft_detect_regs[13]); } /** * a3xx_fault_detect_stop() - Release performance counters used for fast fault * detection * @adreno_dev: Pointer to an adreno_device structure * * Release the counters allocated in a3xx_fault_detect_start */ void a3xx_fault_detect_stop(struct adreno_device *adreno_dev) { _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES, &ft_detect_regs[6], &ft_detect_regs[7]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES, &ft_detect_regs[8], &ft_detect_regs[9]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS, &ft_detect_regs[10], &ft_detect_regs[11]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM, &ft_detect_regs[12], &ft_detect_regs[13]); } struct adreno_ft_perf_counters a3xx_ft_perf_counters[] = { {KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES}, {KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES}, {KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS}, {KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM}, }; /** * a3xx_perfcounter_close() - Put counters that were initialized in Loading @@ -2175,7 +2093,7 @@ void a3xx_perfcounter_close(struct adreno_device *adreno_dev) PERFCOUNTER_FLAG_KERNEL); if (adreno_dev->fast_hang_detect) a3xx_fault_detect_stop(adreno_dev); adreno_fault_detect_stop(adreno_dev); } /** Loading Loading @@ -2203,7 +2121,7 @@ int a3xx_perfcounter_init(struct adreno_device *adreno_dev) } if (adreno_dev->fast_hang_detect) a3xx_fault_detect_start(adreno_dev); adreno_fault_detect_start(adreno_dev); /* Turn on the GPU busy counter(s) and let them run free */ /* GPU busy counts */ Loading Loading @@ -2483,6 +2401,8 @@ static struct adreno_snapshot_data a3xx_snapshot_data = { struct adreno_gpudev adreno_a3xx_gpudev = { .reg_offsets = &a3xx_reg_offsets, .ft_perf_counters = a3xx_ft_perf_counters, .ft_perf_counters_count = ARRAY_SIZE(a3xx_ft_perf_counters), .perfcounters = &a3xx_perfcounters, .irq = &a3xx_irq, .snapshot_data = &a3xx_snapshot_data, Loading @@ -2503,7 +2423,5 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .perfcounter_enable = a3xx_perfcounter_enable, .perfcounter_read = a3xx_perfcounter_read, .perfcounter_write = a3xx_perfcounter_write, .fault_detect_start = a3xx_fault_detect_start, .fault_detect_stop = a3xx_fault_detect_stop, .coresight = &a3xx_coresight, }; drivers/gpu/msm/adreno_a3xx.h +0 −3 Original line number Diff line number Diff line Loading @@ -34,9 +34,6 @@ void a3xx_a4xx_err_callback(struct adreno_device *adreno_dev, int bit); void a3xx_fatal_err_callback(struct adreno_device *adreno_dev, int bit); void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq); void a3xx_fault_detect_start(struct adreno_device *adreno_dev); void a3xx_fault_detect_stop(struct adreno_device *adreno_dev); void a3xx_snapshot(struct adreno_device *adreno_dev, struct kgsl_snapshot *snapshot); #endif /*__A3XX_H */ Loading
drivers/gpu/msm/a3xx_reg.h +0 −1 Original line number Diff line number Diff line Loading @@ -883,7 +883,6 @@ #define A310_RBBM_GPR0_CTL_DEFAULT 0x000000AA /* COUNTABLE FOR SP PERFCOUNTER */ #define SP_FS_FULL_ALU_INSTRUCTIONS 0x0E #define SP_ALU_ACTIVE_CYCLES 0x1D #define SP0_ICL1_MISSES 0x1A #define SP_FS_CFLOW_INSTRUCTIONS 0x0C Loading
drivers/gpu/msm/adreno.c +116 −29 Original line number Diff line number Diff line Loading @@ -94,7 +94,21 @@ static struct adreno_device device_3d0 = { adreno_input_work), }; unsigned int ft_detect_regs[FT_DETECT_REGS_COUNT]; /* Ptr to array for the current set of fault detect registers */ unsigned int *adreno_ft_regs; /* Total number of fault detect registers */ unsigned int adreno_ft_regs_num; /* Ptr to array for the current fault detect registers values */ unsigned int *adreno_ft_regs_val; /* Array of default fault detect registers */ static unsigned int adreno_ft_regs_default[] = { ADRENO_REG_RBBM_STATUS, ADRENO_REG_CP_RB_RPTR, ADRENO_REG_CP_IB1_BASE, ADRENO_REG_CP_IB1_BUFSZ, ADRENO_REG_CP_IB2_BASE, ADRENO_REG_CP_IB2_BUFSZ }; static struct workqueue_struct *adreno_wq; Loading @@ -104,6 +118,86 @@ static unsigned int _wake_nice = -7; /* Number of milliseconds to stay active active after a wake on touch */ static unsigned int _wake_timeout = 100; static int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { int ret = 0; if (*lo == 0) { ret = adreno_perfcounter_get(adreno_dev, group, countable, lo, hi, PERFCOUNTER_FLAG_KERNEL); if (ret) { struct kgsl_device *device = &adreno_dev->dev; KGSL_DRV_ERR(device, "Unable to allocate fault detect performance counter %d/%d\n", group, countable); KGSL_DRV_ERR(device, "GPU fault detect will be less reliable\n"); } } return ret; } static inline void _put_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { if (*lo != 0) adreno_perfcounter_put(adreno_dev, group, countable, PERFCOUNTER_FLAG_KERNEL); *lo = 0; *hi = 0; } /** * adreno_fault_detect_start() - Allocate performance counters * used for fast fault detection * @adreno_dev: Pointer to an adreno_device structure * * Allocate the series of performance counters that should be periodically * checked to verify that the GPU is still moving */ void adreno_fault_detect_start(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned int i, j = ARRAY_SIZE(adreno_ft_regs_default); for (i = 0; i < gpudev->ft_perf_counters_count; i++) { _get_counter(adreno_dev, gpudev->ft_perf_counters[i].counter, gpudev->ft_perf_counters[i].countable, &adreno_ft_regs[j + (i * 2)], &adreno_ft_regs[j + ((i * 2) + 1)]); } } /** * adreno_fault_detect_stop() - Release performance counters * used for fast fault detection * @adreno_dev: Pointer to an adreno_device structure * * Release the counters allocated in adreno_fault_detect_start */ void adreno_fault_detect_stop(struct adreno_device *adreno_dev) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned int i, j = ARRAY_SIZE(adreno_ft_regs_default); for (i = 0; i < gpudev->ft_perf_counters_count; i++) { _put_counter(adreno_dev, gpudev->ft_perf_counters[i].counter, gpudev->ft_perf_counters[i].countable, &adreno_ft_regs[j + (i * 2)], &adreno_ft_regs[j + ((i * 2) + 1)]); } } /* * A workqueue callback responsible for actually turning on the GPU after a * touch event. kgsl_pwrctrl_change_state(ACTIVE) is used without any Loading Loading @@ -1269,21 +1363,20 @@ static int adreno_init(struct kgsl_device *device) adreno_dev->gpucore->sync_lock_pfp_ver) >= 0)) device->mmu.flags |= KGSL_MMU_FLAGS_IOMMU_SYNC; /* Initialize ft detection register offsets */ ft_detect_regs[0] = adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS); ft_detect_regs[1] = adreno_getreg(adreno_dev, ADRENO_REG_CP_RB_RPTR); ft_detect_regs[2] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB1_BASE); ft_detect_regs[3] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB1_BUFSZ); ft_detect_regs[4] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB2_BASE); ft_detect_regs[5] = adreno_getreg(adreno_dev, ADRENO_REG_CP_IB2_BUFSZ); for (i = 6; i < FT_DETECT_REGS_COUNT; i++) ft_detect_regs[i] = 0; adreno_ft_regs_num = (ARRAY_SIZE(adreno_ft_regs_default) + gpudev->ft_perf_counters_count*2); adreno_ft_regs = kzalloc(adreno_ft_regs_num, GFP_KERNEL); if (!adreno_ft_regs) return -ENOMEM; adreno_ft_regs_val = kzalloc(adreno_ft_regs_num, GFP_KERNEL); if (!adreno_ft_regs_val) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(adreno_ft_regs_default); i++) adreno_ft_regs[i] = adreno_getreg(adreno_dev, adreno_ft_regs_default[i]); /* turn on hang interrupt for A4XX and a330v2 by default */ if ((adreno_is_a4xx(adreno_dev)) || (adreno_is_a330v2(adreno_dev))) Loading Loading @@ -1760,15 +1853,12 @@ static ssize_t _ft_fast_hang_detect_store(struct device *dev, if (tmp != adreno_dev->fast_hang_detect) { if (adreno_dev->fast_hang_detect) { if (gpudev->fault_detect_start && !kgsl_active_count_get(&adreno_dev->dev)) { gpudev->fault_detect_start(adreno_dev); if (kgsl_active_count_get(&adreno_dev->dev)) { adreno_fault_detect_start(adreno_dev); kgsl_active_count_put(&adreno_dev->dev); } } else { if (gpudev->fault_detect_stop) gpudev->fault_detect_stop(adreno_dev); } } else adreno_fault_detect_stop(adreno_dev); } mutex_unlock(&adreno_dev->dev.mutex); Loading Loading @@ -2345,7 +2435,6 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, int status = -EINVAL; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); switch (type) { case KGSL_PROP_PWRCTRL: { Loading @@ -2365,9 +2454,8 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, device->pwrctrl.ctrl_flags = 0; adreno_dev->fast_hang_detect = 1; if (gpudev->fault_detect_start && !kgsl_active_count_get(&adreno_dev->dev)) { gpudev->fault_detect_start(adreno_dev); if (!kgsl_active_count_get(&adreno_dev->dev)) { adreno_fault_detect_start(adreno_dev); kgsl_active_count_put(&adreno_dev->dev); } Loading @@ -2377,8 +2465,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, KGSL_STATE_ACTIVE); device->pwrctrl.ctrl_flags = KGSL_PWR_ON; adreno_dev->fast_hang_detect = 0; if (gpudev->fault_detect_stop) gpudev->fault_detect_stop(adreno_dev); adreno_fault_detect_stop(adreno_dev); kgsl_pwrscale_disable(device); } Loading
drivers/gpu/msm/adreno.h +14 −6 Original line number Diff line number Diff line Loading @@ -591,6 +591,8 @@ struct adreno_gpudev { * so define them in the structure and use them as variables. */ const struct adreno_reg_offsets *reg_offsets; const struct adreno_ft_perf_counters *ft_perf_counters; unsigned int ft_perf_counters_count; struct adreno_perfcounters *perfcounters; const struct adreno_invalid_countables Loading @@ -612,8 +614,6 @@ struct adreno_gpudev { void (*perfcounter_close)(struct adreno_device *); void (*perfcounter_save)(struct adreno_device *); void (*perfcounter_restore)(struct adreno_device *); void (*fault_detect_start)(struct adreno_device *); void (*fault_detect_stop)(struct adreno_device *); void (*start)(struct adreno_device *); void (*busy_cycles)(struct adreno_device *, struct adreno_busy_data *); int (*perfcounter_enable)(struct adreno_device *, unsigned int group, Loading @@ -629,8 +629,6 @@ struct adreno_gpudev { void (*regulator_disable)(struct adreno_device *); }; #define FT_DETECT_REGS_COUNT 14 struct log_field { bool show; const char *display; Loading Loading @@ -678,6 +676,15 @@ struct log_field { (_i) < (_dev)->num_ringbuffers; \ (_i)++, (_rb)++) struct adreno_ft_perf_counters { unsigned int counter; unsigned int countable; }; extern unsigned int *adreno_ft_regs; extern unsigned int adreno_ft_regs_num; extern unsigned int *adreno_ft_regs_val; extern struct adreno_gpudev adreno_a3xx_gpudev; extern struct adreno_gpudev adreno_a4xx_gpudev; Loading Loading @@ -705,8 +712,6 @@ extern const struct adreno_vbif_snapshot_registers a4xx_vbif_snapshot_registers[]; extern const unsigned int a4xx_vbif_snapshot_reg_cnt; extern unsigned int ft_detect_regs[]; int adreno_spin_idle(struct kgsl_device *device); int adreno_idle(struct kgsl_device *device); bool adreno_isidle(struct kgsl_device *device); Loading Loading @@ -788,6 +793,9 @@ int adreno_iommu_set_pt(struct adreno_ringbuffer *rb, void adreno_iommu_set_pt_generate_rb_cmds(struct adreno_ringbuffer *rb, struct kgsl_pagetable *pt); void adreno_fault_detect_start(struct adreno_device *adreno_dev); void adreno_fault_detect_stop(struct adreno_device *adreno_dev); static inline int adreno_is_a3xx(struct adreno_device *adreno_dev) { return ((ADRENO_GPUREV(adreno_dev) >= 300) && Loading
drivers/gpu/msm/adreno_a3xx.c +11 −93 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/sched.h> #include <linux/msm_kgsl.h> #include "kgsl.h" #include "adreno.h" Loading Loading @@ -2074,95 +2075,12 @@ static struct adreno_perfcounters a3xx_perfcounters = { ARRAY_SIZE(a3xx_perfcounter_groups), }; static inline int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { int ret = 0; if (*lo == 0) { ret = adreno_perfcounter_get(adreno_dev, group, countable, lo, hi, PERFCOUNTER_FLAG_KERNEL); if (ret) { struct kgsl_device *device = &adreno_dev->dev; KGSL_DRV_ERR(device, "Unable to allocate fault detect performance counter %d/%d\n", group, countable); KGSL_DRV_ERR(device, "GPU fault detect will be less reliable\n"); } } return ret; } static inline void _put_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) { if (*lo != 0) { adreno_perfcounter_put(adreno_dev, group, countable, PERFCOUNTER_FLAG_KERNEL); } *lo = 0; *hi = 0; } /** * a3xx_fault_detect_start() - Allocate performance counters used for fast fault * detection * @adreno_dev: Pointer to an adreno_device structure * * Allocate the series of performance counters that should be periodically * checked to verify that the GPU is still moving */ void a3xx_fault_detect_start(struct adreno_device *adreno_dev) { _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES, &ft_detect_regs[6], &ft_detect_regs[7]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES, &ft_detect_regs[8], &ft_detect_regs[9]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS, &ft_detect_regs[10], &ft_detect_regs[11]); _get_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM, &ft_detect_regs[12], &ft_detect_regs[13]); } /** * a3xx_fault_detect_stop() - Release performance counters used for fast fault * detection * @adreno_dev: Pointer to an adreno_device structure * * Release the counters allocated in a3xx_fault_detect_start */ void a3xx_fault_detect_stop(struct adreno_device *adreno_dev) { _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES, &ft_detect_regs[6], &ft_detect_regs[7]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES, &ft_detect_regs[8], &ft_detect_regs[9]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS, &ft_detect_regs[10], &ft_detect_regs[11]); _put_counter(adreno_dev, KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM, &ft_detect_regs[12], &ft_detect_regs[13]); } struct adreno_ft_perf_counters a3xx_ft_perf_counters[] = { {KGSL_PERFCOUNTER_GROUP_SP, SP_ALU_ACTIVE_CYCLES}, {KGSL_PERFCOUNTER_GROUP_SP, SP0_ICL1_MISSES}, {KGSL_PERFCOUNTER_GROUP_SP, SP_FS_CFLOW_INSTRUCTIONS}, {KGSL_PERFCOUNTER_GROUP_TSE, TSE_INPUT_PRIM_NUM}, }; /** * a3xx_perfcounter_close() - Put counters that were initialized in Loading @@ -2175,7 +2093,7 @@ void a3xx_perfcounter_close(struct adreno_device *adreno_dev) PERFCOUNTER_FLAG_KERNEL); if (adreno_dev->fast_hang_detect) a3xx_fault_detect_stop(adreno_dev); adreno_fault_detect_stop(adreno_dev); } /** Loading Loading @@ -2203,7 +2121,7 @@ int a3xx_perfcounter_init(struct adreno_device *adreno_dev) } if (adreno_dev->fast_hang_detect) a3xx_fault_detect_start(adreno_dev); adreno_fault_detect_start(adreno_dev); /* Turn on the GPU busy counter(s) and let them run free */ /* GPU busy counts */ Loading Loading @@ -2483,6 +2401,8 @@ static struct adreno_snapshot_data a3xx_snapshot_data = { struct adreno_gpudev adreno_a3xx_gpudev = { .reg_offsets = &a3xx_reg_offsets, .ft_perf_counters = a3xx_ft_perf_counters, .ft_perf_counters_count = ARRAY_SIZE(a3xx_ft_perf_counters), .perfcounters = &a3xx_perfcounters, .irq = &a3xx_irq, .snapshot_data = &a3xx_snapshot_data, Loading @@ -2503,7 +2423,5 @@ struct adreno_gpudev adreno_a3xx_gpudev = { .perfcounter_enable = a3xx_perfcounter_enable, .perfcounter_read = a3xx_perfcounter_read, .perfcounter_write = a3xx_perfcounter_write, .fault_detect_start = a3xx_fault_detect_start, .fault_detect_stop = a3xx_fault_detect_stop, .coresight = &a3xx_coresight, };
drivers/gpu/msm/adreno_a3xx.h +0 −3 Original line number Diff line number Diff line Loading @@ -34,9 +34,6 @@ void a3xx_a4xx_err_callback(struct adreno_device *adreno_dev, int bit); void a3xx_fatal_err_callback(struct adreno_device *adreno_dev, int bit); void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq); void a3xx_fault_detect_start(struct adreno_device *adreno_dev); void a3xx_fault_detect_stop(struct adreno_device *adreno_dev); void a3xx_snapshot(struct adreno_device *adreno_dev, struct kgsl_snapshot *snapshot); #endif /*__A3XX_H */