| .. | .. |
|---|
| 22 | 22 | #include "gf100.h" |
|---|
| 23 | 23 | #include "ctxgf100.h" |
|---|
| 24 | 24 | |
|---|
| 25 | +#include <core/firmware.h> |
|---|
| 26 | +#include <subdev/acr.h> |
|---|
| 25 | 27 | #include <subdev/timer.h> |
|---|
| 26 | 28 | |
|---|
| 29 | +#include <nvfw/flcn.h> |
|---|
| 30 | + |
|---|
| 27 | 31 | #include <nvif/class.h> |
|---|
| 32 | + |
|---|
| 33 | +void |
|---|
| 34 | +gm20b_gr_acr_bld_patch(struct nvkm_acr *acr, u32 bld, s64 adjust) |
|---|
| 35 | +{ |
|---|
| 36 | + struct flcn_bl_dmem_desc hdr; |
|---|
| 37 | + u64 addr; |
|---|
| 38 | + |
|---|
| 39 | + nvkm_robj(acr->wpr, bld, &hdr, sizeof(hdr)); |
|---|
| 40 | + addr = ((u64)hdr.code_dma_base1 << 40 | hdr.code_dma_base << 8); |
|---|
| 41 | + hdr.code_dma_base = lower_32_bits((addr + adjust) >> 8); |
|---|
| 42 | + hdr.code_dma_base1 = upper_32_bits((addr + adjust) >> 8); |
|---|
| 43 | + addr = ((u64)hdr.data_dma_base1 << 40 | hdr.data_dma_base << 8); |
|---|
| 44 | + hdr.data_dma_base = lower_32_bits((addr + adjust) >> 8); |
|---|
| 45 | + hdr.data_dma_base1 = upper_32_bits((addr + adjust) >> 8); |
|---|
| 46 | + nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr)); |
|---|
| 47 | + |
|---|
| 48 | + flcn_bl_dmem_desc_dump(&acr->subdev, &hdr); |
|---|
| 49 | +} |
|---|
| 50 | + |
|---|
| 51 | +void |
|---|
| 52 | +gm20b_gr_acr_bld_write(struct nvkm_acr *acr, u32 bld, |
|---|
| 53 | + struct nvkm_acr_lsfw *lsfw) |
|---|
| 54 | +{ |
|---|
| 55 | + const u64 base = lsfw->offset.img + lsfw->app_start_offset; |
|---|
| 56 | + const u64 code = (base + lsfw->app_resident_code_offset) >> 8; |
|---|
| 57 | + const u64 data = (base + lsfw->app_resident_data_offset) >> 8; |
|---|
| 58 | + const struct flcn_bl_dmem_desc hdr = { |
|---|
| 59 | + .ctx_dma = FALCON_DMAIDX_UCODE, |
|---|
| 60 | + .code_dma_base = lower_32_bits(code), |
|---|
| 61 | + .non_sec_code_off = lsfw->app_resident_code_offset, |
|---|
| 62 | + .non_sec_code_size = lsfw->app_resident_code_size, |
|---|
| 63 | + .code_entry_point = lsfw->app_imem_entry, |
|---|
| 64 | + .data_dma_base = lower_32_bits(data), |
|---|
| 65 | + .data_size = lsfw->app_resident_data_size, |
|---|
| 66 | + .code_dma_base1 = upper_32_bits(code), |
|---|
| 67 | + .data_dma_base1 = upper_32_bits(data), |
|---|
| 68 | + }; |
|---|
| 69 | + |
|---|
| 70 | + nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr)); |
|---|
| 71 | +} |
|---|
| 72 | + |
|---|
| 73 | +const struct nvkm_acr_lsf_func |
|---|
| 74 | +gm20b_gr_fecs_acr = { |
|---|
| 75 | + .bld_size = sizeof(struct flcn_bl_dmem_desc), |
|---|
| 76 | + .bld_write = gm20b_gr_acr_bld_write, |
|---|
| 77 | + .bld_patch = gm20b_gr_acr_bld_patch, |
|---|
| 78 | +}; |
|---|
| 28 | 79 | |
|---|
| 29 | 80 | static void |
|---|
| 30 | 81 | gm20b_gr_init_gpc_mmu(struct gf100_gr *gr) |
|---|
| .. | .. |
|---|
| 33 | 84 | u32 val; |
|---|
| 34 | 85 | |
|---|
| 35 | 86 | /* Bypass MMU check for non-secure boot */ |
|---|
| 36 | | - if (!device->secboot) { |
|---|
| 87 | + if (!device->acr) { |
|---|
| 37 | 88 | nvkm_wr32(device, 0x100ce4, 0xffffffff); |
|---|
| 38 | 89 | |
|---|
| 39 | 90 | if (nvkm_rd32(device, 0x100ce4) != 0xffffffff) |
|---|
| .. | .. |
|---|
| 85 | 136 | } |
|---|
| 86 | 137 | }; |
|---|
| 87 | 138 | |
|---|
| 139 | +static int |
|---|
| 140 | +gm20b_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif) |
|---|
| 141 | +{ |
|---|
| 142 | + struct nvkm_subdev *subdev = &gr->base.engine.subdev; |
|---|
| 143 | + int ret; |
|---|
| 144 | + |
|---|
| 145 | + ret = nvkm_acr_lsfw_load_bl_inst_data_sig(subdev, &gr->fecs.falcon, |
|---|
| 146 | + NVKM_ACR_LSF_FECS, |
|---|
| 147 | + "gr/fecs_", ver, fwif->fecs); |
|---|
| 148 | + if (ret) |
|---|
| 149 | + return ret; |
|---|
| 150 | + |
|---|
| 151 | + |
|---|
| 152 | + if (nvkm_firmware_load_blob(subdev, "gr/", "gpccs_inst", ver, |
|---|
| 153 | + &gr->gpccs.inst) || |
|---|
| 154 | + nvkm_firmware_load_blob(subdev, "gr/", "gpccs_data", ver, |
|---|
| 155 | + &gr->gpccs.data)) |
|---|
| 156 | + return -ENOENT; |
|---|
| 157 | + |
|---|
| 158 | + gr->firmware = true; |
|---|
| 159 | + |
|---|
| 160 | + return gk20a_gr_load_sw(gr, "gr/", ver); |
|---|
| 161 | +} |
|---|
| 162 | + |
|---|
| 163 | +#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) |
|---|
| 164 | +MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_bl.bin"); |
|---|
| 165 | +MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_inst.bin"); |
|---|
| 166 | +MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_data.bin"); |
|---|
| 167 | +MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_sig.bin"); |
|---|
| 168 | +MODULE_FIRMWARE("nvidia/gm20b/gr/gpccs_inst.bin"); |
|---|
| 169 | +MODULE_FIRMWARE("nvidia/gm20b/gr/gpccs_data.bin"); |
|---|
| 170 | +MODULE_FIRMWARE("nvidia/gm20b/gr/sw_ctx.bin"); |
|---|
| 171 | +MODULE_FIRMWARE("nvidia/gm20b/gr/sw_nonctx.bin"); |
|---|
| 172 | +MODULE_FIRMWARE("nvidia/gm20b/gr/sw_bundle_init.bin"); |
|---|
| 173 | +MODULE_FIRMWARE("nvidia/gm20b/gr/sw_method_init.bin"); |
|---|
| 174 | +#endif |
|---|
| 175 | + |
|---|
| 176 | +static const struct gf100_gr_fwif |
|---|
| 177 | +gm20b_gr_fwif[] = { |
|---|
| 178 | + { 0, gm20b_gr_load, &gm20b_gr, &gm20b_gr_fecs_acr }, |
|---|
| 179 | + { -1, gm200_gr_nofw }, |
|---|
| 180 | + {} |
|---|
| 181 | +}; |
|---|
| 182 | + |
|---|
| 88 | 183 | int |
|---|
| 89 | 184 | gm20b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) |
|---|
| 90 | 185 | { |
|---|
| 91 | | - return gm200_gr_new_(&gm20b_gr, device, index, pgr); |
|---|
| 186 | + return gf100_gr_new_(gm20b_gr_fwif, device, index, pgr); |
|---|
| 92 | 187 | } |
|---|