mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: Handle iGPU in pci probe and remove
When iGPU is probed as pci device, power and clocks are driven from the platform, hence the pci_probe and pci_remove to handle both iGPU and dGPU. Also enable the runtime PM for the PCI-iGPU device. JIRA NVGPU-9348 Change-Id: Id5dd88dc0c905655f9174ecd7936bdf2996f06e6 Signed-off-by: Ramalingam C <ramalingamc@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2835341 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
ebb60b7f5e
commit
7ba33f3dec
@@ -17,8 +17,11 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include <nvgpu/nvhost.h>
|
||||
#include <nvgpu/nvgpu_common.h>
|
||||
@@ -575,7 +578,6 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
||||
if (err)
|
||||
goto err_free_platform;
|
||||
|
||||
|
||||
g->is_pci_igpu = platform->is_pci_igpu;
|
||||
nvgpu_info(g, "is_pci_igpu: %s", g->is_pci_igpu ? "true" : "false");
|
||||
pci_set_drvdata(pdev, platform);
|
||||
@@ -598,9 +600,14 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
||||
nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true);
|
||||
}
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
goto err_free_platform;
|
||||
if (!g->is_pci_igpu) {
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
goto err_free_platform;
|
||||
} else {
|
||||
if (nvgpu_platform_is_simulation(g))
|
||||
nvgpu_set_enabled(g, NVGPU_IS_FMODEL, true);
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
|
||||
g->pci_vendor_id = pdev->vendor;
|
||||
@@ -672,6 +679,20 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
||||
if (err)
|
||||
goto err_free_irq;
|
||||
|
||||
if (g->is_pci_igpu) {
|
||||
err = nvgpu_read_fuse_overrides(g);
|
||||
#ifdef CONFIG_RESET_CONTROLLER
|
||||
platform->reset_control = devm_reset_control_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(platform->reset_control))
|
||||
platform->reset_control = NULL;
|
||||
#endif
|
||||
err = gk20a_pm_init(&pdev->dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "pm init failed");
|
||||
goto err_free_irq;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(dev_name(&pdev->dev), '%')) {
|
||||
nvgpu_err(g, "illegal character in device name");
|
||||
err = -EINVAL;
|
||||
@@ -682,10 +703,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
||||
if (err)
|
||||
goto err_free_irq;
|
||||
|
||||
err = nvgpu_pci_pm_init(&pdev->dev);
|
||||
if (err) {
|
||||
nvgpu_err(g, "pm init failed");
|
||||
goto err_free_irq;
|
||||
if (!g->is_pci_igpu) {
|
||||
err = nvgpu_pci_pm_init(&pdev->dev);
|
||||
if (err) {
|
||||
nvgpu_err(g, "pm init failed");
|
||||
goto err_free_irq;
|
||||
}
|
||||
}
|
||||
|
||||
if (!platform->disable_nvlink) {
|
||||
@@ -716,17 +739,29 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
err = nvgpu_get_dt_clock_limit(g, &g->dgpu_max_clk);
|
||||
if (err != 0) {
|
||||
nvgpu_info(g, "Missing nvgpu node");
|
||||
}
|
||||
if (g->is_pci_igpu) {
|
||||
err = gk20a_pm_late_init(&pdev->dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "pm late_init failed");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
err = nvgpu_pci_add_pci_power(pdev);
|
||||
if (err) {
|
||||
nvgpu_err(g, "add pci power failed (%d).", err);
|
||||
goto err_free_irq;
|
||||
}
|
||||
l->nvgpu_reboot_nb.notifier_call =
|
||||
nvgpu_kernel_shutdown_notification;
|
||||
err = register_reboot_notifier(&l->nvgpu_reboot_nb);
|
||||
if (err)
|
||||
goto err_free_irq;
|
||||
} else {
|
||||
err = nvgpu_get_dt_clock_limit(g, &g->dgpu_max_clk);
|
||||
if (err != 0)
|
||||
nvgpu_info(g, "Missing nvgpu node");
|
||||
|
||||
err = nvgpu_pci_add_pci_power(pdev);
|
||||
if (err) {
|
||||
nvgpu_err(g, "add pci power failed (%d).", err);
|
||||
goto err_free_irq;
|
||||
}
|
||||
}
|
||||
nvgpu_mutex_init(&l->dmabuf_priv_list_lock);
|
||||
nvgpu_init_list_node(&l->dmabuf_priv_list);
|
||||
|
||||
@@ -749,6 +784,9 @@ err_free_errata:
|
||||
err_free_platform:
|
||||
nvgpu_kfree(g, platform);
|
||||
err_free_l:
|
||||
|
||||
if (g->is_pci_igpu)
|
||||
nvgpu_kmem_fini(g, NVGPU_KMEM_FINI_FORCE_CLEANUP);
|
||||
kfree(l);
|
||||
return err;
|
||||
}
|
||||
@@ -782,8 +820,10 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
|
||||
#endif
|
||||
nvgpu_mutex_destroy(&l->dmabuf_priv_list_lock);
|
||||
|
||||
err = nvgpu_pci_clear_pci_power(dev_name(dev));
|
||||
WARN(err, "gpu failed to clear pci power");
|
||||
if (!g->is_pci_igpu) {
|
||||
err = nvgpu_pci_clear_pci_power(dev_name(dev));
|
||||
WARN(err, "gpu failed to clear pci power");
|
||||
}
|
||||
|
||||
err = nvgpu_nvlink_deinit(g);
|
||||
/* ENODEV is a legal error if there is no NVLINK */
|
||||
@@ -817,7 +857,10 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
nvgpu_pci_pm_deinit(&pdev->dev);
|
||||
if (!g->is_pci_igpu)
|
||||
nvgpu_pci_pm_deinit(&pdev->dev);
|
||||
else
|
||||
gk20a_pm_deinit(dev);
|
||||
|
||||
/* free allocated platform data space */
|
||||
gk20a_get_platform(&pdev->dev)->g = NULL;
|
||||
|
||||
Reference in New Issue
Block a user