diff options
author | David Nieto <dmartineznie@nvidia.com> | 2017-08-04 00:42:46 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-08-11 14:07:17 -0400 |
commit | eb9864d92dfc494d0186c4afaca81280c0953f8c (patch) | |
tree | 47b7fd47d02fb39b210d9e21cd4ef36d898450b1 /drivers/gpu/nvgpu/common/vbios/bios.c | |
parent | f7c5a179fe860524846f1e2b01b25b7af3a89ba6 (diff) |
gpu: nvgpu: PG503 support
Adds basic PG503 support allowing devinit to complete.
JIRA: EVLR-1693
Change-Id: Ice8a9ba18c8bba11f6bc174ba2c2d8802a738706
Signed-off-by: David Nieto <dmartineznie@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1532746
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/vbios/bios.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/vbios/bios.c | 103 |
1 files changed, 92 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/common/vbios/bios.c b/drivers/gpu/nvgpu/common/vbios/bios.c index b84542bf..068c9af8 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios.c +++ b/drivers/gpu/nvgpu/common/vbios/bios.c | |||
@@ -133,6 +133,22 @@ struct falcon_ucode_table_entry_v1 { | |||
133 | #define APPLICATION_ID_DEVINIT 0x04 | 133 | #define APPLICATION_ID_DEVINIT 0x04 |
134 | #define APPLICATION_ID_PRE_OS 0x01 | 134 | #define APPLICATION_ID_PRE_OS 0x01 |
135 | 135 | ||
136 | #define FALCON_UCODE_FLAGS_VERSION_AVAILABLE 0x1 | ||
137 | #define FALCON_UCODE_IS_VERSION_AVAILABLE(hdr) \ | ||
138 | ((hdr.v2.v_desc & FALCON_UCODE_FLAGS_VERSION_AVAILABLE) == \ | ||
139 | FALCON_UCODE_FLAGS_VERSION_AVAILABLE) | ||
140 | |||
141 | /* | ||
142 | * version is embedded in bits 8:15 of the header on version 2+ | ||
143 | * and the header length in bits 16:31 | ||
144 | */ | ||
145 | |||
146 | #define FALCON_UCODE_GET_VERSION(hdr) \ | ||
147 | ((hdr.v2.v_desc >> 8) & 0xff) | ||
148 | |||
149 | #define FALCON_UCODE_GET_DESC_SIZE(hdr) \ | ||
150 | ((hdr.v2.v_desc >> 16) & 0xffff) | ||
151 | |||
136 | struct falcon_ucode_desc_v1 { | 152 | struct falcon_ucode_desc_v1 { |
137 | union { | 153 | union { |
138 | u32 v_desc; | 154 | u32 v_desc; |
@@ -151,6 +167,29 @@ struct falcon_ucode_desc_v1 { | |||
151 | u32 dmem_load_size; | 167 | u32 dmem_load_size; |
152 | } __packed; | 168 | } __packed; |
153 | 169 | ||
170 | struct falcon_ucode_desc_v2 { | ||
171 | u32 v_desc; | ||
172 | u32 stored_size; | ||
173 | u32 uncompressed_size; | ||
174 | u32 virtual_entry; | ||
175 | u32 interface_offset; | ||
176 | u32 imem_phys_base; | ||
177 | u32 imem_load_size; | ||
178 | u32 imem_virt_base; | ||
179 | u32 imem_sec_base; | ||
180 | u32 imem_sec_size; | ||
181 | u32 dmem_offset; | ||
182 | u32 dmem_phys_base; | ||
183 | u32 dmem_load_size; | ||
184 | u32 alt_imem_load_size; | ||
185 | u32 alt_dmem_load_size; | ||
186 | } __packed; | ||
187 | |||
188 | union falcon_ucode_desc { | ||
189 | struct falcon_ucode_desc_v1 v1; | ||
190 | struct falcon_ucode_desc_v2 v2; | ||
191 | }; | ||
192 | |||
154 | struct application_interface_table_hdr_v1 { | 193 | struct application_interface_table_hdr_v1 { |
155 | u8 version; | 194 | u8 version; |
156 | u8 header_size; | 195 | u8 header_size; |
@@ -166,8 +205,10 @@ struct application_interface_entry_v1 { | |||
166 | #define APPINFO_ID_DEVINIT 0x01 | 205 | #define APPINFO_ID_DEVINIT 0x01 |
167 | 206 | ||
168 | struct devinit_engine_interface { | 207 | struct devinit_engine_interface { |
169 | u32 field0; | 208 | u16 version; |
170 | u32 field1; | 209 | u16 size; |
210 | u16 application_version; | ||
211 | u16 application_features; | ||
171 | u32 tables_phys_base; | 212 | u32 tables_phys_base; |
172 | u32 tables_virt_base; | 213 | u32 tables_virt_base; |
173 | u32 script_phys_base; | 214 | u32 script_phys_base; |
@@ -348,11 +389,14 @@ static void nvgpu_bios_parse_devinit_appinfo(struct gk20a *g, int dmem_offset) | |||
348 | struct devinit_engine_interface interface; | 389 | struct devinit_engine_interface interface; |
349 | 390 | ||
350 | memcpy(&interface, &g->bios.devinit.dmem[dmem_offset], sizeof(interface)); | 391 | memcpy(&interface, &g->bios.devinit.dmem[dmem_offset], sizeof(interface)); |
351 | gk20a_dbg_fn("devinit tables phys %x script phys %x size %d", | 392 | gk20a_dbg_fn("devinit version %x tables phys %x script phys %x size %d", |
393 | interface.version, | ||
352 | interface.tables_phys_base, | 394 | interface.tables_phys_base, |
353 | interface.script_phys_base, | 395 | interface.script_phys_base, |
354 | interface.script_size); | 396 | interface.script_size); |
355 | 397 | ||
398 | if (interface.version != 1) | ||
399 | return; | ||
356 | g->bios.devinit_tables_phys_base = interface.tables_phys_base; | 400 | g->bios.devinit_tables_phys_base = interface.tables_phys_base; |
357 | g->bios.devinit_script_phys_base = interface.script_phys_base; | 401 | g->bios.devinit_script_phys_base = interface.script_phys_base; |
358 | } | 402 | } |
@@ -392,28 +436,65 @@ static int nvgpu_bios_parse_appinfo_table(struct gk20a *g, int offset) | |||
392 | static int nvgpu_bios_parse_falcon_ucode_desc(struct gk20a *g, | 436 | static int nvgpu_bios_parse_falcon_ucode_desc(struct gk20a *g, |
393 | struct nvgpu_bios_ucode *ucode, int offset) | 437 | struct nvgpu_bios_ucode *ucode, int offset) |
394 | { | 438 | { |
395 | struct falcon_ucode_desc_v1 desc; | 439 | union falcon_ucode_desc udesc; |
440 | struct falcon_ucode_desc_v2 desc; | ||
441 | u8 version; | ||
442 | u16 desc_size; | ||
443 | |||
444 | memcpy(&udesc, &g->bios.data[offset], sizeof(udesc)); | ||
445 | |||
446 | if (FALCON_UCODE_IS_VERSION_AVAILABLE(udesc)) { | ||
447 | version = FALCON_UCODE_GET_VERSION(udesc); | ||
448 | desc_size = FALCON_UCODE_GET_DESC_SIZE(udesc); | ||
449 | } else { | ||
450 | version = 1; | ||
451 | desc_size = sizeof(udesc.v1); | ||
452 | } | ||
453 | |||
454 | switch (version) { | ||
455 | case 1: | ||
456 | desc.stored_size = udesc.v1.hdr_size.stored_size; | ||
457 | desc.uncompressed_size = udesc.v1.uncompressed_size; | ||
458 | desc.virtual_entry = udesc.v1.virtual_entry; | ||
459 | desc.interface_offset = udesc.v1.interface_offset; | ||
460 | desc.imem_phys_base = udesc.v1.imem_phys_base; | ||
461 | desc.imem_load_size = udesc.v1.imem_load_size; | ||
462 | desc.imem_virt_base = udesc.v1.imem_virt_base; | ||
463 | desc.imem_sec_base = udesc.v1.imem_sec_base; | ||
464 | desc.imem_sec_size = udesc.v1.imem_sec_size; | ||
465 | desc.dmem_offset = udesc.v1.dmem_offset; | ||
466 | desc.dmem_phys_base = udesc.v1.dmem_phys_base; | ||
467 | desc.dmem_load_size = udesc.v1.dmem_load_size; | ||
468 | break; | ||
469 | case 2: | ||
470 | memcpy(&desc, &udesc, sizeof(udesc.v2)); | ||
471 | break; | ||
472 | default: | ||
473 | gk20a_dbg_info("invalid version"); | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | |||
477 | gk20a_dbg_info("falcon ucode desc version %x len %x", version, desc_size); | ||
396 | 478 | ||
397 | memcpy(&desc, &g->bios.data[offset], sizeof(desc)); | 479 | gk20a_dbg_info("falcon ucode desc stored size %x uncompressed size %x", |
398 | gk20a_dbg_info("falcon ucode desc stored size %d uncompressed size %d", | 480 | desc.stored_size, desc.uncompressed_size); |
399 | desc.hdr_size.stored_size, desc.uncompressed_size); | ||
400 | gk20a_dbg_info("falcon ucode desc virtualEntry %x, interfaceOffset %x", | 481 | gk20a_dbg_info("falcon ucode desc virtualEntry %x, interfaceOffset %x", |
401 | desc.virtual_entry, desc.interface_offset); | 482 | desc.virtual_entry, desc.interface_offset); |
402 | gk20a_dbg_info("falcon ucode IMEM phys base %x, load size %x virt base %x sec base %x sec size %x", | 483 | gk20a_dbg_info("falcon ucode IMEM phys base %x, load size %x virt base %x sec base %x sec size %x", |
403 | desc.imem_phys_base, desc.imem_load_size, | 484 | desc.imem_phys_base, desc.imem_load_size, |
404 | desc.imem_virt_base, desc.imem_sec_base, | 485 | desc.imem_virt_base, desc.imem_sec_base, |
405 | desc.imem_sec_size); | 486 | desc.imem_sec_size); |
406 | gk20a_dbg_info("falcon ucode DMEM offset %d phys base %x, load size %d", | 487 | gk20a_dbg_info("falcon ucode DMEM offset %x phys base %x, load size %x", |
407 | desc.dmem_offset, desc.dmem_phys_base, | 488 | desc.dmem_offset, desc.dmem_phys_base, |
408 | desc.dmem_load_size); | 489 | desc.dmem_load_size); |
409 | 490 | ||
410 | if (desc.hdr_size.stored_size != desc.uncompressed_size) { | 491 | if (desc.stored_size != desc.uncompressed_size) { |
411 | gk20a_dbg_info("does not match"); | 492 | gk20a_dbg_info("does not match"); |
412 | return -EINVAL; | 493 | return -EINVAL; |
413 | } | 494 | } |
414 | 495 | ||
415 | ucode->code_entry_point = desc.virtual_entry; | 496 | ucode->code_entry_point = desc.virtual_entry; |
416 | ucode->bootloader = &g->bios.data[offset] + sizeof(desc); | 497 | ucode->bootloader = &g->bios.data[offset] + desc_size; |
417 | ucode->bootloader_phys_base = desc.imem_phys_base; | 498 | ucode->bootloader_phys_base = desc.imem_phys_base; |
418 | ucode->bootloader_size = desc.imem_load_size - desc.imem_sec_size; | 499 | ucode->bootloader_size = desc.imem_load_size - desc.imem_sec_size; |
419 | ucode->ucode = ucode->bootloader + ucode->bootloader_size; | 500 | ucode->ucode = ucode->bootloader + ucode->bootloader_size; |
@@ -424,7 +505,7 @@ static int nvgpu_bios_parse_falcon_ucode_desc(struct gk20a *g, | |||
424 | ucode->dmem_size = desc.dmem_load_size; | 505 | ucode->dmem_size = desc.dmem_load_size; |
425 | 506 | ||
426 | return nvgpu_bios_parse_appinfo_table(g, | 507 | return nvgpu_bios_parse_appinfo_table(g, |
427 | offset + sizeof(desc) + | 508 | offset + desc_size + |
428 | desc.dmem_offset + desc.interface_offset); | 509 | desc.dmem_offset + desc.interface_offset); |
429 | } | 510 | } |
430 | 511 | ||