diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 20:47:51 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 10:44:58 +1000 |
commit | 0e44c21708761977dcbea9b846b51a6fb684907a (patch) | |
tree | 47e980cd3ae55c9971c1f78ff5b419de183f68bc /drivers/gpu/drm/nouveau/include | |
parent | f15cde64b66161bfa74fb58f4e5697d8265b802e (diff) | |
download | lwn-0e44c21708761977dcbea9b846b51a6fb684907a.tar.gz lwn-0e44c21708761977dcbea9b846b51a6fb684907a.zip |
drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)
Adds the start of common interfaces to load and boot the HS binaries
provided by NVIDIA that enable the usage of GR.
ACR already handles most of this, but it's very much tied into ACR's
init process, and there's other code that could benefit from reusing
a lot of this stuff too (ie. VBIOS DEVINIT/PreOS, VPR scrubber).
The VPR scrubber code is fairly independent, and a good first target.
- adds better debug output to fw loading process, to ease bring-up/debug
v2:
- whitespace, 0->false
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/include')
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h | 94 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h | 5 |
3 files changed, 115 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h index 625ffe31eaaf..d8fd2cbd2872 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h @@ -1,15 +1,44 @@ #ifndef __NVKM_FALCON_H__ #define __NVKM_FALCON_H__ +#include <core/firmware.h> #include <engine/falcon.h> +enum nvkm_falcon_mem { + IMEM, + DMEM, +}; + +static inline const char * +nvkm_falcon_mem(enum nvkm_falcon_mem mem) +{ + switch (mem) { + case IMEM: return "imem"; + case DMEM: return "dmem"; + default: + WARN_ON(1); + return "?mem"; + } +} + +struct nvkm_falcon_func_pio { + int min; + int max; + void (*wr_init)(struct nvkm_falcon *, u8 port, bool sec, u32 mem_base); + void (*wr)(struct nvkm_falcon *, u8 port, const u8 *img, int len, u16 tag); +}; + int nvkm_falcon_ctor(const struct nvkm_falcon_func *, struct nvkm_subdev *owner, const char *name, u32 addr, struct nvkm_falcon *); void nvkm_falcon_dtor(struct nvkm_falcon *); int nvkm_falcon_reset(struct nvkm_falcon *); +int nvkm_falcon_pio_wr(struct nvkm_falcon *, const u8 *img, u32 img_base, u8 port, + enum nvkm_falcon_mem mem_type, u32 mem_base, int len, u16 tag, bool sec); int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *); int gm200_flcn_disable(struct nvkm_falcon *); int gm200_flcn_enable(struct nvkm_falcon *); +extern const struct nvkm_falcon_func_pio gm200_flcn_imem_pio; +extern const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio; int gp102_flcn_reset_eng(struct nvkm_falcon *); @@ -33,6 +62,71 @@ void gp102_sec2_flcn_bind_context(struct nvkm_falcon *, struct nvkm_memory *); }) #define FLCN_DBG(f,fmt,a...) FLCN_PRINTK((f), DEBUG, info, " "fmt"\n", ##a) #define FLCN_ERR(f,fmt,a...) FLCN_PRINTK((f), ERROR, err, " "fmt"\n", ##a) +#define FLCN_ERRON(f,c,fmt,a...) \ + ({ bool _cond = (c); _cond ? FLCN_ERR(f, fmt, ##a) : FLCN_DBG(f, fmt, ##a); _cond; }) + + +struct nvkm_falcon_fw { + const struct nvkm_falcon_fw_func { + int (*signature)(struct nvkm_falcon_fw *, u32 *sig_base_src); + int (*reset)(struct nvkm_falcon_fw *); + int (*load)(struct nvkm_falcon_fw *); + int (*boot)(struct nvkm_falcon_fw *, + u32 *mbox0, u32 *mbox1, u32 mbox0_ok, u32 irqsclr); + } *func; + struct nvkm_firmware fw; + + u32 sig_base_prd; + u32 sig_base_dbg; + u32 sig_base_img; + u32 sig_size; + int sig_nr; + u8 *sigs; + + u32 nmem_base_img; + u32 nmem_base; + u32 nmem_size; + + u32 imem_base_img; + u32 imem_base; + u32 imem_size; + + u32 dmem_base_img; + u32 dmem_base; + u32 dmem_size; + u32 dmem_sign; + + u32 boot_addr; + + struct nvkm_falcon *falcon; + struct nvkm_memory *inst; + struct nvkm_vmm *vmm; +}; + +int nvkm_falcon_fw_ctor(const struct nvkm_falcon_fw_func *, const char *name, struct nvkm_device *, + bool bl, const void *src, u32 len, struct nvkm_falcon *, + struct nvkm_falcon_fw *); +int nvkm_falcon_fw_ctor_hs(const struct nvkm_falcon_fw_func *, const char *name, + struct nvkm_subdev *, const char *bl, const char *img, int ver, + struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw); +int nvkm_falcon_fw_sign(struct nvkm_falcon_fw *, u32 sig_base_img, u32 sig_size, const u8 *sigs, + int sig_nr_prd, u32 sig_base_prd, int sig_nr_dbg, u32 sig_base_dbg); +int nvkm_falcon_fw_patch(struct nvkm_falcon_fw *); +void nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *); +int nvkm_falcon_fw_oneinit(struct nvkm_falcon_fw *, struct nvkm_falcon *, struct nvkm_vmm *, + struct nvkm_memory *inst); +int nvkm_falcon_fw_boot(struct nvkm_falcon_fw *, struct nvkm_subdev *user, + bool release, u32 *pmbox0, u32 *pmbox1, u32 mbox0_ok, u32 irqsclr); + +extern const struct nvkm_falcon_fw_func gm200_flcn_fw; +int gm200_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *); +int gm200_flcn_fw_reset(struct nvkm_falcon_fw *); +int gm200_flcn_fw_load(struct nvkm_falcon_fw *); +int gm200_flcn_fw_boot(struct nvkm_falcon_fw *, u32 *, u32 *, u32, u32); + +#define FLCNFW_PRINTK(f,l,p,fmt,a...) FLCN_PRINTK((f)->falcon, l, p, "%s: "fmt, (f)->fw.name, ##a) +#define FLCNFW_DBG(f,fmt,a...) FLCNFW_PRINTK((f), DEBUG, info, fmt"\n", ##a) +#define FLCNFW_ERR(f,fmt,a...) FLCNFW_PRINTK((f), ERROR, err, fmt"\n", ##a) /** * struct nvfw_falcon_msg - header for all messages diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h index 85bcb80f6873..8453025891a5 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h @@ -4,6 +4,23 @@ #include <core/option.h> #include <core/subdev.h> +struct nvkm_firmware { + const struct nvkm_firmware_func { + enum nvkm_firmware_type { + NVKM_FIRMWARE_IMG_RAM, + } type; + } *func; + const char *name; + struct nvkm_device *device; + + int len; + u8 *img; +}; + +int nvkm_firmware_ctor(const struct nvkm_firmware_func *, const char *name, struct nvkm_device *, + const void *ptr, int len, struct nvkm_firmware *); +void nvkm_firmware_dtor(struct nvkm_firmware *); + int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver, const struct firmware **); void nvkm_firmware_put(const struct firmware *); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index 45c73893f100..ca751199379e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -63,6 +63,10 @@ struct nvkm_falcon_func { int (*reset_eng)(struct nvkm_falcon *); int (*reset_wait_mem_scrubbing)(struct nvkm_falcon *); + u32 debug; + const struct nvkm_falcon_func_pio *imem_pio; + const struct nvkm_falcon_func_pio *dmem_pio; + struct { u32 *data; u32 size; @@ -74,7 +78,6 @@ struct nvkm_falcon_func { void (*init)(struct nvkm_falcon *); void (*intr)(struct nvkm_falcon *, struct nvkm_chan *); - u32 debug; u32 fbif; void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool); |