summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm206
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gm206')
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.c635
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.h56
-rw-r--r--drivers/gpu/nvgpu/gm206/hal_gm206.c2
3 files changed, 12 insertions, 681 deletions
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c
index a5551f42..3d12b9ac 100644
--- a/drivers/gpu/nvgpu/gm206/bios_gm206.c
+++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c
@@ -16,6 +16,8 @@
16#include <linux/firmware.h> 16#include <linux/firmware.h>
17#include <linux/pci.h> 17#include <linux/pci.h>
18 18
19#include <nvgpu/bios.h>
20
19#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
20#include "gm20b/fifo_gm20b.h" 22#include "gm20b/fifo_gm20b.h"
21#include "fifo_gm206.h" 23#include "fifo_gm206.h"
@@ -27,617 +29,12 @@
27#include <nvgpu/hw/gm206/hw_mc_gm206.h> 29#include <nvgpu/hw/gm206/hw_mc_gm206.h>
28#include <nvgpu/hw/gm206/hw_top_gm206.h> 30#include <nvgpu/hw/gm206/hw_top_gm206.h>
29 31
30#define BIT_HEADER_ID 0xb8ff
31#define BIT_HEADER_SIGNATURE 0x00544942
32#define BIOS_SIZE 0x40000
33#define PCI_EXP_ROM_SIG 0xaa55
34#define PCI_EXP_ROM_SIG_NV 0x4e56
35#define ROM_FILE_PAYLOAD_OFFSET 0xa00
36#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */ 32#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */
37#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */ 33#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */
38#define BIOS_OVERLAY_NAME "bios-%04x.rom" 34#define BIOS_OVERLAY_NAME "bios-%04x.rom"
39#define BIOS_OVERLAY_NAME_FORMATTED "bios-xxxx.rom" 35#define BIOS_OVERLAY_NAME_FORMATTED "bios-xxxx.rom"
40 36#define ROM_FILE_PAYLOAD_OFFSET 0xa00
41static u16 gm206_bios_rdu16(struct gk20a *g, int offset) 37#define BIOS_SIZE 0x40000
42{
43 u16 val = (g->bios.data[offset+1] << 8) + g->bios.data[offset];
44 return val;
45}
46
47static u32 gm206_bios_rdu32(struct gk20a *g, int offset)
48{
49 u32 val = (g->bios.data[offset+3] << 24) +
50 (g->bios.data[offset+2] << 16) +
51 (g->bios.data[offset+1] << 8) +
52 g->bios.data[offset];
53 return val;
54}
55
56struct bit {
57 u16 id;
58 u32 signature;
59 u16 bcd_version;
60 u8 header_size;
61 u8 token_size;
62 u8 token_entries;
63 u8 header_checksum;
64} __packed;
65
66#define TOKEN_ID_BIOSDATA 0x42
67#define TOKEN_ID_NVINIT_PTRS 0x49
68#define TOKEN_ID_FALCON_DATA 0x70
69#define TOKEN_ID_PERF_PTRS 0x50
70#define TOKEN_ID_CLOCK_PTRS 0x43
71#define TOKEN_ID_VIRT_PTRS 0x56
72#define TOKEN_ID_MEMORY_PTRS 0x4D
73
74
75union memory_ptrs {
76 struct {
77 u8 rsvd0[2];
78 u8 mem_strap_data_count;
79 u16 mem_strap_xlat_tbl_ptr;
80 u8 rsvd1[8];
81 } v1 __packed;
82 struct {
83 u8 mem_strap_data_count;
84 u16 mem_strap_xlat_tbl_ptr;
85 u8 rsvd[14];
86 } v2 __packed;
87};
88
89struct biosdata {
90 u32 version;
91 u8 oem_version;
92 u8 checksum;
93 u16 int15callbackspost;
94 u16 int16callbackssystem;
95 u16 boardid;
96 u16 framecount;
97 u8 biosmoddate[8];
98} __packed;
99
100struct nvinit_ptrs {
101 u16 initscript_table_ptr;
102 u16 macro_index_table_ptr;
103 u16 macro_table_ptr;
104 u16 condition_table_ptr;
105 u16 io_condition_table_ptr;
106 u16 io_flag_condition_table_ptr;
107 u16 init_function_table_ptr;
108 u16 vbios_private_table_ptr;
109 u16 data_arrays_table_ptr;
110 u16 pcie_settings_script_ptr;
111 u16 devinit_tables_ptr;
112 u16 devinit_tables_size;
113 u16 bootscripts_ptr;
114 u16 bootscripts_size;
115 u16 nvlink_config_data_ptr;
116} __packed;
117
118struct falcon_data_v2 {
119 u32 falcon_ucode_table_ptr;
120} __packed;
121
122struct falcon_ucode_table_hdr_v1 {
123 u8 version;
124 u8 header_size;
125 u8 entry_size;
126 u8 entry_count;
127 u8 desc_version;
128 u8 desc_size;
129} __packed;
130
131struct falcon_ucode_table_entry_v1 {
132 u8 application_id;
133 u8 target_id;
134 u32 desc_ptr;
135} __packed;
136
137#define TARGET_ID_PMU 0x01
138#define APPLICATION_ID_DEVINIT 0x04
139#define APPLICATION_ID_PRE_OS 0x01
140
141struct falcon_ucode_desc_v1 {
142 union {
143 u32 v_desc;
144 u32 stored_size;
145 } hdr_size;
146 u32 uncompressed_size;
147 u32 virtual_entry;
148 u32 interface_offset;
149 u32 imem_phys_base;
150 u32 imem_load_size;
151 u32 imem_virt_base;
152 u32 imem_sec_base;
153 u32 imem_sec_size;
154 u32 dmem_offset;
155 u32 dmem_phys_base;
156 u32 dmem_load_size;
157} __packed;
158
159struct application_interface_table_hdr_v1 {
160 u8 version;
161 u8 header_size;
162 u8 entry_size;
163 u8 entry_count;
164} __packed;
165
166struct application_interface_entry_v1 {
167 u32 id;
168 u32 dmem_offset;
169} __packed;
170
171#define APPINFO_ID_DEVINIT 0x01
172
173struct devinit_engine_interface {
174 u32 field0;
175 u32 field1;
176 u32 tables_phys_base;
177 u32 tables_virt_base;
178 u32 script_phys_base;
179 u32 script_virt_base;
180 u32 script_virt_entry;
181 u16 script_size;
182 u8 memory_strap_count;
183 u8 reserved;
184 u32 memory_information_table_virt_base;
185 u32 empty_script_virt_base;
186 u32 cond_table_virt_base;
187 u32 io_cond_table_virt_base;
188 u32 data_arrays_table_virt_base;
189 u32 gpio_assignment_table_virt_base;
190} __packed;
191
192struct pci_exp_rom {
193 u16 sig;
194 u8 reserved[0x16];
195 u16 pci_data_struct_ptr;
196 u32 size_of_block;
197} __packed;
198
199struct pci_data_struct {
200 u32 sig;
201 u16 vendor_id;
202 u16 device_id;
203 u16 device_list_ptr;
204 u16 pci_data_struct_len;
205 u8 pci_data_struct_rev;
206 u8 class_code[3];
207 u16 image_len;
208 u16 vendor_rom_rev;
209 u8 code_type;
210 u8 last_image;
211 u16 max_runtime_image_len;
212} __packed;
213
214struct pci_ext_data_struct {
215 u32 sig;
216 u16 nv_pci_data_ext_rev;
217 u16 nv_pci_data_ext_len;
218 u16 sub_image_len;
219 u8 priv_last_image;
220 u8 flags;
221} __packed;
222
223static int gm206_bios_parse_rom(struct gk20a *g)
224{
225 int offset = 0;
226 int last = 0;
227
228 while (!last) {
229 struct pci_exp_rom *pci_rom;
230 struct pci_data_struct *pci_data;
231 struct pci_ext_data_struct *pci_ext_data;
232
233 pci_rom = (struct pci_exp_rom *)&g->bios.data[offset];
234 gk20a_dbg_fn("pci rom sig %04x ptr %04x block %x",
235 pci_rom->sig, pci_rom->pci_data_struct_ptr,
236 pci_rom->size_of_block);
237
238 if (pci_rom->sig != PCI_EXP_ROM_SIG &&
239 pci_rom->sig != PCI_EXP_ROM_SIG_NV) {
240 gk20a_err(g->dev, "invalid VBIOS signature");
241 return -EINVAL;
242 }
243
244 pci_data =
245 (struct pci_data_struct *)
246 &g->bios.data[offset + pci_rom->pci_data_struct_ptr];
247 gk20a_dbg_fn("pci data sig %08x len %d image len %x type %x last %d max %08x",
248 pci_data->sig, pci_data->pci_data_struct_len,
249 pci_data->image_len, pci_data->code_type,
250 pci_data->last_image,
251 pci_data->max_runtime_image_len);
252
253 if (pci_data->code_type == 0x3) {
254 pci_ext_data = (struct pci_ext_data_struct *)
255 &g->bios.data[(offset +
256 pci_rom->pci_data_struct_ptr +
257 pci_data->pci_data_struct_len +
258 0xf)
259 & ~0xf];
260 gk20a_dbg_fn("pci ext data sig %08x rev %x len %x sub_image_len %x priv_last %d flags %x",
261 pci_ext_data->sig,
262 pci_ext_data->nv_pci_data_ext_rev,
263 pci_ext_data->nv_pci_data_ext_len,
264 pci_ext_data->sub_image_len,
265 pci_ext_data->priv_last_image,
266 pci_ext_data->flags);
267
268 gk20a_dbg_fn("expansion rom offset %x",
269 pci_data->image_len * 512);
270 g->bios.expansion_rom_offset =
271 pci_data->image_len * 512;
272 offset += pci_ext_data->sub_image_len * 512;
273 last = pci_ext_data->priv_last_image;
274 } else {
275 offset += pci_data->image_len * 512;
276 last = pci_data->last_image;
277 }
278 }
279
280 return 0;
281}
282
283static void gm206_bios_parse_biosdata(struct gk20a *g, int offset)
284{
285 struct biosdata biosdata;
286
287 memcpy(&biosdata, &g->bios.data[offset], sizeof(biosdata));
288 gk20a_dbg_fn("bios version %x, oem version %x",
289 biosdata.version,
290 biosdata.oem_version);
291
292 g->gpu_characteristics.vbios_version = biosdata.version;
293 g->gpu_characteristics.vbios_oem_version = biosdata.oem_version;
294}
295
296static void gm206_bios_parse_nvinit_ptrs(struct gk20a *g, int offset)
297{
298 struct nvinit_ptrs nvinit_ptrs;
299
300 memcpy(&nvinit_ptrs, &g->bios.data[offset], sizeof(nvinit_ptrs));
301 gk20a_dbg_fn("devinit ptr %x size %d", nvinit_ptrs.devinit_tables_ptr,
302 nvinit_ptrs.devinit_tables_size);
303 gk20a_dbg_fn("bootscripts ptr %x size %d", nvinit_ptrs.bootscripts_ptr,
304 nvinit_ptrs.bootscripts_size);
305
306 g->bios.devinit_tables = &g->bios.data[nvinit_ptrs.devinit_tables_ptr];
307 g->bios.devinit_tables_size = nvinit_ptrs.devinit_tables_size;
308 g->bios.bootscripts = &g->bios.data[nvinit_ptrs.bootscripts_ptr];
309 g->bios.bootscripts_size = nvinit_ptrs.bootscripts_size;
310 g->bios.condition_table_ptr = nvinit_ptrs.condition_table_ptr;
311}
312
313static void gm206_bios_parse_memory_ptrs(struct gk20a *g, int offset, u8 version)
314{
315 union memory_ptrs memory_ptrs;
316
317 if ((version < 1) || (version > 2))
318 return;
319
320 memcpy(&memory_ptrs, &g->bios.data[offset], sizeof(memory_ptrs));
321
322 g->bios.mem_strap_data_count = (version > 1) ? memory_ptrs.v2.mem_strap_data_count :
323 memory_ptrs.v1.mem_strap_data_count;
324 g->bios.mem_strap_xlat_tbl_ptr = (version > 1) ? memory_ptrs.v2.mem_strap_xlat_tbl_ptr :
325 memory_ptrs.v1.mem_strap_xlat_tbl_ptr;
326}
327
328static void gm206_bios_parse_devinit_appinfo(struct gk20a *g, int dmem_offset)
329{
330 struct devinit_engine_interface interface;
331
332 memcpy(&interface, &g->bios.devinit.dmem[dmem_offset], sizeof(interface));
333 gk20a_dbg_fn("devinit tables phys %x script phys %x size %d",
334 interface.tables_phys_base,
335 interface.script_phys_base,
336 interface.script_size);
337
338 g->bios.devinit_tables_phys_base = interface.tables_phys_base;
339 g->bios.devinit_script_phys_base = interface.script_phys_base;
340}
341
342static int gm206_bios_parse_appinfo_table(struct gk20a *g, int offset)
343{
344 struct application_interface_table_hdr_v1 hdr;
345 int i;
346
347 memcpy(&hdr, &g->bios.data[offset], sizeof(hdr));
348
349 gk20a_dbg_fn("appInfoHdr ver %d size %d entrySize %d entryCount %d",
350 hdr.version, hdr.header_size,
351 hdr.entry_size, hdr.entry_count);
352
353 if (hdr.version != 1)
354 return 0;
355
356 offset += sizeof(hdr);
357 for (i = 0; i < hdr.entry_count; i++) {
358 struct application_interface_entry_v1 entry;
359
360 memcpy(&entry, &g->bios.data[offset], sizeof(entry));
361
362 gk20a_dbg_fn("appInfo id %d dmem_offset %d",
363 entry.id, entry.dmem_offset);
364
365 if (entry.id == APPINFO_ID_DEVINIT)
366 gm206_bios_parse_devinit_appinfo(g, entry.dmem_offset);
367
368 offset += hdr.entry_size;
369 }
370
371 return 0;
372}
373
374static int gm206_bios_parse_falcon_ucode_desc(struct gk20a *g,
375 struct nvgpu_bios_ucode *ucode, int offset)
376{
377 struct falcon_ucode_desc_v1 desc;
378
379 memcpy(&desc, &g->bios.data[offset], sizeof(desc));
380 gk20a_dbg_info("falcon ucode desc stored size %d uncompressed size %d",
381 desc.hdr_size.stored_size, desc.uncompressed_size);
382 gk20a_dbg_info("falcon ucode desc virtualEntry %x, interfaceOffset %x",
383 desc.virtual_entry, desc.interface_offset);
384 gk20a_dbg_info("falcon ucode IMEM phys base %x, load size %x virt base %x sec base %x sec size %x",
385 desc.imem_phys_base, desc.imem_load_size,
386 desc.imem_virt_base, desc.imem_sec_base,
387 desc.imem_sec_size);
388 gk20a_dbg_info("falcon ucode DMEM offset %d phys base %x, load size %d",
389 desc.dmem_offset, desc.dmem_phys_base,
390 desc.dmem_load_size);
391
392 if (desc.hdr_size.stored_size != desc.uncompressed_size) {
393 gk20a_dbg_info("does not match");
394 return -EINVAL;
395 }
396
397 ucode->code_entry_point = desc.virtual_entry;
398 ucode->bootloader = &g->bios.data[offset] + sizeof(desc);
399 ucode->bootloader_phys_base = desc.imem_phys_base;
400 ucode->bootloader_size = desc.imem_load_size - desc.imem_sec_size;
401 ucode->ucode = ucode->bootloader + ucode->bootloader_size;
402 ucode->phys_base = ucode->bootloader_phys_base + ucode->bootloader_size;
403 ucode->size = desc.imem_sec_size;
404 ucode->dmem = ucode->bootloader + desc.dmem_offset;
405 ucode->dmem_phys_base = desc.dmem_phys_base;
406 ucode->dmem_size = desc.dmem_load_size;
407
408 return gm206_bios_parse_appinfo_table(g,
409 offset + sizeof(desc) +
410 desc.dmem_offset + desc.interface_offset);
411}
412
413static int gm206_bios_parse_falcon_ucode_table(struct gk20a *g, int offset)
414{
415 struct falcon_ucode_table_hdr_v1 hdr;
416 int i;
417
418 memcpy(&hdr, &g->bios.data[offset], sizeof(hdr));
419 gk20a_dbg_fn("falcon ucode table ver %d size %d entrySize %d entryCount %d descVer %d descSize %d",
420 hdr.version, hdr.header_size,
421 hdr.entry_size, hdr.entry_count,
422 hdr.desc_version, hdr.desc_size);
423
424 if (hdr.version != 1)
425 return -EINVAL;
426
427 offset += hdr.header_size;
428
429 for (i = 0; i < hdr.entry_count; i++) {
430 struct falcon_ucode_table_entry_v1 entry;
431
432 memcpy(&entry, &g->bios.data[offset], sizeof(entry));
433
434 gk20a_dbg_fn("falcon ucode table entry appid %x targetId %x descPtr %x",
435 entry.application_id, entry.target_id,
436 entry.desc_ptr);
437
438 if (entry.target_id == TARGET_ID_PMU &&
439 entry.application_id == APPLICATION_ID_DEVINIT) {
440 int err;
441
442 err = gm206_bios_parse_falcon_ucode_desc(g,
443 &g->bios.devinit, entry.desc_ptr);
444 if (err)
445 err = gm206_bios_parse_falcon_ucode_desc(g,
446 &g->bios.devinit,
447 entry.desc_ptr +
448 g->bios.expansion_rom_offset);
449
450 if (err)
451 gk20a_err(dev_from_gk20a(g),
452 "could not parse devinit ucode desc");
453 } else if (entry.target_id == TARGET_ID_PMU &&
454 entry.application_id == APPLICATION_ID_PRE_OS) {
455 int err;
456
457 err = gm206_bios_parse_falcon_ucode_desc(g,
458 &g->bios.preos, entry.desc_ptr);
459 if (err)
460 err = gm206_bios_parse_falcon_ucode_desc(g,
461 &g->bios.preos,
462 entry.desc_ptr +
463 g->bios.expansion_rom_offset);
464
465 if (err)
466 gk20a_err(dev_from_gk20a(g),
467 "could not parse preos ucode desc");
468 }
469
470 offset += hdr.entry_size;
471 }
472
473 return 0;
474}
475
476static void gm206_bios_parse_falcon_data_v2(struct gk20a *g, int offset)
477{
478 struct falcon_data_v2 falcon_data;
479 int err;
480
481 memcpy(&falcon_data, &g->bios.data[offset], sizeof(falcon_data));
482 gk20a_dbg_fn("falcon ucode table ptr %x",
483 falcon_data.falcon_ucode_table_ptr);
484 err = gm206_bios_parse_falcon_ucode_table(g,
485 falcon_data.falcon_ucode_table_ptr);
486 if (err)
487 err = gm206_bios_parse_falcon_ucode_table(g,
488 falcon_data.falcon_ucode_table_ptr +
489 g->bios.expansion_rom_offset);
490
491 if (err)
492 gk20a_err(dev_from_gk20a(g),
493 "could not parse falcon ucode table");
494}
495
496static void *gm206_bios_get_perf_table_ptrs(struct gk20a *g,
497 struct bit_token *ptoken, u8 table_id)
498{
499 u32 perf_table_id_offset = 0;
500 u8 *perf_table_ptr = NULL;
501 u8 data_size = 4;
502
503 if (ptoken != NULL) {
504
505 if (ptoken->token_id == TOKEN_ID_VIRT_PTRS) {
506 perf_table_id_offset = *((u16 *)&g->bios.data[
507 ptoken->data_ptr +
508 (table_id * PERF_PTRS_WIDTH_16)]);
509 data_size = PERF_PTRS_WIDTH_16;
510 } else {
511 perf_table_id_offset = *((u32 *)&g->bios.data[
512 ptoken->data_ptr +
513 (table_id * PERF_PTRS_WIDTH)]);
514 data_size = PERF_PTRS_WIDTH;
515 }
516 } else
517 return (void *)perf_table_ptr;
518
519 if (table_id < (ptoken->data_size/data_size)) {
520
521 gk20a_dbg_info("Perf_Tbl_ID-offset 0x%x Tbl_ID_Ptr-offset- 0x%x",
522 (ptoken->data_ptr +
523 (table_id * data_size)),
524 perf_table_id_offset);
525
526 if (perf_table_id_offset != 0) {
527 /* check is perf_table_id_offset is > 64k */
528 if (perf_table_id_offset & ~0xFFFF)
529 perf_table_ptr =
530 &g->bios.data[g->bios.expansion_rom_offset +
531 perf_table_id_offset];
532 else
533 perf_table_ptr =
534 &g->bios.data[perf_table_id_offset];
535 } else
536 gk20a_warn(g->dev, "PERF TABLE ID %d is NULL",
537 table_id);
538 } else
539 gk20a_warn(g->dev, "INVALID PERF TABLE ID - %d ", table_id);
540
541 return (void *)perf_table_ptr;
542}
543
544static void gm206_bios_parse_bit(struct gk20a *g, int offset)
545{
546 struct bit bit;
547 struct bit_token bit_token;
548 int i;
549
550 gk20a_dbg_fn("");
551 memcpy(&bit, &g->bios.data[offset], sizeof(bit));
552
553 gk20a_dbg_info("BIT header: %04x %08x", bit.id, bit.signature);
554 gk20a_dbg_info("tokens: %d entries * %d bytes",
555 bit.token_entries, bit.token_size);
556
557 offset += bit.header_size;
558 for (i = 0; i < bit.token_entries; i++) {
559 memcpy(&bit_token, &g->bios.data[offset], sizeof(bit_token));
560
561 gk20a_dbg_info("BIT token id %d ptr %d size %d ver %d",
562 bit_token.token_id, bit_token.data_ptr,
563 bit_token.data_size, bit_token.data_version);
564
565 switch (bit_token.token_id) {
566 case TOKEN_ID_BIOSDATA:
567 gm206_bios_parse_biosdata(g, bit_token.data_ptr);
568 break;
569 case TOKEN_ID_NVINIT_PTRS:
570 gm206_bios_parse_nvinit_ptrs(g, bit_token.data_ptr);
571 break;
572 case TOKEN_ID_FALCON_DATA:
573 if (bit_token.data_version == 2)
574 gm206_bios_parse_falcon_data_v2(g,
575 bit_token.data_ptr);
576 break;
577 case TOKEN_ID_PERF_PTRS:
578 g->bios.perf_token =
579 (struct bit_token *)&g->bios.data[offset];
580 break;
581 case TOKEN_ID_CLOCK_PTRS:
582 g->bios.clock_token =
583 (struct bit_token *)&g->bios.data[offset];
584 break;
585 case TOKEN_ID_VIRT_PTRS:
586 g->bios.virt_token =
587 (struct bit_token *)&g->bios.data[offset];
588 break;
589 case TOKEN_ID_MEMORY_PTRS:
590 gm206_bios_parse_memory_ptrs(g, bit_token.data_ptr,
591 bit_token.data_version);
592 default:
593 break;
594 }
595
596 offset += bit.token_size;
597 }
598 gk20a_dbg_fn("done");
599}
600
601static u32 __gm206_bios_readbyte(struct gk20a *g, u32 offset)
602{
603 return (u32) g->bios.data[offset];
604}
605
606u8 gm206_bios_read_u8(struct gk20a *g, u32 offset)
607{
608 return (u8) __gm206_bios_readbyte(g, offset);
609}
610
611s8 gm206_bios_read_s8(struct gk20a *g, u32 offset)
612{
613 u32 val;
614 val = __gm206_bios_readbyte(g, offset);
615 val = val & 0x80 ? (val | ~0xff) : val;
616
617 return (s8) val;
618}
619
620u16 gm206_bios_read_u16(struct gk20a *g, u32 offset)
621{
622 u16 val;
623
624 val = __gm206_bios_readbyte(g, offset) |
625 (__gm206_bios_readbyte(g, offset+1) << 8);
626
627 return val;
628}
629
630u32 gm206_bios_read_u32(struct gk20a *g, u32 offset)
631{
632 u32 val;
633
634 val = __gm206_bios_readbyte(g, offset) |
635 (__gm206_bios_readbyte(g, offset+1) << 8) |
636 (__gm206_bios_readbyte(g, offset+2) << 16) |
637 (__gm206_bios_readbyte(g, offset+3) << 24);
638
639 return val;
640}
641 38
642static void upload_code(struct gk20a *g, u32 dst, 39static void upload_code(struct gk20a *g, u32 dst,
643 u8 *src, u32 size, u8 port, bool sec) 40 u8 *src, u32 size, u8 port, bool sec)
@@ -831,14 +228,13 @@ static int gm206_bios_preos(struct gk20a *g)
831 return err; 228 return err;
832} 229}
833 230
834static int gm206_bios_init(struct gk20a *g) 231int gm206_bios_init(struct gk20a *g)
835{ 232{
836 unsigned int i; 233 unsigned int i;
837 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 234 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
838 struct dentry *d; 235 struct dentry *d;
839 const struct firmware *bios_fw; 236 const struct firmware *bios_fw;
840 int err; 237 int err;
841 bool found = 0;
842 struct pci_dev *pdev = to_pci_dev(g->dev); 238 struct pci_dev *pdev = to_pci_dev(g->dev);
843 char rom_name[sizeof(BIOS_OVERLAY_NAME_FORMATTED)]; 239 char rom_name[sizeof(BIOS_OVERLAY_NAME_FORMATTED)];
844 240
@@ -880,24 +276,10 @@ static int gm206_bios_init(struct gk20a *g)
880 g->ops.xve.enable_shadow_rom(g); 276 g->ops.xve.enable_shadow_rom(g);
881 } 277 }
882 278
883 err = gm206_bios_parse_rom(g); 279 err = nvgpu_bios_parse_rom(g);
884 if (err) 280 if (err)
885 return err; 281 return err;
886 282
887 gk20a_dbg_info("read bios");
888 for (i = 0; i < g->bios.size - 6; i++) {
889 if (gm206_bios_rdu16(g, i) == BIT_HEADER_ID &&
890 gm206_bios_rdu32(g, i+2) == BIT_HEADER_SIGNATURE) {
891 gm206_bios_parse_bit(g, i);
892 found = true;
893 }
894 }
895
896 if (!found) {
897 gk20a_err(g->dev, "no valid VBIOS found");
898 return -EINVAL;
899 }
900
901 if (g->gpu_characteristics.vbios_version < 283 if (g->gpu_characteristics.vbios_version <
902 platform->vbios_min_version) { 284 platform->vbios_min_version) {
903 gk20a_err(g->dev, "unsupported VBIOS version %08x", 285 gk20a_err(g->dev, "unsupported VBIOS version %08x",
@@ -936,8 +318,7 @@ free_firmware:
936 return err; 318 return err;
937} 319}
938 320
939void gm206_init_bios(struct gpu_ops *gops) 321void gm206_init_bios_ops(struct gpu_ops *gops)
940{ 322{
941 gops->bios.init = gm206_bios_init; 323 gops->bios_init = gm206_bios_init;
942 gops->bios.get_perf_table_ptrs = gm206_bios_get_perf_table_ptrs;
943} 324}
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.h b/drivers/gpu/nvgpu/gm206/bios_gm206.h
index 6fe19fb0..090c7d24 100644
--- a/drivers/gpu/nvgpu/gm206/bios_gm206.h
+++ b/drivers/gpu/nvgpu/gm206/bios_gm206.h
@@ -14,60 +14,10 @@
14#ifndef NVGPU_BIOS_GM206_H 14#ifndef NVGPU_BIOS_GM206_H
15#define NVGPU_BIOS_GM206_H 15#define NVGPU_BIOS_GM206_H
16 16
17#define PERF_PTRS_WIDTH 0x4 17struct gk20a;
18#define PERF_PTRS_WIDTH_16 0x2
19
20#define NV_PCFG 0x88000
21
22enum {
23 CLOCKS_TABLE = 2,
24 CLOCK_PROGRAMMING_TABLE,
25 FLL_TABLE,
26 VIN_TABLE,
27 FREQUENCY_CONTROLLER_TABLE
28};
29
30enum {
31 PERFORMANCE_TABLE = 0,
32 MEMORY_CLOCK_TABLE,
33 MEMORY_TWEAK_TABLE,
34 POWER_CONTROL_TABLE,
35 THERMAL_CONTROL_TABLE,
36 THERMAL_DEVICE_TABLE,
37 THERMAL_COOLERS_TABLE,
38 PERFORMANCE_SETTINGS_SCRIPT,
39 CONTINUOUS_VIRTUAL_BINNING_TABLE,
40 POWER_SENSORS_TABLE = 0xA,
41 POWER_CAPPING_TABLE = 0xB,
42 POWER_TOPOLOGY_TABLE = 0xF,
43 THERMAL_CHANNEL_TABLE = 0x12,
44 VOLTAGE_RAIL_TABLE = 26,
45 VOLTAGE_DEVICE_TABLE,
46 VOLTAGE_POLICY_TABLE,
47 LOWPOWER_TABLE,
48 LOWPOWER_GR_TABLE = 32,
49 LOWPOWER_MS_TABLE = 33,
50};
51
52enum {
53 VP_FIELD_TABLE = 0,
54 VP_FIELD_REGISTER,
55 VP_TRANSLATION_TABLE,
56};
57
58struct bit_token {
59 u8 token_id;
60 u8 data_version;
61 u16 data_size;
62 u16 data_ptr;
63} __packed;
64
65struct gpu_ops; 18struct gpu_ops;
66 19
67void gm206_init_bios(struct gpu_ops *gops); 20int gm206_bios_init(struct gk20a *g);
68u8 gm206_bios_read_u8(struct gk20a *g, u32 offset); 21void gm206_init_bios_ops(struct gpu_ops *gops);
69s8 gm206_bios_read_s8(struct gk20a *g, u32 offset);
70u16 gm206_bios_read_u16(struct gk20a *g, u32 offset);
71u32 gm206_bios_read_u32(struct gk20a *g, u32 offset);
72 22
73#endif 23#endif
diff --git a/drivers/gpu/nvgpu/gm206/hal_gm206.c b/drivers/gpu/nvgpu/gm206/hal_gm206.c
index 8ad5a397..e2b84d81 100644
--- a/drivers/gpu/nvgpu/gm206/hal_gm206.c
+++ b/drivers/gpu/nvgpu/gm206/hal_gm206.c
@@ -198,7 +198,7 @@ int gm206_init_hal(struct gk20a *g)
198#if defined(CONFIG_GK20A_CYCLE_STATS) 198#if defined(CONFIG_GK20A_CYCLE_STATS)
199 gk20a_init_css_ops(gops); 199 gk20a_init_css_ops(gops);
200#endif 200#endif
201 gm206_init_bios(gops); 201 gm206_init_bios_ops(gops);
202 switch(ver){ 202 switch(ver){
203 case GK20A_GPUID_GM206: 203 case GK20A_GPUID_GM206:
204 gops->name = "gm206"; 204 gops->name = "gm206";