Loading Documentation/devicetree/bindings/gpu/adreno.txt +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ Required properties: - qcom,gpu-efuse-leakage: memory region for GPU power rail leakage. - qcom,base-leakage-coefficient: Dynamic leakage coefficient. - qcom,lm-limit: Current limit for GPU limit management. Bus Scaling Data: - qcom,msm-bus,name: String property to describe the name of the 3D graphics processor. Loading arch/arm/boot/dts/qcom/msm8996-gpu.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ qcom,chipid = <0x05030000>; qcom,gpu-efuse-leakage = <0x00070130 24>; qcom,base-leakage-coefficient = <34>; qcom,lm-limit = <6000>; qcom,initial-pwrlevel = <2>; Loading drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,7 @@ struct adreno_gpu_core { * @lm_fw: The LM firmware handle * @lm_sequence: Pointer to the start of the register write sequence for LM * @lm_size: The dword size of the LM sequence * @lm_limit: limiting value for LM */ struct adreno_device { struct kgsl_device dev; /* Must be first field in this struct */ Loading Loading @@ -341,6 +342,7 @@ struct adreno_device { struct kgsl_memdesc preemption_counters; struct work_struct gpmu_work; uint32_t lm_leakage; uint32_t lm_limit; struct kgsl_memdesc capturescript; struct kgsl_memdesc snapshot_registers; Loading drivers/gpu/msm/adreno_a5xx.c +17 −1 Original line number Diff line number Diff line Loading @@ -104,6 +104,8 @@ static int _read_fw2_block_header(uint32_t *header, uint32_t id, #define AGC_POWER_CONFIG_PRODUCTION_ID 1 #define GFX_DEFAULT_LEAKAGE 0x004E001A #define LM_DEFAULT_LIMIT 6000 /* * a5xx_preemption_start() - Setup state to start preemption Loading Loading @@ -1379,6 +1381,19 @@ static uint32_t gfx_base_leakage(struct adreno_device *adreno_dev) return adreno_dev->lm_leakage; } static uint32_t lm_limit(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; if (adreno_dev->lm_limit) return adreno_dev->lm_limit; if (of_property_read_u32(device->pdev->dev.of_node, "qcom,lm-limit", &adreno_dev->lm_limit)) adreno_dev->lm_limit = LM_DEFAULT_LIMIT; return adreno_dev->lm_limit; } /* * a5xx_lm_init() - Initialize LM/DPM on the GPMU * @adreno_dev: The adreno device pointer Loading Loading @@ -1418,7 +1433,8 @@ static void a5xx_lm_init(struct adreno_device *adreno_dev) gfx_base_leakage(adreno_dev)); /* Enable the power threshold and set it to 6000m */ kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000); kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | lm_limit(adreno_dev)); kgsl_regwrite(device, A5XX_GPMU_BEC_ENABLE, 0x10001FFF); kgsl_regwrite(device, A5XX_GDPM_CONFIG1, 0x00201FF1); Loading drivers/gpu/msm/adreno_debugfs.c +44 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,46 @@ static int _isdb_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n"); static int _lm_limit_set(void *data, u64 val) { struct kgsl_device *device = data; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return 0; /* assure value is between 3A and 10A */ if (val > 10000) val = 10000; else if (val < 3000) val = 3000; adreno_dev->lm_limit = val; if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) { mutex_lock(&device->mutex); kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); mutex_unlock(&device->mutex); } return 0; } static int _lm_limit_get(void *data, u64 *val) { struct kgsl_device *device = data; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) *val = 0; *val = (u64) adreno_dev->lm_limit; return 0; } DEFINE_SIMPLE_ATTRIBUTE(_lm_limit_fops, _lm_limit_get, _lm_limit_set, "%llu\n"); static int _active_count_get(void *data, u64 *val) { struct kgsl_device *device = data; Loading Loading @@ -308,6 +348,10 @@ void adreno_debugfs_init(struct adreno_device *adreno_dev) adreno_dev->ctx_d_debugfs = debugfs_create_dir("ctx", device->d_debugfs); if (ADRENO_FEATURE(adreno_dev, ADRENO_LM)) debugfs_create_file("lm_limit", 0644, device->d_debugfs, device, &_lm_limit_fops); if (adreno_is_a5xx(adreno_dev)) debugfs_create_file("isdb", 0644, device->d_debugfs, device, &_isdb_fops); Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ Required properties: - qcom,gpu-efuse-leakage: memory region for GPU power rail leakage. - qcom,base-leakage-coefficient: Dynamic leakage coefficient. - qcom,lm-limit: Current limit for GPU limit management. Bus Scaling Data: - qcom,msm-bus,name: String property to describe the name of the 3D graphics processor. Loading
arch/arm/boot/dts/qcom/msm8996-gpu.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ qcom,chipid = <0x05030000>; qcom,gpu-efuse-leakage = <0x00070130 24>; qcom,base-leakage-coefficient = <34>; qcom,lm-limit = <6000>; qcom,initial-pwrlevel = <2>; Loading
drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,7 @@ struct adreno_gpu_core { * @lm_fw: The LM firmware handle * @lm_sequence: Pointer to the start of the register write sequence for LM * @lm_size: The dword size of the LM sequence * @lm_limit: limiting value for LM */ struct adreno_device { struct kgsl_device dev; /* Must be first field in this struct */ Loading Loading @@ -341,6 +342,7 @@ struct adreno_device { struct kgsl_memdesc preemption_counters; struct work_struct gpmu_work; uint32_t lm_leakage; uint32_t lm_limit; struct kgsl_memdesc capturescript; struct kgsl_memdesc snapshot_registers; Loading
drivers/gpu/msm/adreno_a5xx.c +17 −1 Original line number Diff line number Diff line Loading @@ -104,6 +104,8 @@ static int _read_fw2_block_header(uint32_t *header, uint32_t id, #define AGC_POWER_CONFIG_PRODUCTION_ID 1 #define GFX_DEFAULT_LEAKAGE 0x004E001A #define LM_DEFAULT_LIMIT 6000 /* * a5xx_preemption_start() - Setup state to start preemption Loading Loading @@ -1379,6 +1381,19 @@ static uint32_t gfx_base_leakage(struct adreno_device *adreno_dev) return adreno_dev->lm_leakage; } static uint32_t lm_limit(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; if (adreno_dev->lm_limit) return adreno_dev->lm_limit; if (of_property_read_u32(device->pdev->dev.of_node, "qcom,lm-limit", &adreno_dev->lm_limit)) adreno_dev->lm_limit = LM_DEFAULT_LIMIT; return adreno_dev->lm_limit; } /* * a5xx_lm_init() - Initialize LM/DPM on the GPMU * @adreno_dev: The adreno device pointer Loading Loading @@ -1418,7 +1433,8 @@ static void a5xx_lm_init(struct adreno_device *adreno_dev) gfx_base_leakage(adreno_dev)); /* Enable the power threshold and set it to 6000m */ kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000); kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | lm_limit(adreno_dev)); kgsl_regwrite(device, A5XX_GPMU_BEC_ENABLE, 0x10001FFF); kgsl_regwrite(device, A5XX_GDPM_CONFIG1, 0x00201FF1); Loading
drivers/gpu/msm/adreno_debugfs.c +44 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,46 @@ static int _isdb_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n"); static int _lm_limit_set(void *data, u64 val) { struct kgsl_device *device = data; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return 0; /* assure value is between 3A and 10A */ if (val > 10000) val = 10000; else if (val < 3000) val = 3000; adreno_dev->lm_limit = val; if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) { mutex_lock(&device->mutex); kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); mutex_unlock(&device->mutex); } return 0; } static int _lm_limit_get(void *data, u64 *val) { struct kgsl_device *device = data; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) *val = 0; *val = (u64) adreno_dev->lm_limit; return 0; } DEFINE_SIMPLE_ATTRIBUTE(_lm_limit_fops, _lm_limit_get, _lm_limit_set, "%llu\n"); static int _active_count_get(void *data, u64 *val) { struct kgsl_device *device = data; Loading Loading @@ -308,6 +348,10 @@ void adreno_debugfs_init(struct adreno_device *adreno_dev) adreno_dev->ctx_d_debugfs = debugfs_create_dir("ctx", device->d_debugfs); if (ADRENO_FEATURE(adreno_dev, ADRENO_LM)) debugfs_create_file("lm_limit", 0644, device->d_debugfs, device, &_lm_limit_fops); if (adreno_is_a5xx(adreno_dev)) debugfs_create_file("isdb", 0644, device->d_debugfs, device, &_isdb_fops); Loading