Skip to content

Commit 2541626

Browse files
author
Ben Skeggs
committed
drm/nouveau/acr: use common falcon HS FW code for ACR FWs
Adds context binding and support for FWs with a bootloader to the code that was added to load VPR scrubber HS binaries, and ports ACR over to using all of it. - gv100 split from gp108 to handle FW exit status differences Signed-off-by: Ben Skeggs <[email protected]> Reviewed-by: Lyude Paul <[email protected]>
1 parent e3f3249 commit 2541626

File tree

30 files changed

+648
-856
lines changed

30 files changed

+648
-856
lines changed

drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h

+14-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
enum nvkm_falcon_mem {
77
IMEM,
88
DMEM,
9+
EMEM,
910
};
1011

1112
static inline const char *
@@ -14,6 +15,7 @@ nvkm_falcon_mem(enum nvkm_falcon_mem mem)
1415
switch (mem) {
1516
case IMEM: return "imem";
1617
case DMEM: return "dmem";
18+
case EMEM: return "emem";
1719
default:
1820
WARN_ON(1);
1921
return "?mem";
@@ -25,6 +27,8 @@ struct nvkm_falcon_func_pio {
2527
int max;
2628
void (*wr_init)(struct nvkm_falcon *, u8 port, bool sec, u32 mem_base);
2729
void (*wr)(struct nvkm_falcon *, u8 port, const u8 *img, int len, u16 tag);
30+
void (*rd_init)(struct nvkm_falcon *, u8 port, u32 mem_base);
31+
void (*rd)(struct nvkm_falcon *, u8 port, const u8 *img, int len);
2832
};
2933

3034
int nvkm_falcon_ctor(const struct nvkm_falcon_func *, struct nvkm_subdev *owner,
@@ -33,27 +37,25 @@ void nvkm_falcon_dtor(struct nvkm_falcon *);
3337
int nvkm_falcon_reset(struct nvkm_falcon *);
3438
int nvkm_falcon_pio_wr(struct nvkm_falcon *, const u8 *img, u32 img_base, u8 port,
3539
enum nvkm_falcon_mem mem_type, u32 mem_base, int len, u16 tag, bool sec);
40+
int nvkm_falcon_pio_rd(struct nvkm_falcon *, u8 port, enum nvkm_falcon_mem type, u32 mem_base,
41+
const u8 *img, u32 img_base, int len);
3642

3743
int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *);
3844
int gm200_flcn_disable(struct nvkm_falcon *);
3945
int gm200_flcn_enable(struct nvkm_falcon *);
46+
void gm200_flcn_bind_inst(struct nvkm_falcon *, int, u64);
47+
int gm200_flcn_bind_stat(struct nvkm_falcon *, bool);
4048
extern const struct nvkm_falcon_func_pio gm200_flcn_imem_pio;
4149
extern const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio;
4250

4351
int gp102_flcn_reset_eng(struct nvkm_falcon *);
52+
extern const struct nvkm_falcon_func_pio gp102_flcn_emem_pio;
4453

4554
void nvkm_falcon_v1_load_imem(struct nvkm_falcon *,
4655
void *, u32, u32, u16, u8, bool);
4756
void nvkm_falcon_v1_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
48-
void nvkm_falcon_v1_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
49-
void nvkm_falcon_v1_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
50-
int nvkm_falcon_v1_wait_for_halt(struct nvkm_falcon *, u32);
51-
int nvkm_falcon_v1_clear_interrupt(struct nvkm_falcon *, u32);
52-
void nvkm_falcon_v1_set_start_addr(struct nvkm_falcon *, u32 start_addr);
5357
void nvkm_falcon_v1_start(struct nvkm_falcon *);
5458

55-
void gp102_sec2_flcn_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
56-
5759
#define FLCN_PRINTK(f,l,p,fmt,a...) ({ \
5860
if ((f)->owner->name != (f)->name) \
5961
nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, "%s:"fmt, (f)->name, ##a); \
@@ -70,7 +72,9 @@ struct nvkm_falcon_fw {
7072
const struct nvkm_falcon_fw_func {
7173
int (*signature)(struct nvkm_falcon_fw *, u32 *sig_base_src);
7274
int (*reset)(struct nvkm_falcon_fw *);
75+
int (*setup)(struct nvkm_falcon_fw *);
7376
int (*load)(struct nvkm_falcon_fw *);
77+
int (*load_bld)(struct nvkm_falcon_fw *);
7478
int (*boot)(struct nvkm_falcon_fw *,
7579
u32 *mbox0, u32 *mbox1, u32 mbox0_ok, u32 irqsclr);
7680
} *func;
@@ -96,11 +100,14 @@ struct nvkm_falcon_fw {
96100
u32 dmem_size;
97101
u32 dmem_sign;
98102

103+
u8 *boot;
104+
u32 boot_size;
99105
u32 boot_addr;
100106

101107
struct nvkm_falcon *falcon;
102108
struct nvkm_memory *inst;
103109
struct nvkm_vmm *vmm;
110+
struct nvkm_vma *vma;
104111
};
105112

106113
int nvkm_falcon_fw_ctor(const struct nvkm_falcon_fw_func *, const char *name, struct nvkm_device *,

drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h

+8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
/* SPDX-License-Identifier: MIT */
22
#ifndef __NVKM_FIRMWARE_H__
33
#define __NVKM_FIRMWARE_H__
4+
#include <core/memory.h>
45
#include <core/option.h>
56
#include <core/subdev.h>
67

78
struct nvkm_firmware {
89
const struct nvkm_firmware_func {
910
enum nvkm_firmware_type {
1011
NVKM_FIRMWARE_IMG_RAM,
12+
NVKM_FIRMWARE_IMG_DMA,
1113
} type;
1214
} *func;
1315
const char *name;
1416
struct nvkm_device *device;
1517

1618
int len;
1719
u8 *img;
20+
u64 phys;
21+
22+
struct nvkm_firmware_mem {
23+
struct nvkm_memory memory;
24+
struct scatterlist sgl;
25+
} mem;
1826
};
1927

2028
int nvkm_firmware_ctor(const struct nvkm_firmware_func *, const char *name, struct nvkm_device *,

drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h

+13-19
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,22 @@ struct nvkm_falcon_func {
6464
int (*reset_wait_mem_scrubbing)(struct nvkm_falcon *);
6565

6666
u32 debug;
67+
void (*bind_inst)(struct nvkm_falcon *, int target, u64 addr);
68+
int (*bind_stat)(struct nvkm_falcon *, bool intr);
69+
bool bind_intr;
70+
6771
const struct nvkm_falcon_func_pio *imem_pio;
6872
const struct nvkm_falcon_func_pio *dmem_pio;
6973

74+
u32 emem_addr;
75+
const struct nvkm_falcon_func_pio *emem_pio;
76+
77+
struct {
78+
u32 head;
79+
u32 tail;
80+
u32 stride;
81+
} cmdq, msgq;
82+
7083
struct {
7184
u32 *data;
7285
u32 size;
@@ -78,24 +91,10 @@ struct nvkm_falcon_func {
7891
void (*init)(struct nvkm_falcon *);
7992
void (*intr)(struct nvkm_falcon *, struct nvkm_chan *);
8093

81-
u32 fbif;
82-
8394
void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
8495
void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
85-
void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *);
86-
u32 emem_addr;
87-
void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *);
88-
int (*wait_for_halt)(struct nvkm_falcon *, u32);
89-
int (*clear_interrupt)(struct nvkm_falcon *, u32);
90-
void (*set_start_addr)(struct nvkm_falcon *, u32 start_addr);
9196
void (*start)(struct nvkm_falcon *);
9297

93-
struct {
94-
u32 head;
95-
u32 tail;
96-
u32 stride;
97-
} cmdq, msgq;
98-
9998
struct nvkm_sclass sclass[];
10099
};
101100

@@ -122,10 +121,5 @@ nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
122121
void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
123122
bool);
124123
void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
125-
void nvkm_falcon_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
126-
void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
127-
void nvkm_falcon_set_start_addr(struct nvkm_falcon *, u32);
128124
void nvkm_falcon_start(struct nvkm_falcon *);
129-
int nvkm_falcon_wait_for_halt(struct nvkm_falcon *, u32);
130-
int nvkm_falcon_clear_interrupt(struct nvkm_falcon *, u32);
131125
#endif

drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct nvkm_acr {
3636
const struct nvkm_acr_func *func;
3737
struct nvkm_subdev subdev;
3838

39-
struct list_head hsfw, hsf;
39+
struct list_head hsfw;
4040
struct list_head lsfw, lsf;
4141

4242
u64 managed_falcons;
@@ -65,6 +65,7 @@ int gm20b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
6565
int gp102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
6666
int gp108_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
6767
int gp10b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
68+
int gv100_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
6869
int tu102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
6970

7071
struct nvkm_acr_lsfw {

drivers/gpu/drm/nouveau/nvkm/core/firmware.c

+86-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include <core/device.h>
2323
#include <core/firmware.h>
2424

25+
#include <subdev/fb.h>
26+
#include <subdev/mmu.h>
27+
2528
int
2629
nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *base,
2730
const char *name, int ver, const struct firmware **pfw)
@@ -108,16 +111,81 @@ nvkm_firmware_put(const struct firmware *fw)
108111
release_firmware(fw);
109112
}
110113

114+
#define nvkm_firmware_mem(p) container_of((p), struct nvkm_firmware, mem.memory)
115+
116+
static int
117+
nvkm_firmware_mem_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm,
118+
struct nvkm_vma *vma, void *argv, u32 argc)
119+
{
120+
struct nvkm_firmware *fw = nvkm_firmware_mem(memory);
121+
struct nvkm_vmm_map map = {
122+
.memory = &fw->mem.memory,
123+
.offset = offset,
124+
.sgl = &fw->mem.sgl,
125+
};
126+
127+
if (WARN_ON(fw->func->type != NVKM_FIRMWARE_IMG_DMA))
128+
return -ENOSYS;
129+
130+
return nvkm_vmm_map(vmm, vma, argv, argc, &map);
131+
}
132+
133+
static u64
134+
nvkm_firmware_mem_size(struct nvkm_memory *memory)
135+
{
136+
return sg_dma_len(&nvkm_firmware_mem(memory)->mem.sgl);
137+
}
138+
139+
static u64
140+
nvkm_firmware_mem_addr(struct nvkm_memory *memory)
141+
{
142+
return nvkm_firmware_mem(memory)->phys;
143+
}
144+
145+
static u8
146+
nvkm_firmware_mem_page(struct nvkm_memory *memory)
147+
{
148+
return PAGE_SHIFT;
149+
}
150+
151+
static enum nvkm_memory_target
152+
nvkm_firmware_mem_target(struct nvkm_memory *memory)
153+
{
154+
return NVKM_MEM_TARGET_HOST;
155+
}
156+
157+
static void *
158+
nvkm_firmware_mem_dtor(struct nvkm_memory *memory)
159+
{
160+
return NULL;
161+
}
162+
163+
static const struct nvkm_memory_func
164+
nvkm_firmware_mem = {
165+
.dtor = nvkm_firmware_mem_dtor,
166+
.target = nvkm_firmware_mem_target,
167+
.page = nvkm_firmware_mem_page,
168+
.addr = nvkm_firmware_mem_addr,
169+
.size = nvkm_firmware_mem_size,
170+
.map = nvkm_firmware_mem_map,
171+
};
172+
111173
void
112174
nvkm_firmware_dtor(struct nvkm_firmware *fw)
113175
{
176+
struct nvkm_memory *memory = &fw->mem.memory;
177+
114178
if (!fw->img)
115179
return;
116180

117181
switch (fw->func->type) {
118182
case NVKM_FIRMWARE_IMG_RAM:
119183
kfree(fw->img);
120184
break;
185+
case NVKM_FIRMWARE_IMG_DMA:
186+
nvkm_memory_unref(&memory);
187+
dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys);
188+
break;
121189
default:
122190
WARN_ON(1);
123191
break;
@@ -133,12 +201,28 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name,
133201
fw->func = func;
134202
fw->name = name;
135203
fw->device = device;
204+
fw->len = len;
136205

137206
switch (fw->func->type) {
138207
case NVKM_FIRMWARE_IMG_RAM:
139-
fw->len = len;
140208
fw->img = kmemdup(src, fw->len, GFP_KERNEL);
141209
break;
210+
case NVKM_FIRMWARE_IMG_DMA: {
211+
dma_addr_t addr;
212+
213+
len = ALIGN(fw->len, PAGE_SIZE);
214+
215+
fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL);
216+
if (fw->img) {
217+
memcpy(fw->img, src, fw->len);
218+
fw->phys = addr;
219+
}
220+
221+
sg_init_one(&fw->mem.sgl, fw->img, len);
222+
sg_dma_address(&fw->mem.sgl) = fw->phys;
223+
sg_dma_len(&fw->mem.sgl) = len;
224+
}
225+
break;
142226
default:
143227
WARN_ON(1);
144228
return -EINVAL;
@@ -147,5 +231,6 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name,
147231
if (!fw->img)
148232
return -ENOMEM;
149233

234+
nvkm_memory_ctor(&nvkm_firmware_mem, &fw->mem.memory);
150235
return 0;
151236
}

drivers/gpu/drm/nouveau/nvkm/engine/device/base.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2364,7 +2364,7 @@ nv13b_chipset = {
23642364
static const struct nvkm_device_chip
23652365
nv140_chipset = {
23662366
.name = "GV100",
2367-
.acr = { 0x00000001, gp108_acr_new },
2367+
.acr = { 0x00000001, gv100_acr_new },
23682368
.bar = { 0x00000001, gm107_bar_new },
23692369
.bios = { 0x00000001, nvkm_bios_new },
23702370
.bus = { 0x00000001, gf100_bus_new },

drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c

+6-47
Original file line numberDiff line numberDiff line change
@@ -190,45 +190,6 @@ gp102_sec2_intr(struct nvkm_inth *inth)
190190
return IRQ_HANDLED;
191191
}
192192

193-
void
194-
gp102_sec2_flcn_bind_context(struct nvkm_falcon *falcon,
195-
struct nvkm_memory *ctx)
196-
{
197-
struct nvkm_device *device = falcon->owner->device;
198-
199-
nvkm_falcon_v1_bind_context(falcon, ctx);
200-
if (!ctx)
201-
return;
202-
203-
/* Not sure if this is a WAR for a HW issue, or some additional
204-
* programming sequence that's needed to properly complete the
205-
* context switch we trigger above.
206-
*
207-
* Fixes unreliability of booting the SEC2 RTOS on Quadro P620,
208-
* particularly when resuming from suspend.
209-
*
210-
* Also removes the need for an odd workaround where we needed
211-
* to program SEC2's FALCON_CPUCTL_ALIAS_STARTCPU twice before
212-
* the SEC2 RTOS would begin executing.
213-
*/
214-
nvkm_msec(device, 10,
215-
u32 irqstat = nvkm_falcon_rd32(falcon, 0x008);
216-
u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
217-
if ((irqstat & 0x00000008) &&
218-
(flcn0dc & 0x00007000) == 0x00005000)
219-
break;
220-
);
221-
222-
nvkm_falcon_mask(falcon, 0x004, 0x00000008, 0x00000008);
223-
nvkm_falcon_mask(falcon, 0x058, 0x00000002, 0x00000002);
224-
225-
nvkm_msec(device, 10,
226-
u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
227-
if ((flcn0dc & 0x00007000) == 0x00000000)
228-
break;
229-
);
230-
}
231-
232193
static const struct nvkm_falcon_func
233194
gp102_sec2_flcn = {
234195
.disable = gm200_flcn_disable,
@@ -237,15 +198,13 @@ gp102_sec2_flcn = {
237198
.reset_eng = gp102_flcn_reset_eng,
238199
.reset_wait_mem_scrubbing = gm200_flcn_reset_wait_mem_scrubbing,
239200
.debug = 0x408,
240-
.fbif = 0x600,
241-
.load_imem = nvkm_falcon_v1_load_imem,
242-
.load_dmem = nvkm_falcon_v1_load_dmem,
243-
.read_dmem = nvkm_falcon_v1_read_dmem,
201+
.bind_inst = gm200_flcn_bind_inst,
202+
.bind_stat = gm200_flcn_bind_stat,
203+
.bind_intr = true,
204+
.imem_pio = &gm200_flcn_imem_pio,
205+
.dmem_pio = &gm200_flcn_dmem_pio,
244206
.emem_addr = 0x01000000,
245-
.bind_context = gp102_sec2_flcn_bind_context,
246-
.wait_for_halt = nvkm_falcon_v1_wait_for_halt,
247-
.clear_interrupt = nvkm_falcon_v1_clear_interrupt,
248-
.set_start_addr = nvkm_falcon_v1_set_start_addr,
207+
.emem_pio = &gp102_flcn_emem_pio,
249208
.start = nvkm_falcon_v1_start,
250209
.cmdq = { 0xa00, 0xa04, 8 },
251210
.msgq = { 0xa30, 0xa34, 8 },

0 commit comments

Comments
 (0)