From 174e6ad1b22cb7aab1bd250679231e4dec568a65 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 26 Sep 2016 14:02:11 -0700 Subject: gpu: nvgpu: VBIOS version check Add a minimum VBIOS version field for each SKU. This requires the gk20a_platform structure to be per SKU. Also sets power_on back to false if there was any error in booting GPU. Bug 1811880 Change-Id: I23ef312f0db7061b31a3d503ded7e41ef45ad6b3 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1227229 (cherry picked from commit 69c9ab4349ec7526a7f8a2fcad01f9128ed4769c) Reviewed-on: http://git-master/r/1239428 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/gk20a.c | 3 ++ drivers/gpu/nvgpu/gk20a/platform_gk20a.h | 2 + drivers/gpu/nvgpu/gm206/bios_gm206.c | 8 +++ drivers/gpu/nvgpu/pci.c | 93 ++++++++++++++++++++++++-------- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 9eebfe88..55ebf2da 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -1059,6 +1059,9 @@ int gk20a_pm_finalize_poweron(struct device *dev) } done: + if (err) + g->power_on = false; + return err; } diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h index 6afd4852..de7bbd06 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h @@ -225,6 +225,8 @@ struct gk20a_platform { /* if vidmem aperture actually points to vidmem*/ bool vidmem_is_vidmem; + /* minimum supported VBIOS version */ + u32 vbios_min_version; }; static inline struct gk20a_platform *gk20a_get_platform( diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index ea65e392..aa40f410 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c @@ -894,6 +894,14 @@ static int gm206_bios_init(struct gk20a *g) gk20a_err(g->dev, "no valid VBIOS found"); return -EINVAL; } + + if (g->gpu_characteristics.vbios_version < + platform->vbios_min_version) { + gk20a_err(g->dev, "unsupported VBIOS version %08x", + g->gpu_characteristics.vbios_version); + return -EINVAL; + } + g->bios_blob.data = g->bios.data; g->bios_blob.size = g->bios.size; diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c index a3d53440..838ad706 100644 --- a/drivers/gpu/nvgpu/pci.c +++ b/drivers/gpu/nvgpu/pci.c @@ -39,7 +39,8 @@ static bool nvgpu_pci_tegra_is_railgated(struct device *pdev) return false; } -static struct gk20a_platform nvgpu_pci_device = { +static struct gk20a_platform nvgpu_pci_device[] = { + { /* DEVICE=0x1c35 */ /* ptimer src frequency in hz */ .ptimer_src_freq = 31250000, @@ -50,6 +51,9 @@ static struct gk20a_platform nvgpu_pci_device = { .railgate_delay = 500, .can_railgate = false, .can_elpg = false, + .enable_elcg = true, + .enable_slcg = true, + .enable_blcg = true, /* power management callbacks */ .is_railgated = nvgpu_pci_tegra_is_railgated, @@ -61,35 +65,82 @@ static struct gk20a_platform nvgpu_pci_device = { .has_ce = true, .vidmem_is_vidmem = true, -}; + .vbios_min_version = 0x86062d00, + }, + { /* DEVICE=0x1c36 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay = 500, + .can_railgate = false, + .can_elpg = false, + .enable_elcg = true, + .enable_slcg = true, + .enable_blcg = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + + .default_big_page_size = SZ_64K, + + .ch_wdt_timeout_ms = 7000, + + .has_ce = true, + + .vidmem_is_vidmem = true, + .vbios_min_version = 0x86062d00, + }, + { /* DEVICE=0x1c37 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, -#define NVGPU_PCI_ENABLE_BLCG BIT(0) -#define NVGPU_PCI_ENABLE_SLCG BIT(1) -#define NVGPU_PCI_ENABLE_ELCG BIT(2) + /* power management configuration */ + .railgate_delay = 500, + .can_railgate = false, + .can_elpg = false, + .enable_elcg = true, + .enable_slcg = true, + .enable_blcg = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + + .default_big_page_size = SZ_64K, + + .ch_wdt_timeout_ms = 7000, + + .has_ce = true, + + .vidmem_is_vidmem = true, + .vbios_min_version = 0x86063000, + } +}; static struct pci_device_id nvgpu_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c35), .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, - .driver_data = NVGPU_PCI_ENABLE_BLCG | - NVGPU_PCI_ENABLE_SLCG, + .driver_data = 0, }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c36), .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, - .driver_data = NVGPU_PCI_ENABLE_BLCG | - NVGPU_PCI_ENABLE_SLCG | - NVGPU_PCI_ENABLE_ELCG, + .driver_data = 1, }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c37), .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, - .driver_data = NVGPU_PCI_ENABLE_BLCG | - NVGPU_PCI_ENABLE_SLCG | - NVGPU_PCI_ENABLE_ELCG, + .driver_data = 2, }, {} }; @@ -202,11 +253,18 @@ static int nvgpu_pci_pm_init(struct device *dev) static int nvgpu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pent) { - struct gk20a_platform *platform = &nvgpu_pci_device; + struct gk20a_platform *platform = NULL; struct gk20a *g; int err; char *nodefmt; + /* make sure driver_data is a sane index */ + if (pent->driver_data >= sizeof(nvgpu_pci_device) / + sizeof(nvgpu_pci_device[0])) { + return -EINVAL; + } + + platform = &nvgpu_pci_device[pent->driver_data]; pci_set_drvdata(pdev, platform); g = kzalloc(sizeof(struct gk20a), GFP_KERNEL); @@ -218,13 +276,6 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, platform->g = g; g->dev = &pdev->dev; - if (pent->driver_data & NVGPU_PCI_ENABLE_BLCG) - platform->enable_blcg = true; - if (pent->driver_data & NVGPU_PCI_ENABLE_SLCG) - platform->enable_slcg = true; - if (pent->driver_data & NVGPU_PCI_ENABLE_ELCG) - platform->enable_elcg = true; - err = pci_enable_device(pdev); if (err) return err; -- cgit v1.2.2