Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_CLIENT_H__
#define __NVKM_CLIENT_H__
#define nvkm_client(p) container_of((p), struct nvkm_client, object)
#include <core/object.h>
struct nvkm_client {
struct nvkm_object object;
char name[32];
u64 device;
u32 debug;
struct rb_root objroot;
spinlock_t obj_lock;
void *data;
int (*event)(u64 token, void *argv, u32 argc);
struct list_head umem;
spinlock_t lock;
};
int nvkm_client_new(const char *name, u64 device, const char *cfg, const char *dbg,
int (*)(u64, void *, u32), struct nvkm_client **);
/* logging for client-facing objects */
#define nvif_printk(o,l,p,f,a...) do { \
const struct nvkm_object *_object = (o); \
const struct nvkm_client *_client = _object->client; \
if (_client->debug >= NV_DBG_##l) \
printk(KERN_##p "nouveau: %s:%08x:%08x: "f, _client->name, \
_object->handle, _object->oclass, ##a); \
} while(0)
#define nvif_fatal(o,f,a...) nvif_printk((o), FATAL, CRIT, f, ##a)
#define nvif_error(o,f,a...) nvif_printk((o), ERROR, ERR, f, ##a)
#define nvif_debug(o,f,a...) nvif_printk((o), DEBUG, INFO, f, ##a)
#define nvif_trace(o,f,a...) nvif_printk((o), TRACE, INFO, f, ##a)
#define nvif_info(o,f,a...) nvif_printk((o), INFO, INFO, f, ##a)
#define nvif_ioctl(o,f,a...) nvif_trace((o), "ioctl: "f, ##a)
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DEBUG_H__
#define __NVKM_DEBUG_H__
#define NV_DBG_FATAL 0
#define NV_DBG_ERROR 1
#define NV_DBG_WARN 2
#define NV_DBG_INFO 3
#define NV_DBG_DEBUG 4
#define NV_DBG_TRACE 5
#define NV_DBG_PARANOIA 6
#define NV_DBG_SPAM 7
#endif
@@ -0,0 +1,165 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DEVICE_H__
#define __NVKM_DEVICE_H__
#include <core/oclass.h>
#include <core/suspend_state.h>
#include <core/intr.h>
enum nvkm_subdev_type;
enum nvkm_device_type {
NVKM_DEVICE_PCI,
NVKM_DEVICE_AGP,
NVKM_DEVICE_PCIE,
NVKM_DEVICE_TEGRA,
};
struct nvkm_device {
const struct nvkm_device_func *func;
const struct nvkm_device_quirk *quirk;
struct device *dev;
enum nvkm_device_type type;
u64 handle;
const char *name;
const char *cfgopt;
const char *dbgopt;
struct list_head head;
struct mutex mutex;
int refcount;
void __iomem *pri;
u32 debug;
const struct nvkm_device_chip *chip;
enum {
NV_04 = 0x04,
NV_10 = 0x10,
NV_11 = 0x11,
NV_20 = 0x20,
NV_30 = 0x30,
NV_40 = 0x40,
NV_50 = 0x50,
NV_C0 = 0xc0,
NV_E0 = 0xe0,
GM100 = 0x110,
GP100 = 0x130,
GV100 = 0x140,
TU100 = 0x160,
GA100 = 0x170,
GH100 = 0x180,
AD100 = 0x190,
GB10x = 0x1a0,
GB20x = 0x1b0,
} card_type;
u32 chipset;
u8 chiprev;
u32 crystal;
struct {
struct notifier_block nb;
} acpi;
#define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr;
#define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt];
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
struct list_head subdev;
struct {
struct list_head intr;
struct list_head prio[NVKM_INTR_PRIO_NR];
spinlock_t lock;
int irq;
bool alloc;
bool armed;
bool legacy_done;
} intr;
};
struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst);
struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst);
enum nvkm_bar_id {
NVKM_BAR_INVALID = 0,
NVKM_BAR0_PRI,
NVKM_BAR1_FB,
NVKM_BAR2_INST,
};
struct nvkm_device_func {
struct nvkm_device_pci *(*pci)(struct nvkm_device *);
struct nvkm_device_tegra *(*tegra)(struct nvkm_device *);
void *(*dtor)(struct nvkm_device *);
int (*preinit)(struct nvkm_device *);
int (*init)(struct nvkm_device *);
void (*fini)(struct nvkm_device *, enum nvkm_suspend_state suspend);
int (*irq)(struct nvkm_device *);
resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id);
resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id);
bool cpu_coherent;
};
struct nvkm_device_quirk {
u8 tv_pin_mask;
u8 tv_gpio;
};
struct nvkm_device_chip {
const char *name;
#define NVKM_LAYOUT_ONCE(type,data,ptr,...) \
struct { \
u32 inst; \
int (*ctor)(struct nvkm_device *, enum nvkm_subdev_type, int inst, data **); \
} ptr;
#define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A)
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
};
struct nvkm_device *nvkm_device_find(u64 name);
/* privileged register interface accessor macros */
#define nvkm_rd08(d,a) ioread8((d)->pri + (a))
#define nvkm_rd16(d,a) ioread16_native((d)->pri + (a))
#define nvkm_rd32(d,a) ioread32_native((d)->pri + (a))
#define nvkm_wr08(d,a,v) iowrite8((v), (d)->pri + (a))
#define nvkm_wr16(d,a,v) iowrite16_native((v), (d)->pri + (a))
#define nvkm_wr32(d,a,v) iowrite32_native((v), (d)->pri + (a))
#define nvkm_mask(d,a,m,v) ({ \
struct nvkm_device *_device = (d); \
u32 _addr = (a), _temp = nvkm_rd32(_device, _addr); \
nvkm_wr32(_device, _addr, (_temp & ~(m)) | (v)); \
_temp; \
})
#define NVKM_RD32_(p,o,dr) nvkm_rd32((p), (o) + (dr))
#define NVKM_RD32(p,A...) DRF_RV(NVKM_RD32_, (p), 0, ##A)
void nvkm_device_del(struct nvkm_device **);
struct nvkm_device_oclass {
int (*ctor)(struct nvkm_device *, const struct nvkm_oclass *,
void *data, u32 size, struct nvkm_object **);
struct nvkm_sclass base;
};
extern const struct nvkm_sclass nvkm_udevice_sclass;
/* device logging */
#define nvdev_printk_(d,l,p,f,a...) do { \
const struct nvkm_device *_device = (d); \
if (_device->debug >= (l)) \
dev_##p(_device->dev, f, ##a); \
} while(0)
#define nvdev_printk(d,l,p,f,a...) nvdev_printk_((d), NV_DBG_##l, p, f, ##a)
#define nvdev_fatal(d,f,a...) nvdev_printk((d), FATAL, crit, f, ##a)
#define nvdev_error(d,f,a...) nvdev_printk((d), ERROR, err, f, ##a)
#define nvdev_warn(d,f,a...) nvdev_printk((d), WARN, notice, f, ##a)
#define nvdev_info(d,f,a...) nvdev_printk((d), INFO, info, f, ##a)
#define nvdev_debug(d,f,a...) nvdev_printk((d), DEBUG, info, f, ##a)
#define nvdev_trace(d,f,a...) nvdev_printk((d), TRACE, info, f, ##a)
#define nvdev_spam(d,f,a...) nvdev_printk((d), SPAM, dbg, f, ##a)
#endif
@@ -0,0 +1,55 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_ENGINE_H__
#define __NVKM_ENGINE_H__
#define nvkm_engine(p) container_of((p), struct nvkm_engine, subdev)
#include <core/subdev.h>
struct nvkm_chan;
struct nvkm_fb_tile;
extern const struct nvkm_subdev_func nvkm_engine;
struct nvkm_engine {
const struct nvkm_engine_func *func;
struct nvkm_subdev subdev;
spinlock_t lock;
};
struct nvkm_engine_func {
void *(*dtor)(struct nvkm_engine *);
void (*preinit)(struct nvkm_engine *);
int (*oneinit)(struct nvkm_engine *);
int (*info)(struct nvkm_engine *, u64 mthd, u64 *data);
int (*init)(struct nvkm_engine *);
int (*fini)(struct nvkm_engine *, enum nvkm_suspend_state suspend);
int (*reset)(struct nvkm_engine *);
int (*nonstall)(struct nvkm_engine *);
void (*intr)(struct nvkm_engine *);
void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
bool (*chsw_load)(struct nvkm_engine *);
struct {
int (*sclass)(struct nvkm_oclass *, int index,
const struct nvkm_device_oclass **);
} base;
struct {
int (*cclass)(struct nvkm_chan *, const struct nvkm_oclass *,
struct nvkm_object **);
int (*sclass)(struct nvkm_oclass *, int index);
} fifo;
const struct nvkm_object_func *cclass;
struct nvkm_sclass sclass[];
};
int nvkm_engine_ctor(const struct nvkm_engine_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, bool enable, struct nvkm_engine *);
int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
enum nvkm_subdev_type, int, bool enable, struct nvkm_engine **);
struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
void nvkm_engine_unref(struct nvkm_engine **);
int nvkm_engine_reset(struct nvkm_engine *);
void nvkm_engine_tile(struct nvkm_engine *, int region);
bool nvkm_engine_chsw_load(struct nvkm_engine *);
#endif
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_ENUM_H__
#define __NVKM_ENUM_H__
#include <core/os.h>
struct nvkm_enum {
u32 value;
const char *name;
const void *data;
u32 data2;
int inst;
};
const struct nvkm_enum *nvkm_enum_find(const struct nvkm_enum *, u32 value);
struct nvkm_bitfield {
u32 mask;
const char *name;
};
void nvkm_snprintbf(char *, int, const struct nvkm_bitfield *, u32 value);
#endif
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_EVENT_H__
#define __NVKM_EVENT_H__
#include <core/os.h>
struct nvkm_object;
struct nvkm_oclass;
struct nvkm_uevent;
struct nvkm_event {
const struct nvkm_event_func *func;
struct nvkm_subdev *subdev;
int types_nr;
int index_nr;
spinlock_t refs_lock;
rwlock_t list_lock;
int *refs;
struct list_head ntfy;
};
struct nvkm_event_func {
void (*init)(struct nvkm_event *, int type, int index);
void (*fini)(struct nvkm_event *, int type, int index);
};
int __nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr,
int index_nr, struct nvkm_event *);
/* Each nvkm_event needs its own lockdep class due to inter-dependencies, to
* prevent lockdep false-positives.
*
* Inlining the spinlock initialisation ensures each is unique.
*/
static __always_inline int
nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
int types_nr, int index_nr, struct nvkm_event *event)
{
spin_lock_init(&event->refs_lock);
rwlock_init(&event->list_lock);
return __nvkm_event_init(func, subdev, types_nr, index_nr, event);
}
void nvkm_event_fini(struct nvkm_event *);
#define NVKM_EVENT_KEEP 0
#define NVKM_EVENT_DROP 1
struct nvkm_event_ntfy;
typedef int (*nvkm_event_func)(struct nvkm_event_ntfy *, u32 bits);
struct nvkm_event_ntfy {
struct nvkm_event *event;
int id;
u32 bits;
bool wait;
nvkm_event_func func;
atomic_t allowed;
bool running;
struct list_head head;
};
void nvkm_event_ntfy(struct nvkm_event *, int id, u32 bits);
bool nvkm_event_ntfy_valid(struct nvkm_event *, int id, u32 bits);
void nvkm_event_ntfy_add(struct nvkm_event *, int id, u32 bits, bool wait, nvkm_event_func,
struct nvkm_event_ntfy *);
void nvkm_event_ntfy_del(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_allow(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_block(struct nvkm_event_ntfy *);
typedef int (*nvkm_uevent_func)(struct nvkm_object *, u64 token, u32 bits);
int nvkm_uevent_new(const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **);
int nvkm_uevent_add(struct nvkm_uevent *, struct nvkm_event *, int id, u32 bits, nvkm_uevent_func);
#endif
@@ -0,0 +1,217 @@
#ifndef __NVKM_FALCON_H__
#define __NVKM_FALCON_H__
#include <core/firmware.h>
#include <engine/falcon.h>
enum nvkm_falcon_mem {
IMEM,
DMEM,
EMEM,
};
static inline const char *
nvkm_falcon_mem(enum nvkm_falcon_mem mem)
{
switch (mem) {
case IMEM: return "imem";
case DMEM: return "dmem";
case EMEM: return "emem";
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);
void (*rd_init)(struct nvkm_falcon *, u8 port, u32 mem_base);
void (*rd)(struct nvkm_falcon *, u8 port, const u8 *img, int len);
};
struct nvkm_falcon_func_dma {
int (*init)(struct nvkm_falcon *, u64 dma_addr, int xfer_len,
enum nvkm_falcon_mem, bool sec, u32 *cmd);
void (*xfer)(struct nvkm_falcon *, u32 mem_base, u32 dma_base, u32 cmd);
bool (*done)(struct nvkm_falcon *);
};
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 nvkm_falcon_pio_rd(struct nvkm_falcon *, u8 port, enum nvkm_falcon_mem type, u32 mem_base,
const u8 *img, u32 img_base, int len);
int nvkm_falcon_dma_wr(struct nvkm_falcon *, const u8 *img, u64 dma_addr, u32 dma_base,
enum nvkm_falcon_mem mem_type, u32 mem_base, int len, bool sec);
bool nvkm_falcon_riscv_active(struct nvkm_falcon *);
void nvkm_falcon_intr_retrigger(struct nvkm_falcon *);
int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *);
int gm200_flcn_disable(struct nvkm_falcon *);
int gm200_flcn_enable(struct nvkm_falcon *);
void gm200_flcn_bind_inst(struct nvkm_falcon *, int, u64);
int gm200_flcn_bind_stat(struct nvkm_falcon *, bool);
extern const struct nvkm_falcon_func_pio gm200_flcn_imem_pio;
extern const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio;
void gm200_flcn_tracepc(struct nvkm_falcon *);
int gp102_flcn_reset_eng(struct nvkm_falcon *);
extern const struct nvkm_falcon_func_pio gp102_flcn_emem_pio;
bool tu102_flcn_riscv_active(struct nvkm_falcon *);
void ga100_flcn_intr_retrigger(struct nvkm_falcon *);
int ga102_flcn_select(struct nvkm_falcon *);
int ga102_flcn_reset_prep(struct nvkm_falcon *);
int ga102_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *);
extern const struct nvkm_falcon_func_dma ga102_flcn_dma;
bool ga102_flcn_riscv_active(struct nvkm_falcon *);
void nvkm_falcon_v1_load_imem(struct nvkm_falcon *,
void *, u32, u32, u16, u8, bool);
void nvkm_falcon_v1_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_v1_start(struct nvkm_falcon *);
#define FLCN_PRINTK(f,l,p,fmt,a...) ({ \
if ((f)->owner->name != (f)->name) \
nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, "%s:"fmt, (f)->name, ##a); \
else \
nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, fmt, ##a); \
})
#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 (*setup)(struct nvkm_falcon_fw *);
int (*load)(struct nvkm_falcon_fw *);
int (*load_bld)(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 fuse_ver;
u32 engine_id;
u32 ucode_id;
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;
u8 *boot;
u32 boot_size;
u32 boot_addr;
struct nvkm_falcon *falcon;
struct nvkm_memory *inst;
struct nvkm_vmm *vmm;
struct nvkm_vma *vma;
};
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_ctor_hs_v2(const struct nvkm_falcon_fw_func *, const char *name,
struct nvkm_subdev *, const char *img, int ver, struct nvkm_falcon *,
struct nvkm_falcon_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);
int ga100_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *);
extern const struct nvkm_falcon_fw_func ga102_flcn_fw;
int ga102_flcn_fw_load(struct nvkm_falcon_fw *);
int ga102_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
*
* @unit_id: id of firmware process that sent the message
* @size: total size of message
* @ctrl_flags: control flags
* @seq_id: used to match a message from its corresponding command
*/
struct nvfw_falcon_msg {
u8 unit_id;
u8 size;
u8 ctrl_flags;
u8 seq_id;
};
#define nvfw_falcon_cmd nvfw_falcon_msg
#define NV_FALCON_CMD_UNIT_ID_REWIND 0x00
struct nvkm_falcon_qmgr;
int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **);
void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **);
typedef int
(*nvkm_falcon_qmgr_callback)(void *priv, struct nvfw_falcon_msg *);
struct nvkm_falcon_cmdq;
int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_cmdq **);
void nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **);
void nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *,
u32 index, u32 offset, u32 size);
void nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *);
int nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *, struct nvfw_falcon_cmd *,
nvkm_falcon_qmgr_callback, void *priv,
unsigned long timeout_jiffies);
struct nvkm_falcon_msgq;
int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_msgq **);
void nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **);
void nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *,
u32 index, u32 offset, u32 size);
bool nvkm_falcon_msgq_empty(struct nvkm_falcon_msgq *);
int nvkm_falcon_msgq_recv_initmsg(struct nvkm_falcon_msgq *, void *, u32 size);
void nvkm_falcon_msgq_recv(struct nvkm_falcon_msgq *);
#endif
@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FIRMWARE_H__
#define __NVKM_FIRMWARE_H__
#include <core/memory.h>
#include <core/option.h>
#include <core/subdev.h>
struct nvkm_firmware {
const struct nvkm_firmware_func {
enum nvkm_firmware_type {
NVKM_FIRMWARE_IMG_RAM,
NVKM_FIRMWARE_IMG_DMA,
NVKM_FIRMWARE_IMG_SGT,
} type;
} *func;
const char *name;
struct nvkm_device *device;
int len;
u8 *img;
u64 phys;
struct nvkm_firmware_mem {
struct nvkm_memory memory;
union {
struct scatterlist sgl; /* DMA */
struct sg_table sgt; /* SGT */
};
} mem;
};
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 *);
int nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *path,
const char *name, int ver, struct nvkm_blob *);
int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *path,
const char *name, int ver,
const struct firmware **);
#define nvkm_firmware_load(s,l,o,p...) ({ \
struct nvkm_subdev *_s = (s); \
const char *_opts = (o); \
char _option[32]; \
typeof(l[0]) *_list = (l), *_next, *_fwif = NULL; \
int _ver, _fwv, _ret = 0; \
\
snprintf(_option, sizeof(_option), "Nv%sFw", _opts); \
_ver = nvkm_longopt(_s->device->cfgopt, _option, -2); \
if (_ver >= -1) { \
for (_next = _list; !_fwif && _next->load; _next++) { \
if (_next->version == _ver) \
_fwif = _next; \
} \
_ret = _fwif ? 0 : -EINVAL; \
} \
\
if (_ret == 0) { \
snprintf(_option, sizeof(_option), "Nv%sFwVer", _opts); \
_fwv = _fwif ? _fwif->version : -1; \
_ver = nvkm_longopt(_s->device->cfgopt, _option, _fwv); \
for (_next = _fwif ? _fwif : _list; _next->load; _next++) { \
_fwv = (_ver >= 0) ? _ver : _next->version; \
_ret = _next->load(p, _fwv, _next); \
if (_ret == 0 || _ver >= 0) { \
_fwif = _next; \
break; \
} \
} \
} \
\
if (_ret) \
_fwif = ERR_PTR(_ret); \
_fwif; \
})
#endif
@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_GPUOBJ_H__
#define __NVKM_GPUOBJ_H__
#include <core/memory.h>
#include <core/mm.h>
#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
#define NVOBJ_FLAG_HEAP 0x00000004
struct nvkm_gpuobj {
union {
const struct nvkm_gpuobj_func *func;
const struct nvkm_gpuobj_func *ptrs;
};
struct nvkm_gpuobj *parent;
struct nvkm_memory *memory;
struct nvkm_mm_node *node;
u64 addr;
u32 size;
struct nvkm_mm heap;
void __iomem *map;
};
struct nvkm_gpuobj_func {
void *(*acquire)(struct nvkm_gpuobj *);
void (*release)(struct nvkm_gpuobj *);
u32 (*rd32)(struct nvkm_gpuobj *, u32 offset);
void (*wr32)(struct nvkm_gpuobj *, u32 offset, u32 data);
int (*map)(struct nvkm_gpuobj *, u64 offset, struct nvkm_vmm *,
struct nvkm_vma *, void *argv, u32 argc);
};
int nvkm_gpuobj_new(struct nvkm_device *, u32 size, int align, bool zero,
struct nvkm_gpuobj *parent, struct nvkm_gpuobj **);
void nvkm_gpuobj_del(struct nvkm_gpuobj **);
int nvkm_gpuobj_wrap(struct nvkm_memory *, struct nvkm_gpuobj **);
void nvkm_gpuobj_memcpy_to(struct nvkm_gpuobj *dst, u32 dstoffset, void *src,
u32 length);
void nvkm_gpuobj_memcpy_from(void *dst, struct nvkm_gpuobj *src, u32 srcoffset,
u32 length);
#endif
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_INTR_H__
#define __NVKM_INTR_H__
#include <core/os.h>
struct nvkm_device;
struct nvkm_subdev;
enum nvkm_intr_prio {
NVKM_INTR_PRIO_VBLANK = 0,
NVKM_INTR_PRIO_NORMAL,
NVKM_INTR_PRIO_NR
};
enum nvkm_intr_type {
NVKM_INTR_SUBDEV = -1, /* lookup vector by requesting subdev, in mapping table. */
NVKM_INTR_VECTOR_0 = 0,
};
struct nvkm_intr {
const struct nvkm_intr_func {
bool (*pending)(struct nvkm_intr *);
void (*unarm)(struct nvkm_intr *);
void (*rearm)(struct nvkm_intr *);
void (*block)(struct nvkm_intr *, int leaf, u32 mask);
void (*allow)(struct nvkm_intr *, int leaf, u32 mask);
void (*reset)(struct nvkm_intr *, int leaf, u32 mask);
} *func;
const struct nvkm_intr_data {
int type; /* enum nvkm_subdev_type (+ve), enum nvkm_intr_type (-ve) */
int inst;
int leaf;
u32 mask; /* 0-terminated. */
bool legacy; /* auto-create "legacy" nvkm_subdev_intr() handler */
} *data;
struct nvkm_subdev *subdev;
int leaves;
u32 *stat;
u32 *mask;
struct list_head head;
};
void nvkm_intr_ctor(struct nvkm_device *);
void nvkm_intr_dtor(struct nvkm_device *);
int nvkm_intr_install(struct nvkm_device *);
void nvkm_intr_unarm(struct nvkm_device *);
void nvkm_intr_rearm(struct nvkm_device *);
int nvkm_intr_add(const struct nvkm_intr_func *, const struct nvkm_intr_data *,
struct nvkm_subdev *, int leaves, struct nvkm_intr *);
void nvkm_intr_block(struct nvkm_subdev *, enum nvkm_intr_type);
void nvkm_intr_allow(struct nvkm_subdev *, enum nvkm_intr_type);
struct nvkm_inth;
typedef irqreturn_t (*nvkm_inth_func)(struct nvkm_inth *);
struct nvkm_inth {
struct nvkm_intr *intr;
int leaf;
u32 mask;
nvkm_inth_func func;
atomic_t allowed;
struct list_head head;
};
int nvkm_inth_add(struct nvkm_intr *, enum nvkm_intr_type, enum nvkm_intr_prio,
struct nvkm_subdev *, nvkm_inth_func, struct nvkm_inth *);
void nvkm_inth_allow(struct nvkm_inth *);
void nvkm_inth_block(struct nvkm_inth *);
#endif
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_IOCTL_H__
#define __NVKM_IOCTL_H__
#include <core/os.h>
struct nvkm_client;
int nvkm_ioctl(struct nvkm_client *, void *, u32, void **);
#endif
@@ -0,0 +1,54 @@
/* SPDX-License-Identifier: MIT */
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FSP , struct nvkm_fsp , fsp)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VFN , struct nvkm_vfn , vfn)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PCI , struct nvkm_pci , pci)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VBIOS , struct nvkm_bios , bios)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_DEVINIT , struct nvkm_devinit , devinit)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PRIVRING, struct nvkm_subdev , privring)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GPIO , struct nvkm_gpio , gpio)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_I2C , struct nvkm_i2c , i2c)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FUSE , struct nvkm_fuse , fuse)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MXM , struct nvkm_subdev , mxm)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MC , struct nvkm_mc , mc)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_BUS , struct nvkm_bus , bus)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TIMER , struct nvkm_timer , timer)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_INSTMEM , struct nvkm_instmem , imem)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FB , struct nvkm_fb , fb)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_LTC , struct nvkm_ltc , ltc)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_MMU , struct nvkm_mmu , mmu)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_BAR , struct nvkm_bar , bar)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FAULT , struct nvkm_fault , fault)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_ACR , struct nvkm_acr , acr)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PMU , struct nvkm_pmu , pmu)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VOLT , struct nvkm_volt , volt)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_ICCSENSE, struct nvkm_iccsense, iccsense)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_THERM , struct nvkm_therm , therm)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_CLK , struct nvkm_clk , clk)
NVKM_LAYOUT_INST(NVKM_SUBDEV_IOCTRL , struct nvkm_subdev , ioctrl, 3)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FLA , struct nvkm_subdev , fla)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_BSP , struct nvkm_engine , bsp)
NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 20)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_CIPHER , struct nvkm_engine , cipher)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_DISP , struct nvkm_disp , disp)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_DMAOBJ , struct nvkm_dma , dma)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_FIFO , struct nvkm_fifo , fifo)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_GR , struct nvkm_gr , gr)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_IFB , struct nvkm_engine , ifb)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_ME , struct nvkm_engine , me)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_MPEG , struct nvkm_engine , mpeg)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSENC , struct nvkm_engine , msenc)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPDEC , struct nvkm_engine , mspdec)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPPP , struct nvkm_engine , msppp)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSVLD , struct nvkm_engine , msvld)
NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 8)
NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 4)
NVKM_LAYOUT_INST(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg, 8)
NVKM_LAYOUT_INST(NVKM_ENGINE_OFA , struct nvkm_engine , ofa, 2)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC , struct nvkm_engine , sec)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC2 , struct nvkm_sec2 , sec2)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_SW , struct nvkm_sw , sw)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_VIC , struct nvkm_engine , vic)
NVKM_LAYOUT_ONCE(NVKM_ENGINE_VP , struct nvkm_engine , vp)
@@ -0,0 +1,124 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MEMORY_H__
#define __NVKM_MEMORY_H__
#include <core/os.h>
struct nvkm_device;
struct nvkm_vma;
struct nvkm_vmm;
struct nvkm_tags {
struct nvkm_mm_node *mn;
refcount_t refcount;
};
enum nvkm_memory_target {
NVKM_MEM_TARGET_INST_SR_LOST, /* instance memory - not preserved across suspend */
NVKM_MEM_TARGET_INST, /* instance memory */
NVKM_MEM_TARGET_VRAM, /* video memory */
NVKM_MEM_TARGET_HOST, /* coherent system memory */
NVKM_MEM_TARGET_NCOH, /* non-coherent system memory */
};
struct nvkm_memory {
const struct nvkm_memory_func *func;
const struct nvkm_memory_ptrs *ptrs;
struct kref kref;
struct nvkm_tags *tags;
};
struct nvkm_memory_func {
void *(*dtor)(struct nvkm_memory *);
enum nvkm_memory_target (*target)(struct nvkm_memory *);
u8 (*page)(struct nvkm_memory *);
u64 (*bar2)(struct nvkm_memory *);
u64 (*addr)(struct nvkm_memory *);
u64 (*size)(struct nvkm_memory *);
void (*boot)(struct nvkm_memory *, struct nvkm_vmm *);
void __iomem *(*acquire)(struct nvkm_memory *);
void (*release)(struct nvkm_memory *);
int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *,
struct nvkm_vma *, void *argv, u32 argc);
int (*kmap)(struct nvkm_memory *, struct nvkm_memory **);
};
struct nvkm_memory_ptrs {
u32 (*rd32)(struct nvkm_memory *, u64 offset);
void (*wr32)(struct nvkm_memory *, u64 offset, u32 data);
};
void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *);
int nvkm_memory_new(struct nvkm_device *, enum nvkm_memory_target,
u64 size, u32 align, bool zero, struct nvkm_memory **);
struct nvkm_memory *nvkm_memory_ref(struct nvkm_memory *);
void nvkm_memory_unref(struct nvkm_memory **);
int nvkm_memory_tags_get(struct nvkm_memory *, struct nvkm_device *, u32 tags,
void (*clear)(struct nvkm_device *, u32, u32),
struct nvkm_tags **);
void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *,
struct nvkm_tags **);
#define nvkm_memory_target(p) (p)->func->target(p)
#define nvkm_memory_page(p) (p)->func->page(p)
#define nvkm_memory_bar2(p) (p)->func->bar2(p)
#define nvkm_memory_addr(p) (p)->func->addr(p)
#define nvkm_memory_size(p) (p)->func->size(p)
#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v))
#define nvkm_memory_map(p,o,vm,va,av,ac) \
(p)->func->map((p),(o),(vm),(va),(av),(ac))
#define nvkm_memory_kmap(p,i) ((p)->func->kmap ? (p)->func->kmap((p), (i)) : -ENOSYS)
/* accessor macros - kmap()/done() must bracket use of the other accessor
* macros to guarantee correct behaviour across all chipsets
*/
#define nvkm_kmap(o) (o)->func->acquire(o)
#define nvkm_done(o) (o)->func->release(o)
#define nvkm_ro32(o,a) (o)->ptrs->rd32((o), (a))
#define nvkm_wo32(o,a,d) (o)->ptrs->wr32((o), (a), (d))
#define nvkm_mo32(o,a,m,d) ({ \
u32 _addr = (a), _data = nvkm_ro32((o), _addr); \
nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \
_data; \
})
#define nvkm_wo64(o,a,d) do { \
u64 __a = (a), __d = (d); \
nvkm_wo32((o), __a + 0, lower_32_bits(__d)); \
nvkm_wo32((o), __a + 4, upper_32_bits(__d)); \
} while(0)
#define nvkm_robj(o,a,p,s) do { \
u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \
while (_size--) { \
*(_data++) = nvkm_ro32((o), _addr); \
_addr += 4; \
} \
} while(0)
#define nvkm_wobj(o,a,p,s) do { \
u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \
while (_size--) { \
nvkm_wo32((o), _addr, *(_data++)); \
_addr += 4; \
} \
} while(0)
#define nvkm_fill(t,s,o,a,d,c) do { \
u64 _a = (a), _c = (c), _d = (d), _o = _a >> s, _s = _c << s; \
u##t __iomem *_m = nvkm_kmap(o); \
if (likely(_m)) { \
if (_d) { \
while (_c--) \
iowrite##t##_native(_d, &_m[_o++]); \
} else { \
memset_io(&_m[_o], _d, _s); \
} \
} else { \
for (; _c; _c--, _a += BIT(s)) \
nvkm_wo##t((o), _a, _d); \
} \
nvkm_done(o); \
} while(0)
#define nvkm_fo32(o,a,d,c) nvkm_fill(32, 2, (o), (a), (d), (c))
#define nvkm_fo64(o,a,d,c) nvkm_fill(64, 3, (o), (a), (d), (c))
#endif
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MM_H__
#define __NVKM_MM_H__
#include <core/os.h>
struct nvkm_mm_node {
struct list_head nl_entry;
struct list_head fl_entry;
struct nvkm_mm_node *next;
#define NVKM_MM_HEAP_ANY 0x00
u8 heap;
#define NVKM_MM_TYPE_NONE 0x00
#define NVKM_MM_TYPE_HOLE 0xff
u8 type;
u32 offset;
u32 length;
};
struct nvkm_mm {
struct list_head nodes;
struct list_head free;
u32 block_size;
int heap_nodes;
};
static inline bool
nvkm_mm_initialised(struct nvkm_mm *mm)
{
return mm->heap_nodes;
}
int nvkm_mm_init(struct nvkm_mm *, u8 heap, u32 offset, u32 length, u32 block);
int nvkm_mm_fini(struct nvkm_mm *);
int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
u32 size_min, u32 align, struct nvkm_mm_node **);
int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
u32 size_min, u32 align, struct nvkm_mm_node **);
void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **);
void nvkm_mm_dump(struct nvkm_mm *, const char *);
static inline u32
nvkm_mm_heap_size(struct nvkm_mm *mm, u8 heap)
{
struct nvkm_mm_node *node;
u32 size = 0;
list_for_each_entry(node, &mm->nodes, nl_entry) {
if (node->heap == heap)
size += node->length;
}
return size;
}
static inline bool
nvkm_mm_contiguous(struct nvkm_mm_node *node)
{
return !node->next;
}
static inline u32
nvkm_mm_addr(struct nvkm_mm_node *node)
{
if (WARN_ON(!nvkm_mm_contiguous(node)))
return 0;
return node->offset;
}
static inline u32
nvkm_mm_size(struct nvkm_mm_node *node)
{
u32 size = 0;
do {
size += node->length;
} while ((node = node->next));
return size;
}
#endif
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_OBJECT_H__
#define __NVKM_OBJECT_H__
#include <core/oclass.h>
#include <core/suspend_state.h>
struct nvkm_event;
struct nvkm_gpuobj;
struct nvkm_uevent;
struct nvkm_object {
const struct nvkm_object_func *func;
struct nvkm_client *client;
struct nvkm_engine *engine;
s32 oclass;
u32 handle;
struct list_head head;
struct list_head tree;
u64 object;
struct rb_node node;
};
enum nvkm_object_map {
NVKM_OBJECT_MAP_IO,
NVKM_OBJECT_MAP_VA
};
struct nvkm_object_func {
void *(*dtor)(struct nvkm_object *);
int (*init)(struct nvkm_object *);
int (*fini)(struct nvkm_object *, enum nvkm_suspend_state suspend);
int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size);
int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **);
int (*map)(struct nvkm_object *, void *argv, u32 argc,
enum nvkm_object_map *, u64 *addr, u64 *size);
int (*unmap)(struct nvkm_object *);
int (*bind)(struct nvkm_object *, struct nvkm_gpuobj *, int align,
struct nvkm_gpuobj **);
int (*sclass)(struct nvkm_object *, int index, struct nvkm_oclass *);
int (*uevent)(struct nvkm_object *, void *argv, u32 argc, struct nvkm_uevent *);
};
void nvkm_object_ctor(const struct nvkm_object_func *,
const struct nvkm_oclass *, struct nvkm_object *);
int nvkm_object_new_(const struct nvkm_object_func *,
const struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
void nvkm_object_del(struct nvkm_object **);
void *nvkm_object_dtor(struct nvkm_object *);
int nvkm_object_init(struct nvkm_object *);
int nvkm_object_fini(struct nvkm_object *, enum nvkm_suspend_state);
int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **);
int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc,
enum nvkm_object_map *, u64 *addr, u64 *size);
int nvkm_object_unmap(struct nvkm_object *);
int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align,
struct nvkm_gpuobj **);
bool nvkm_object_insert(struct nvkm_object *);
void nvkm_object_remove(struct nvkm_object *);
struct nvkm_object *nvkm_object_search(struct nvkm_client *, u64 object,
const struct nvkm_object_func *);
#endif
@@ -0,0 +1,29 @@
#ifndef __NVKM_OCLASS_H__
#define __NVKM_OCLASS_H__
#include <core/os.h>
#include <core/debug.h>
struct nvkm_oclass;
struct nvkm_object;
struct nvkm_sclass {
int minver;
int maxver;
s32 oclass;
const struct nvkm_object_func *func;
int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
};
struct nvkm_oclass {
int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
struct nvkm_object **);
struct nvkm_sclass base;
const void *priv;
const void *engn;
u32 handle;
u64 object;
struct nvkm_client *client;
struct nvkm_object *parent;
struct nvkm_engine *engine;
};
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_OPROXY_H__
#define __NVKM_OPROXY_H__
#define nvkm_oproxy(p) container_of((p), struct nvkm_oproxy, base)
#include <core/object.h>
struct nvkm_oproxy {
const struct nvkm_oproxy_func *func;
struct nvkm_object base;
struct nvkm_object *object;
};
struct nvkm_oproxy_func {
void (*dtor[2])(struct nvkm_oproxy *);
int (*init[2])(struct nvkm_oproxy *);
int (*fini[2])(struct nvkm_oproxy *, enum nvkm_suspend_state suspend);
};
void nvkm_oproxy_ctor(const struct nvkm_oproxy_func *,
const struct nvkm_oclass *, struct nvkm_oproxy *);
int nvkm_oproxy_new_(const struct nvkm_oproxy_func *,
const struct nvkm_oclass *, struct nvkm_oproxy **);
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_OPTION_H__
#define __NVKM_OPTION_H__
#include <core/os.h>
const char *nvkm_stropt(const char *optstr, const char *opt, int *len);
bool nvkm_boolopt(const char *optstr, const char *opt, bool value);
long nvkm_longopt(const char *optstr, const char *opt, long value);
int nvkm_dbgopt(const char *optstr, const char *sub);
/* compares unterminated string 'str' with zero-terminated string 'cmp' */
static inline int
strncasecmpz(const char *str, const char *cmp, size_t len)
{
if (strlen(cmp) != len)
return len;
return strncasecmp(str, cmp, len);
}
#endif
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_OS_H__
#define __NVKM_OS_H__
#include <nvif/os.h>
struct nvkm_blob {
void *data;
u32 size;
};
static inline void
nvkm_blob_dtor(struct nvkm_blob *blob)
{
kfree(blob->data);
blob->data = NULL;
blob->size = 0;
}
#define nvkm_list_find_next(p,h,m,c) ({ \
typeof(p) _p = NULL; \
list_for_each_entry_continue(p, (h), m) { \
if (c) { \
_p = p; \
break; \
} \
} \
_p; \
})
#define nvkm_list_find(p,h,m,c) \
(p = container_of((h), typeof(*p), m), nvkm_list_find_next(p, (h), m, (c)))
#define nvkm_list_foreach(p,h,m,c) \
for (p = nvkm_list_find(p, (h), m, (c)); p; p = nvkm_list_find_next(p, (h), m, (c)))
#endif
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DEVICE_PCI_H__
#define __NVKM_DEVICE_PCI_H__
#include <core/device.h>
struct nvkm_device_pci {
struct nvkm_device device;
struct pci_dev *pdev;
bool suspend;
};
int nvkm_device_pci_new(struct pci_dev *, const char *cfg, const char *dbg,
struct nvkm_device **);
#endif
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_RAMHT_H__
#define __NVKM_RAMHT_H__
#include <core/gpuobj.h>
struct nvkm_object;
struct nvkm_ramht_data {
struct nvkm_gpuobj *inst;
int chid;
u32 handle;
};
struct nvkm_ramht {
struct nvkm_device *device;
struct nvkm_gpuobj *parent;
struct nvkm_gpuobj *gpuobj;
int size;
int bits;
struct nvkm_ramht_data data[];
};
int nvkm_ramht_new(struct nvkm_device *, u32 size, u32 align,
struct nvkm_gpuobj *, struct nvkm_ramht **);
void nvkm_ramht_del(struct nvkm_ramht **);
int nvkm_ramht_insert(struct nvkm_ramht *, struct nvkm_object *,
int chid, int addr, u32 handle, u32 context);
void nvkm_ramht_remove(struct nvkm_ramht *, int cookie);
struct nvkm_gpuobj *
nvkm_ramht_search(struct nvkm_ramht *, int chid, u32 handle);
#endif
@@ -0,0 +1,95 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SUBDEV_H__
#define __NVKM_SUBDEV_H__
#include <core/device.h>
enum nvkm_subdev_type {
#define NVKM_LAYOUT_ONCE(t,s,p,...) t,
#define NVKM_LAYOUT_INST NVKM_LAYOUT_ONCE
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
NVKM_SUBDEV_NR
};
struct nvkm_subdev {
const struct nvkm_subdev_func *func;
struct nvkm_device *device;
enum nvkm_subdev_type type;
int inst;
char name[16];
u32 debug;
struct {
refcount_t refcount;
struct mutex mutex;
bool enabled;
} use;
struct nvkm_inth inth;
struct list_head head;
void **pself;
bool oneinit;
};
struct nvkm_subdev_func {
void *(*dtor)(struct nvkm_subdev *);
int (*preinit)(struct nvkm_subdev *);
int (*oneinit)(struct nvkm_subdev *);
int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data);
int (*init)(struct nvkm_subdev *);
int (*fini)(struct nvkm_subdev *, enum nvkm_suspend_state suspend);
void (*intr)(struct nvkm_subdev *);
};
extern const char *nvkm_subdev_type[NVKM_SUBDEV_NR];
int nvkm_subdev_new_(const struct nvkm_subdev_func *, struct nvkm_device *, enum nvkm_subdev_type,
int inst, struct nvkm_subdev **);
void __nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, struct nvkm_subdev *);
static inline void
nvkm_subdev_ctor(const struct nvkm_subdev_func *func, struct nvkm_device *device,
enum nvkm_subdev_type type, int inst, struct nvkm_subdev *subdev)
{
__nvkm_subdev_ctor(func, device, type, inst, subdev);
mutex_init(&subdev->use.mutex);
}
void nvkm_subdev_disable(struct nvkm_device *, enum nvkm_subdev_type, int inst);
void nvkm_subdev_del(struct nvkm_subdev **);
int nvkm_subdev_ref(struct nvkm_subdev *);
void nvkm_subdev_unref(struct nvkm_subdev *);
int nvkm_subdev_preinit(struct nvkm_subdev *);
int nvkm_subdev_oneinit(struct nvkm_subdev *);
int nvkm_subdev_init(struct nvkm_subdev *);
int nvkm_subdev_fini(struct nvkm_subdev *, enum nvkm_suspend_state suspend);
int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *);
void nvkm_subdev_intr(struct nvkm_subdev *);
/* subdev logging */
#define nvkm_printk_ok(s,u,l) \
((CONFIG_NOUVEAU_DEBUG >= (l)) && ((s)->debug >= (l) || ((u) && (u)->debug >= (l))))
#define nvkm_printk___(s,u,l,p,f,a...) do { \
if (nvkm_printk_ok((s), (u), (l))) { \
if ((u) && (u) != (s)) \
dev_##p((s)->device->dev, "%s(%s):"f, (s)->name, (u)->name, ##a); \
else \
dev_##p((s)->device->dev, "%s:"f, (s)->name, ##a); \
} \
} while(0)
#define nvkm_printk__(s,l,p,f,a...) nvkm_printk___((s), (s), (l), p, f, ##a)
#define nvkm_printk_(s,l,p,f,a...) nvkm_printk__((s), (l), p, " "f, ##a)
#define nvkm_printk(s,l,p,f,a...) nvkm_printk_((s), NV_DBG_##l, p, f, ##a)
#define nvkm_fatal(s,f,a...) nvkm_printk((s), FATAL, crit, f, ##a)
#define nvkm_error(s,f,a...) nvkm_printk((s), ERROR, err, f, ##a)
#define nvkm_warn(s,f,a...) nvkm_printk((s), WARN, notice, f, ##a)
#define nvkm_info(s,f,a...) nvkm_printk((s), INFO, info, f, ##a)
#define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG, info, f, ##a)
#define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE, info, f, ##a)
#define nvkm_spam(s,f,a...) nvkm_printk((s), SPAM, dbg, f, ##a)
#define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, err_ratelimited, f, ##a)
#endif
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SUSPEND_STATE_H__
#define __NVKM_SUSPEND_STATE_H__
enum nvkm_suspend_state {
NVKM_POWEROFF,
NVKM_SUSPEND,
NVKM_RUNTIME_SUSPEND,
};
#endif
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DEVICE_TEGRA_H__
#define __NVKM_DEVICE_TEGRA_H__
#include <core/device.h>
#include <core/mm.h>
struct nvkm_device_tegra {
const struct nvkm_device_tegra_func *func;
struct nvkm_device device;
struct platform_device *pdev;
void __iomem *regs;
struct reset_control *rst;
struct clk *clk;
struct clk *clk_ref;
struct clk *clk_pwr;
struct regulator *vdd;
struct tegra_pmc *pmc;
struct {
/*
* Protects accesses to mm from subsystems
*/
struct mutex mutex;
struct nvkm_mm mm;
struct iommu_domain *domain;
unsigned long pgshift;
} iommu;
int gpu_speedo;
int gpu_speedo_id;
};
struct nvkm_device_tegra_func {
/*
* If an IOMMU is used, indicates which address bit will trigger a
* IOMMU translation when set (when this bit is not set, IOMMU is
* bypassed). A value of 0 means an IOMMU is never used.
*/
u8 iommu_bit;
/*
* Whether the chip requires a reference clock
*/
bool require_ref_clk;
/*
* Whether the chip requires the VDD regulator
*/
bool require_vdd;
};
int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
struct platform_device *,
const char *cfg, const char *dbg,
struct nvkm_device **);
#endif
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_BSP_H__
#define __NVKM_BSP_H__
#include <engine/xtensa.h>
int g84_bsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_CE_H__
#define __NVKM_CE_H__
#include <engine/falcon.h>
int gt215_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gf100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gk104_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gm107_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gm200_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gp100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gp102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gv100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int tu102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int ga100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int ga102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_CIPHER_H__
#define __NVKM_CIPHER_H__
#include <core/engine.h>
int g84_cipher_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DISP_H__
#define __NVKM_DISP_H__
#define nvkm_disp(p) container_of((p), struct nvkm_disp, engine)
#include <core/engine.h>
#include <core/object.h>
#include <core/event.h>
#include <subdev/gsp.h>
struct nvkm_disp {
const struct nvkm_disp_func *func;
struct nvkm_engine engine;
struct {
struct nvkm_gsp_client client;
struct nvkm_gsp_device device;
struct nvkm_gsp_object objcom;
struct nvkm_gsp_object object;
#define NVKM_DPYID_PLUG BIT(0)
#define NVKM_DPYID_UNPLUG BIT(1)
#define NVKM_DPYID_IRQ BIT(2)
struct nvkm_event event;
struct nvkm_gsp_event hpd;
struct nvkm_gsp_event irq;
u32 assigned_sors;
} rm;
struct list_head heads;
struct list_head iors;
struct list_head outps;
struct list_head conns;
struct nvkm_event hpd;
#define NVKM_DISP_HEAD_EVENT_VBLANK BIT(0)
struct nvkm_event vblank;
struct {
struct workqueue_struct *wq;
struct work_struct work;
u32 pending;
struct mutex mutex;
} super;
#define NVKM_DISP_EVENT_CHAN_AWAKEN BIT(0)
struct nvkm_event uevent;
struct {
unsigned long mask;
int nr;
} wndw, head, dac, sor;
struct {
unsigned long mask;
int nr;
u8 type[3];
} pior;
struct nvkm_gpuobj *inst;
struct nvkm_ramht *ramht;
struct nvkm_disp_chan *chan[81];
struct {
spinlock_t lock;
struct nvkm_object object;
} client;
};
int nv04_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int nv50_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int g84_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gt200_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int g94_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int mcp77_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gt215_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int mcp89_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gf119_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gk104_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gk110_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gm107_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gm200_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gp100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
#endif
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DMA_H__
#define __NVKM_DMA_H__
#include <core/engine.h>
#include <core/object.h>
struct nvkm_client;
struct nvkm_dmaobj {
const struct nvkm_dmaobj_func *func;
struct nvkm_dma *dma;
struct nvkm_object object;
u32 target;
u32 access;
u64 start;
u64 limit;
};
struct nvkm_dma {
const struct nvkm_dma_func *func;
struct nvkm_engine engine;
};
struct nvkm_dmaobj *nvkm_dmaobj_search(struct nvkm_client *, u64 object);
int nv04_dma_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_dma **);
int nv50_dma_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_dma **);
int gf100_dma_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_dma **);
int gf119_dma_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_dma **);
int gv100_dma_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_dma **);
#endif
@@ -0,0 +1,136 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FLCNEN_H__
#define __NVKM_FLCNEN_H__
#define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine)
#include <core/engine.h>
struct nvkm_chan;
enum nvkm_falcon_dmaidx {
FALCON_DMAIDX_UCODE = 0,
FALCON_DMAIDX_VIRT = 1,
FALCON_DMAIDX_PHYS_VID = 2,
FALCON_DMAIDX_PHYS_SYS_COH = 3,
FALCON_DMAIDX_PHYS_SYS_NCOH = 4,
FALCON_SEC2_DMAIDX_UCODE = 6,
};
struct nvkm_falcon {
const struct nvkm_falcon_func *func;
struct nvkm_subdev *owner;
const char *name;
u32 addr;
u32 addr2;
struct mutex mutex;
struct mutex dmem_mutex;
bool oneinit;
struct nvkm_subdev *user;
u8 version;
u8 secret;
bool debug;
struct nvkm_memory *core;
bool external;
struct {
u32 limit;
u32 *data;
u32 size;
u8 ports;
} code;
struct {
u32 limit;
u32 *data;
u32 size;
u8 ports;
} data;
struct nvkm_engine engine;
};
int nvkm_falcon_get(struct nvkm_falcon *, struct nvkm_subdev *);
void nvkm_falcon_put(struct nvkm_falcon *, struct nvkm_subdev *);
int nvkm_falcon_new_(const struct nvkm_falcon_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, bool enable, u32 addr, struct nvkm_engine **);
struct nvkm_falcon_func {
int (*disable)(struct nvkm_falcon *);
int (*enable)(struct nvkm_falcon *);
int (*select)(struct nvkm_falcon *);
u32 addr2;
u32 riscv_irqmask;
bool reset_pmc;
int (*reset_eng)(struct nvkm_falcon *);
int (*reset_prep)(struct nvkm_falcon *);
int (*reset_wait_mem_scrubbing)(struct nvkm_falcon *);
u32 debug;
void (*bind_inst)(struct nvkm_falcon *, int target, u64 addr);
int (*bind_stat)(struct nvkm_falcon *, bool intr);
bool bind_intr;
const struct nvkm_falcon_func_pio *imem_pio;
const struct nvkm_falcon_func_dma *imem_dma;
const struct nvkm_falcon_func_pio *dmem_pio;
const struct nvkm_falcon_func_dma *dmem_dma;
u32 emem_addr;
const struct nvkm_falcon_func_pio *emem_pio;
struct {
u32 head;
u32 tail;
u32 stride;
} cmdq, msgq;
bool (*riscv_active)(struct nvkm_falcon *);
void (*intr_retrigger)(struct nvkm_falcon *);
struct {
u32 *data;
u32 size;
} code;
struct {
u32 *data;
u32 size;
} data;
void (*init)(struct nvkm_falcon *);
void (*intr)(struct nvkm_falcon *, struct nvkm_chan *);
void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
void (*start)(struct nvkm_falcon *);
struct nvkm_sclass sclass[];
};
static inline u32
nvkm_falcon_rd32(struct nvkm_falcon *falcon, u32 addr)
{
return nvkm_rd32(falcon->owner->device, falcon->addr + addr);
}
static inline void
nvkm_falcon_wr32(struct nvkm_falcon *falcon, u32 addr, u32 data)
{
nvkm_wr32(falcon->owner->device, falcon->addr + addr, data);
}
static inline u32
nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
{
struct nvkm_device *device = falcon->owner->device;
return nvkm_mask(device, falcon->addr + addr, mask, val);
}
void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
bool);
void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_start(struct nvkm_falcon *);
#endif
@@ -0,0 +1,115 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FIFO_H__
#define __NVKM_FIFO_H__
#include <core/engine.h>
#include <core/object.h>
#include <core/event.h>
#include <subdev/gsp.h>
struct nvkm_fault_data;
#define NVKM_FIFO_ENGN_NR 16
struct nvkm_chan {
const struct nvkm_chan_func *func;
char name[64];
struct nvkm_cgrp *cgrp;
int runq;
struct nvkm_gpuobj *inst;
struct nvkm_vmm *vmm;
struct nvkm_gpuobj *push;
int id;
struct {
struct nvkm_memory *mem;
u32 base;
} userd;
u32 ramfc_offset;
struct nvkm_gpuobj *ramfc;
struct nvkm_gpuobj *cache;
struct nvkm_gpuobj *eng;
struct nvkm_gpuobj *pgd;
struct nvkm_ramht *ramht;
spinlock_t lock;
atomic_t blocked;
atomic_t errored;
struct {
struct nvkm_gsp_object object;
struct {
dma_addr_t addr;
void *ptr;
} mthdbuf;
struct nvkm_vctx *grctx;
} rm;
struct list_head cctxs;
struct list_head head;
};
struct nvkm_chan *nvkm_chan_get_chid(struct nvkm_engine *, int id, unsigned long *irqflags);
struct nvkm_chan *nvkm_chan_get_inst(struct nvkm_engine *, u64 inst, unsigned long *irqflags);
void nvkm_chan_put(struct nvkm_chan **, unsigned long irqflags);
struct nvkm_chan *nvkm_uchan_chan(struct nvkm_object *);
struct nvkm_fifo {
const struct nvkm_fifo_func *func;
struct nvkm_engine engine;
struct nvkm_chid *chid;
struct nvkm_chid *cgid;
struct list_head runqs;
struct list_head runls;
struct {
#define NVKM_FIFO_NONSTALL_EVENT BIT(0)
struct nvkm_event event;
struct nvkm_inth intr;
} nonstall;
struct {
u32 chan_msec;
} timeout;
struct {
struct nvkm_memory *mem;
struct nvkm_vma *bar1;
} userd;
struct {
u32 mthdbuf_size;
} rm;
spinlock_t lock;
struct mutex mutex;
};
void nvkm_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *);
void nvkm_fifo_pause(struct nvkm_fifo *, unsigned long *);
void nvkm_fifo_start(struct nvkm_fifo *, unsigned long *);
bool nvkm_fifo_ctxsw_in_progress(struct nvkm_engine *);
int nv04_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv10_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv17_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv40_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv50_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int g84_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int g98_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gf100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk104_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk110_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk208_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk20a_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gm107_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gm200_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int ga100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
#endif
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_GR_H__
#define __NVKM_GR_H__
#include <core/engine.h>
struct nvkm_gr_zcull_info {
__u32 width_align_pixels;
__u32 height_align_pixels;
__u32 pixel_squares_by_aliquots;
__u32 aliquot_total;
__u32 zcull_region_byte_multiplier;
__u32 zcull_region_header_size;
__u32 zcull_subregion_header_size;
__u32 subregion_count;
__u32 subregion_width_align_pixels;
__u32 subregion_height_align_pixels;
__u32 ctxsw_size;
__u32 ctxsw_align;
};
struct nvkm_gr {
const struct nvkm_gr_func *func;
struct nvkm_engine engine;
struct nvkm_gr_zcull_info zcull_info;
bool has_zcull_info;
};
u64 nvkm_gr_units(struct nvkm_gr *);
int nvkm_gr_tlb_flush(struct nvkm_gr *);
int nvkm_gr_ctxsw_pause(struct nvkm_device *);
int nvkm_gr_ctxsw_resume(struct nvkm_device *);
u32 nvkm_gr_ctxsw_inst(struct nvkm_device *);
int nv04_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv10_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv15_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv17_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv20_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv25_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv2a_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv30_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv34_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv35_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv40_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv44_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int nv50_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int g84_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gt200_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int mcp79_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gt215_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int mcp89_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf104_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf108_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf110_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf117_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gf119_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gk104_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gk110_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gk110b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gk208_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gk20a_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gm107_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gm200_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gm20b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp104_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp107_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp108_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gp10b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gv100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int tu102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int ga102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
#endif
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MPEG_H__
#define __NVKM_MPEG_H__
#include <core/engine.h>
int nv31_mpeg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int nv40_mpeg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int nv44_mpeg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int nv50_mpeg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int g84_mpeg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,5 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MSENC_H__
#define __NVKM_MSENC_H__
#include <core/engine.h>
#endif
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MSPDEC_H__
#define __NVKM_MSPDEC_H__
#include <engine/falcon.h>
int g98_mspdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gt215_mspdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gf100_mspdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gk104_mspdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MSPPP_H__
#define __NVKM_MSPPP_H__
#include <engine/falcon.h>
int g98_msppp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gt215_msppp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gf100_msppp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MSVLD_H__
#define __NVKM_MSVLD_H__
#include <engine/falcon.h>
int g98_msvld_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gt215_msvld_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int mcp89_msvld_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gf100_msvld_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gk104_msvld_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_NVDEC_H__
#define __NVKM_NVDEC_H__
#define nvkm_nvdec(p) container_of((p), struct nvkm_nvdec, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_nvdec {
const struct nvkm_nvdec_func *func;
struct nvkm_engine engine;
struct nvkm_falcon falcon;
};
int gm107_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **);
int tu102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **);
int ga102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **);
#endif
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_NVENC_H__
#define __NVKM_NVENC_H__
#define nvkm_nvenc(p) container_of((p), struct nvkm_nvenc, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_nvenc {
const struct nvkm_nvenc_func *func;
struct nvkm_engine engine;
struct nvkm_falcon falcon;
};
int gm107_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **);
int tu102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **);
#endif
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SEC_H__
#define __NVKM_SEC_H__
#include <engine/falcon.h>
int g98_sec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SEC2_H__
#define __NVKM_SEC2_H__
#define nvkm_sec2(p) container_of((p), struct nvkm_sec2, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_sec2 {
const struct nvkm_sec2_func *func;
struct nvkm_engine engine;
struct nvkm_falcon falcon;
atomic_t running;
atomic_t initmsg;
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *cmdq;
struct nvkm_falcon_msgq *msgq;
struct work_struct work;
};
int gp102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int gp108_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int tu102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int ga102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SW_H__
#define __NVKM_SW_H__
#include <core/engine.h>
struct nvkm_sw {
const struct nvkm_sw_func *func;
struct nvkm_engine engine;
struct list_head chan;
};
bool nvkm_sw_mthd(struct nvkm_sw *sw, int chid, int subc, u32 mthd, u32 data);
int nv04_sw_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sw **);
int nv10_sw_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sw **);
int nv50_sw_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sw **);
int gf100_sw_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sw **);
#endif
@@ -0,0 +1,5 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_VIC_H__
#define __NVKM_VIC_H__
#include <core/engine.h>
#endif
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_VP_H__
#define __NVKM_VP_H__
#include <engine/xtensa.h>
int g84_vp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_XTENSA_H__
#define __NVKM_XTENSA_H__
#define nvkm_xtensa(p) container_of((p), struct nvkm_xtensa, engine)
#include <core/engine.h>
struct nvkm_xtensa {
const struct nvkm_xtensa_func *func;
u32 addr;
struct nvkm_engine engine;
struct nvkm_memory *gpu_fw;
};
int nvkm_xtensa_new_(const struct nvkm_xtensa_func *, struct nvkm_device *,
enum nvkm_subdev_type, int, bool enable, u32 addr, struct nvkm_engine **);
struct nvkm_xtensa_func {
u32 fifo_val;
u32 unkd28;
struct nvkm_sclass sclass[];
};
#endif
@@ -0,0 +1,154 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_ACR_H__
#define __NVKM_ACR_H__
#define nvkm_acr(p) container_of((p), struct nvkm_acr, subdev)
#include <core/subdev.h>
#include <core/falcon.h>
enum nvkm_acr_lsf_id {
NVKM_ACR_LSF_PMU = 0,
NVKM_ACR_LSF_GSPLITE = 1,
NVKM_ACR_LSF_FECS = 2,
NVKM_ACR_LSF_GPCCS = 3,
NVKM_ACR_LSF_NVDEC = 4,
NVKM_ACR_LSF_SEC2 = 7,
NVKM_ACR_LSF_MINION = 10,
NVKM_ACR_LSF_NUM
};
static inline const char *
nvkm_acr_lsf_id(enum nvkm_acr_lsf_id id)
{
switch (id) {
case NVKM_ACR_LSF_PMU : return "pmu";
case NVKM_ACR_LSF_GSPLITE: return "gsplite";
case NVKM_ACR_LSF_FECS : return "fecs";
case NVKM_ACR_LSF_GPCCS : return "gpccs";
case NVKM_ACR_LSF_NVDEC : return "nvdec";
case NVKM_ACR_LSF_SEC2 : return "sec2";
case NVKM_ACR_LSF_MINION : return "minion";
default:
return "unknown";
}
}
struct nvkm_acr {
const struct nvkm_acr_func *func;
struct nvkm_subdev subdev;
struct list_head hsfw;
struct list_head lsfw, lsf;
u64 managed_falcons;
struct nvkm_memory *wpr;
u64 wpr_start;
u64 wpr_end;
u64 shadow_start;
struct nvkm_memory *inst;
struct nvkm_vmm *vmm;
bool done;
struct nvkm_acr_lsf *rtos;
const struct firmware *wpr_fw;
bool wpr_comp;
u64 wpr_prev;
};
bool nvkm_acr_managed_falcon(struct nvkm_device *, enum nvkm_acr_lsf_id);
int nvkm_acr_bootstrap_falcons(struct nvkm_device *, unsigned long mask);
int gm200_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gm20b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gp102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gp108_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gp10b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gv100_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int tu102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int ga102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
struct nvkm_acr_lsfw {
const struct nvkm_acr_lsf_func *func;
struct nvkm_falcon *falcon;
enum nvkm_acr_lsf_id id;
struct list_head head;
struct nvkm_blob img;
const struct firmware *sig;
bool secure_bootloader;
u32 bootloader_size;
u32 bootloader_imem_offset;
u32 app_size;
u32 app_start_offset;
u32 app_imem_entry;
u32 app_resident_code_offset;
u32 app_resident_code_size;
u32 app_resident_data_offset;
u32 app_resident_data_size;
u32 app_imem_offset;
u32 app_dmem_offset;
u32 ucode_size;
u32 data_size;
u32 fuse_ver;
u32 engine_id;
u32 ucode_id;
u32 sig_size;
u32 sig_nr;
u8 *sigs;
struct {
u32 lsb;
u32 img;
u32 bld;
} offset;
u32 bl_data_size;
};
struct nvkm_acr_lsf_func {
/* The (currently) map directly to LSB header flags. */
#define NVKM_ACR_LSF_LOAD_CODE_AT_0 0x00000001
#define NVKM_ACR_LSF_DMACTL_REQ_CTX 0x00000004
#define NVKM_ACR_LSF_FORCE_PRIV_LOAD 0x00000008
u32 flags;
u32 bl_entry;
u32 bld_size;
void (*bld_write)(struct nvkm_acr *, u32 bld, struct nvkm_acr_lsfw *);
void (*bld_patch)(struct nvkm_acr *, u32 bld, s64 adjust);
u64 bootstrap_falcons;
int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
};
int
nvkm_acr_lsfw_load_sig_image_desc(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_sig_image_desc_v1(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_sig_image_desc_v2(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_bl_inst_data_sig(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_bl_sig_net(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *,
const void *, u32, const void *, u32);
#endif
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_BAR_H__
#define __NVKM_BAR_H__
#include <core/subdev.h>
struct nvkm_vma;
struct nvkm_bar {
const struct nvkm_bar_func *func;
struct nvkm_subdev subdev;
spinlock_t lock;
bool bar2;
void __iomem *flushBAR2PhysMode;
struct nvkm_memory *flushFBZero;
void __iomem *flushBAR2;
/* whether the BAR supports to be ioremapped WC or should be uncached */
bool iomap_uncached;
};
struct nvkm_vmm *nvkm_bar_bar1_vmm(struct nvkm_device *);
void nvkm_bar_bar1_reset(struct nvkm_device *);
void nvkm_bar_bar2_init(struct nvkm_device *);
void nvkm_bar_bar2_fini(struct nvkm_device *);
void nvkm_bar_bar2_reset(struct nvkm_device *);
struct nvkm_vmm *nvkm_bar_bar2_vmm(struct nvkm_device *);
void nvkm_bar_flush(struct nvkm_bar *);
int nv50_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int g84_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int gf100_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int gk20a_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int gm107_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int gm20b_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
int tu102_bar_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bar **);
#endif
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_BIOS_H__
#define __NVKM_BIOS_H__
#include <core/subdev.h>
struct nvkm_bios {
struct nvkm_subdev subdev;
u32 size;
u8 *data;
u32 image0_size;
u32 imaged_addr;
u32 bmp_offset;
u32 bit_offset;
struct {
u8 major;
u8 chip;
u8 minor;
u8 micro;
u8 patch;
} version;
};
u8 nvbios_checksum(const u8 *data, int size);
u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
int nvbios_memcmp(struct nvkm_bios *, u32 addr, const char *, u32 len);
u8 nvbios_rd08(struct nvkm_bios *, u32 addr);
u16 nvbios_rd16(struct nvkm_bios *, u32 addr);
u32 nvbios_rd32(struct nvkm_bios *, u32 addr);
void *nvbios_pointer(struct nvkm_bios *, u32 addr);
int nvkm_bios_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_bios **);
#endif
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_M0203_H__
#define __NVBIOS_M0203_H__
struct nvbios_M0203T {
#define M0203T_TYPE_RAMCFG 0x00
u8 type;
u16 pointer;
};
u32 nvbios_M0203Te(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_M0203Tp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_M0203T *);
struct nvbios_M0203E {
#define M0203E_TYPE_DDR2 0x0
#define M0203E_TYPE_DDR3 0x1
#define M0203E_TYPE_GDDR3 0x2
#define M0203E_TYPE_GDDR5 0x3
#define M0203E_TYPE_HBM2 0x6
#define M0203E_TYPE_GDDR5X 0x8
#define M0203E_TYPE_GDDR6 0x9
#define M0203E_TYPE_SKIP 0xf
u8 type;
u8 strap;
u8 group;
};
u32 nvbios_M0203Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_M0203Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0203E *);
u32 nvbios_M0203Em(struct nvkm_bios *, u8 ramcfg, u8 *ver, u8 *hdr,
struct nvbios_M0203E *);
#endif
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_M0205_H__
#define __NVBIOS_M0205_H__
struct nvbios_M0205T {
u16 freq;
};
u32 nvbios_M0205Te(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u32 nvbios_M0205Tp(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
struct nvbios_M0205T *);
struct nvbios_M0205E {
u8 type;
};
u32 nvbios_M0205Ee(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_M0205Ep(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0205E *);
struct nvbios_M0205S {
u8 data;
};
u32 nvbios_M0205Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
u32 nvbios_M0205Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0205S *);
#endif
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_M0209_H__
#define __NVBIOS_M0209_H__
u32 nvbios_M0209Te(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
struct nvbios_M0209E {
u8 v00_40;
u8 bits;
u8 modulo;
u8 v02_40;
u8 v02_07;
u8 v03;
};
u32 nvbios_M0209Ee(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_M0209Ep(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0209E *);
struct nvbios_M0209S {
u32 data[0x200];
};
u32 nvbios_M0209Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
u32 nvbios_M0209Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0209S *);
#endif
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_P0260_H__
#define __NVBIOS_P0260_H__
u32 nvbios_P0260Te(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
struct nvbios_P0260E {
u32 data;
};
u32 nvbios_P0260Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_P0260Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_P0260E *);
struct nvbios_P0260X {
u32 data;
};
u32 nvbios_P0260Xe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_P0260Xp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_P0260X *);
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_BIT_H__
#define __NVBIOS_BIT_H__
struct bit_entry {
u8 id;
u8 version;
u16 length;
u16 offset;
};
int bit_entry(struct nvkm_bios *, u8 id, struct bit_entry *);
#endif
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_BMP_H__
#define __NVBIOS_BMP_H__
static inline u16
bmp_version(struct nvkm_bios *bios)
{
if (bios->bmp_offset) {
return nvbios_rd08(bios, bios->bmp_offset + 5) << 8 |
nvbios_rd08(bios, bios->bmp_offset + 6);
}
return 0x0000;
}
static inline u16
bmp_mem_init_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nvbios_rd16(bios, bios->bmp_offset + 24);
return 0x0000;
}
static inline u16
bmp_sdr_seq_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nvbios_rd16(bios, bios->bmp_offset + 26);
return 0x0000;
}
static inline u16
bmp_ddr_seq_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nvbios_rd16(bios, bios->bmp_offset + 28);
return 0x0000;
}
#endif
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_BOOST_H__
#define __NVBIOS_BOOST_H__
u32 nvbios_boostTe(struct nvkm_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
struct nvbios_boostE {
u8 pstate;
u32 min;
u32 max;
};
u32 nvbios_boostEe(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *);
u32 nvbios_boostEp(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *,
struct nvbios_boostE *);
u32 nvbios_boostEm(struct nvkm_bios *, u8, u8 *, u8 *, u8 *, u8 *,
struct nvbios_boostE *);
struct nvbios_boostS {
u8 domain;
u8 percent;
u32 min;
u32 max;
};
u32 nvbios_boostSe(struct nvkm_bios *, int, u32, u8 *, u8 *, u8, u8);
u32 nvbios_boostSp(struct nvkm_bios *, int, u32, u8 *, u8 *, u8, u8,
struct nvbios_boostS *);
#endif
@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_CONN_H__
#define __NVBIOS_CONN_H__
/*
* An enumerator representing all of the possible VBIOS connector types defined
* by Nvidia at
* https://nvidia.github.io/open-gpu-doc/DCB/DCB-4.x-Specification.html.
*
* [1] Nvidia's documentation actually claims DCB_CONNECTOR_HDMI_0 is a "3-Pin
* DIN Stereo Connector". This seems very likely to be a documentation typo
* or some sort of funny historical baggage, because we've treated this
* connector type as HDMI for years without issue.
* TODO: Check with Nvidia what's actually happening here.
*/
enum dcb_connector_type {
/* Analog outputs */
DCB_CONNECTOR_VGA = 0x00, // VGA 15-pin connector
DCB_CONNECTOR_DVI_A = 0x01, // DVI-A
DCB_CONNECTOR_POD_VGA = 0x02, // Pod - VGA 15-pin connector
DCB_CONNECTOR_TV_0 = 0x10, // TV - Composite Out
DCB_CONNECTOR_TV_1 = 0x11, // TV - S-Video Out
DCB_CONNECTOR_TV_2 = 0x12, // TV - S-Video Breakout - Composite
DCB_CONNECTOR_TV_3 = 0x13, // HDTV Component - YPrPb
DCB_CONNECTOR_TV_SCART = 0x14, // TV - SCART Connector
DCB_CONNECTOR_TV_SCART_D = 0x16, // TV - Composite SCART over D-connector
DCB_CONNECTOR_TV_DTERM = 0x17, // HDTV - D-connector (EIAJ4120)
DCB_CONNECTOR_POD_TV_3 = 0x18, // Pod - HDTV - YPrPb
DCB_CONNECTOR_POD_TV_1 = 0x19, // Pod - S-Video
DCB_CONNECTOR_POD_TV_0 = 0x1a, // Pod - Composite
/* DVI digital outputs */
DCB_CONNECTOR_DVI_I_TV_1 = 0x20, // DVI-I-TV-S-Video
DCB_CONNECTOR_DVI_I_TV_0 = 0x21, // DVI-I-TV-Composite
DCB_CONNECTOR_DVI_I_TV_2 = 0x22, // DVI-I-TV-S-Video Breakout-Composite
DCB_CONNECTOR_DVI_I = 0x30, // DVI-I
DCB_CONNECTOR_DVI_D = 0x31, // DVI-D
DCB_CONNECTOR_DVI_ADC = 0x32, // Apple Display Connector (ADC)
DCB_CONNECTOR_DMS59_0 = 0x38, // LFH-DVI-I-1
DCB_CONNECTOR_DMS59_1 = 0x39, // LFH-DVI-I-2
DCB_CONNECTOR_BNC = 0x3c, // BNC Connector [for SDI?]
/* LVDS / TMDS digital outputs */
DCB_CONNECTOR_LVDS = 0x40, // LVDS-SPWG-Attached [is this name correct?]
DCB_CONNECTOR_LVDS_SPWG = 0x41, // LVDS-OEM-Attached (non-removable)
DCB_CONNECTOR_LVDS_REM = 0x42, // LVDS-SPWG-Detached [following naming above]
DCB_CONNECTOR_LVDS_SPWG_REM = 0x43, // LVDS-OEM-Detached (removable)
DCB_CONNECTOR_TMDS = 0x45, // TMDS-OEM-Attached (non-removable)
/* DP digital outputs */
DCB_CONNECTOR_DP = 0x46, // DisplayPort External Connector
DCB_CONNECTOR_eDP = 0x47, // DisplayPort Internal Connector
DCB_CONNECTOR_mDP = 0x48, // DisplayPort (Mini) External Connector
/* Dock outputs (not used) */
DCB_CONNECTOR_DOCK_VGA_0 = 0x50, // VGA 15-pin if not docked
DCB_CONNECTOR_DOCK_VGA_1 = 0x51, // VGA 15-pin if docked
DCB_CONNECTOR_DOCK_DVI_I_0 = 0x52, // DVI-I if not docked
DCB_CONNECTOR_DOCK_DVI_I_1 = 0x53, // DVI-I if docked
DCB_CONNECTOR_DOCK_DVI_D_0 = 0x54, // DVI-D if not docked
DCB_CONNECTOR_DOCK_DVI_D_1 = 0x55, // DVI-D if docked
DCB_CONNECTOR_DOCK_DP_0 = 0x56, // DisplayPort if not docked
DCB_CONNECTOR_DOCK_DP_1 = 0x57, // DisplayPort if docked
DCB_CONNECTOR_DOCK_mDP_0 = 0x58, // DisplayPort (Mini) if not docked
DCB_CONNECTOR_DOCK_mDP_1 = 0x59, // DisplayPort (Mini) if docked
/* HDMI? digital outputs */
DCB_CONNECTOR_HDMI_0 = 0x60, // HDMI? See [1] in top-level enum comment above
DCB_CONNECTOR_HDMI_1 = 0x61, // HDMI-A connector
DCB_CONNECTOR_SPDIF = 0x62, // Audio S/PDIF connector
DCB_CONNECTOR_HDMI_C = 0x63, // HDMI-C (Mini) connector
/* Misc. digital outputs */
DCB_CONNECTOR_DMS59_DP0 = 0x64, // LFH-DP-1
DCB_CONNECTOR_DMS59_DP1 = 0x65, // LFH-DP-2
DCB_CONNECTOR_WFD = 0x70, // Virtual connector for Wifi Display (WFD)
DCB_CONNECTOR_USB_C = 0x71, // [DP over USB-C; not present in docs]
DCB_CONNECTOR_NONE = 0xff // Skip Entry
};
struct nvbios_connT {
};
u32 nvbios_connTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_connTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_connT *info);
struct nvbios_connE {
u8 type;
u8 location;
u8 hpd;
u8 dp;
u8 di;
u8 sr;
u8 lcdid;
};
u32 nvbios_connEe(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr);
u32 nvbios_connEp(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr,
struct nvbios_connE *info);
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_CSTEP_H__
#define __NVBIOS_CSTEP_H__
u32 nvbios_cstepTe(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
struct nvbios_cstepE {
u8 pstate;
u8 index;
};
u32 nvbios_cstepEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_cstepEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_cstepE *);
u32 nvbios_cstepEm(struct nvkm_bios *, u8 pstate, u8 *ver, u8 *hdr,
struct nvbios_cstepE *);
struct nvbios_cstepX {
u32 freq;
u8 unkn[2];
u8 voltage;
};
u32 nvbios_cstepXe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_cstepXp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_cstepX *);
#endif
@@ -0,0 +1,68 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_DCB_H__
#define __NVBIOS_DCB_H__
enum dcb_output_type {
DCB_OUTPUT_ANALOG = 0x0,
DCB_OUTPUT_TV = 0x1,
DCB_OUTPUT_TMDS = 0x2,
DCB_OUTPUT_LVDS = 0x3,
DCB_OUTPUT_DP = 0x6,
DCB_OUTPUT_WFD = 0x8,
DCB_OUTPUT_EOL = 0xe,
DCB_OUTPUT_UNUSED = 0xf,
DCB_OUTPUT_ANY = -1,
};
struct dcb_output {
int index; /* may not be raw dcb index if merging has happened */
u16 hasht;
u16 hashm;
enum dcb_output_type type;
uint8_t i2c_index;
uint8_t heads;
uint8_t connector;
uint8_t bus;
uint8_t location;
uint8_t or;
uint8_t link;
bool duallink_possible;
uint8_t extdev;
union {
struct sor_conf {
int link;
} sorconf;
struct {
int maxfreq;
} crtconf;
struct {
struct sor_conf sor;
bool use_straps_for_mode;
bool use_acpi_for_edid;
bool use_power_scripts;
} lvdsconf;
struct {
bool has_component_output;
} tvconf;
struct {
struct sor_conf sor;
int link_nr;
int link_bw;
} dpconf;
struct {
struct sor_conf sor;
int slave_addr;
} tmdsconf;
};
bool i2c_upper_default;
int id;
};
u16 dcb_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
u16 dcb_outp(struct nvkm_bios *, u8 idx, u8 *ver, u8 *len);
u16 dcb_outp_parse(struct nvkm_bios *, u8 idx, u8 *, u8 *,
struct dcb_output *);
u16 dcb_outp_match(struct nvkm_bios *, u16 type, u16 mask, u8 *, u8 *,
struct dcb_output *);
int dcb_outp_foreach(struct nvkm_bios *, void *data, int (*exec)
(struct nvkm_bios *, void *, int index, u16 entry));
#endif
@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_DISP_H__
#define __NVBIOS_DISP_H__
u16 nvbios_disp_table(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub);
struct nvbios_disp {
u16 data;
};
u16 nvbios_disp_entry(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub);
u16 nvbios_disp_parse(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub,
struct nvbios_disp *);
struct nvbios_outp {
u16 type;
u16 mask;
u16 script[3];
};
u16 nvbios_outp_entry(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 nvbios_outp_parse(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
struct nvbios_ocfg {
u8 proto;
u8 flags;
u16 clkcmp[2];
};
u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz);
#endif
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_DP_H__
#define __NVBIOS_DP_H__
u16
nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
struct nvbios_dpout {
u16 type;
u16 mask;
u8 flags;
u32 script[5];
u32 lnkcmp;
};
u16 nvbios_dpout_parse(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpout *);
u16 nvbios_dpout_match(struct nvkm_bios *, u16 type, u16 mask,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpout *);
struct nvbios_dpcfg {
u8 pc;
u8 dc;
u8 pe;
u8 tx_pu;
};
u16
nvbios_dpcfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
u16
nvbios_dpcfg_match(struct nvkm_bios *, u16 outp, u8 pc, u8 vs, u8 pe,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
#endif
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_EXTDEV_H__
#define __NVBIOS_EXTDEV_H__
enum nvbios_extdev_type {
NVBIOS_EXTDEV_LM89 = 0x02,
NVBIOS_EXTDEV_VT1103M = 0x40,
NVBIOS_EXTDEV_PX3540 = 0x41,
NVBIOS_EXTDEV_VT1105M = 0x42, /* or close enough... */
NVBIOS_EXTDEV_INA219 = 0x4c,
NVBIOS_EXTDEV_INA209 = 0x4d,
NVBIOS_EXTDEV_INA3221 = 0x4e,
NVBIOS_EXTDEV_ADT7473 = 0x70, /* can also be a LM64 */
NVBIOS_EXTDEV_HDCP_EEPROM = 0x90,
NVBIOS_EXTDEV_NONE = 0xff,
};
struct nvbios_extdev_func {
u8 type;
u8 addr;
u8 bus;
};
int
nvbios_extdev_parse(struct nvkm_bios *, int, struct nvbios_extdev_func *);
int
nvbios_extdev_find(struct nvkm_bios *, enum nvbios_extdev_type,
struct nvbios_extdev_func *);
bool nvbios_extdev_skip_probe(struct nvkm_bios *);
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_FAN_H__
#define __NVBIOS_FAN_H__
#include <subdev/bios/therm.h>
u32 nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan);
#endif
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_GPIO_H__
#define __NVBIOS_GPIO_H__
enum dcb_gpio_func_name {
DCB_GPIO_PANEL_POWER = 0x01,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_TVDAC0 = 0x0c,
DCB_GPIO_THERM_EXT_POWER_EVENT = 0x10,
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN_SENSE = 0x3d,
DCB_GPIO_POWER_ALERT = 0x4c,
DCB_GPIO_EXT_POWER_LOW = 0x79,
DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
DCB_GPIO_VID1 = 0x05,
DCB_GPIO_VID2 = 0x06,
DCB_GPIO_VID3 = 0x1a,
DCB_GPIO_VID4 = 0x73,
DCB_GPIO_VID5 = 0x74,
DCB_GPIO_VID6 = 0x75,
DCB_GPIO_VID7 = 0x76,
DCB_GPIO_VID_PWM = 0x81,
};
#define DCB_GPIO_LOG_DIR 0x02
#define DCB_GPIO_LOG_DIR_OUT 0x00
#define DCB_GPIO_LOG_DIR_IN 0x02
#define DCB_GPIO_LOG_VAL 0x01
#define DCB_GPIO_LOG_VAL_LO 0x00
#define DCB_GPIO_LOG_VAL_HI 0x01
struct dcb_gpio_func {
u8 func;
u8 line;
u8 log[2];
/* so far, "param" seems to only have an influence on PWM-related
* GPIOs such as FAN_CONTROL and PANEL_BACKLIGHT_LEVEL.
* if param equals 1, hardware PWM is available
* if param equals 0, the host should toggle the GPIO itself
*/
u8 param;
};
u16 dcb_gpio_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dcb_gpio_entry(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len);
u16 dcb_gpio_parse(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len,
struct dcb_gpio_func *);
u16 dcb_gpio_match(struct nvkm_bios *, int idx, u8 func, u8 line,
u8 *ver, u8 *len, struct dcb_gpio_func *);
#endif
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_I2C_H__
#define __NVBIOS_I2C_H__
enum dcb_i2c_type {
/* matches bios type field prior to ccb 4.1 */
DCB_I2C_NV04_BIT = 0x00,
DCB_I2C_NV4E_BIT = 0x04,
DCB_I2C_NVIO_BIT = 0x05,
DCB_I2C_NVIO_AUX = 0x06,
/* made up - mostly */
DCB_I2C_PMGR = 0x80,
DCB_I2C_UNUSED = 0xff
};
struct dcb_i2c_entry {
enum dcb_i2c_type type;
u8 drive;
u8 sense;
u8 share;
u8 auxch;
};
u16 dcb_i2c_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dcb_i2c_entry(struct nvkm_bios *, u8 index, u8 *ver, u8 *len);
int dcb_i2c_parse(struct nvkm_bios *, u8 index, struct dcb_i2c_entry *);
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_ICCSENSE_H__
#define __NVBIOS_ICCSENSE_H__
struct pwr_rail_resistor_t {
u8 mohm;
bool enabled;
};
struct pwr_rail_t {
u8 mode;
u8 extdev_id;
u8 resistor_count;
struct pwr_rail_resistor_t resistors[3];
u16 config;
};
struct nvbios_iccsense {
int nr_entry;
struct pwr_rail_t *rail;
};
int nvbios_iccsense_parse(struct nvkm_bios *, struct nvbios_iccsense *);
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_IMAGE_H__
#define __NVBIOS_IMAGE_H__
struct nvbios_image {
u32 base;
u32 size;
u8 type;
bool last;
};
bool nvbios_image(struct nvkm_bios *, int, struct nvbios_image *);
#endif
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_INIT_H__
#define __NVBIOS_INIT_H__
struct nvbios_init {
struct nvkm_subdev *subdev;
u32 offset;
struct dcb_output *outp;
int or;
int link;
int head;
/* internal state used during parsing */
u8 execute;
u32 nested;
u32 repeat;
u32 repend;
u32 ramcfg;
};
#define nvbios_init(s,o,ARGS...) ({ \
struct nvbios_init init = { \
.subdev = (s), \
.offset = (o), \
.or = -1, \
.link = 0, \
.head = -1, \
.execute = 1, \
}; \
ARGS \
nvbios_exec(&init); \
})
int nvbios_exec(struct nvbios_init *);
int nvbios_post(struct nvkm_subdev *, bool execute);
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_MXM_H__
#define __NVBIOS_MXM_H__
u16 mxm_table(struct nvkm_bios *, u8 *ver, u8 *hdr);
u8 mxm_sor_map(struct nvkm_bios *, u8 conn);
u8 mxm_ddc_map(struct nvkm_bios *, u8 port);
#endif
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_NPDE_H__
#define __NVBIOS_NPDE_H__
struct nvbios_npdeT {
u32 image_size;
bool last;
};
u32 nvbios_npdeTe(struct nvkm_bios *, u32);
u32 nvbios_npdeTp(struct nvkm_bios *, u32, struct nvbios_npdeT *);
#endif
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_PCIR_H__
#define __NVBIOS_PCIR_H__
struct nvbios_pcirT {
u16 vendor_id;
u16 device_id;
u8 class_code[3];
u32 image_size;
u16 image_rev;
u8 image_type;
bool last;
};
u32 nvbios_pcirTe(struct nvkm_bios *, u32, u8 *ver, u16 *hdr);
u32 nvbios_pcirTp(struct nvkm_bios *, u32, u8 *ver, u16 *hdr,
struct nvbios_pcirT *);
#endif
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_PERF_H__
#define __NVBIOS_PERF_H__
u32 nvbios_perf_table(struct nvkm_bios *, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
struct nvbios_perfE {
u8 pstate;
u8 fanspeed;
u8 voltage;
u32 core;
u32 shader;
u32 memory;
u32 vdec;
u32 disp;
u32 script;
u8 pcie_speed;
u8 pcie_width;
};
u32 nvbios_perf_entry(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_perfEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *);
struct nvbios_perfS {
union {
struct {
u32 freq;
} v40;
};
};
u32 nvbios_perfSe(struct nvkm_bios *, u32 data, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len);
u32 nvbios_perfSp(struct nvkm_bios *, u32 data, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len, struct nvbios_perfS *);
struct nvbios_perf_fan {
u32 pwm_divisor;
};
int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
#endif
@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_PLL_H__
#define __NVBIOS_PLL_H__
/*XXX: kill me */
struct nvkm_pll_vals {
union {
struct {
#ifdef __BIG_ENDIAN
uint8_t N1, M1, N2, M2;
#else
uint8_t M1, N1, M2, N2;
#endif
};
struct {
uint16_t NM1, NM2;
} __attribute__((packed));
};
int log2P;
int refclk;
};
/* these match types in pll limits table version 0x40,
* nvkm uses them on all chipsets internally where a
* specific pll needs to be referenced, but the exact
* register isn't known.
*/
enum nvbios_pll_type {
PLL_CORE = 0x01,
PLL_SHADER = 0x02,
PLL_UNK03 = 0x03,
PLL_MEMORY = 0x04,
PLL_VDEC = 0x05,
PLL_UNK40 = 0x40,
PLL_UNK41 = 0x41,
PLL_UNK42 = 0x42,
PLL_VPLL0 = 0x80,
PLL_VPLL1 = 0x81,
PLL_VPLL2 = 0x82,
PLL_VPLL3 = 0x83,
PLL_MAX = 0xff
};
struct nvbios_pll {
enum nvbios_pll_type type;
u32 reg;
u32 refclk;
u8 min_p;
u8 max_p;
u8 bias_p;
/*
* for most pre nv50 cards setting a log2P of 7 (the common max_log2p
* value) is no different to 6 (at least for vplls) so allowing the MNP
* calc to use 7 causes the generated clock to be out by a factor of 2.
* however, max_log2p cannot be fixed-up during parsing as the
* unmodified max_log2p value is still needed for setting mplls, hence
* an additional max_usable_log2p member
*/
u8 max_p_usable;
struct {
u32 min_freq;
u32 max_freq;
u32 min_inputfreq;
u32 max_inputfreq;
u8 min_m;
u8 max_m;
u8 min_n;
u8 max_n;
} vco1, vco2;
};
int nvbios_pll_parse(struct nvkm_bios *, u32 type, struct nvbios_pll *);
#endif
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_PMU_H__
#define __NVBIOS_PMU_H__
struct nvbios_pmuT {
};
u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
struct nvbios_pmuE {
u8 type;
u32 data;
};
u32 nvbios_pmuEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
u32 nvbios_pmuEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_pmuE *);
struct nvbios_pmuR {
u32 boot_addr_pmu;
u32 boot_addr;
u32 boot_size;
u32 code_addr_pmu;
u32 code_addr;
u32 code_size;
u32 init_addr_pmu;
u32 data_addr_pmu;
u32 data_addr;
u32 data_size;
u32 args_addr_pmu;
};
bool nvbios_pmuRm(struct nvkm_bios *, u8 type, struct nvbios_pmuR *);
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_POWER_BUDGET_H__
#define __NVBIOS_POWER_BUDGET_H__
#include <nvkm/subdev/bios.h>
struct nvbios_power_budget_entry {
u32 min_w;
u32 avg_w;
u32 max_w;
};
struct nvbios_power_budget {
u32 offset;
u8 ver;
u8 hlen;
u8 elen;
u8 ecount;
u8 cap_entry;
};
int nvbios_power_budget_header(struct nvkm_bios *,
struct nvbios_power_budget *);
int nvbios_power_budget_entry(struct nvkm_bios *, struct nvbios_power_budget *,
u8 idx, struct nvbios_power_budget_entry *);
#endif
@@ -0,0 +1,164 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_RAMCFG_H__
#define __NVBIOS_RAMCFG_H__
struct nvbios_ramcfg {
unsigned rammap_ver;
unsigned rammap_hdr;
unsigned rammap_min;
unsigned rammap_max;
union {
struct {
unsigned rammap_00_16_20:1;
unsigned rammap_00_16_40:1;
unsigned rammap_00_17_02:1;
};
struct {
unsigned rammap_10_04_02:1;
unsigned rammap_10_04_08:1;
};
struct {
unsigned rammap_11_08_01:1;
unsigned rammap_11_08_0c:2;
unsigned rammap_11_08_10:1;
unsigned rammap_11_09_01ff:9;
unsigned rammap_11_0a_03fe:9;
unsigned rammap_11_0a_0400:1;
unsigned rammap_11_0a_0800:1;
unsigned rammap_11_0b_01f0:5;
unsigned rammap_11_0b_0200:1;
unsigned rammap_11_0b_0400:1;
unsigned rammap_11_0b_0800:1;
unsigned rammap_11_0d:8;
unsigned rammap_11_0e:8;
unsigned rammap_11_0f:8;
unsigned rammap_11_11_0c:2;
};
};
unsigned ramcfg_ver;
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
union {
struct {
unsigned ramcfg_00_03_01:1;
unsigned ramcfg_00_03_02:1;
unsigned ramcfg_00_03_08:1;
unsigned ramcfg_00_03_10:1;
unsigned ramcfg_00_04_02:1;
unsigned ramcfg_00_04_04:1;
unsigned ramcfg_00_04_20:1;
unsigned ramcfg_00_05:8;
unsigned ramcfg_00_06:8;
unsigned ramcfg_00_07:8;
unsigned ramcfg_00_08:8;
unsigned ramcfg_00_09:8;
unsigned ramcfg_00_0a_0f:4;
unsigned ramcfg_00_0a_f0:4;
};
struct {
unsigned ramcfg_10_02_01:1;
unsigned ramcfg_10_02_02:1;
unsigned ramcfg_10_02_04:1;
unsigned ramcfg_10_02_08:1;
unsigned ramcfg_10_02_10:1;
unsigned ramcfg_10_02_20:1;
unsigned ramcfg_10_03_0f:4;
unsigned ramcfg_10_04_01:1;
unsigned ramcfg_10_05:8;
unsigned ramcfg_10_06:8;
unsigned ramcfg_10_07:8;
unsigned ramcfg_10_08:8;
unsigned ramcfg_10_09_0f:4;
unsigned ramcfg_10_09_f0:4;
};
struct {
unsigned ramcfg_11_01_01:1;
unsigned ramcfg_11_01_02:1;
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
unsigned ramcfg_11_02_04:1;
unsigned ramcfg_11_02_08:1;
unsigned ramcfg_11_02_10:1;
unsigned ramcfg_11_02_40:1;
unsigned ramcfg_11_02_80:1;
unsigned ramcfg_11_03_0f:4;
unsigned ramcfg_11_03_30:2;
unsigned ramcfg_11_03_c0:2;
unsigned ramcfg_11_03_f0:4;
unsigned ramcfg_11_04:8;
unsigned ramcfg_11_06:8;
unsigned ramcfg_11_07_02:1;
unsigned ramcfg_11_07_04:1;
unsigned ramcfg_11_07_08:1;
unsigned ramcfg_11_07_10:1;
unsigned ramcfg_11_07_40:1;
unsigned ramcfg_11_07_80:1;
unsigned ramcfg_11_08_01:1;
unsigned ramcfg_11_08_02:1;
unsigned ramcfg_11_08_04:1;
unsigned ramcfg_11_08_08:1;
unsigned ramcfg_11_08_10:1;
unsigned ramcfg_11_08_20:1;
unsigned ramcfg_11_09:8;
};
};
unsigned timing_ver;
unsigned timing_hdr;
unsigned timing[11];
union {
struct {
unsigned timing_10_WR:8;
unsigned timing_10_WTR:8;
unsigned timing_10_CL:8;
unsigned timing_10_RC:8;
/*empty: 4 */
unsigned timing_10_RFC:8; /* Byte 5 */
/*empty: 6 */
unsigned timing_10_RAS:8; /* Byte 7 */
/*empty: 8 */
unsigned timing_10_RP:8; /* Byte 9 */
unsigned timing_10_RCDRD:8;
unsigned timing_10_RCDWR:8;
unsigned timing_10_RRD:8;
unsigned timing_10_13:8;
unsigned timing_10_ODT:3;
/* empty: 15 */
unsigned timing_10_16:8;
/* empty: 17 */
unsigned timing_10_18:8;
unsigned timing_10_CWL:8;
unsigned timing_10_20:8;
unsigned timing_10_21:8;
/* empty: 22, 23 */
unsigned timing_10_24:8;
};
struct {
unsigned timing_20_2e_03:2;
unsigned timing_20_2e_30:2;
unsigned timing_20_2e_c0:2;
unsigned timing_20_2f_03:2;
unsigned timing_20_2c_003f:6;
unsigned timing_20_2c_1fc0:7;
unsigned timing_20_30_f8:5;
unsigned timing_20_30_07:3;
unsigned timing_20_31_0007:3;
unsigned timing_20_31_0078:4;
unsigned timing_20_31_0780:4;
unsigned timing_20_31_0800:1;
unsigned timing_20_31_7000:3;
unsigned timing_20_31_8000:1;
};
};
};
u8 nvbios_ramcfg_count(struct nvkm_bios *);
u8 nvbios_ramcfg_index(struct nvkm_subdev *);
#endif
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_RAMMAP_H__
#define __NVBIOS_RAMMAP_H__
#include <subdev/bios/ramcfg.h>
u32 nvbios_rammapTe(struct nvkm_bios *, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u32 nvbios_rammapEe(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
struct nvbios_ramcfg *p);
u32 nvbios_rammapEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr);
u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
struct nvbios_ramcfg *p);
u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
#endif
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_THERM_H__
#define __NVBIOS_THERM_H__
struct nvbios_therm_threshold {
u8 temp;
u8 hysteresis;
};
struct nvbios_therm_sensor {
/* diode */
s16 slope_mult;
s16 slope_div;
s16 offset_num;
s16 offset_den;
s8 offset_constant;
/* thresholds */
struct nvbios_therm_threshold thrs_fan_boost;
struct nvbios_therm_threshold thrs_down_clock;
struct nvbios_therm_threshold thrs_critical;
struct nvbios_therm_threshold thrs_shutdown;
};
enum nvbios_therm_fan_type {
NVBIOS_THERM_FAN_UNK = 0,
NVBIOS_THERM_FAN_TOGGLE = 1,
NVBIOS_THERM_FAN_PWM = 2,
};
/* no vbios have more than 6 */
#define NVKM_TEMP_FAN_TRIP_MAX 10
struct nvbios_therm_trip_point {
int fan_duty;
int temp;
int hysteresis;
};
enum nvbios_therm_fan_mode {
NVBIOS_THERM_FAN_TRIP = 0,
NVBIOS_THERM_FAN_LINEAR = 1,
NVBIOS_THERM_FAN_OTHER = 2,
};
struct nvbios_therm_fan {
enum nvbios_therm_fan_type type;
u32 pwm_freq;
u8 min_duty;
u8 max_duty;
u16 bump_period;
u16 slow_down_period;
enum nvbios_therm_fan_mode fan_mode;
struct nvbios_therm_trip_point trip[NVKM_TEMP_FAN_TRIP_MAX];
u8 nr_fan_trip;
u8 linear_min_temp;
u8 linear_max_temp;
};
enum nvbios_therm_domain {
NVBIOS_THERM_DOMAIN_CORE,
NVBIOS_THERM_DOMAIN_AMBIENT,
};
int
nvbios_therm_sensor_parse(struct nvkm_bios *, enum nvbios_therm_domain,
struct nvbios_therm_sensor *);
int
nvbios_therm_fan_parse(struct nvkm_bios *, struct nvbios_therm_fan *);
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_TIMING_H__
#define __NVBIOS_TIMING_H__
#include <subdev/bios/ramcfg.h>
u32 nvbios_timingTe(struct nvkm_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u32 nvbios_timingEe(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_timingEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
#endif
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_VMAP_H__
#define __NVBIOS_VMAP_H__
struct nvbios_vmap {
u8 max0;
u8 max1;
u8 max2;
};
u32 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_vmap_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_vmap *);
struct nvbios_vmap_entry {
u8 mode;
u8 link;
u32 min;
u32 max;
s32 arg[6];
};
u32 nvbios_vmap_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
u32 nvbios_vmap_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
struct nvbios_vmap_entry *);
#endif
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_VOLT_H__
#define __NVBIOS_VOLT_H__
enum nvbios_volt_type {
NVBIOS_VOLT_GPIO = 0,
NVBIOS_VOLT_PWM,
};
struct nvbios_volt {
enum nvbios_volt_type type;
u32 min;
u32 max;
u32 base;
/* GPIO mode */
bool ranged;
u8 vidmask;
s16 step;
/* PWM mode */
u32 pwm_freq;
u32 pwm_range;
};
u32 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_volt_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_volt *);
struct nvbios_volt_entry {
u32 voltage;
u8 vid;
};
u32 nvbios_volt_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
u32 nvbios_volt_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
struct nvbios_volt_entry *);
#endif
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_VPSTATE_H__
#define __NVBIOS_VPSTATE_H__
struct nvbios_vpstate_header {
u32 offset;
u8 version;
u8 hlen;
u8 ecount;
u8 elen;
u8 scount;
u8 slen;
u8 base_id;
u8 boost_id;
u8 tdp_id;
};
struct nvbios_vpstate_entry {
u8 pstate;
u16 clock_mhz;
};
int nvbios_vpstate_parse(struct nvkm_bios *, struct nvbios_vpstate_header *);
int nvbios_vpstate_entry(struct nvkm_bios *, struct nvbios_vpstate_header *,
u8 idx, struct nvbios_vpstate_entry *);
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVBIOS_XPIO_H__
#define __NVBIOS_XPIO_H__
#define NVBIOS_XPIO_FLAG_AUX 0x10
#define NVBIOS_XPIO_FLAG_AUX0 0x00
#define NVBIOS_XPIO_FLAG_AUX1 0x10
struct nvbios_xpio {
u8 type;
u8 addr;
u8 flags;
};
u16 dcb_xpio_table(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dcb_xpio_parse(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *);
#endif
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_BUS_H__
#define __NVKM_BUS_H__
#include <core/subdev.h>
struct nvkm_bus {
const struct nvkm_bus_func *func;
struct nvkm_subdev subdev;
};
/* interface to sequencer */
struct nvkm_hwsq;
int nvkm_hwsq_init(struct nvkm_subdev *, struct nvkm_hwsq **);
int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
void nvkm_hwsq_wait_vblank(struct nvkm_hwsq *);
void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
int nv04_bus_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bus **);
int nv31_bus_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bus **);
int nv50_bus_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bus **);
int g94_bus_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bus **);
int gf100_bus_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_bus **);
#endif
@@ -0,0 +1,138 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_CLK_H__
#define __NVKM_CLK_H__
#include <core/subdev.h>
#include <subdev/pci.h>
struct nvbios_pll;
struct nvkm_pll_vals;
#define NVKM_CLK_CSTATE_DEFAULT -1 /* POSTed default */
#define NVKM_CLK_CSTATE_BASE -2 /* pstate base */
#define NVKM_CLK_CSTATE_HIGHEST -3 /* highest possible */
enum nv_clk_src {
nv_clk_src_crystal,
nv_clk_src_href,
nv_clk_src_hclk,
nv_clk_src_hclkm3,
nv_clk_src_hclkm3d2,
nv_clk_src_hclkm2d3, /* NVAA */
nv_clk_src_hclkm4, /* NVAA */
nv_clk_src_cclk, /* NVAA */
nv_clk_src_host,
nv_clk_src_sppll0,
nv_clk_src_sppll1,
nv_clk_src_mpllsrcref,
nv_clk_src_mpllsrc,
nv_clk_src_mpll,
nv_clk_src_mdiv,
nv_clk_src_core,
nv_clk_src_core_intm,
nv_clk_src_shader,
nv_clk_src_mem,
nv_clk_src_gpc,
nv_clk_src_rop,
nv_clk_src_hubk01,
nv_clk_src_hubk06,
nv_clk_src_hubk07,
nv_clk_src_copy,
nv_clk_src_pmu,
nv_clk_src_disp,
nv_clk_src_vdec,
nv_clk_src_dom6,
nv_clk_src_max,
};
struct nvkm_cstate {
struct list_head head;
u8 voltage;
u32 domain[nv_clk_src_max];
u8 id;
};
struct nvkm_pstate {
struct list_head head;
struct list_head list; /* c-states */
struct nvkm_cstate base;
u8 pstate;
u8 fanspeed;
enum nvkm_pcie_speed pcie_speed;
u8 pcie_width;
};
struct nvkm_domain {
enum nv_clk_src name;
u8 bios; /* 0xff for none */
#define NVKM_CLK_DOM_FLAG_CORE 0x01
#define NVKM_CLK_DOM_FLAG_VPSTATE 0x02
u8 flags;
const char *mname;
int mdiv;
};
struct nvkm_clk {
const struct nvkm_clk_func *func;
struct nvkm_subdev subdev;
const struct nvkm_domain *domains;
struct nvkm_pstate bstate;
struct list_head states;
int state_nr;
struct work_struct work;
wait_queue_head_t wait;
atomic_t waiting;
int pwrsrc;
int pstate; /* current */
int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
int astate; /* perfmon adjustment (base) */
int dstate; /* display adjustment (min+) */
u8 temp;
bool allow_reclock;
#define NVKM_CLK_BOOST_NONE 0x0
#define NVKM_CLK_BOOST_BIOS 0x1
#define NVKM_CLK_BOOST_FULL 0x2
u8 boost_mode;
u32 base_khz;
u32 boost_khz;
/*XXX: die, these are here *only* to support the completely
* bat-shit insane what-was-nouveau_hw.c code
*/
int (*pll_calc)(struct nvkm_clk *, struct nvbios_pll *, int clk,
struct nvkm_pll_vals *pv);
int (*pll_prog)(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *pv);
};
int nvkm_clk_read(struct nvkm_clk *, enum nv_clk_src);
int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
int nvkm_clk_tstate(struct nvkm_clk *, u8 temperature);
int nvkm_clk_pwrsrc(struct nvkm_device *);
int nv04_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int nv40_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int nv50_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int g84_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int mcp77_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gt215_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gf100_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gk104_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gk20a_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gm20b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gp10b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
#endif
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_DEVINIT_H__
#define __NVKM_DEVINIT_H__
#include <core/subdev.h>
struct nvkm_devinit;
struct nvkm_devinit {
const struct nvkm_devinit_func *func;
struct nvkm_subdev subdev;
bool post;
bool force_post;
};
u32 nvkm_devinit_mmio(struct nvkm_devinit *, u32 addr);
int nvkm_devinit_pll_set(struct nvkm_devinit *, u32 type, u32 khz);
void nvkm_devinit_meminit(struct nvkm_devinit *);
int nvkm_devinit_post(struct nvkm_devinit *);
int nv04_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int nv05_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int nv10_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int nv1a_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int nv20_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int nv50_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int g84_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int g98_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int gt215_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int mcp89_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int gf100_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int gm107_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int gm200_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int gv100_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int tu102_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
int ga100_devinit_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_devinit **);
#endif
@@ -0,0 +1,41 @@
#ifndef __NVKM_FAULT_H__
#define __NVKM_FAULT_H__
#include <core/subdev.h>
#include <core/event.h>
struct nvkm_fault {
const struct nvkm_fault_func *func;
struct nvkm_subdev subdev;
struct nvkm_inth info_fault;
struct nvkm_fault_buffer *buffer[2];
int buffer_nr;
#define NVKM_FAULT_BUFFER_EVENT_PENDING BIT(0)
struct nvkm_event event;
struct nvkm_event_ntfy nrpfb;
struct work_struct nrpfb_work;
struct nvkm_device_oclass user;
};
struct nvkm_fault_data {
u64 addr;
u64 inst;
u64 time;
u8 engine;
u8 valid;
u8 gpc;
u8 hub;
u8 access;
u8 client;
u8 reason;
};
int gp100_fault_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fault **);
int gp10b_fault_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fault **);
int gv100_fault_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fault **);
int tu102_fault_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fault **);
#endif
@@ -0,0 +1,182 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FB_H__
#define __NVKM_FB_H__
#include <core/subdev.h>
#include <core/falcon.h>
#include <core/mm.h>
/* memory type/access flags, do not match hardware values */
#define NV_MEM_ACCESS_RO 1
#define NV_MEM_ACCESS_WO 2
#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
#define NV_MEM_ACCESS_SYS 4
#define NV_MEM_ACCESS_VM 8
#define NV_MEM_ACCESS_NOSNOOP 16
#define NV_MEM_TARGET_VRAM 0
#define NV_MEM_TARGET_PCI 1
#define NV_MEM_TARGET_PCI_NOSNOOP 2
#define NV_MEM_TARGET_VM 3
#define NV_MEM_TARGET_GART 4
#define NVKM_RAM_TYPE_VM 0x7f
#define NV_MEM_COMP_VM 0x03
struct nvkm_fb_tile {
struct nvkm_mm_node *tag;
u32 addr;
u32 limit;
u32 pitch;
u32 zcomp;
};
struct nvkm_fb {
const struct nvkm_fb_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon_fw vpr_scrubber;
struct {
struct page *flush_page;
dma_addr_t flush_page_addr;
} sysmem;
struct nvkm_ram *ram;
struct {
struct mutex mutex; /* protects mm and nvkm_memory::tags */
struct nvkm_mm mm;
} tags;
struct {
struct nvkm_fb_tile region[16];
int regions;
} tile;
u8 page;
struct nvkm_memory *mmu_rd;
struct nvkm_memory *mmu_wr;
};
u64 nvkm_fb_vidmem_size(struct nvkm_device *);
int nvkm_fb_mem_unlock(struct nvkm_fb *);
void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size,
u32 pitch, u32 flags, struct nvkm_fb_tile *);
void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *);
void nvkm_fb_tile_prog(struct nvkm_fb *, int region, struct nvkm_fb_tile *);
int nv04_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv10_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv1a_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv20_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv25_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv30_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv35_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv36_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv40_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv41_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv44_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv46_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv47_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv49_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv4e_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int nv50_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int g84_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gt215_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int mcp77_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int mcp89_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gf100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gf108_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gk104_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gk110_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gk20a_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gm107_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gm200_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gm20b_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gp100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gp102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gp10b_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gv100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gh100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gb100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
int gb202_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **);
#include <subdev/bios.h>
#include <subdev/bios/ramcfg.h>
struct nvkm_ram_data {
struct list_head head;
struct nvbios_ramcfg bios;
u32 freq;
};
enum nvkm_ram_type {
NVKM_RAM_TYPE_UNKNOWN = 0,
NVKM_RAM_TYPE_STOLEN,
NVKM_RAM_TYPE_SGRAM,
NVKM_RAM_TYPE_SDRAM,
NVKM_RAM_TYPE_DDR1,
NVKM_RAM_TYPE_DDR2,
NVKM_RAM_TYPE_DDR3,
NVKM_RAM_TYPE_GDDR2,
NVKM_RAM_TYPE_GDDR3,
NVKM_RAM_TYPE_GDDR4,
NVKM_RAM_TYPE_GDDR5,
NVKM_RAM_TYPE_GDDR5X,
NVKM_RAM_TYPE_GDDR6,
NVKM_RAM_TYPE_HBM2,
};
struct nvkm_ram {
const struct nvkm_ram_func *func;
struct nvkm_fb *fb;
enum nvkm_ram_type type;
u64 size;
#define NVKM_RAM_MM_SHIFT 12
#define NVKM_RAM_MM_ANY (NVKM_MM_HEAP_ANY + 0)
#define NVKM_RAM_MM_NORMAL (NVKM_MM_HEAP_ANY + 1)
#define NVKM_RAM_MM_NOMAP (NVKM_MM_HEAP_ANY + 2)
#define NVKM_RAM_MM_MIXED (NVKM_MM_HEAP_ANY + 3)
struct nvkm_mm vram;
u64 stolen;
struct mutex mutex;
int ranks;
int parts;
int part_mask;
u32 freq;
u32 mr[16];
u32 mr1_nuts;
struct nvkm_ram_data *next;
struct nvkm_ram_data former;
struct nvkm_ram_data xition;
struct nvkm_ram_data target;
};
int nvkm_ram_wrap(struct nvkm_device *, u64 addr, u64 size, struct nvkm_memory **);
int nvkm_ram_get(struct nvkm_device *, u8 heap, u8 type, u8 page, u64 size,
bool contig, bool back, struct nvkm_memory **);
struct nvkm_ram_func {
u64 upper;
u32 (*probe_fbp)(const struct nvkm_ram_func *, struct nvkm_device *,
int fbp, int *pltcs);
u32 (*probe_fbp_amount)(const struct nvkm_ram_func *, u32 fbpao,
struct nvkm_device *, int fbp, int *pltcs);
u32 (*probe_fbpa_amount)(struct nvkm_device *, int fbpa);
void *(*dtor)(struct nvkm_ram *);
int (*init)(struct nvkm_ram *);
int (*calc)(struct nvkm_ram *, u32 freq);
int (*prog)(struct nvkm_ram *);
void (*tidy)(struct nvkm_ram *);
};
#endif
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
*/
#ifndef __NVKM_FSP_H__
#define __NVKM_FSP_H__
#include <core/subdev.h>
#include <core/falcon.h>
struct nvkm_fsp {
const struct nvkm_fsp_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon falcon;
};
bool nvkm_fsp_verify_gsp_fmc(struct nvkm_fsp *, u32 hash_size, u32 pkey_size, u32 sig_size);
int nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume,
u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig);
int gh100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **);
int gb100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **);
int gb202_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **);
#endif
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FUSE_H__
#define __NVKM_FUSE_H__
#include <core/subdev.h>
struct nvkm_fuse {
const struct nvkm_fuse_func *func;
struct nvkm_subdev subdev;
spinlock_t lock;
};
u32 nvkm_fuse_read(struct nvkm_fuse *, u32 addr);
int nv50_fuse_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fuse **);
int gf100_fuse_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fuse **);
int gm107_fuse_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fuse **);
#endif
@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_GPIO_H__
#define __NVKM_GPIO_H__
#include <core/subdev.h>
#include <core/event.h>
#include <subdev/bios.h>
#include <subdev/bios/gpio.h>
struct nvkm_gpio_ntfy_req {
u8 mask;
u8 line;
};
struct nvkm_gpio_ntfy_rep {
u8 mask;
};
struct nvkm_gpio {
const struct nvkm_gpio_func *func;
struct nvkm_subdev subdev;
#define NVKM_GPIO_HI BIT(0)
#define NVKM_GPIO_LO BIT(1)
#define NVKM_GPIO_TOGGLED (NVKM_GPIO_HI | NVKM_GPIO_LO)
struct nvkm_event event;
};
void nvkm_gpio_reset(struct nvkm_gpio *, u8 func);
int nvkm_gpio_find(struct nvkm_gpio *, int idx, u8 tag, u8 line,
struct dcb_gpio_func *);
int nvkm_gpio_set(struct nvkm_gpio *, int idx, u8 tag, u8 line, int state);
int nvkm_gpio_get(struct nvkm_gpio *, int idx, u8 tag, u8 line);
int nv10_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
int nv50_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
int g94_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
int gf119_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
int gk104_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
int ga102_gpio_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gpio **);
#endif
@@ -0,0 +1,507 @@
#ifndef __NVKM_GSP_H__
#define __NVKM_GSP_H__
#define nvkm_gsp(p) container_of((p), struct nvkm_gsp, subdev)
#include <core/subdev.h>
#include <core/falcon.h>
#include <core/firmware.h>
#include <linux/debugfs.h>
#define GSP_PAGE_SHIFT 12
#define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT)
struct nvkm_gsp_mem {
struct device *dev;
size_t size;
void *data;
dma_addr_t addr;
};
int nvkm_gsp_mem_ctor(struct nvkm_gsp *, size_t size, struct nvkm_gsp_mem *);
void nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *);
struct nvkm_gsp_radix3 {
struct nvkm_gsp_mem lvl0;
struct nvkm_gsp_mem lvl1;
struct sg_table lvl2;
};
int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *);
void nvkm_gsp_sg_free(struct nvkm_device *, struct sg_table *);
typedef int (*nvkm_gsp_msg_ntfy_func)(void *priv, u32 fn, void *repv, u32 repc);
struct nvkm_gsp_event;
typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc);
/**
* DOC: GSP message handling policy
*
* When sending a GSP RPC command, there can be multiple cases of handling
* the GSP RPC messages, which are the reply of GSP RPC commands, according
* to the requirement of the callers and the nature of the GSP RPC commands.
*
* NVKM_GSP_RPC_REPLY_NOWAIT - If specified, immediately return to the
* caller after the GSP RPC command is issued.
*
* NVKM_GSP_RPC_REPLY_NOSEQ - If specified, exactly like NOWAIT
* but don't emit RPC sequence number.
*
* NVKM_GSP_RPC_REPLY_RECV - If specified, wait and receive the entire GSP
* RPC message after the GSP RPC command is issued.
*
* NVKM_GSP_RPC_REPLY_POLL - If specified, wait for the specific reply and
* discard the reply before returning to the caller.
*
*/
enum nvkm_gsp_rpc_reply_policy {
NVKM_GSP_RPC_REPLY_NOWAIT = 0,
NVKM_GSP_RPC_REPLY_NOSEQ,
NVKM_GSP_RPC_REPLY_RECV,
NVKM_GSP_RPC_REPLY_POLL,
};
struct nvkm_gsp {
const struct nvkm_gsp_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon falcon;
struct {
struct {
const struct firmware *load;
const struct firmware *unload;
} booter;
const struct firmware *fmc;
const struct firmware *bl;
const struct firmware *rm;
struct {
struct nvkm_falcon_fw sb;
} falcon;
} fws;
struct nvkm_firmware fw;
struct nvkm_gsp_mem sig;
struct nvkm_gsp_radix3 radix3;
struct {
struct {
struct {
u64 addr;
u64 size;
} vga_workspace;
u64 addr;
u64 size;
} bios;
struct {
struct {
u64 addr;
u64 size;
} frts, boot, elf, heap;
u64 addr;
u64 size;
} wpr2;
struct {
u64 addr;
u64 size;
} heap;
u64 addr;
u64 size;
struct {
u64 addr;
u64 size;
} region[16];
int region_nr;
u32 rsvd_size;
} fb;
struct {
struct nvkm_falcon_fw load;
struct nvkm_falcon_fw unload;
} booter;
struct {
struct nvkm_gsp_mem fw;
u8 *hash;
u8 *pkey;
u8 *sig;
struct nvkm_gsp_mem args;
} fmc;
struct {
struct nvkm_gsp_mem fw;
u32 code_offset;
u32 data_offset;
u32 manifest_offset;
u32 app_version;
} boot;
struct nvkm_gsp_mem libos;
struct nvkm_gsp_mem loginit;
struct nvkm_gsp_mem logintr;
struct nvkm_gsp_mem logrm;
struct nvkm_gsp_mem rmargs;
struct nvkm_gsp_mem wpr_meta;
struct {
struct sg_table sgt;
struct nvkm_gsp_radix3 radix3;
struct nvkm_gsp_mem meta;
struct sg_table fbsr;
} sr;
struct {
struct nvkm_gsp_mem mem;
struct {
int nr;
u32 size;
u64 *ptr;
} ptes;
struct {
u32 size;
void *ptr;
} cmdq, msgq;
} shm;
struct nvkm_gsp_cmdq {
struct mutex mutex;
u32 cnt;
u32 seq;
u32 *wptr;
u32 *rptr;
} cmdq;
struct nvkm_gsp_msgq {
struct mutex mutex;
u32 cnt;
u32 *wptr;
u32 *rptr;
struct nvkm_gsp_msgq_ntfy {
u32 fn;
nvkm_gsp_msg_ntfy_func func;
void *priv;
} ntfy[16];
int ntfy_nr;
struct work_struct work;
} msgq;
bool running;
/* Internal GSP-RM control handles. */
struct {
struct nvkm_gsp_client {
struct nvkm_gsp_object {
struct nvkm_gsp_client *client;
struct nvkm_gsp_object *parent;
u32 handle;
} object;
struct nvkm_gsp *gsp;
struct list_head events;
} client;
struct nvkm_gsp_device {
struct nvkm_gsp_object object;
struct nvkm_gsp_object subdevice;
} device;
} internal;
struct {
enum nvkm_subdev_type type;
int inst;
u32 stall;
u32 nonstall;
} intr[32];
int intr_nr;
struct {
u64 rm_bar1_pdb;
u64 rm_bar2_pdb;
} bar;
struct {
u8 gpcs;
u8 tpcs;
} gr;
struct nvkm_rm *rm;
struct {
struct mutex mutex;
struct idr idr;
} client_id;
/* A linked list of registry items. The registry RPC will be built from it. */
struct list_head registry_list;
/* The size of the registry RPC */
size_t registry_rpc_size;
u32 rpc_seq;
#ifdef CONFIG_DEBUG_FS
/*
* Logging buffers in debugfs. The wrapper objects need to remain
* in memory until the dentry is deleted.
*/
struct {
struct dentry *parent;
struct dentry *init;
struct dentry *rm;
struct dentry *intr;
struct dentry *pmu;
} debugfs;
struct debugfs_blob_wrapper blob_init;
struct debugfs_blob_wrapper blob_intr;
struct debugfs_blob_wrapper blob_rm;
struct debugfs_blob_wrapper blob_pmu;
#endif
};
static inline bool
nvkm_gsp_rm(struct nvkm_gsp *gsp)
{
return gsp && (gsp->fws.rm || gsp->fw.img);
}
#include <rm/rm.h>
static inline void *
nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc)
{
return gsp->rm->api->rpc->get(gsp, fn, argc);
}
static inline void *
nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv,
enum nvkm_gsp_rpc_reply_policy policy, u32 repc)
{
return gsp->rm->api->rpc->push(gsp, argv, policy, repc);
}
static inline void *
nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
{
void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
if (IS_ERR_OR_NULL(argv))
return argv;
return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
}
static inline int
nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv,
enum nvkm_gsp_rpc_reply_policy policy)
{
void *repv = nvkm_gsp_rpc_push(gsp, argv, policy, 0);
if (IS_ERR(repv))
return PTR_ERR(repv);
return 0;
}
static inline void
nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
{
gsp->rm->api->rpc->done(gsp, repv);
}
static inline void *
nvkm_gsp_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 argc)
{
return object->client->gsp->rm->api->ctrl->get(object, cmd, argc);
}
static inline int
nvkm_gsp_rm_ctrl_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
{
return object->client->gsp->rm->api->ctrl->push(object, argv, repc);
}
static inline void *
nvkm_gsp_rm_ctrl_rd(struct nvkm_gsp_object *object, u32 cmd, u32 repc)
{
void *argv = nvkm_gsp_rm_ctrl_get(object, cmd, repc);
int ret;
if (IS_ERR(argv))
return argv;
ret = nvkm_gsp_rm_ctrl_push(object, &argv, repc);
if (ret)
return ERR_PTR(ret);
return argv;
}
static inline int
nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv)
{
int ret = nvkm_gsp_rm_ctrl_push(object, &argv, 0);
if (ret)
return ret;
return 0;
}
static inline void
nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)
{
object->client->gsp->rm->api->ctrl->done(object, repv);
}
static inline void *
nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
struct nvkm_gsp_object *object)
{
struct nvkm_gsp_client *client = parent->client;
struct nvkm_gsp *gsp = client->gsp;
void *argv;
object->client = parent->client;
object->parent = parent;
object->handle = handle;
argv = gsp->rm->api->alloc->get(object, oclass, argc);
if (IS_ERR_OR_NULL(argv)) {
object->client = NULL;
return argv;
}
return argv;
}
static inline void *
nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv)
{
void *repv = object->client->gsp->rm->api->alloc->push(object, argv);
if (IS_ERR(repv))
object->client = NULL;
return repv;
}
static inline int
nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv)
{
void *repv = nvkm_gsp_rm_alloc_push(object, argv);
if (IS_ERR(repv))
return PTR_ERR(repv);
return 0;
}
static inline void
nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)
{
object->client->gsp->rm->api->alloc->done(object, repv);
}
static inline int
nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
struct nvkm_gsp_object *object)
{
void *argv = nvkm_gsp_rm_alloc_get(parent, handle, oclass, argc, object);
if (IS_ERR_OR_NULL(argv))
return argv ? PTR_ERR(argv) : -EIO;
return nvkm_gsp_rm_alloc_wr(object, argv);
}
static inline int
nvkm_gsp_rm_free(struct nvkm_gsp_object *object)
{
if (object->client) {
int ret = object->client->gsp->rm->api->alloc->free(object);
object->client = NULL;
return ret;
}
return 0;
}
int nvkm_gsp_client_ctor(struct nvkm_gsp *, struct nvkm_gsp_client *);
void nvkm_gsp_client_dtor(struct nvkm_gsp_client *);
static inline int
nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
{
return client->gsp->rm->api->device->ctor(client, device);
}
static inline void
nvkm_gsp_device_dtor(struct nvkm_gsp_device *device)
{
if (device->object.client)
device->object.client->gsp->rm->api->device->dtor(device);
}
static inline int
nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp,
struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
{
int ret = nvkm_gsp_client_ctor(gsp, client);
if (ret == 0) {
ret = nvkm_gsp_device_ctor(client, device);
if (ret)
nvkm_gsp_client_dtor(client);
}
return ret;
}
struct nvkm_gsp_event {
struct nvkm_gsp_device *device;
u32 id;
nvkm_gsp_event_func func;
struct nvkm_gsp_object object;
struct list_head head;
};
static inline int
nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id,
nvkm_gsp_event_func func, struct nvkm_gsp_event *event)
{
struct nvkm_rm *rm = device->object.client->gsp->rm;
return rm->api->device->event.ctor(device, handle, id, func, event);
}
static inline void
nvkm_gsp_event_dtor(struct nvkm_gsp_event *event)
{
struct nvkm_gsp_device *device = event->device;
if (device)
device->object.client->gsp->rm->api->device->event.dtor(event);
}
int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int gh100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int gb100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int gb202_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
#endif
@@ -0,0 +1,180 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_I2C_H__
#define __NVKM_I2C_H__
#include <core/subdev.h>
#include <core/event.h>
#include <subdev/bios.h>
#include <subdev/bios/i2c.h>
struct nvkm_i2c_bus_probe {
struct i2c_board_info dev;
u8 udelay; /* set to 0 to use the standard delay */
};
struct nvkm_i2c_bus {
const struct nvkm_i2c_bus_func *func;
struct nvkm_i2c_pad *pad;
#define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */ (n)
#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10)
#define NVKM_I2C_BUS_PRI /* ccb primary comm. port */ -1
#define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */ -2
int id;
struct mutex mutex;
struct list_head head;
struct i2c_adapter i2c;
u8 enabled;
};
int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *);
void nvkm_i2c_bus_release(struct nvkm_i2c_bus *);
int nvkm_i2c_bus_probe(struct nvkm_i2c_bus *, const char *,
struct nvkm_i2c_bus_probe *,
bool (*)(struct nvkm_i2c_bus *,
struct i2c_board_info *, void *), void *);
struct nvkm_i2c_aux {
const struct nvkm_i2c_aux_func *func;
struct nvkm_i2c_pad *pad;
#define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */ (n)
#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10)
int id;
struct mutex mutex;
struct list_head head;
struct i2c_adapter i2c;
u8 enabled;
u32 intr;
};
void nvkm_i2c_aux_monitor(struct nvkm_i2c_aux *, bool monitor);
int nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *);
void nvkm_i2c_aux_release(struct nvkm_i2c_aux *);
int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
u32 addr, u8 *data, u8 *size);
int nvkm_i2c_aux_lnk_ctl(struct nvkm_i2c_aux *, int link_nr, int link_bw,
bool enhanced_framing);
struct nvkm_i2c {
const struct nvkm_i2c_func *func;
struct nvkm_subdev subdev;
struct list_head pad;
struct list_head bus;
struct list_head aux;
#define NVKM_I2C_PLUG BIT(0)
#define NVKM_I2C_UNPLUG BIT(1)
#define NVKM_I2C_IRQ BIT(2)
#define NVKM_I2C_DONE BIT(3)
#define NVKM_I2C_ANY (NVKM_I2C_PLUG | NVKM_I2C_UNPLUG | NVKM_I2C_IRQ | NVKM_I2C_DONE)
struct nvkm_event event;
};
struct nvkm_i2c_bus *nvkm_i2c_bus_find(struct nvkm_i2c *, int);
struct nvkm_i2c_aux *nvkm_i2c_aux_find(struct nvkm_i2c *, int);
int nv04_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int nv4e_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int nv50_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int g94_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int gf117_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int gf119_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int gk104_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int gk110_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
int gm200_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
static inline int
nvkm_rdi2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
{
u8 val;
struct i2c_msg msgs[] = {
{ .addr = addr, .flags = 0, .len = 1, .buf = &reg },
{ .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
};
int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
if (ret != 2)
return -EIO;
return val;
}
static inline int
nv_rd16i2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
{
u8 val[2];
struct i2c_msg msgs[] = {
{ .addr = addr, .flags = 0, .len = 1, .buf = &reg },
{ .addr = addr, .flags = I2C_M_RD, .len = 2, .buf = val },
};
int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
if (ret != 2)
return -EIO;
return val[0] << 8 | val[1];
}
static inline int
nvkm_wri2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u8 val)
{
u8 buf[2] = { reg, val };
struct i2c_msg msgs[] = {
{ .addr = addr, .flags = 0, .len = 2, .buf = buf },
};
int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
return -EIO;
return 0;
}
static inline int
nv_wr16i2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u16 val)
{
u8 buf[3] = { reg, val >> 8, val & 0xff};
struct i2c_msg msgs[] = {
{ .addr = addr, .flags = 0, .len = 3, .buf = buf },
};
int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
return -EIO;
return 0;
}
static inline bool
nvkm_probe_i2c(struct i2c_adapter *adap, u8 addr)
{
return nvkm_rdi2cr(adap, addr, 0) >= 0;
}
static inline int
nvkm_rdaux(struct nvkm_i2c_aux *aux, u32 addr, u8 *data, u8 size)
{
const u8 xfer = size;
int ret = nvkm_i2c_aux_acquire(aux);
if (ret == 0) {
ret = nvkm_i2c_aux_xfer(aux, true, 9, addr, data, &size);
WARN_ON(!ret && size != xfer);
nvkm_i2c_aux_release(aux);
}
return ret;
}
static inline int
nvkm_wraux(struct nvkm_i2c_aux *aux, u32 addr, u8 *data, u8 size)
{
int ret = nvkm_i2c_aux_acquire(aux);
if (ret == 0) {
ret = nvkm_i2c_aux_xfer(aux, true, 8, addr, data, &size);
nvkm_i2c_aux_release(aux);
}
return ret;
}
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_ICCSENSE_H__
#define __NVKM_ICCSENSE_H__
#include <core/subdev.h>
struct nvkm_iccsense {
struct nvkm_subdev subdev;
bool data_valid;
struct list_head sensors;
struct list_head rails;
u32 power_w_max;
u32 power_w_crit;
};
int gf100_iccsense_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_iccsense **);
int nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense);
#endif
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_INSTMEM_H__
#define __NVKM_INSTMEM_H__
#include <core/subdev.h>
struct nvkm_memory;
struct nvkm_instmem {
const struct nvkm_instmem_func *func;
struct nvkm_subdev subdev;
bool suspend;
spinlock_t lock;
struct list_head list;
struct list_head boot;
u32 reserved;
/* <=nv4x: protects NV_PRAMIN/BAR2 MM
* >=nv50: protects BAR2 MM & LRU
*/
struct mutex mutex;
struct nvkm_memory *vbios;
struct nvkm_ramht *ramht;
struct nvkm_memory *ramro;
struct nvkm_memory *ramfc;
};
u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, bool preserve,
struct nvkm_memory **);
int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct nvkm_memory **);
int nv04_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int nv50_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int gk20a_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int gh100_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
#endif
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_LTC_H__
#define __NVKM_LTC_H__
#include <core/subdev.h>
#include <core/mm.h>
#define NVKM_LTC_MAX_ZBC_COLOR_CNT 32
#define NVKM_LTC_MAX_ZBC_DEPTH_CNT 16
struct nvkm_ltc {
const struct nvkm_ltc_func *func;
struct nvkm_subdev subdev;
u32 ltc_nr;
u32 lts_nr;
struct mutex mutex; /* serialises CBC operations */
u32 num_tags;
u32 tag_base;
struct nvkm_memory *tag_ram;
int zbc_color_min;
int zbc_color_max;
u32 zbc_color[NVKM_LTC_MAX_ZBC_COLOR_CNT][4];
int zbc_depth_min;
int zbc_depth_max;
u32 zbc_depth[NVKM_LTC_MAX_ZBC_DEPTH_CNT];
u32 zbc_stencil[NVKM_LTC_MAX_ZBC_DEPTH_CNT];
};
void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count);
int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32);
int nvkm_ltc_zbc_stencil_get(struct nvkm_ltc *, int index, const u32);
void nvkm_ltc_invalidate(struct nvkm_ltc *);
void nvkm_ltc_flush(struct nvkm_ltc *);
int gf100_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gk104_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gm107_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gm200_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gp100_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gp102_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gp10b_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int ga102_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
#endif
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MC_H__
#define __NVKM_MC_H__
#include <core/subdev.h>
struct nvkm_mc {
const struct nvkm_mc_func *func;
struct nvkm_subdev subdev;
struct nvkm_intr intr;
};
void nvkm_mc_enable(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_disable(struct nvkm_device *, enum nvkm_subdev_type, int);
bool nvkm_mc_enabled(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_reset(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_intr_mask(struct nvkm_device *, enum nvkm_subdev_type, int, bool enable);
void nvkm_mc_unk260(struct nvkm_device *, u32 data);
int nv04_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int nv11_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int nv17_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int nv44_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int nv50_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int g84_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int g98_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gt215_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gf100_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gk104_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gk20a_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gp100_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gp10b_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int ga100_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
#endif
@@ -0,0 +1,170 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MMU_H__
#define __NVKM_MMU_H__
#include <core/subdev.h>
#include <subdev/gsp.h>
struct nvkm_vma {
struct list_head head;
struct rb_node tree;
u64 addr;
u64 size;
bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */
bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */
#define NVKM_VMA_PAGE_NONE 7
u8 page:3; /* Requested page type (index, or NONE for automatic). */
u8 refd:3; /* Current page type (index, or NONE for unreferenced). */
bool used:1; /* Region allocated. */
bool part:1; /* Region was split from an allocated region by map(). */
bool busy:1; /* Region busy (for temporarily preventing user access). */
bool mapped:1; /* Region contains valid pages. */
bool no_comp:1; /* Force no memory compression. */
struct nvkm_memory *memory; /* Memory currently mapped into VMA. */
struct nvkm_tags *tags; /* Compression tag reference. */
};
struct nvkm_vmm {
const struct nvkm_vmm_func *func;
struct nvkm_mmu *mmu;
const char *name;
u32 debug;
struct kref kref;
struct {
struct mutex vmm;
struct mutex ref;
struct mutex map;
} mutex;
u64 start;
u64 limit;
struct {
struct {
u64 addr;
u64 size;
} p;
struct {
u64 addr;
u64 size;
} n;
bool raw;
} managed;
struct nvkm_vmm_pt *pd;
struct list_head join;
struct list_head list;
struct rb_root free;
struct rb_root root;
bool bootstrapped;
atomic_t engref[NVKM_SUBDEV_NR];
dma_addr_t null;
void *nullp;
bool replay;
struct {
u64 bar2_pdb;
struct nvkm_gsp_client client;
struct nvkm_gsp_device device;
struct nvkm_gsp_object object;
struct nvkm_vma *rsvd;
bool external;
} rm;
};
int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc,
struct lock_class_key *, const char *name, struct nvkm_vmm **);
struct nvkm_vmm *nvkm_vmm_ref(struct nvkm_vmm *);
void nvkm_vmm_unref(struct nvkm_vmm **);
int nvkm_vmm_boot(struct nvkm_vmm *);
int nvkm_vmm_join(struct nvkm_vmm *, struct nvkm_memory *inst);
void nvkm_vmm_part(struct nvkm_vmm *, struct nvkm_memory *inst);
int nvkm_vmm_get(struct nvkm_vmm *, u8 page, u64 size, struct nvkm_vma **);
void nvkm_vmm_put(struct nvkm_vmm *, struct nvkm_vma **);
struct nvkm_vmm_map {
struct nvkm_memory *memory;
u64 offset;
struct nvkm_mm_node *mem;
struct scatterlist *sgl;
dma_addr_t *dma;
u64 *pfn;
u64 off;
const struct nvkm_vmm_page *page;
bool no_comp;
struct nvkm_tags *tags;
u64 next;
u64 type;
u64 ctag;
};
int nvkm_vmm_map(struct nvkm_vmm *, struct nvkm_vma *, void *argv, u32 argc,
struct nvkm_vmm_map *);
void nvkm_vmm_unmap(struct nvkm_vmm *, struct nvkm_vma *);
struct nvkm_memory *nvkm_umem_search(struct nvkm_client *, u64);
struct nvkm_vmm *nvkm_uvmm_search(struct nvkm_client *, u64 handle);
struct nvkm_mmu {
const struct nvkm_mmu_func *func;
struct nvkm_subdev subdev;
u8 dma_bits;
int heap_nr;
struct {
#define NVKM_MEM_VRAM 0x01
#define NVKM_MEM_HOST 0x02
#define NVKM_MEM_COMP 0x04
#define NVKM_MEM_DISP 0x08
u8 type;
u64 size;
} heap[4];
int type_nr;
struct {
#define NVKM_MEM_KIND 0x10
#define NVKM_MEM_MAPPABLE 0x20
#define NVKM_MEM_COHERENT 0x40
#define NVKM_MEM_UNCACHED 0x80
u8 type;
u8 heap;
} type[16];
struct nvkm_vmm *vmm;
struct {
struct mutex mutex;
struct list_head list;
} ptc, ptp;
struct mutex mutex; /* serialises mmu invalidations */
struct nvkm_device_oclass user;
};
int nv04_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int nv41_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int nv44_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int nv50_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int g84_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int mcp77_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gf100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gk104_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gk20a_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gm200_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gm20b_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gp100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gp10b_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gv100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int tu102_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
int gh100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_MXM_H__
#define __NVKM_MXM_H__
#include <core/subdev.h>
int nv50_mxm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
#endif
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_PCI_H__
#define __NVKM_PCI_H__
#include <core/subdev.h>
enum nvkm_pcie_speed {
NVKM_PCIE_SPEED_2_5,
NVKM_PCIE_SPEED_5_0,
NVKM_PCIE_SPEED_8_0,
};
struct nvkm_pci {
const struct nvkm_pci_func *func;
struct nvkm_subdev subdev;
struct pci_dev *pdev;
struct {
struct agp_bridge_data *bridge;
u32 mode;
u64 base;
u64 size;
int mtrr;
bool cma;
bool acquired;
} agp;
struct {
enum nvkm_pcie_speed speed;
u8 width;
} pcie;
bool msi;
};
u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
void nvkm_pci_msi_rearm(struct nvkm_device *);
int nv04_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int nv40_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int nv46_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int nv4c_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int g84_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int g92_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int g94_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int gf106_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int gk104_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int gp100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int gh100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
/* pcie functions */
int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width);
#endif
@@ -0,0 +1,68 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_PMU_H__
#define __NVKM_PMU_H__
#include <core/subdev.h>
#include <core/falcon.h>
struct nvkm_pmu {
const struct nvkm_pmu_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon falcon;
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *hpq;
struct nvkm_falcon_cmdq *lpq;
struct nvkm_falcon_msgq *msgq;
bool initmsg_received;
struct completion wpr_ready;
struct {
struct mutex mutex;
u32 base;
u32 size;
} send;
struct {
u32 base;
u32 size;
struct work_struct work;
wait_queue_head_t wait;
u32 process;
u32 message;
u32 data[2];
} recv;
};
int nvkm_pmu_send(struct nvkm_pmu *, u32 reply[2], u32 process,
u32 message, u32 data0, u32 data1);
void nvkm_pmu_pgob(struct nvkm_pmu *, bool enable);
bool nvkm_pmu_fan_controlled(struct nvkm_device *);
int gt215_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gf100_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gf119_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gk104_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gk110_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gk208_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gk20a_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gm107_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gm200_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gm20b_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gp102_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
int gp10b_pmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pmu **);
/* interface to MEMX process running on PMU */
struct nvkm_memx;
int nvkm_memx_init(struct nvkm_pmu *, struct nvkm_memx **);
int nvkm_memx_fini(struct nvkm_memx **, bool exec);
void nvkm_memx_wr32(struct nvkm_memx *, u32 addr, u32 data);
void nvkm_memx_wait(struct nvkm_memx *, u32 addr, u32 mask, u32 data, u32 nsec);
void nvkm_memx_nsec(struct nvkm_memx *, u32 nsec);
void nvkm_memx_wait_vblank(struct nvkm_memx *);
void nvkm_memx_train(struct nvkm_memx *);
int nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
void nvkm_memx_block(struct nvkm_memx *);
void nvkm_memx_unblock(struct nvkm_memx *);
#endif

Some files were not shown because too many files have changed in this diff Show More