diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index 23d74d5db..3c2ecff01 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -189,6 +189,7 @@ static struct gk20a_platform nvgpu_pci_device[] = { /* power management configuration */ .railgate_delay_init = 500, .can_railgate_init = false, + .can_pci_gc_off = true, .can_elpg_init = false, .enable_elpg = false, .enable_elcg = false, @@ -263,6 +264,7 @@ static struct gk20a_platform nvgpu_pci_device[] = { /* power management configuration */ .railgate_delay_init = 500, .can_railgate_init = false, + .can_pci_gc_off = true, .can_elpg_init = false, .enable_elpg = false, .enable_elcg = false, diff --git a/drivers/gpu/nvgpu/os/linux/pci_power.c b/drivers/gpu/nvgpu/os/linux/pci_power.c index 8dee39ee0..91ac82034 100644 --- a/drivers/gpu/nvgpu/os/linux/pci_power.c +++ b/drivers/gpu/nvgpu/os/linux/pci_power.c @@ -52,6 +52,7 @@ struct nvgpu_pci_power { char pci_dev_name[PCI_DEV_NAME_MAX]; void *pci_cookie; struct pci_power_stats stats; + bool can_pci_gc_off; }; static struct list_head nvgpu_pci_power_devs = @@ -70,6 +71,7 @@ static struct nvgpu_pci_power *nvgpu_pci_get_pci_power(const char *dev_name) int nvgpu_pci_add_pci_power(struct pci_dev *pdev) { + struct gk20a_platform *platform; struct nvgpu_pci_power *pp; if (!pdev) @@ -90,6 +92,9 @@ int nvgpu_pci_add_pci_power(struct pci_dev *pdev) strlcpy(pp->pci_dev_name, dev_name(&pdev->dev), PCI_DEV_NAME_MAX); + platform = pci_get_drvdata(pdev); + pp->can_pci_gc_off = platform->can_pci_gc_off; + list_add(&pp->list, &nvgpu_pci_power_devs); return 0; @@ -440,6 +445,11 @@ static int nvgpu_pci_gpu_power_on(char *dev_name) return -ENODEV; } + if (pp->can_pci_gc_off == false) { + pr_err("nvgpu: gc-off not enabled for pdev: %s\n", dev_name); + return -EPERM; + } + time_start = ktime_get(); nvgpu_mutex_acquire(&pp->mutex); @@ -504,6 +514,11 @@ static int nvgpu_pci_gpu_power_off(char *dev_name) return -ENODEV; } + if (pp->can_pci_gc_off == false) { + pr_err("nvgpu: gc-off not enabled for pdev: %s\n", dev_name); + return -EPERM; + } + time_start = ktime_get(); nvgpu_mutex_acquire(&pp->mutex); diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h index 16aea33fc..3ba1bc847 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h @@ -59,6 +59,9 @@ struct gk20a_platform { /* Should be populated at probe. */ bool can_railgate_init; + /* controls gc off feature for pci gpu */ + bool can_pci_gc_off; + /* Should be populated at probe. */ bool can_tpc_powergate;