2 * Copyright 2019 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
24 #include <core/firmware.h>
25 #include <core/memory.h>
26 #include <subdev/mmu.h>
27 #include <subdev/pmu.h>
30 #include <nvfw/flcn.h>
33 gm20b_acr_wpr_alloc(struct nvkm_acr
*acr
, u32 wpr_size
)
35 struct nvkm_subdev
*subdev
= &acr
->subdev
;
37 acr
->func
->wpr_check(acr
, &acr
->wpr_start
, &acr
->wpr_end
);
39 if ((acr
->wpr_end
- acr
->wpr_start
) < wpr_size
) {
40 nvkm_error(subdev
, "WPR image too big for WPR!\n");
44 return nvkm_memory_new(subdev
->device
, NVKM_MEM_TARGET_INST
,
45 wpr_size
, 0, true, &acr
->wpr
);
49 gm20b_acr_load_bld(struct nvkm_acr
*acr
, struct nvkm_acr_hsf
*hsf
)
51 struct flcn_bl_dmem_desc hsdesc
= {
52 .ctx_dma
= FALCON_DMAIDX_VIRT
,
53 .code_dma_base
= hsf
->vma
->addr
>> 8,
54 .non_sec_code_off
= hsf
->non_sec_addr
,
55 .non_sec_code_size
= hsf
->non_sec_size
,
56 .sec_code_off
= hsf
->sec_addr
,
57 .sec_code_size
= hsf
->sec_size
,
58 .code_entry_point
= 0,
59 .data_dma_base
= (hsf
->vma
->addr
+ hsf
->data_addr
) >> 8,
60 .data_size
= hsf
->data_size
,
63 flcn_bl_dmem_desc_dump(&acr
->subdev
, &hsdesc
);
65 nvkm_falcon_load_dmem(hsf
->falcon
, &hsdesc
, 0, sizeof(hsdesc
), 0);
69 gm20b_acr_load_load(struct nvkm_acr
*acr
, struct nvkm_acr_hsfw
*hsfw
)
71 struct flcn_acr_desc
*desc
= (void *)&hsfw
->image
[hsfw
->data_addr
];
73 desc
->ucode_blob_base
= nvkm_memory_addr(acr
->wpr
);
74 desc
->ucode_blob_size
= nvkm_memory_size(acr
->wpr
);
75 flcn_acr_desc_dump(&acr
->subdev
, desc
);
77 return gm200_acr_hsfw_load(acr
, hsfw
, &acr
->subdev
.device
->pmu
->falcon
);
80 const struct nvkm_acr_hsf_func
82 .load
= gm20b_acr_load_load
,
83 .boot
= gm200_acr_load_boot
,
84 .bld
= gm20b_acr_load_bld
,
87 #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
88 MODULE_FIRMWARE("nvidia/gm20b/acr/bl.bin");
89 MODULE_FIRMWARE("nvidia/gm20b/acr/ucode_load.bin");
92 static const struct nvkm_acr_hsf_fwif
93 gm20b_acr_load_fwif
[] = {
94 { 0, nvkm_acr_hsfw_load
, &gm20b_acr_load_0
},
98 static const struct nvkm_acr_func
100 .load
= gm20b_acr_load_fwif
,
101 .wpr_parse
= gm200_acr_wpr_parse
,
102 .wpr_layout
= gm200_acr_wpr_layout
,
103 .wpr_alloc
= gm20b_acr_wpr_alloc
,
104 .wpr_build
= gm200_acr_wpr_build
,
105 .wpr_patch
= gm200_acr_wpr_patch
,
106 .wpr_check
= gm200_acr_wpr_check
,
107 .init
= gm200_acr_init
,
111 gm20b_acr_load(struct nvkm_acr
*acr
, int ver
, const struct nvkm_acr_fwif
*fwif
)
113 struct nvkm_subdev
*subdev
= &acr
->subdev
;
114 const struct nvkm_acr_hsf_fwif
*hsfwif
;
116 hsfwif
= nvkm_firmware_load(subdev
, fwif
->func
->load
, "AcrLoad",
117 acr
, "acr/bl", "acr/ucode_load", "load");
119 return PTR_ERR(hsfwif
);
124 static const struct nvkm_acr_fwif
126 { 0, gm20b_acr_load
, &gm20b_acr
},
127 { -1, gm200_acr_nofw
, &gm200_acr
},
132 gm20b_acr_new(struct nvkm_device
*device
, int index
, struct nvkm_acr
**pacr
)
134 return nvkm_acr_new_(gm20b_acr_fwif
, device
, index
, pacr
);