Loading drivers/gpu/msm/adreno.c +4 −1 Original line number Diff line number Diff line Loading @@ -3574,7 +3574,7 @@ static void adreno_power_stats(struct kgsl_device *device, struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_busy_data *busy = &adreno_dev->busy_data; uint64_t adj = 0; int64_t adj = 0; memset(stats, 0, sizeof(*stats)); Loading @@ -3587,6 +3587,9 @@ static void adreno_power_stats(struct kgsl_device *device, if (gpudev->read_throttling_counters) { adj = gpudev->read_throttling_counters(adreno_dev); if (adj < 0 && -adj > gpu_busy) adj = -gpu_busy; gpu_busy += adj; } Loading drivers/gpu/msm/adreno.h +1 −1 Original line number Diff line number Diff line Loading @@ -967,7 +967,7 @@ struct adreno_gpudev { void (*pwrlevel_change_settings)(struct adreno_device *, unsigned int prelevel, unsigned int postlevel, bool post); uint64_t (*read_throttling_counters)(struct adreno_device *); int64_t (*read_throttling_counters)(struct adreno_device *); void (*count_throttles)(struct adreno_device *, uint64_t adj); int (*enable_pwr_counters)(struct adreno_device *, unsigned int counter); Loading drivers/gpu/msm/adreno_a5xx.c +3 −2 Original line number Diff line number Diff line Loading @@ -1688,9 +1688,10 @@ static int a5xx_enable_pwr_counters(struct adreno_device *adreno_dev, /* number of cycles when clock is throttle by less than 50% (CRC) */ #define CRC_LESS50PCT 3 static uint64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev) static int64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i, adj; int i; int64_t adj; uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; Loading drivers/gpu/msm/adreno_a6xx.c +32 −0 Original line number Diff line number Diff line Loading @@ -1414,6 +1414,37 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev) return 0; } static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i; int64_t adj = 0; uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; for (i = 0; i < ARRAY_SIZE(counts); i++) { if (!adreno_dev->gpmu_throttle_counters[i]) counts[i] = 0; else counts[i] = counter_delta(KGSL_DEVICE(adreno_dev), adreno_dev->gpmu_throttle_counters[i], &busy->throttle_cycles[i]); } /* * The adjustment is the number of cycles lost to throttling, which * is calculated as a weighted average of the cycles throttled * at 10%, 50%, and 90%. The adjustment is negative because in A6XX, * the busy count includes the throttled cycles. Therefore, we want * to remove them to prevent appearing to be busier than * we actually are. */ adj = -((counts[0] * 1) + (counts[1] * 5) + (counts[2] * 9)) / 10; trace_kgsl_clock_throttling(0, counts[1], counts[2], counts[0], adj); return adj; } static void a6xx_count_throttles(struct adreno_device *adreno_dev, uint64_t adj) { Loading Loading @@ -2951,6 +2982,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .regulator_disable = a6xx_sptprac_disable, .perfcounters = &a6xx_perfcounters, .enable_pwr_counters = a6xx_enable_pwr_counters, .read_throttling_counters = a6xx_read_throttling_counters, .count_throttles = a6xx_count_throttles, .microcode_read = a6xx_microcode_read, .enable_64bit = a6xx_enable_64bit, Loading drivers/gpu/msm/adreno_a6xx_gmu.c +37 −0 Original line number Diff line number Diff line Loading @@ -1259,6 +1259,37 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev) return adreno_dev->lm_limit; } static int a640_throttling_counters[ADRENO_GPMU_THROTTLE_COUNTERS] = { 0x11, 0x15, 0x19 }; static void _setup_throttling_counters(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); int i, ret; for (i = 0; i < ARRAY_SIZE(a640_throttling_counters); i++) { adreno_dev->busy_data.throttle_cycles[i] = 0; if (!a640_throttling_counters[i]) continue; if (adreno_dev->gpmu_throttle_counters[i]) continue; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, a640_throttling_counters[i], &adreno_dev->gpmu_throttle_counters[i], NULL, PERFCOUNTER_FLAG_KERNEL); if (ret) dev_err_once(&gmu->pdev->dev, "Unable to get counter for LM: GPMU_PWR %d\n", a640_throttling_counters[i]); } } #define LIMITS_CONFIG(t, s, c, i, a) ( \ (t & 0xF) | \ ((s & 0xF) << 4) | \ Loading @@ -1278,6 +1309,12 @@ void a6xx_gmu_enable_lm(struct kgsl_device *device) !test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) return; /* a640 only needs to set up throttling counters for DCVS */ if (adreno_is_a640(adreno_dev)) { _setup_throttling_counters(adreno_dev); return; } gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_THRESHOLD, GPU_LIMIT_THRESHOLD_ENABLE | lm_limit(adreno_dev)); gmu_core_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1); Loading Loading
drivers/gpu/msm/adreno.c +4 −1 Original line number Diff line number Diff line Loading @@ -3574,7 +3574,7 @@ static void adreno_power_stats(struct kgsl_device *device, struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_busy_data *busy = &adreno_dev->busy_data; uint64_t adj = 0; int64_t adj = 0; memset(stats, 0, sizeof(*stats)); Loading @@ -3587,6 +3587,9 @@ static void adreno_power_stats(struct kgsl_device *device, if (gpudev->read_throttling_counters) { adj = gpudev->read_throttling_counters(adreno_dev); if (adj < 0 && -adj > gpu_busy) adj = -gpu_busy; gpu_busy += adj; } Loading
drivers/gpu/msm/adreno.h +1 −1 Original line number Diff line number Diff line Loading @@ -967,7 +967,7 @@ struct adreno_gpudev { void (*pwrlevel_change_settings)(struct adreno_device *, unsigned int prelevel, unsigned int postlevel, bool post); uint64_t (*read_throttling_counters)(struct adreno_device *); int64_t (*read_throttling_counters)(struct adreno_device *); void (*count_throttles)(struct adreno_device *, uint64_t adj); int (*enable_pwr_counters)(struct adreno_device *, unsigned int counter); Loading
drivers/gpu/msm/adreno_a5xx.c +3 −2 Original line number Diff line number Diff line Loading @@ -1688,9 +1688,10 @@ static int a5xx_enable_pwr_counters(struct adreno_device *adreno_dev, /* number of cycles when clock is throttle by less than 50% (CRC) */ #define CRC_LESS50PCT 3 static uint64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev) static int64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i, adj; int i; int64_t adj; uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; Loading
drivers/gpu/msm/adreno_a6xx.c +32 −0 Original line number Diff line number Diff line Loading @@ -1414,6 +1414,37 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev) return 0; } static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i; int64_t adj = 0; uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; for (i = 0; i < ARRAY_SIZE(counts); i++) { if (!adreno_dev->gpmu_throttle_counters[i]) counts[i] = 0; else counts[i] = counter_delta(KGSL_DEVICE(adreno_dev), adreno_dev->gpmu_throttle_counters[i], &busy->throttle_cycles[i]); } /* * The adjustment is the number of cycles lost to throttling, which * is calculated as a weighted average of the cycles throttled * at 10%, 50%, and 90%. The adjustment is negative because in A6XX, * the busy count includes the throttled cycles. Therefore, we want * to remove them to prevent appearing to be busier than * we actually are. */ adj = -((counts[0] * 1) + (counts[1] * 5) + (counts[2] * 9)) / 10; trace_kgsl_clock_throttling(0, counts[1], counts[2], counts[0], adj); return adj; } static void a6xx_count_throttles(struct adreno_device *adreno_dev, uint64_t adj) { Loading Loading @@ -2951,6 +2982,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .regulator_disable = a6xx_sptprac_disable, .perfcounters = &a6xx_perfcounters, .enable_pwr_counters = a6xx_enable_pwr_counters, .read_throttling_counters = a6xx_read_throttling_counters, .count_throttles = a6xx_count_throttles, .microcode_read = a6xx_microcode_read, .enable_64bit = a6xx_enable_64bit, Loading
drivers/gpu/msm/adreno_a6xx_gmu.c +37 −0 Original line number Diff line number Diff line Loading @@ -1259,6 +1259,37 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev) return adreno_dev->lm_limit; } static int a640_throttling_counters[ADRENO_GPMU_THROTTLE_COUNTERS] = { 0x11, 0x15, 0x19 }; static void _setup_throttling_counters(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); int i, ret; for (i = 0; i < ARRAY_SIZE(a640_throttling_counters); i++) { adreno_dev->busy_data.throttle_cycles[i] = 0; if (!a640_throttling_counters[i]) continue; if (adreno_dev->gpmu_throttle_counters[i]) continue; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, a640_throttling_counters[i], &adreno_dev->gpmu_throttle_counters[i], NULL, PERFCOUNTER_FLAG_KERNEL); if (ret) dev_err_once(&gmu->pdev->dev, "Unable to get counter for LM: GPMU_PWR %d\n", a640_throttling_counters[i]); } } #define LIMITS_CONFIG(t, s, c, i, a) ( \ (t & 0xF) | \ ((s & 0xF) << 4) | \ Loading @@ -1278,6 +1309,12 @@ void a6xx_gmu_enable_lm(struct kgsl_device *device) !test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) return; /* a640 only needs to set up throttling counters for DCVS */ if (adreno_is_a640(adreno_dev)) { _setup_throttling_counters(adreno_dev); return; } gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_THRESHOLD, GPU_LIMIT_THRESHOLD_ENABLE | lm_limit(adreno_dev)); gmu_core_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1); Loading