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,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
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_PRIVRING_H__
#define __NVKM_PRIVRING_H__
#include <core/subdev.h>
int gf100_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
int gf117_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
int gk104_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
int gk20a_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
int gm200_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
int gp10b_privring_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_subdev **);
#endif
@@ -0,0 +1,119 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_THERM_H__
#define __NVKM_THERM_H__
#include <core/subdev.h>
#include <subdev/bios.h>
#include <subdev/bios/therm.h>
#include <subdev/timer.h>
enum nvkm_therm_thrs_direction {
NVKM_THERM_THRS_FALLING = 0,
NVKM_THERM_THRS_RISING = 1
};
enum nvkm_therm_thrs_state {
NVKM_THERM_THRS_LOWER = 0,
NVKM_THERM_THRS_HIGHER = 1
};
enum nvkm_therm_thrs {
NVKM_THERM_THRS_FANBOOST = 0,
NVKM_THERM_THRS_DOWNCLOCK = 1,
NVKM_THERM_THRS_CRITICAL = 2,
NVKM_THERM_THRS_SHUTDOWN = 3,
NVKM_THERM_THRS_NR
};
enum nvkm_therm_fan_mode {
NVKM_THERM_CTRL_NONE = 0,
NVKM_THERM_CTRL_MANUAL = 1,
NVKM_THERM_CTRL_AUTO = 2,
};
enum nvkm_therm_attr_type {
NVKM_THERM_ATTR_FAN_MIN_DUTY = 0,
NVKM_THERM_ATTR_FAN_MAX_DUTY = 1,
NVKM_THERM_ATTR_FAN_MODE = 2,
NVKM_THERM_ATTR_THRS_FAN_BOOST = 10,
NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
NVKM_THERM_ATTR_THRS_DOWN_CLK = 12,
NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
NVKM_THERM_ATTR_THRS_CRITICAL = 14,
NVKM_THERM_ATTR_THRS_CRITICAL_HYST = 15,
NVKM_THERM_ATTR_THRS_SHUTDOWN = 16,
NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
};
struct nvkm_therm_clkgate_init {
u32 addr;
u8 count;
u32 data;
};
struct nvkm_therm_clkgate_pack {
const struct nvkm_therm_clkgate_init *init;
};
struct nvkm_therm {
const struct nvkm_therm_func *func;
struct nvkm_subdev subdev;
/* automatic thermal management */
struct nvkm_alarm alarm;
spinlock_t lock;
struct nvbios_therm_trip_point *last_trip;
int mode;
int cstate;
int suspend;
/* bios */
struct nvbios_therm_sensor bios_sensor;
/* fan priv */
struct nvkm_fan *fan;
/* alarms priv */
struct {
spinlock_t alarm_program_lock;
struct nvkm_alarm therm_poll_alarm;
enum nvkm_therm_thrs_state alarm_state[NVKM_THERM_THRS_NR];
} sensor;
/* what should be done if the card overheats */
struct {
void (*downclock)(struct nvkm_therm *, bool active);
void (*pause)(struct nvkm_therm *, bool active);
} emergency;
/* ic */
struct i2c_client *ic;
int (*fan_get)(struct nvkm_therm *);
int (*fan_set)(struct nvkm_therm *, int);
int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type);
int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
bool clkgating_enabled;
};
int nvkm_therm_temp_get(struct nvkm_therm *);
int nvkm_therm_fan_sense(struct nvkm_therm *);
int nvkm_therm_cstate(struct nvkm_therm *, int, int);
void nvkm_therm_clkgate_init(struct nvkm_therm *,
const struct nvkm_therm_clkgate_pack *);
void nvkm_therm_clkgate_enable(struct nvkm_therm *);
void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool);
int nv40_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int nv50_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int g84_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gt215_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gf119_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gk104_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gm107_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gm200_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
int gp100_therm_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_therm **);
#endif
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_TIMER_H__
#define __NVKM_TIMER_H__
#include <core/subdev.h>
struct nvkm_alarm {
struct list_head head;
struct list_head exec;
u64 timestamp;
void (*func)(struct nvkm_alarm *);
};
static inline void
nvkm_alarm_init(struct nvkm_alarm *alarm, void (*func)(struct nvkm_alarm *))
{
INIT_LIST_HEAD(&alarm->head);
alarm->func = func;
}
struct nvkm_timer {
const struct nvkm_timer_func *func;
struct nvkm_subdev subdev;
struct list_head alarms;
spinlock_t lock;
};
u64 nvkm_timer_read(struct nvkm_timer *);
void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *);
struct nvkm_timer_wait {
struct nvkm_timer *tmr;
u64 limit;
u64 time0;
u64 time1;
int reads;
};
void nvkm_timer_wait_init(struct nvkm_device *, u64 nsec,
struct nvkm_timer_wait *);
s64 nvkm_timer_wait_test(struct nvkm_timer_wait *);
/* Delay based on GPU time (ie. PTIMER).
*
* Will return -ETIMEDOUT unless the loop was terminated with 'break',
* where it will return the number of nanoseconds taken instead.
*
* NVKM_DELAY can be passed for 'cond' to disable the timeout warning,
* which is useful for unconditional delay loops.
*/
#define NVKM_DELAY _warn = false;
#define nvkm_nsec(d,n,cond...) ({ \
struct nvkm_timer_wait _wait; \
bool _warn = true; \
s64 _taken = 0; \
\
nvkm_timer_wait_init((d), (n), &_wait); \
do { \
cond \
} while ((_taken = nvkm_timer_wait_test(&_wait)) >= 0); \
\
if (_warn && _taken < 0) \
dev_WARN(_wait.tmr->subdev.device->dev, "timeout\n"); \
_taken; \
})
#define nvkm_usec(d, u, cond...) nvkm_nsec((d), (u) * 1000ULL, ##cond)
#define nvkm_msec(d, m, cond...) nvkm_usec((d), (m) * 1000ULL, ##cond)
#define nvkm_wait_nsec(d,n,addr,mask,data) \
nvkm_nsec(d, n, \
if ((nvkm_rd32(d, (addr)) & (mask)) == (data)) \
break; \
)
#define nvkm_wait_usec(d,u,addr,mask,data) \
nvkm_wait_nsec((d), (u) * 1000, (addr), (mask), (data))
#define nvkm_wait_msec(d,m,addr,mask,data) \
nvkm_wait_usec((d), (m) * 1000, (addr), (mask), (data))
int nv04_timer_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_timer **);
int nv40_timer_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_timer **);
int nv41_timer_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_timer **);
int gk20a_timer_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_timer **);
#endif
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_TOP_H__
#define __NVKM_TOP_H__
#include <core/subdev.h>
struct nvkm_top {
const struct nvkm_top_func *func;
struct nvkm_subdev subdev;
struct list_head device;
};
struct nvkm_top_device {
enum nvkm_subdev_type type;
int inst;
u32 addr;
int fault;
int engine;
int runlist;
int reset;
int intr;
struct list_head head;
};
int nvkm_top_parse(struct nvkm_device *);
u32 nvkm_top_addr(struct nvkm_device *, enum nvkm_subdev_type, int);
u32 nvkm_top_reset(struct nvkm_device *, enum nvkm_subdev_type, int);
u32 nvkm_top_intr_mask(struct nvkm_device *, enum nvkm_subdev_type, int);
int nvkm_top_fault_id(struct nvkm_device *, enum nvkm_subdev_type, int);
struct nvkm_subdev *nvkm_top_fault(struct nvkm_device *, int fault);
int gk104_top_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_top **);
int ga100_top_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_top **);
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_VFN_H__
#define __NVKM_VFN_H__
#include <core/subdev.h>
struct nvkm_vfn {
const struct nvkm_vfn_func *func;
struct nvkm_subdev subdev;
struct {
u32 priv;
u32 user;
} addr;
struct nvkm_intr intr;
struct nvkm_device_oclass user;
};
int gv100_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
int tu102_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
int ga100_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
#endif
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NOUVEAU_VGA_H__
#define __NOUVEAU_VGA_H__
#include <core/subdev.h>
/* access to various legacy io ports */
u8 nvkm_rdport(struct nvkm_device *, int head, u16 port);
void nvkm_wrport(struct nvkm_device *, int head, u16 port, u8 value);
/* VGA Sequencer */
u8 nvkm_rdvgas(struct nvkm_device *, int head, u8 index);
void nvkm_wrvgas(struct nvkm_device *, int head, u8 index, u8 value);
/* VGA Graphics */
u8 nvkm_rdvgag(struct nvkm_device *, int head, u8 index);
void nvkm_wrvgag(struct nvkm_device *, int head, u8 index, u8 value);
/* VGA CRTC */
u8 nvkm_rdvgac(struct nvkm_device *, int head, u8 index);
void nvkm_wrvgac(struct nvkm_device *, int head, u8 index, u8 value);
/* VGA indexed port access dispatcher */
u8 nvkm_rdvgai(struct nvkm_device *, int head, u16 port, u8 index);
void nvkm_wrvgai(struct nvkm_device *, int head, u16 port, u8 index, u8 value);
bool nvkm_lockvgac(struct nvkm_device *, bool lock);
u8 nvkm_rdvgaowner(struct nvkm_device *);
void nvkm_wrvgaowner(struct nvkm_device *, u8);
#endif
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_VOLT_H__
#define __NVKM_VOLT_H__
#include <core/subdev.h>
struct nvkm_volt {
const struct nvkm_volt_func *func;
struct nvkm_subdev subdev;
u8 vid_mask;
u8 vid_nr;
struct {
u32 uv;
u8 vid;
} vid[256];
u32 max_uv;
u32 min_uv;
/*
* These are fully functional map entries creating a sw ceiling for
* the voltage. These all can describe different kind of curves, so
* that for any given temperature a different one can return the lowest
* value of all three.
*/
u8 max0_id;
u8 max1_id;
u8 max2_id;
int speedo;
};
int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);
int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
int nvkm_volt_get(struct nvkm_volt *);
int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, u8 temp,
int condition);
int nv40_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gf100_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gf117_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gk104_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gk20a_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gm20b_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
#endif