summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm206/bios_gm206.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2016-08-31 17:39:03 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-10-07 04:35:41 -0400
commit61f26b68f6e2c9245861ed6d1dc7311282549667 (patch)
tree74be79986f79ff3f5a656cc7f40ffd5a4fb60bc7 /drivers/gpu/nvgpu/gm206/bios_gm206.c
parent8b6eb6f11807cb660cad048bd6157a484dece5da (diff)
gpu: nvgpu: VBIOS overlay support
Support loading VBIOS from file system instead of EEPROM. JIRA DNVGPU-134 Change-Id: I4c68dc4ab7c1138e8cf2fa9146de5473274491b4 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1211614 (cherry picked from commit d4e35e60ba513e471fe5a85ed570e7ec06c88f06) Reviewed-on: http://git-master/r/1229492 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/gm206/bios_gm206.c')
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c
index 21c852a5..6a509b04 100644
--- a/drivers/gpu/nvgpu/gm206/bios_gm206.c
+++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c
@@ -13,6 +13,8 @@
13 13
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/firmware.h>
17#include <linux/pci.h>
16 18
17#include "gk20a/gk20a.h" 19#include "gk20a/gk20a.h"
18#include "gm20b/fifo_gm20b.h" 20#include "gm20b/fifo_gm20b.h"
@@ -29,8 +31,11 @@
29#define NV_PCFG 0x88000 31#define NV_PCFG 0x88000
30#define PCI_EXP_ROM_SIG 0xaa55 32#define PCI_EXP_ROM_SIG 0xaa55
31#define PCI_EXP_ROM_SIG_NV 0x4e56 33#define PCI_EXP_ROM_SIG_NV 0x4e56
34#define ROM_FILE_PAYLOAD_OFFSET 0xa00
32#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */ 35#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */
33#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */ 36#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */
37#define BIOS_OVERLAY_NAME "bios-%04x.rom"
38#define BIOS_OVERLAY_NAME_FORMATTED "bios-xxxx.rom"
34 39
35static u16 gm206_bios_rdu16(struct gk20a *g, int offset) 40static u16 gm206_bios_rdu16(struct gk20a *g, int offset)
36{ 41{
@@ -724,34 +729,54 @@ static int gm206_bios_init(struct gk20a *g)
724 int i; 729 int i;
725 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 730 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
726 struct dentry *d; 731 struct dentry *d;
732 const struct firmware *bios_fw;
727 int err; 733 int err;
728 bool found = 0; 734 bool found = 0;
735 struct pci_dev *pdev = to_pci_dev(g->dev);
736 char rom_name[sizeof(BIOS_OVERLAY_NAME_FORMATTED)];
729 737
730 gk20a_dbg_fn(""); 738 gk20a_dbg_fn("");
731 g->bios.data = kzalloc(BIOS_SIZE, GFP_KERNEL); 739
732 if (!g->bios.data) 740 snprintf(rom_name, sizeof(rom_name), BIOS_OVERLAY_NAME, pdev->device);
733 return -ENOMEM; 741 gk20a_dbg_info("checking for VBIOS overlay %s", rom_name);
734 742 bios_fw = gk20a_request_firmware(g, rom_name);
735 gk20a_dbg_info("reading bios"); 743 if (bios_fw) {
736 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(), 744 gk20a_dbg_info("using VBIOS overlay");
737 xve_rom_ctrl_rom_shadow_disabled_f()); 745 g->bios.size = bios_fw->size - ROM_FILE_PAYLOAD_OFFSET;
738 for (i = 0; i < BIOS_SIZE/4; i++) { 746 g->bios.data = vmalloc(g->bios.size);
739 u32 val = be32_to_cpu(gk20a_readl(g, 0x300000 + i*4)); 747 if (!g->bios.data)
740 748 return -ENOMEM;
741 g->bios.data[(i*4)] = (val >> 24) & 0xff; 749
742 g->bios.data[(i*4)+1] = (val >> 16) & 0xff; 750 memcpy(g->bios.data, &bios_fw->data[ROM_FILE_PAYLOAD_OFFSET],
743 g->bios.data[(i*4)+2] = (val >> 8) & 0xff; 751 g->bios.size);
744 g->bios.data[(i*4)+3] = val & 0xff; 752
753 release_firmware(bios_fw);
754 } else {
755 gk20a_dbg_info("reading bios from EEPROM");
756 g->bios.size = BIOS_SIZE;
757 g->bios.data = vmalloc(BIOS_SIZE);
758 if (!g->bios.data)
759 return -ENOMEM;
760 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(),
761 xve_rom_ctrl_rom_shadow_disabled_f());
762 for (i = 0; i < g->bios.size/4; i++) {
763 u32 val = be32_to_cpu(gk20a_readl(g, 0x300000 + i*4));
764
765 g->bios.data[(i*4)] = (val >> 24) & 0xff;
766 g->bios.data[(i*4)+1] = (val >> 16) & 0xff;
767 g->bios.data[(i*4)+2] = (val >> 8) & 0xff;
768 g->bios.data[(i*4)+3] = val & 0xff;
769 }
770 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(),
771 xve_rom_ctrl_rom_shadow_enabled_f());
745 } 772 }
746 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(),
747 xve_rom_ctrl_rom_shadow_enabled_f());
748 773
749 err = gm206_bios_parse_rom(g); 774 err = gm206_bios_parse_rom(g);
750 if (err) 775 if (err)
751 return err; 776 return err;
752 777
753 gk20a_dbg_info("read bios"); 778 gk20a_dbg_info("read bios");
754 for (i = 0; i < BIOS_SIZE; i++) { 779 for (i = 0; i < g->bios.size; i++) {
755 if (gm206_bios_rdu16(g, i) == BIT_HEADER_ID && 780 if (gm206_bios_rdu16(g, i) == BIT_HEADER_ID &&
756 gm206_bios_rdu32(g, i+2) == BIT_HEADER_SIGNATURE) { 781 gm206_bios_rdu32(g, i+2) == BIT_HEADER_SIGNATURE) {
757 gm206_bios_parse_bit(g, i); 782 gm206_bios_parse_bit(g, i);
@@ -764,7 +789,7 @@ static int gm206_bios_init(struct gk20a *g)
764 return -EINVAL; 789 return -EINVAL;
765 } 790 }
766 g->bios_blob.data = g->bios.data; 791 g->bios_blob.data = g->bios.data;
767 g->bios_blob.size = BIOS_SIZE; 792 g->bios_blob.size = g->bios.size;
768 793
769 d = debugfs_create_blob("bios", S_IRUGO, platform->debugfs, 794 d = debugfs_create_blob("bios", S_IRUGO, platform->debugfs,
770 &g->bios_blob); 795 &g->bios_blob);