From a2831f098bb22e347009cd73e17946db14ee06ce Mon Sep 17 00:00:00 2001 From: Sachit Kadle Date: Tue, 12 Jul 2016 14:27:32 -0700 Subject: gpu: nvgpu: enable runtime pm for pci Enable runtime power management ops for PCIe devices, and move gk20a_pm_finalize_poweron call into the resume routine. This change only implements suspend as a stub, as suspend/resume has not yet been verified for dGPU Bug 1785512 Bug 200187507 Change-Id: I076bafc03c6b4ba10dce874804ed3fd0b9c7b0d8 Signed-off-by: Sachit Kadle Reviewed-on: http://git-master/r/1179860 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Konsta Holtta Reviewed-by: Deepak Nibade Reviewed-by: Thomas Fleury GVS: Gerrit_Virtual_Submit Reviewed-by: Richard Zhao Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/pci.c | 62 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/nvgpu/pci.c') diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c index 01c7a2dc..90a54570 100644 --- a/drivers/gpu/nvgpu/pci.c +++ b/drivers/gpu/nvgpu/pci.c @@ -38,25 +38,15 @@ static bool nvgpu_pci_tegra_is_railgated(struct device *pdev) return false; } -static int nvgpu_pci_busy(struct device *dev) -{ - struct gk20a *g = get_gk20a(dev); - int err = 0; - - if (!g->power_on) - err = gk20a_pm_finalize_poweron(dev); - - return err; -} - static struct gk20a_platform nvgpu_pci_device = { /* ptimer src frequency in hz */ .ptimer_src_freq = 31250000, .probe = nvgpu_pci_tegra_probe, .remove = nvgpu_pci_tegra_remove, - .busy = nvgpu_pci_busy, + /* power management configuration */ + .railgate_delay = 500, .can_elpg = false, /* power management callbacks */ @@ -148,6 +138,45 @@ static struct class nvgpu_pci_class = { .devnode = nvgpu_pci_devnode, }; +#ifdef CONFIG_PM +static int nvgpu_pci_pm_runtime_resume(struct device *dev) +{ + return gk20a_pm_finalize_poweron(dev); +} + +static int nvgpu_pci_pm_runtime_suspend(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops nvgpu_pci_pm_ops = { + .runtime_resume = nvgpu_pci_pm_runtime_resume, + .runtime_suspend = nvgpu_pci_pm_runtime_suspend, + .resume = nvgpu_pci_pm_runtime_resume, + .suspend = nvgpu_pci_pm_runtime_suspend, +}; +#endif + +int nvgpu_pci_pm_init(struct device *dev) +{ +#ifdef CONFIG_PM + struct gk20a_platform *platform = gk20a_get_platform(dev); + + if (platform->railgate_delay) + pm_runtime_set_autosuspend_delay(dev, + platform->railgate_delay); + + /* + * Runtime PM for PCI devices is disabled by default, + * so we need to enable it first + */ + pm_runtime_use_autosuspend(dev); + pm_runtime_put_noidle(dev); + pm_runtime_allow(dev); +#endif + return 0; +} + static int nvgpu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pent) { @@ -252,6 +281,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, gk20a_init_gr(g); + err = nvgpu_pci_pm_init(&pdev->dev); + if (err) { + gk20a_err(&pdev->dev, "pm init failed"); + return err; + } + return 0; } @@ -281,6 +316,9 @@ static struct pci_driver nvgpu_pci_driver = { .id_table = nvgpu_pci_table, .probe = nvgpu_pci_probe, .remove = nvgpu_pci_remove, +#ifdef CONFIG_PM + .driver.pm = &nvgpu_pci_pm_ops, +#endif }; int __init nvgpu_pci_init(void) -- cgit v1.2.2