Loading drivers/gpu/msm/kgsl_gmu.c +28 −4 Original line number Original line Diff line number Diff line Loading @@ -1372,6 +1372,31 @@ static void gmu_snapshot(struct kgsl_device *device) gmu->fault_count++; gmu->fault_count++; } } static void gmu_change_gpu_pwrlevel(struct kgsl_device *device, unsigned int new_level) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; unsigned int old_level = pwr->active_pwrlevel; /* * Update the level according to any thermal, * max/min, or power constraints. */ new_level = kgsl_pwrctrl_adjust_pwrlevel(device, new_level); /* * If thermal cycling is required and the new level hits the * thermal limit, kick off the cycling. */ kgsl_pwrctrl_set_thermal_cycle(device, new_level); pwr->active_pwrlevel = new_level; pwr->previous_pwrlevel = old_level; /* Request adjusted DCVS level */ kgsl_clk_set_rate(device, pwr->active_pwrlevel); } /* To be called to power on both GPU and GMU */ /* To be called to power on both GPU and GMU */ int gmu_start(struct kgsl_device *device) int gmu_start(struct kgsl_device *device) { { Loading Loading @@ -1406,8 +1431,7 @@ int gmu_start(struct kgsl_device *device) goto error_gmu; goto error_gmu; /* Request default DCVS level */ /* Request default DCVS level */ kgsl_pwrctrl_pwrlevel_change(device, pwr->default_pwrlevel); gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); msm_bus_scale_client_update_request(gmu->pcl, 0); msm_bus_scale_client_update_request(gmu->pcl, 0); break; break; Loading @@ -1426,7 +1450,7 @@ int gmu_start(struct kgsl_device *device) if (ret) if (ret) goto error_gmu; goto error_gmu; kgsl_pwrctrl_pwrlevel_change(device, pwr->default_pwrlevel); gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); break; break; case KGSL_STATE_RESET: case KGSL_STATE_RESET: Loading @@ -1448,7 +1472,7 @@ int gmu_start(struct kgsl_device *device) goto error_gmu; goto error_gmu; /* Send DCVS level prior to reset*/ /* Send DCVS level prior to reset*/ kgsl_pwrctrl_pwrlevel_change(device, gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); pwr->default_pwrlevel); } else { } else { /* GMU fast boot */ /* GMU fast boot */ Loading drivers/gpu/msm/kgsl_pwrctrl.c +31 −17 Original line number Original line Diff line number Diff line Loading @@ -233,7 +233,7 @@ static int kgsl_bus_scale_request(struct kgsl_device *device, * @device: Pointer to the kgsl_device struct * @device: Pointer to the kgsl_device struct * @pwrlevel: power level in pwrlevels[] table * @pwrlevel: power level in pwrlevels[] table */ */ static int kgsl_clk_set_rate(struct kgsl_device *device, int kgsl_clk_set_rate(struct kgsl_device *device, unsigned int pwrlevel) unsigned int pwrlevel) { { struct gmu_device *gmu = &device->gmu; struct gmu_device *gmu = &device->gmu; Loading Loading @@ -344,12 +344,14 @@ static void kgsl_pwrctrl_pwrlevel_change_settings(struct kgsl_device *device, /** /** * kgsl_pwrctrl_set_thermal_cycle() - set the thermal cycle if required * kgsl_pwrctrl_set_thermal_cycle() - set the thermal cycle if required * @pwr: Pointer to the kgsl_pwrctrl struct * @device: Pointer to the kgsl_device struct * @new_level: the level to transition to * @new_level: the level to transition to */ */ static void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_pwrctrl *pwr, void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_device *device, unsigned int new_level) unsigned int new_level) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; if ((new_level != pwr->thermal_pwrlevel) || !pwr->sysfs_pwr_limit) if ((new_level != pwr->thermal_pwrlevel) || !pwr->sysfs_pwr_limit) return; return; if (pwr->thermal_pwrlevel == pwr->sysfs_pwr_limit->level) { if (pwr->thermal_pwrlevel == pwr->sysfs_pwr_limit->level) { Loading @@ -370,21 +372,15 @@ static void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_pwrctrl *pwr, } } /** /** * kgsl_pwrctrl_pwrlevel_change() - Validate and change power levels * kgsl_pwrctrl_adjust_pwrlevel() - Adjust the power level if * required by thermal, max/min, constraints, etc * @device: Pointer to the kgsl_device struct * @device: Pointer to the kgsl_device struct * @new_level: Requested powerlevel, an index into the pwrlevel array * @new_level: Requested powerlevel, an index into the pwrlevel array * * Check that any power level constraints are still valid. Update the * requested level according to any thermal, max/min, or power constraints. * If a new GPU level is going to be set, update the bus to that level's * default value. Do not change the bus if a constraint keeps the new * level at the current level. Set the new GPU frequency. */ */ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, unsigned int kgsl_pwrctrl_adjust_pwrlevel(struct kgsl_device *device, unsigned int new_level) unsigned int new_level) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrlevel *pwrlevel; unsigned int old_level = pwr->active_pwrlevel; unsigned int old_level = pwr->active_pwrlevel; /* If a pwr constraint is expired, remove it */ /* If a pwr constraint is expired, remove it */ Loading @@ -402,14 +398,35 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, * Adjust the power level if required by thermal, max/min, * Adjust the power level if required by thermal, max/min, * constraints, etc * constraints, etc */ */ new_level = _adjust_pwrlevel(pwr, new_level, &pwr->constraint, return _adjust_pwrlevel(pwr, new_level, &pwr->constraint, device->pwrscale.popp_level); device->pwrscale.popp_level); } /** * kgsl_pwrctrl_pwrlevel_change() - Validate and change power levels * @device: Pointer to the kgsl_device struct * @new_level: Requested powerlevel, an index into the pwrlevel array * * Check that any power level constraints are still valid. Update the * requested level according to any thermal, max/min, or power constraints. * If a new GPU level is going to be set, update the bus to that level's * default value. Do not change the bus if a constraint keeps the new * level at the current level. Set the new GPU frequency. */ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, unsigned int new_level) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrlevel *pwrlevel; unsigned int old_level = pwr->active_pwrlevel; new_level = kgsl_pwrctrl_adjust_pwrlevel(device, new_level); /* /* * If thermal cycling is required and the new level hits the * If thermal cycling is required and the new level hits the * thermal limit, kick off the cycling. * thermal limit, kick off the cycling. */ */ kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); kgsl_pwrctrl_set_thermal_cycle(device, new_level); if (new_level == old_level && if (new_level == old_level && !test_bit(GMU_DCVS_REPLAY, &device->gmu.flags)) !test_bit(GMU_DCVS_REPLAY, &device->gmu.flags)) Loading Loading @@ -2485,9 +2502,6 @@ static int kgsl_pwrctrl_enable(struct kgsl_device *device) static void kgsl_pwrctrl_disable(struct kgsl_device *device) static void kgsl_pwrctrl_disable(struct kgsl_device *device) { { if (kgsl_gmu_isenabled(device)) { if (kgsl_gmu_isenabled(device)) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; pwr->active_pwrlevel = pwr->num_pwrlevels - 1; kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); return gmu_stop(device); return gmu_stop(device); } } Loading drivers/gpu/msm/kgsl_pwrctrl.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -237,6 +237,12 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device, int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device); int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device); void kgsl_pwrctrl_uninit_sysfs(struct kgsl_device *device); void kgsl_pwrctrl_uninit_sysfs(struct kgsl_device *device); int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state); int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state); int kgsl_clk_set_rate(struct kgsl_device *device, unsigned int pwrlevel); unsigned int kgsl_pwrctrl_adjust_pwrlevel(struct kgsl_device *device, unsigned int new_level); void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_device *device, unsigned int new_level); static inline unsigned long kgsl_get_clkrate(struct clk *clk) static inline unsigned long kgsl_get_clkrate(struct clk *clk) { { Loading Loading
drivers/gpu/msm/kgsl_gmu.c +28 −4 Original line number Original line Diff line number Diff line Loading @@ -1372,6 +1372,31 @@ static void gmu_snapshot(struct kgsl_device *device) gmu->fault_count++; gmu->fault_count++; } } static void gmu_change_gpu_pwrlevel(struct kgsl_device *device, unsigned int new_level) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; unsigned int old_level = pwr->active_pwrlevel; /* * Update the level according to any thermal, * max/min, or power constraints. */ new_level = kgsl_pwrctrl_adjust_pwrlevel(device, new_level); /* * If thermal cycling is required and the new level hits the * thermal limit, kick off the cycling. */ kgsl_pwrctrl_set_thermal_cycle(device, new_level); pwr->active_pwrlevel = new_level; pwr->previous_pwrlevel = old_level; /* Request adjusted DCVS level */ kgsl_clk_set_rate(device, pwr->active_pwrlevel); } /* To be called to power on both GPU and GMU */ /* To be called to power on both GPU and GMU */ int gmu_start(struct kgsl_device *device) int gmu_start(struct kgsl_device *device) { { Loading Loading @@ -1406,8 +1431,7 @@ int gmu_start(struct kgsl_device *device) goto error_gmu; goto error_gmu; /* Request default DCVS level */ /* Request default DCVS level */ kgsl_pwrctrl_pwrlevel_change(device, pwr->default_pwrlevel); gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); msm_bus_scale_client_update_request(gmu->pcl, 0); msm_bus_scale_client_update_request(gmu->pcl, 0); break; break; Loading @@ -1426,7 +1450,7 @@ int gmu_start(struct kgsl_device *device) if (ret) if (ret) goto error_gmu; goto error_gmu; kgsl_pwrctrl_pwrlevel_change(device, pwr->default_pwrlevel); gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); break; break; case KGSL_STATE_RESET: case KGSL_STATE_RESET: Loading @@ -1448,7 +1472,7 @@ int gmu_start(struct kgsl_device *device) goto error_gmu; goto error_gmu; /* Send DCVS level prior to reset*/ /* Send DCVS level prior to reset*/ kgsl_pwrctrl_pwrlevel_change(device, gmu_change_gpu_pwrlevel(device, pwr->default_pwrlevel); pwr->default_pwrlevel); } else { } else { /* GMU fast boot */ /* GMU fast boot */ Loading
drivers/gpu/msm/kgsl_pwrctrl.c +31 −17 Original line number Original line Diff line number Diff line Loading @@ -233,7 +233,7 @@ static int kgsl_bus_scale_request(struct kgsl_device *device, * @device: Pointer to the kgsl_device struct * @device: Pointer to the kgsl_device struct * @pwrlevel: power level in pwrlevels[] table * @pwrlevel: power level in pwrlevels[] table */ */ static int kgsl_clk_set_rate(struct kgsl_device *device, int kgsl_clk_set_rate(struct kgsl_device *device, unsigned int pwrlevel) unsigned int pwrlevel) { { struct gmu_device *gmu = &device->gmu; struct gmu_device *gmu = &device->gmu; Loading Loading @@ -344,12 +344,14 @@ static void kgsl_pwrctrl_pwrlevel_change_settings(struct kgsl_device *device, /** /** * kgsl_pwrctrl_set_thermal_cycle() - set the thermal cycle if required * kgsl_pwrctrl_set_thermal_cycle() - set the thermal cycle if required * @pwr: Pointer to the kgsl_pwrctrl struct * @device: Pointer to the kgsl_device struct * @new_level: the level to transition to * @new_level: the level to transition to */ */ static void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_pwrctrl *pwr, void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_device *device, unsigned int new_level) unsigned int new_level) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; if ((new_level != pwr->thermal_pwrlevel) || !pwr->sysfs_pwr_limit) if ((new_level != pwr->thermal_pwrlevel) || !pwr->sysfs_pwr_limit) return; return; if (pwr->thermal_pwrlevel == pwr->sysfs_pwr_limit->level) { if (pwr->thermal_pwrlevel == pwr->sysfs_pwr_limit->level) { Loading @@ -370,21 +372,15 @@ static void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_pwrctrl *pwr, } } /** /** * kgsl_pwrctrl_pwrlevel_change() - Validate and change power levels * kgsl_pwrctrl_adjust_pwrlevel() - Adjust the power level if * required by thermal, max/min, constraints, etc * @device: Pointer to the kgsl_device struct * @device: Pointer to the kgsl_device struct * @new_level: Requested powerlevel, an index into the pwrlevel array * @new_level: Requested powerlevel, an index into the pwrlevel array * * Check that any power level constraints are still valid. Update the * requested level according to any thermal, max/min, or power constraints. * If a new GPU level is going to be set, update the bus to that level's * default value. Do not change the bus if a constraint keeps the new * level at the current level. Set the new GPU frequency. */ */ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, unsigned int kgsl_pwrctrl_adjust_pwrlevel(struct kgsl_device *device, unsigned int new_level) unsigned int new_level) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrlevel *pwrlevel; unsigned int old_level = pwr->active_pwrlevel; unsigned int old_level = pwr->active_pwrlevel; /* If a pwr constraint is expired, remove it */ /* If a pwr constraint is expired, remove it */ Loading @@ -402,14 +398,35 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, * Adjust the power level if required by thermal, max/min, * Adjust the power level if required by thermal, max/min, * constraints, etc * constraints, etc */ */ new_level = _adjust_pwrlevel(pwr, new_level, &pwr->constraint, return _adjust_pwrlevel(pwr, new_level, &pwr->constraint, device->pwrscale.popp_level); device->pwrscale.popp_level); } /** * kgsl_pwrctrl_pwrlevel_change() - Validate and change power levels * @device: Pointer to the kgsl_device struct * @new_level: Requested powerlevel, an index into the pwrlevel array * * Check that any power level constraints are still valid. Update the * requested level according to any thermal, max/min, or power constraints. * If a new GPU level is going to be set, update the bus to that level's * default value. Do not change the bus if a constraint keeps the new * level at the current level. Set the new GPU frequency. */ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, unsigned int new_level) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrlevel *pwrlevel; unsigned int old_level = pwr->active_pwrlevel; new_level = kgsl_pwrctrl_adjust_pwrlevel(device, new_level); /* /* * If thermal cycling is required and the new level hits the * If thermal cycling is required and the new level hits the * thermal limit, kick off the cycling. * thermal limit, kick off the cycling. */ */ kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); kgsl_pwrctrl_set_thermal_cycle(device, new_level); if (new_level == old_level && if (new_level == old_level && !test_bit(GMU_DCVS_REPLAY, &device->gmu.flags)) !test_bit(GMU_DCVS_REPLAY, &device->gmu.flags)) Loading Loading @@ -2485,9 +2502,6 @@ static int kgsl_pwrctrl_enable(struct kgsl_device *device) static void kgsl_pwrctrl_disable(struct kgsl_device *device) static void kgsl_pwrctrl_disable(struct kgsl_device *device) { { if (kgsl_gmu_isenabled(device)) { if (kgsl_gmu_isenabled(device)) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; pwr->active_pwrlevel = pwr->num_pwrlevels - 1; kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); return gmu_stop(device); return gmu_stop(device); } } Loading
drivers/gpu/msm/kgsl_pwrctrl.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -237,6 +237,12 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device, int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device); int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device); void kgsl_pwrctrl_uninit_sysfs(struct kgsl_device *device); void kgsl_pwrctrl_uninit_sysfs(struct kgsl_device *device); int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state); int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state); int kgsl_clk_set_rate(struct kgsl_device *device, unsigned int pwrlevel); unsigned int kgsl_pwrctrl_adjust_pwrlevel(struct kgsl_device *device, unsigned int new_level); void kgsl_pwrctrl_set_thermal_cycle(struct kgsl_device *device, unsigned int new_level); static inline unsigned long kgsl_get_clkrate(struct clk *clk) static inline unsigned long kgsl_get_clkrate(struct clk *clk) { { Loading