msm: kgsl: Make a child device just for the bwmon governor

Now that we are creating the OPP tables at runtime, we don't need a
platform device defined in the device tree just for the bwmon governor.
Instead, create a simple child device and use that.

Change-Id: Ic0dedbadbebc2dac4f9a1e05045a7462742aaefd
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2019-10-14 10:41:09 -06:00
commit 52ffecfb04
4 changed files with 49 additions and 70 deletions

View file

@ -3750,35 +3750,6 @@ static struct platform_driver adreno_platform_driver = {
}
};
static const struct of_device_id busmon_match_table[] = {
{ .compatible = "qcom,kgsl-busmon", .data = &device_3d0 },
{}
};
static int adreno_busmon_probe(struct platform_device *pdev)
{
struct kgsl_device *device;
const struct of_device_id *pdid =
of_match_device(busmon_match_table, &pdev->dev);
if (pdid == NULL)
return -ENXIO;
device = (struct kgsl_device *)pdid->data;
device->busmondev = &pdev->dev;
dev_set_drvdata(device->busmondev, device);
return 0;
}
static struct platform_driver kgsl_bus_platform_driver = {
.probe = adreno_busmon_probe,
.driver = {
.name = "kgsl-busmon",
.of_match_table = busmon_match_table,
}
};
static int __init kgsl_3d_init(void)
{
int ret;
@ -3787,17 +3758,9 @@ static int __init kgsl_3d_init(void)
if (ret)
return ret;
ret = platform_driver_register(&kgsl_bus_platform_driver);
if (ret) {
kgsl_core_exit();
return ret;
}
ret = platform_driver_register(&adreno_platform_driver);
if (ret) {
platform_driver_unregister(&kgsl_bus_platform_driver);
if (ret)
kgsl_core_exit();
}
return ret;
}
@ -3805,8 +3768,6 @@ static int __init kgsl_3d_init(void)
static void __exit kgsl_3d_exit(void)
{
platform_driver_unregister(&adreno_platform_driver);
platform_driver_unregister(&kgsl_bus_platform_driver);
kgsl_core_exit();
}

View file

@ -297,8 +297,6 @@ struct kgsl_device {
int reset_counter; /* Track how many GPU core resets have occurred */
struct workqueue_struct *events_wq;
struct device *busmondev; /* pseudo dev for GPU BW voting governor */
/* Number of active contexts seen globally for this device */
int active_context_count;
struct kobject *gpu_sysfs_kobj;

View file

@ -654,13 +654,50 @@ static int opp_notify(struct notifier_block *nb,
return 0;
}
static void pwrscale_busmon_create(struct kgsl_device *device,
struct platform_device *pdev, unsigned long *table)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
struct kgsl_pwrscale *pwrscale = &device->pwrscale;
struct device *dev = &pwrscale->busmondev;
struct devfreq *bus_devfreq;
int i;
pwrscale->bus_profile.profile.max_state = pwr->num_pwrlevels - 1;
pwrscale->bus_profile.profile.freq_table = table;
dev->parent = &pdev->dev;
dev_set_name(dev, "kgsl-busmon");
if (device_register(dev))
return;
/* Build out the OPP table for the busmon device */
for (i = 0; i < pwr->num_pwrlevels; i++) {
if (!pwr->pwrlevels[i].gpu_freq)
continue;
dev_pm_opp_add(dev, pwr->pwrlevels[i].gpu_freq, 0);
}
bus_devfreq = devfreq_add_device(dev, &pwrscale->bus_profile.profile,
"gpubw_mon", NULL);
if (IS_ERR_OR_NULL(bus_devfreq)) {
dev_err(&pdev->dev, "Bus scaling not enabled\n");
put_device(dev);
return;
}
pwrscale->gpu_profile.bus_devfreq = bus_devfreq;
}
int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
const char *governor)
{
struct kgsl_pwrscale *pwrscale;
struct kgsl_pwrctrl *pwr;
struct devfreq *devfreq;
struct devfreq *bus_devfreq = NULL;
struct msm_adreno_extended_profile *gpu_profile;
struct devfreq_dev_profile *profile;
struct devfreq_msm_adreno_tz_data *data;
@ -758,34 +795,9 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
pwrscale->cooling_dev = NULL;
pwrscale->gpu_profile.bus_devfreq = NULL;
if (data->bus.num) {
pwrscale->bus_profile.profile.max_state
= pwr->num_pwrlevels - 1;
pwrscale->bus_profile.profile.freq_table
= pwrscale->freq_table;
/*
* This is needed because devfreq expects the device
* to have an opp table handle to calculate the min/max
* frequency.
*/
ret = dev_pm_opp_of_add_table(device->busmondev);
/*
* Disable OPP which are not supported as per GPU freq plan.
* This is need to ensure freq_table specified in bus_profile
* above matches OPP table.
*/
kgsl_pwrctrl_disable_unused_opp(device, device->busmondev);
if (!ret)
bus_devfreq = devfreq_add_device(device->busmondev,
&pwrscale->bus_profile.profile, "gpubw_mon",
NULL);
if (IS_ERR_OR_NULL(bus_devfreq))
dev_err(device->dev, "Bus scaling not enabled\n");
else
pwrscale->gpu_profile.bus_devfreq = bus_devfreq;
}
if (data->bus.num)
pwrscale_busmon_create(device, pdev, pwrscale->freq_table);
ret = sysfs_create_link(&device->dev->kobj,
&devfreq->dev.kobj, "devfreq");
@ -825,6 +837,12 @@ void kgsl_pwrscale_close(struct kgsl_device *device)
pwr = &device->pwrctrl;
pwrscale = &device->pwrscale;
if (pwrscale->gpu_profile.bus_devfreq) {
devfreq_remove_device(pwrscale->gpu_profile.bus_devfreq);
put_device(&pwrscale->busmondev);
}
if (!pwrscale->devfreqptr)
return;
if (pwrscale->cooling_dev)

View file

@ -63,6 +63,8 @@ struct kgsl_pwrscale {
bool ctxt_aware_enable;
unsigned int ctxt_aware_target_pwrlevel;
unsigned int ctxt_aware_busy_penalty;
/** @busmondev: A child device for the busmon governor */
struct device busmondev;
};
/**