提交 f2c48821 编写于 作者: D Dave Airlie

Merge branch 'linux-4.6' of git://github.com/skeggsb/linux into drm-next

- GM20x secure boot support (hence, acceleration, finally \o/)
- GM200 support
- GM20B clock driver
- Support for power sensors on some GPUs
- Various other fixes all over the place

* 'linux-4.6' of git://github.com/skeggsb/linux: (95 commits)
  drm/nouveau/clk/gm20b: add basic driver
  drm/nouveau/clk/gk20a: share reusable structures/functions
  drm/nouveau/clk/gk20a: set lowest frequency during init()
  drm/nouveau/clk/gk20a: split gk20a_clk_new()
  drm/nouveau/clk/gk20a: abstract pl_to_div
  drm/nouveau/clk/gk20a: put mnp values into their own struct
  drm/nouveau/clk/gk20a: emit parent rate as debug message
  drm/nouveau/clk/gk20a: only restore divider to 1:1 if needed
  drm/nouveau/clk/gk20a: only compute n_lo if needed
  drm/nouveau/clk/gk20a: fix VCO bit mask
  drm/nouveau/clk/gk20a: rename enable/disable functions
  drm/nouveau/clk/gk20a: reorganize variables in gk20a_pllg_calc_mnp()
  drm/nouveau/clk/gk20a: convert parameters to Khz
  drm/nouveau/volt: add GM20B driver
  drm/nouveau/volt/gk20a: split constructor
  drm/nouveau/volt/gk20a: share reusable members & functions
  drm/nouveau/ce/gm107: expose MaxwellDmaCopyA
  drm/nouveau/fifo/gm107: KeplerChannelGpfifoB, and 2048 channels
  drm/nouveau/fifo/gk110: expose KeplerChannelGpfifoB
  drm/nouveau/fifo/gk104: submit NOP after all PBDMA_INTR_0, not just DEVICE
  ...
......@@ -3,19 +3,27 @@
struct kepler_channel_gpfifo_a_v0 {
__u8 version;
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
__u8 engine;
__u8 pad01[5];
__u16 chid;
#define NVA06F_V0_ENGINE_SW 0x00000001
#define NVA06F_V0_ENGINE_GR 0x00000002
#define NVA06F_V0_ENGINE_SEC 0x00000004
#define NVA06F_V0_ENGINE_MSVLD 0x00000010
#define NVA06F_V0_ENGINE_MSPDEC 0x00000020
#define NVA06F_V0_ENGINE_MSPPP 0x00000040
#define NVA06F_V0_ENGINE_MSENC 0x00000080
#define NVA06F_V0_ENGINE_VIC 0x00000100
#define NVA06F_V0_ENGINE_NVDEC 0x00000200
#define NVA06F_V0_ENGINE_NVENC0 0x00000400
#define NVA06F_V0_ENGINE_NVENC1 0x00000800
#define NVA06F_V0_ENGINE_CE0 0x00010000
#define NVA06F_V0_ENGINE_CE1 0x00020000
#define NVA06F_V0_ENGINE_CE2 0x00040000
__u32 engines;
__u32 ilength;
__u64 ioffset;
__u64 vm;
};
#define KEPLER_CHANNEL_GPFIFO_A_V0_NTFY_UEVENT 0x00
#define NVA06F_V0_NTFY_UEVENT 0x00
#endif
......@@ -37,6 +37,7 @@
#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f
#define FERMI_CHANNEL_GPFIFO /* cl906f.h */ 0x0000906f
#define KEPLER_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000a06f
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
#define NV50_DISP /* cl5070.h */ 0x00005070
......@@ -48,7 +49,7 @@
#define GK104_DISP /* cl5070.h */ 0x00009170
#define GK110_DISP /* cl5070.h */ 0x00009270
#define GM107_DISP /* cl5070.h */ 0x00009470
#define GM204_DISP /* cl5070.h */ 0x00009570
#define GM200_DISP /* cl5070.h */ 0x00009570
#define NV31_MPEG 0x00003174
#define G82_MPEG 0x00008274
......@@ -84,7 +85,7 @@
#define GK104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000917d
#define GK110_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000927d
#define GM107_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000947d
#define GM204_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d
#define GM200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d
#define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e
#define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e
......
......@@ -62,6 +62,7 @@ u64 nvif_device_time(struct nvif_device *);
#define nvxx_gpio(a) nvxx_device(a)->gpio
#define nvxx_clk(a) nvxx_device(a)->clk
#define nvxx_i2c(a) nvxx_device(a)->i2c
#define nvxx_iccsense(a) nvxx_device(a)->iccsense
#define nvxx_therm(a) nvxx_device(a)->therm
#define nvxx_volt(a) nvxx_device(a)->volt
......
......@@ -22,30 +22,41 @@ enum nvkm_devidx {
NVKM_SUBDEV_BAR,
NVKM_SUBDEV_PMU,
NVKM_SUBDEV_VOLT,
NVKM_SUBDEV_ICCSENSE,
NVKM_SUBDEV_THERM,
NVKM_SUBDEV_CLK,
NVKM_SUBDEV_SECBOOT,
NVKM_ENGINE_DMAOBJ,
NVKM_ENGINE_IFB,
NVKM_ENGINE_FIFO,
NVKM_ENGINE_SW,
NVKM_ENGINE_GR,
NVKM_ENGINE_MPEG,
NVKM_ENGINE_ME,
NVKM_ENGINE_VP,
NVKM_ENGINE_CIPHER,
NVKM_ENGINE_BSP,
NVKM_ENGINE_MSPPP,
NVKM_ENGINE_CE0,
NVKM_ENGINE_CE1,
NVKM_ENGINE_CE2,
NVKM_ENGINE_VIC,
NVKM_ENGINE_MSENC,
NVKM_ENGINE_CE_LAST = NVKM_ENGINE_CE2,
NVKM_ENGINE_CIPHER,
NVKM_ENGINE_DISP,
NVKM_ENGINE_PM,
NVKM_ENGINE_DMAOBJ,
NVKM_ENGINE_FIFO,
NVKM_ENGINE_GR,
NVKM_ENGINE_IFB,
NVKM_ENGINE_ME,
NVKM_ENGINE_MPEG,
NVKM_ENGINE_MSENC,
NVKM_ENGINE_MSPDEC,
NVKM_ENGINE_MSPPP,
NVKM_ENGINE_MSVLD,
NVKM_ENGINE_NVENC0,
NVKM_ENGINE_NVENC1,
NVKM_ENGINE_NVENC_LAST = NVKM_ENGINE_NVENC1,
NVKM_ENGINE_NVDEC,
NVKM_ENGINE_PM,
NVKM_ENGINE_SEC,
NVKM_ENGINE_MSPDEC,
NVKM_ENGINE_SW,
NVKM_ENGINE_VIC,
NVKM_ENGINE_VP,
NVKM_SUBDEV_NR
};
......@@ -109,6 +120,7 @@ struct nvkm_device {
struct nvkm_gpio *gpio;
struct nvkm_i2c *i2c;
struct nvkm_subdev *ibus;
struct nvkm_iccsense *iccsense;
struct nvkm_instmem *imem;
struct nvkm_ltc *ltc;
struct nvkm_mc *mc;
......@@ -116,6 +128,7 @@ struct nvkm_device {
struct nvkm_subdev *mxm;
struct nvkm_pci *pci;
struct nvkm_pmu *pmu;
struct nvkm_secboot *secboot;
struct nvkm_therm *therm;
struct nvkm_timer *timer;
struct nvkm_volt *volt;
......@@ -134,6 +147,8 @@ struct nvkm_device {
struct nvkm_engine *mspdec;
struct nvkm_engine *msppp;
struct nvkm_engine *msvld;
struct nvkm_engine *nvenc[2];
struct nvkm_engine *nvdec;
struct nvkm_pm *pm;
struct nvkm_engine *sec;
struct nvkm_sw *sw;
......@@ -164,46 +179,50 @@ struct nvkm_device_quirk {
struct nvkm_device_chip {
const char *name;
int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **);
int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **);
int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **);
int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **);
int (*devinit)(struct nvkm_device *, int idx, struct nvkm_devinit **);
int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **);
int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **);
int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **);
int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **);
int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **);
int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **);
int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **);
int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **);
int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*pci )(struct nvkm_device *, int idx, struct nvkm_pci **);
int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **);
int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **);
int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **);
int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **);
int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **);
int (*dma )(struct nvkm_device *, int idx, struct nvkm_dma **);
int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **);
int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **);
int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **);
int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **);
int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **);
int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **);
int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **);
int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **);
int (*devinit )(struct nvkm_device *, int idx, struct nvkm_devinit **);
int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **);
int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **);
int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **);
int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **);
int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*iccsense)(struct nvkm_device *, int idx, struct nvkm_iccsense **);
int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **);
int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **);
int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **);
int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **);
int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*pci )(struct nvkm_device *, int idx, struct nvkm_pci **);
int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **);
int (*secboot )(struct nvkm_device *, int idx, struct nvkm_secboot **);
int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **);
int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **);
int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **);
int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **);
int (*dma )(struct nvkm_device *, int idx, struct nvkm_dma **);
int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **);
int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **);
int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*nvenc[2])(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*nvdec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **);
int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **);
int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **);
};
struct nvkm_device *nvkm_device_find(u64 name);
......
#ifndef __NVKM_FIRMWARE_H__
#define __NVKM_FIRMWARE_H__
#include <core/device.h>
int nvkm_firmware_get(struct nvkm_device *device, const char *fwname,
const struct firmware **fw);
void nvkm_firmware_put(const struct firmware *fw);
#endif
......@@ -37,4 +37,8 @@ int nvkm_gpuobj_wrap(struct nvkm_memory *, struct nvkm_gpuobj **);
int nvkm_gpuobj_map(struct nvkm_gpuobj *, struct nvkm_vm *, u32 access,
struct nvkm_vma *);
void nvkm_gpuobj_unmap(struct nvkm_vma *);
void nvkm_gpuobj_memcpy_to(struct nvkm_gpuobj *dst, u32 dstoffset, void *src,
u32 length);
void nvkm_gpuobj_memcpy_from(void *dst, struct nvkm_gpuobj *src, u32 srcoffset,
u32 length);
#endif
......@@ -5,5 +5,6 @@
int gt215_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gf100_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gk104_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gm204_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gm107_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
#endif
......@@ -31,5 +31,5 @@ int gf119_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gk104_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gk110_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gm107_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gm204_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
#endif
......@@ -60,8 +60,10 @@ int nv50_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int g84_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gf100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gk104_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gk110_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gk208_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gk20a_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gm204_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gm107_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gm200_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
#endif
......@@ -40,7 +40,6 @@ int gk110b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk208_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gk20a_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm107_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm204_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm206_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm200_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gm20b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#endif
#ifndef __NVKM_MSENC_H__
#define __NVKM_MSENC_H__
#include <core/engine.h>
#endif
#ifndef __NVKM_NVDEC_H__
#define __NVKM_NVDEC_H__
#include <core/engine.h>
#endif
#ifndef __NVKM_NVENC_H__
#define __NVKM_NVENC_H__
#include <core/engine.h>
#endif
#ifndef __NVKM_VIC_H__
#define __NVKM_VIC_H__
#include <core/engine.h>
#endif
......@@ -5,6 +5,9 @@ enum nvbios_extdev_type {
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,
......
#ifndef __NVBIOS_ICCSENSE_H__
#define __NVBIOS_ICCSENSE_H__
struct pwr_rail_t {
u8 mode;
u8 extdev_id;
u8 resistor_mohm;
u8 rail;
};
struct nvbios_iccsense {
int nr_entry;
struct pwr_rail_t *rail;
};
int nvbios_iccsense_parse(struct nvkm_bios *, struct nvbios_iccsense *);
#endif
......@@ -121,4 +121,5 @@ int gt215_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
int gf100_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
int gk104_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
int gk20a_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
int gm20b_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
#endif
......@@ -27,5 +27,5 @@ int gt215_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int mcp89_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gf100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gm204_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
#endif
......@@ -89,7 +89,7 @@ int g94_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
int gf117_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
int gf119_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
int gk104_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
int gm204_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
int gm200_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **);
static inline int
nvkm_rdi2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
......@@ -107,6 +107,22 @@ nvkm_rdi2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
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)
{
......@@ -122,6 +138,21 @@ nvkm_wri2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u8 val)
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)
{
......
......@@ -6,5 +6,5 @@ int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gf117_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gm204_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gm200_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
#endif
#ifndef __NVKM_ICCSENSE_H__
#define __NVKM_ICCSENSE_H__
#include <core/subdev.h>
struct nkvm_iccsense_rail;
struct nvkm_iccsense {
struct nvkm_subdev subdev;
u8 rail_count;
bool data_valid;
struct nvkm_iccsense_rail *rails;
};
int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **);
int nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx);
int nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense);
#endif
......@@ -37,5 +37,5 @@ int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gk104_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gk20a_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm204_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm200_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
#endif
/*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef __NVKM_SECURE_BOOT_H__
#define __NVKM_SECURE_BOOT_H__
#include <core/subdev.h>
enum nvkm_secboot_falcon {
NVKM_SECBOOT_FALCON_PMU = 0,
NVKM_SECBOOT_FALCON_RESERVED = 1,
NVKM_SECBOOT_FALCON_FECS = 2,
NVKM_SECBOOT_FALCON_GPCCS = 3,
NVKM_SECBOOT_FALCON_END = 4,
NVKM_SECBOOT_FALCON_INVALID = 0xffffffff,
};
/**
* @base: base IO address of the falcon performing secure boot
* @irq_mask: IRQ mask of the falcon performing secure boot
* @enable_mask: enable mask of the falcon performing secure boot
*/
struct nvkm_secboot {
const struct nvkm_secboot_func *func;
struct nvkm_subdev subdev;
u32 base;
u32 irq_mask;
u32 enable_mask;
};
#define nvkm_secboot(p) container_of((p), struct nvkm_secboot, subdev)
bool nvkm_secboot_is_managed(struct nvkm_secboot *, enum nvkm_secboot_falcon);
int nvkm_secboot_reset(struct nvkm_secboot *, u32 falcon);
int nvkm_secboot_start(struct nvkm_secboot *, u32 falcon);
int gm200_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
int gm20b_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
#endif
......@@ -20,4 +20,5 @@ int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gm20b_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
#endif
......@@ -263,13 +263,23 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
/* hack to allow channel engine type specification on kepler */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
if (init->fb_ctxdma_handle != ~0)
init->fb_ctxdma_handle = KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR;
else
init->fb_ctxdma_handle = init->tt_ctxdma_handle;
init->fb_ctxdma_handle = NVA06F_V0_ENGINE_GR;
else {
init->fb_ctxdma_handle = 0;
#define _(A,B) if (init->tt_ctxdma_handle & (A)) init->fb_ctxdma_handle |= (B)
_(0x01, NVA06F_V0_ENGINE_GR);
_(0x02, NVA06F_V0_ENGINE_MSPDEC);
_(0x04, NVA06F_V0_ENGINE_MSPPP);
_(0x08, NVA06F_V0_ENGINE_MSVLD);
_(0x10, NVA06F_V0_ENGINE_CE0);
_(0x20, NVA06F_V0_ENGINE_CE1);
_(0x40, NVA06F_V0_ENGINE_MSENC);
#undef _
}
/* allow flips to be executed if this is a graphics channel */
init->tt_ctxdma_handle = 0;
if (init->fb_ctxdma_handle == KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR)
if (init->fb_ctxdma_handle == NVA06F_V0_ENGINE_GR)
init->tt_ctxdma_handle = 1;
}
......
......@@ -1502,7 +1502,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}
#endif
#ifdef CONFIG_SWIOTLB
#if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86)
if (swiotlb_nr_tbl()) {
return ttm_dma_populate((void *)ttm, dev->dev);
}
......@@ -1570,7 +1570,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
}
#endif
#ifdef CONFIG_SWIOTLB
#if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86)
if (swiotlb_nr_tbl()) {
ttm_dma_unpopulate((void *)ttm, dev->dev);
return;
......
......@@ -192,6 +192,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
u32 engine, struct nouveau_channel **pchan)
{
static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A,
KEPLER_CHANNEL_GPFIFO_B,
KEPLER_CHANNEL_GPFIFO_A,
FERMI_CHANNEL_GPFIFO,
G82_CHANNEL_GPFIFO,
......@@ -217,7 +218,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
do {
if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
args.kepler.version = 0;
args.kepler.engine = engine;
args.kepler.engines = engine;
args.kepler.ilength = 0x02000;
args.kepler.ioffset = 0x10000 + chan->push.vma.offset;
args.kepler.vm = 0;
......
......@@ -495,7 +495,7 @@ nouveau_display_create(struct drm_device *dev)
if (nouveau_modeset != 2 && drm->vbios.dcb.entries) {
static const u16 oclass[] = {
GM204_DISP,
GM200_DISP,
GM107_DISP,
GK110_DISP,
GK104_DISP,
......
......@@ -198,6 +198,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
break;
case FERMI_CHANNEL_GPFIFO:
case KEPLER_CHANNEL_GPFIFO_A:
case KEPLER_CHANNEL_GPFIFO_B:
case MAXWELL_CHANNEL_GPFIFO_A:
ret = nvc0_fence_create(drm);
break;
......@@ -215,13 +216,13 @@ nouveau_accel_init(struct nouveau_drm *drm)
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
ret = nouveau_channel_new(drm, &drm->device,
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0|
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1,
NVA06F_V0_ENGINE_CE0 |
NVA06F_V0_ENGINE_CE1,
0, &drm->cechan);
if (ret)
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
arg0 = KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR;
arg0 = NVA06F_V0_ENGINE_GR;
arg1 = 1;
} else
if (device->info.chipset >= 0xa3 &&
......@@ -375,7 +376,7 @@ nouveau_get_hdmi_dev(struct nouveau_drm *drm)
struct pci_dev *pdev = drm->dev->pdev;
if (!pdev) {
DRM_INFO("not a PCI device; no HDMI\n");
NV_DEBUG(drm, "not a PCI device; no HDMI\n");
drm->hdmi_device = NULL;
return;
}
......
......@@ -34,6 +34,7 @@
#include "nouveau_drm.h"
#include "nouveau_hwmon.h"
#include <nvkm/subdev/iccsense.h>
#include <nvkm/subdev/volt.h>
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
......@@ -543,6 +544,24 @@ nouveau_hwmon_get_in0_label(struct device *d,
static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO,
nouveau_hwmon_get_in0_label, NULL, 0);
static ssize_t
nouveau_hwmon_get_power1_input(struct device *d, struct device_attribute *a,
char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->device);
int result = nvkm_iccsense_read_all(iccsense);
if (result < 0)
return result;
return sprintf(buf, "%i\n", result);
}
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO,
nouveau_hwmon_get_power1_input, NULL, 0);
static struct attribute *hwmon_default_attributes[] = {
&sensor_dev_attr_name.dev_attr.attr,
&sensor_dev_attr_update_rate.dev_attr.attr,
......@@ -579,6 +598,11 @@ static struct attribute *hwmon_in0_attributes[] = {
NULL
};
static struct attribute *hwmon_power_attributes[] = {
&sensor_dev_attr_power1_input.dev_attr.attr,
NULL
};
static const struct attribute_group hwmon_default_attrgroup = {
.attrs = hwmon_default_attributes,
};
......@@ -594,6 +618,9 @@ static const struct attribute_group hwmon_pwm_fan_attrgroup = {
static const struct attribute_group hwmon_in0_attrgroup = {
.attrs = hwmon_in0_attributes,
};
static const struct attribute_group hwmon_power_attrgroup = {
.attrs = hwmon_power_attributes,
};
#endif
int
......@@ -603,6 +630,7 @@ nouveau_hwmon_init(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(&drm->device);
struct nvkm_volt *volt = nvxx_volt(&drm->device);
struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->device);
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
......@@ -612,10 +640,7 @@ nouveau_hwmon_init(struct drm_device *dev)
return -ENOMEM;
hwmon->dev = dev;
if (!therm || !therm->attr_get || !therm->attr_set)
return -ENODEV;
hwmon_dev = hwmon_device_register(&dev->pdev->dev);
hwmon_dev = hwmon_device_register(dev->dev);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
......@@ -628,26 +653,28 @@ nouveau_hwmon_init(struct drm_device *dev)
if (ret)
goto error;
/* if the card has a working thermal sensor */
if (nvkm_therm_temp_get(therm) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup);
if (ret)
goto error;
}
/* if the card has a pwm fan */
/*XXX: incorrect, need better detection for this, some boards have
* the gpio entries for pwm fan control even when there's no
* actual fan connected to it... therm table? */
if (therm->fan_get && therm->fan_get(therm) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj,
&hwmon_pwm_fan_attrgroup);
if (ret)
goto error;
if (therm && therm->attr_get && therm->attr_set) {
/* if the card has a working thermal sensor */
if (nvkm_therm_temp_get(therm) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup);
if (ret)
goto error;
}
/* if the card has a pwm fan */
/*XXX: incorrect, need better detection for this, some boards have
* the gpio entries for pwm fan control even when there's no
* actual fan connected to it... therm table? */
if (therm->fan_get && therm->fan_get(therm) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj,
&hwmon_pwm_fan_attrgroup);
if (ret)
goto error;
}
}
/* if the card can read the fan rpm */
if (nvkm_therm_fan_sense(therm) >= 0) {
if (therm && nvkm_therm_fan_sense(therm) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj,
&hwmon_fan_rpm_attrgroup);
if (ret)
......@@ -662,6 +689,13 @@ nouveau_hwmon_init(struct drm_device *dev)
goto error;
}
if (iccsense && iccsense->data_valid && iccsense->rail_count) {
ret = sysfs_create_group(&hwmon_dev->kobj,
&hwmon_power_attrgroup);
if (ret)
goto error;
}
hwmon->hwmon = hwmon_dev;
return 0;
......@@ -688,6 +722,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_in0_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_power_attrgroup);
hwmon_device_unregister(hwmon->hwmon);
}
......
......@@ -297,7 +297,7 @@ nv50_core_create(struct nvif_device *device, struct nvif_object *disp,
.pushbuf = 0xb0007d00,
};
static const s32 oclass[] = {
GM204_DISP_CORE_CHANNEL_DMA,
GM200_DISP_CORE_CHANNEL_DMA,
GM107_DISP_CORE_CHANNEL_DMA,
GK110_DISP_CORE_CHANNEL_DMA,
GK104_DISP_CORE_CHANNEL_DMA,
......
......@@ -2,6 +2,7 @@ nvkm-y := nvkm/core/client.o
nvkm-y += nvkm/core/engine.o
nvkm-y += nvkm/core/enum.o
nvkm-y += nvkm/core/event.o
nvkm-y += nvkm/core/firmware.o
nvkm-y += nvkm/core/gpuobj.o
nvkm-y += nvkm/core/ioctl.o
nvkm-y += nvkm/core/memory.o
......
/*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <core/device.h>
/**
* nvkm_firmware_get - load firmware from the official nvidia/chip/ directory
* @device device that will use that firmware
* @fwname name of firmware file to load
* @fw firmware structure to load to
*
* Use this function to load firmware files in the form nvidia/chip/fwname.bin.
* Firmware files released by NVIDIA will always follow this format.
*/
int
nvkm_firmware_get(struct nvkm_device *device, const char *fwname,
const struct firmware **fw)
{
char f[64];
char cname[16];
int i;
/* Convert device name to lowercase */
strncpy(cname, device->chip->name, sizeof(cname));
cname[sizeof(cname) - 1] = '\0';
i = strlen(cname);
while (i) {
--i;
cname[i] = tolower(cname[i]);
}
snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
return request_firmware(fw, f, device->dev);
}
/**
* nvkm_firmware_put - release firmware loaded with nvkm_firmware_get
*/
void
nvkm_firmware_put(const struct firmware *fw)
{
release_firmware(fw);
}
......@@ -253,3 +253,23 @@ nvkm_gpuobj_wrap(struct nvkm_memory *memory, struct nvkm_gpuobj **pgpuobj)
(*pgpuobj)->size = nvkm_memory_size(memory);
return 0;
}
void
nvkm_gpuobj_memcpy_to(struct nvkm_gpuobj *dst, u32 dstoffset, void *src,
u32 length)
{
int i;
for (i = 0; i < length; i += 4)
nvkm_wo32(dst, dstoffset + i, *(u32 *)(src + i));
}
void
nvkm_gpuobj_memcpy_from(void *dst, struct nvkm_gpuobj *src, u32 srcoffset,
u32 length)
{
int i;
for (i = 0; i < length; i += 4)
((u32 *)src)[i / 4] = nvkm_ro32(src, srcoffset + i);
}
......@@ -131,7 +131,7 @@ nvkm_ramht_del(struct nvkm_ramht **pramht)
struct nvkm_ramht *ramht = *pramht;
if (ramht) {
nvkm_gpuobj_del(&ramht->gpuobj);
kfree(*pramht);
vfree(*pramht);
*pramht = NULL;
}
}
......@@ -143,8 +143,8 @@ nvkm_ramht_new(struct nvkm_device *device, u32 size, u32 align,
struct nvkm_ramht *ramht;
int ret, i;
if (!(ramht = *pramht = kzalloc(sizeof(*ramht) + (size >> 3) *
sizeof(*ramht->data), GFP_KERNEL)))
if (!(ramht = *pramht = vzalloc(sizeof(*ramht) +
(size >> 3) * sizeof(*ramht->data))))
return -ENOMEM;
ramht->device = device;
......
......@@ -29,47 +29,52 @@ static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
const char *
nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_BAR ] = "bar",
[NVKM_SUBDEV_VBIOS ] = "bios",
[NVKM_SUBDEV_BUS ] = "bus",
[NVKM_SUBDEV_CLK ] = "clk",
[NVKM_SUBDEV_DEVINIT] = "devinit",
[NVKM_SUBDEV_FB ] = "fb",
[NVKM_SUBDEV_FUSE ] = "fuse",
[NVKM_SUBDEV_GPIO ] = "gpio",
[NVKM_SUBDEV_I2C ] = "i2c",
[NVKM_SUBDEV_IBUS ] = "priv",
[NVKM_SUBDEV_INSTMEM] = "imem",
[NVKM_SUBDEV_LTC ] = "ltc",
[NVKM_SUBDEV_MC ] = "mc",
[NVKM_SUBDEV_MMU ] = "mmu",
[NVKM_SUBDEV_MXM ] = "mxm",
[NVKM_SUBDEV_PCI ] = "pci",
[NVKM_SUBDEV_PMU ] = "pmu",
[NVKM_SUBDEV_THERM ] = "therm",
[NVKM_SUBDEV_TIMER ] = "tmr",
[NVKM_SUBDEV_VOLT ] = "volt",
[NVKM_ENGINE_BSP ] = "bsp",
[NVKM_ENGINE_CE0 ] = "ce0",
[NVKM_ENGINE_CE1 ] = "ce1",
[NVKM_ENGINE_CE2 ] = "ce2",
[NVKM_ENGINE_CIPHER ] = "cipher",
[NVKM_ENGINE_DISP ] = "disp",
[NVKM_ENGINE_DMAOBJ ] = "dma",
[NVKM_ENGINE_FIFO ] = "fifo",
[NVKM_ENGINE_GR ] = "gr",
[NVKM_ENGINE_IFB ] = "ifb",
[NVKM_ENGINE_ME ] = "me",
[NVKM_ENGINE_MPEG ] = "mpeg",
[NVKM_ENGINE_MSENC ] = "msenc",
[NVKM_ENGINE_MSPDEC ] = "mspdec",
[NVKM_ENGINE_MSPPP ] = "msppp",
[NVKM_ENGINE_MSVLD ] = "msvld",
[NVKM_ENGINE_PM ] = "pm",
[NVKM_ENGINE_SEC ] = "sec",
[NVKM_ENGINE_SW ] = "sw",
[NVKM_ENGINE_VIC ] = "vic",
[NVKM_ENGINE_VP ] = "vp",
[NVKM_SUBDEV_BAR ] = "bar",
[NVKM_SUBDEV_VBIOS ] = "bios",
[NVKM_SUBDEV_BUS ] = "bus",
[NVKM_SUBDEV_CLK ] = "clk",
[NVKM_SUBDEV_DEVINIT ] = "devinit",
[NVKM_SUBDEV_FB ] = "fb",
[NVKM_SUBDEV_FUSE ] = "fuse",
[NVKM_SUBDEV_GPIO ] = "gpio",
[NVKM_SUBDEV_I2C ] = "i2c",
[NVKM_SUBDEV_IBUS ] = "priv",
[NVKM_SUBDEV_ICCSENSE] = "iccsense",
[NVKM_SUBDEV_INSTMEM ] = "imem",
[NVKM_SUBDEV_LTC ] = "ltc",
[NVKM_SUBDEV_MC ] = "mc",
[NVKM_SUBDEV_MMU ] = "mmu",
[NVKM_SUBDEV_MXM ] = "mxm",
[NVKM_SUBDEV_PCI ] = "pci",
[NVKM_SUBDEV_PMU ] = "pmu",
[NVKM_SUBDEV_SECBOOT ] = "secboot",
[NVKM_SUBDEV_THERM ] = "therm",
[NVKM_SUBDEV_TIMER ] = "tmr",
[NVKM_SUBDEV_VOLT ] = "volt",
[NVKM_ENGINE_BSP ] = "bsp",
[NVKM_ENGINE_CE0 ] = "ce0",
[NVKM_ENGINE_CE1 ] = "ce1",
[NVKM_ENGINE_CE2 ] = "ce2",
[NVKM_ENGINE_CIPHER ] = "cipher",
[NVKM_ENGINE_DISP ] = "disp",
[NVKM_ENGINE_DMAOBJ ] = "dma",
[NVKM_ENGINE_FIFO ] = "fifo",
[NVKM_ENGINE_GR ] = "gr",
[NVKM_ENGINE_IFB ] = "ifb",
[NVKM_ENGINE_ME ] = "me",
[NVKM_ENGINE_MPEG ] = "mpeg",
[NVKM_ENGINE_MSENC ] = "msenc",
[NVKM_ENGINE_MSPDEC ] = "mspdec",
[NVKM_ENGINE_MSPPP ] = "msppp",
[NVKM_ENGINE_MSVLD ] = "msvld",
[NVKM_ENGINE_NVENC0 ] = "nvenc0",
[NVKM_ENGINE_NVENC1 ] = "nvenc1",
[NVKM_ENGINE_NVDEC ] = "nvdec",
[NVKM_ENGINE_PM ] = "pm",
[NVKM_ENGINE_SEC ] = "sec",
[NVKM_ENGINE_SW ] = "sw",
[NVKM_ENGINE_VIC ] = "vic",
[NVKM_ENGINE_VP ] = "vp",
};
void
......
......@@ -10,10 +10,14 @@ include $(src)/nvkm/engine/dma/Kbuild
include $(src)/nvkm/engine/fifo/Kbuild
include $(src)/nvkm/engine/gr/Kbuild
include $(src)/nvkm/engine/mpeg/Kbuild
include $(src)/nvkm/engine/msenc/Kbuild
include $(src)/nvkm/engine/mspdec/Kbuild
include $(src)/nvkm/engine/msppp/Kbuild
include $(src)/nvkm/engine/msvld/Kbuild
include $(src)/nvkm/engine/nvenc/Kbuild
include $(src)/nvkm/engine/nvdec/Kbuild
include $(src)/nvkm/engine/pm/Kbuild
include $(src)/nvkm/engine/sec/Kbuild
include $(src)/nvkm/engine/sw/Kbuild
include $(src)/nvkm/engine/vic/Kbuild
include $(src)/nvkm/engine/vp/Kbuild
nvkm-y += nvkm/engine/ce/gt215.o
nvkm-y += nvkm/engine/ce/gf100.o
nvkm-y += nvkm/engine/ce/gk104.o
nvkm-y += nvkm/engine/ce/gm204.o
nvkm-y += nvkm/engine/ce/gm107.o
nvkm-y += nvkm/engine/ce/gm200.o
/*
* Copyright 2015 Red Hat Inc.
* Copyright 2016 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -19,30 +19,37 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
* Authors: Ben Skeggs
*/
#include "gf100.h"
#include "ctxgf100.h"
#include "priv.h"
#include <nvif/class.h>
static const struct gf100_gr_func
gm206_gr = {
.init = gm204_gr_init,
.mmio = gm204_gr_pack_mmio,
.ppc_nr = 2,
.grctx = &gm206_grctx,
static const struct nvkm_engine_func
gm107_ce = {
.intr = gk104_ce_intr,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
{ -1, -1, KEPLER_INLINE_TO_MEMORY_B },
{ -1, -1, MAXWELL_B, &gf100_fermi },
{ -1, -1, MAXWELL_COMPUTE_B },
{ -1, -1, KEPLER_DMA_COPY_A },
{ -1, -1, MAXWELL_DMA_COPY_A },
{}
}
};
int
gm206_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
gm107_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
return gf100_gr_new_(&gm206_gr, device, index, pgr);
if (index == NVKM_ENGINE_CE0) {
return nvkm_engine_new_(&gm107_ce, device, index,
0x00000040, true, pengine);
} else
if (index == NVKM_ENGINE_CE1) {
return nvkm_engine_new_(&gm107_ce, device, index,
0x00000080, true, pengine);
} else
if (index == NVKM_ENGINE_CE2) {
return nvkm_engine_new_(&gm107_ce, device, index,
0x00200000, true, pengine);
}
return -ENODEV;
}
......@@ -26,7 +26,7 @@
#include <nvif/class.h>
static const struct nvkm_engine_func
gm204_ce = {
gm200_ce = {
.intr = gk104_ce_intr,
.sclass = {
{ -1, -1, MAXWELL_DMA_COPY_A },
......@@ -35,19 +35,19 @@ gm204_ce = {
};
int
gm204_ce_new(struct nvkm_device *device, int index,
gm200_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
if (index == NVKM_ENGINE_CE0) {
return nvkm_engine_new_(&gm204_ce, device, index,
return nvkm_engine_new_(&gm200_ce, device, index,
0x00000040, true, pengine);
} else
if (index == NVKM_ENGINE_CE1) {
return nvkm_engine_new_(&gm204_ce, device, index,
return nvkm_engine_new_(&gm200_ce, device, index,
0x00000080, true, pengine);
} else
if (index == NVKM_ENGINE_CE2) {
return nvkm_engine_new_(&gm204_ce, device, index,
return nvkm_engine_new_(&gm200_ce, device, index,
0x00200000, true, pengine);
}
return -ENODEV;
......
......@@ -1347,6 +1347,7 @@ nvc0_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1383,6 +1384,7 @@ nvc1_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1418,6 +1420,7 @@ nvc3_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1453,6 +1456,7 @@ nvc4_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1489,6 +1493,7 @@ nvc8_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1525,6 +1530,7 @@ nvce_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1561,6 +1567,7 @@ nvcf_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.ibus = gf100_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1596,6 +1603,7 @@ nvd7_chipset = {
.gpio = gf119_gpio_new,
.i2c = gf117_i2c_new,
.ibus = gf117_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1629,6 +1637,7 @@ nvd9_chipset = {
.gpio = gf119_gpio_new,
.i2c = gf119_i2c_new,
.ibus = gf117_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gf100_ltc_new,
.mc = gf100_mc_new,
......@@ -1664,6 +1673,7 @@ nve4_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gf100_mc_new,
......@@ -1701,6 +1711,7 @@ nve6_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gf100_mc_new,
......@@ -1738,6 +1749,7 @@ nve7_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gf100_mc_new,
......@@ -1799,6 +1811,7 @@ nvf0_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gf100_mc_new,
......@@ -1814,7 +1827,7 @@ nvf0_chipset = {
.ce[2] = gk104_ce_new,
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
.fifo = gk110_fifo_new,
.gr = gk110_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
......@@ -1835,6 +1848,7 @@ nvf1_chipset = {
.gpio = gk104_gpio_new,
.i2c = gf119_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gf100_mc_new,
......@@ -1850,7 +1864,7 @@ nvf1_chipset = {
.ce[2] = gk104_ce_new,
.disp = gk110_disp_new,
.dma = gf119_dma_new,
.fifo = gk104_fifo_new,
.fifo = gk110_fifo_new,
.gr = gk110b_gr_new,
.mspdec = gk104_mspdec_new,
.msppp = gf100_msppp_new,
......@@ -1871,6 +1885,7 @@ nv106_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gk20a_mc_new,
......@@ -1907,6 +1922,7 @@ nv108_chipset = {
.gpio = gk104_gpio_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
.mc = gk20a_mc_new,
......@@ -1943,6 +1959,7 @@ nv117_chipset = {
.gpio = gk104_gpio_new,
.i2c = gf119_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gm107_ltc_new,
.mc = gk20a_mc_new,
......@@ -1953,43 +1970,78 @@ nv117_chipset = {
.therm = gm107_therm_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[2] = gk104_ce_new,
.ce[0] = gm107_ce_new,
.ce[2] = gm107_ce_new,
.disp = gm107_disp_new,
.dma = gf119_dma_new,
.fifo = gk208_fifo_new,
.fifo = gm107_fifo_new,
.gr = gm107_gr_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv120_chipset = {
.name = "GM200",
.bar = gf100_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm200_devinit_new,
.fb = gm107_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm200_i2c_new,
.ibus = gm200_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gm200_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
.ce[2] = gm200_ce_new,
.disp = gm200_disp_new,
.dma = gf119_dma_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv124_chipset = {
.name = "GM204",
.bar = gf100_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm204_devinit_new,
.devinit = gm200_devinit_new,
.fb = gm107_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm204_i2c_new,
.ibus = gm204_ibus_new,
.i2c = gm200_i2c_new,
.ibus = gm200_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gm204_ltc_new,
.ltc = gm200_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gm204_ce_new,
.ce[1] = gm204_ce_new,
.ce[2] = gm204_ce_new,
.disp = gm204_disp_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
.ce[2] = gm200_ce_new,
.disp = gm200_disp_new,
.dma = gf119_dma_new,
.fifo = gm204_fifo_new,
.gr = gm204_gr_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.sw = gf100_sw_new,
};
......@@ -1999,28 +2051,30 @@ nv126_chipset = {
.bar = gf100_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm204_devinit_new,
.devinit = gm200_devinit_new,
.fb = gm107_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm204_i2c_new,
.ibus = gm204_ibus_new,
.i2c = gm200_i2c_new,
.ibus = gm200_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gm204_ltc_new,
.ltc = gm200_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gm204_ce_new,
.ce[1] = gm204_ce_new,
.ce[2] = gm204_ce_new,
.disp = gm204_disp_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
.ce[2] = gm200_ce_new,
.disp = gm200_disp_new,
.dma = gf119_dma_new,
.fifo = gm204_fifo_new,
.gr = gm206_gr_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.sw = gf100_sw_new,
};
......@@ -2029,15 +2083,18 @@ nv12b_chipset = {
.name = "GM20B",
.bar = gk20a_bar_new,
.bus = gf100_bus_new,
.clk = gm20b_clk_new,
.fb = gk20a_fb_new,
.fuse = gm107_fuse_new,
.ibus = gk20a_ibus_new,
.imem = gk20a_instmem_new,
.ltc = gm204_ltc_new,
.ltc = gm200_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.secboot = gm20b_secboot_new,
.timer = gk20a_timer_new,
.ce[2] = gm204_ce_new,
.ce[2] = gm200_ce_new,
.volt = gm20b_volt_new,
.dma = gf119_dma_new,
.fifo = gm20b_fifo_new,
.gr = gm20b_gr_new,
......@@ -2072,26 +2129,28 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
switch (index) {
#define _(n,p,m) case NVKM_SUBDEV_##n: if (p) return (m); break
_(BAR , device->bar , &device->bar->subdev);
_(VBIOS , device->bios , &device->bios->subdev);
_(BUS , device->bus , &device->bus->subdev);
_(CLK , device->clk , &device->clk->subdev);
_(DEVINIT, device->devinit, &device->devinit->subdev);
_(FB , device->fb , &device->fb->subdev);
_(FUSE , device->fuse , &device->fuse->subdev);
_(GPIO , device->gpio , &device->gpio->subdev);
_(I2C , device->i2c , &device->i2c->subdev);
_(IBUS , device->ibus , device->ibus);
_(INSTMEM, device->imem , &device->imem->subdev);
_(LTC , device->ltc , &device->ltc->subdev);
_(MC , device->mc , &device->mc->subdev);
_(MMU , device->mmu , &device->mmu->subdev);
_(MXM , device->mxm , device->mxm);
_(PCI , device->pci , &device->pci->subdev);
_(PMU , device->pmu , &device->pmu->subdev);
_(THERM , device->therm , &device->therm->subdev);
_(TIMER , device->timer , &device->timer->subdev);
_(VOLT , device->volt , &device->volt->subdev);
_(BAR , device->bar , &device->bar->subdev);
_(VBIOS , device->bios , &device->bios->subdev);
_(BUS , device->bus , &device->bus->subdev);
_(CLK , device->clk , &device->clk->subdev);
_(DEVINIT , device->devinit , &device->devinit->subdev);
_(FB , device->fb , &device->fb->subdev);
_(FUSE , device->fuse , &device->fuse->subdev);
_(GPIO , device->gpio , &device->gpio->subdev);
_(I2C , device->i2c , &device->i2c->subdev);
_(IBUS , device->ibus , device->ibus);
_(ICCSENSE, device->iccsense, &device->iccsense->subdev);
_(INSTMEM , device->imem , &device->imem->subdev);
_(LTC , device->ltc , &device->ltc->subdev);
_(MC , device->mc , &device->mc->subdev);
_(MMU , device->mmu , &device->mmu->subdev);
_(MXM , device->mxm , device->mxm);
_(PCI , device->pci , &device->pci->subdev);
_(PMU , device->pmu , &device->pmu->subdev);
_(SECBOOT , device->secboot , &device->secboot->subdev);
_(THERM , device->therm , &device->therm->subdev);
_(TIMER , device->timer , &device->timer->subdev);
_(VOLT , device->volt , &device->volt->subdev);
#undef _
default:
engine = nvkm_device_engine(device, index);
......@@ -2110,27 +2169,30 @@ nvkm_device_engine(struct nvkm_device *device, int index)
switch (index) {
#define _(n,p,m) case NVKM_ENGINE_##n: if (p) return (m); break
_(BSP , device->bsp , device->bsp);
_(CE0 , device->ce[0] , device->ce[0]);
_(CE1 , device->ce[1] , device->ce[1]);
_(CE2 , device->ce[2] , device->ce[2]);
_(CIPHER , device->cipher , device->cipher);
_(DISP , device->disp , &device->disp->engine);
_(DMAOBJ , device->dma , &device->dma->engine);
_(FIFO , device->fifo , &device->fifo->engine);
_(GR , device->gr , &device->gr->engine);
_(IFB , device->ifb , device->ifb);
_(ME , device->me , device->me);
_(MPEG , device->mpeg , device->mpeg);
_(MSENC , device->msenc , device->msenc);
_(MSPDEC , device->mspdec , device->mspdec);
_(MSPPP , device->msppp , device->msppp);
_(MSVLD , device->msvld , device->msvld);
_(PM , device->pm , &device->pm->engine);
_(SEC , device->sec , device->sec);
_(SW , device->sw , &device->sw->engine);
_(VIC , device->vic , device->vic);
_(VP , device->vp , device->vp);
_(BSP , device->bsp , device->bsp);
_(CE0 , device->ce[0] , device->ce[0]);
_(CE1 , device->ce[1] , device->ce[1]);
_(CE2 , device->ce[2] , device->ce[2]);
_(CIPHER , device->cipher , device->cipher);
_(DISP , device->disp , &device->disp->engine);
_(DMAOBJ , device->dma , &device->dma->engine);
_(FIFO , device->fifo , &device->fifo->engine);
_(GR , device->gr , &device->gr->engine);
_(IFB , device->ifb , device->ifb);
_(ME , device->me , device->me);
_(MPEG , device->mpeg , device->mpeg);
_(MSENC , device->msenc , device->msenc);
_(MSPDEC , device->mspdec , device->mspdec);
_(MSPPP , device->msppp , device->msppp);
_(MSVLD , device->msvld , device->msvld);
_(NVENC0 , device->nvenc[0], device->nvenc[0]);
_(NVENC1 , device->nvenc[1], device->nvenc[1]);
_(NVDEC , device->nvdec , device->nvdec);
_(PM , device->pm , &device->pm->engine);
_(SEC , device->sec , device->sec);
_(SW , device->sw , &device->sw->engine);
_(VIC , device->vic , device->vic);
_(VP , device->vp , device->vp);
#undef _
default:
WARN_ON(1);
......@@ -2261,6 +2323,8 @@ nvkm_device_init(struct nvkm_device *device)
} while (--i >= 0);
fail:
nvkm_device_fini(device, false);
nvdev_error(device, "init failed with %d\n", ret);
return ret;
}
......@@ -2459,6 +2523,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x106: device->chip = &nv106_chipset; break;
case 0x108: device->chip = &nv108_chipset; break;
case 0x117: device->chip = &nv117_chipset; break;
case 0x120: device->chip = &nv120_chipset; break;
case 0x124: device->chip = &nv124_chipset; break;
case 0x126: device->chip = &nv126_chipset; break;
case 0x12b: device->chip = &nv12b_chipset; break;
......@@ -2518,47 +2583,52 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
} \
break
switch (i) {
_(NVKM_SUBDEV_BAR , bar);
_(NVKM_SUBDEV_VBIOS , bios);
_(NVKM_SUBDEV_BUS , bus);
_(NVKM_SUBDEV_CLK , clk);
_(NVKM_SUBDEV_DEVINIT, devinit);
_(NVKM_SUBDEV_FB , fb);
_(NVKM_SUBDEV_FUSE , fuse);
_(NVKM_SUBDEV_GPIO , gpio);
_(NVKM_SUBDEV_I2C , i2c);
_(NVKM_SUBDEV_IBUS , ibus);
_(NVKM_SUBDEV_INSTMEM, imem);
_(NVKM_SUBDEV_LTC , ltc);
_(NVKM_SUBDEV_MC , mc);
_(NVKM_SUBDEV_MMU , mmu);
_(NVKM_SUBDEV_MXM , mxm);
_(NVKM_SUBDEV_PCI , pci);
_(NVKM_SUBDEV_PMU , pmu);
_(NVKM_SUBDEV_THERM , therm);
_(NVKM_SUBDEV_TIMER , timer);
_(NVKM_SUBDEV_VOLT , volt);
_(NVKM_ENGINE_BSP , bsp);
_(NVKM_ENGINE_CE0 , ce[0]);
_(NVKM_ENGINE_CE1 , ce[1]);
_(NVKM_ENGINE_CE2 , ce[2]);
_(NVKM_ENGINE_CIPHER , cipher);
_(NVKM_ENGINE_DISP , disp);
_(NVKM_ENGINE_DMAOBJ , dma);
_(NVKM_ENGINE_FIFO , fifo);
_(NVKM_ENGINE_GR , gr);
_(NVKM_ENGINE_IFB , ifb);
_(NVKM_ENGINE_ME , me);
_(NVKM_ENGINE_MPEG , mpeg);
_(NVKM_ENGINE_MSENC , msenc);
_(NVKM_ENGINE_MSPDEC , mspdec);
_(NVKM_ENGINE_MSPPP , msppp);
_(NVKM_ENGINE_MSVLD , msvld);
_(NVKM_ENGINE_PM , pm);
_(NVKM_ENGINE_SEC , sec);
_(NVKM_ENGINE_SW , sw);
_(NVKM_ENGINE_VIC , vic);
_(NVKM_ENGINE_VP , vp);
_(NVKM_SUBDEV_BAR , bar);
_(NVKM_SUBDEV_VBIOS , bios);
_(NVKM_SUBDEV_BUS , bus);
_(NVKM_SUBDEV_CLK , clk);
_(NVKM_SUBDEV_DEVINIT , devinit);
_(NVKM_SUBDEV_FB , fb);
_(NVKM_SUBDEV_FUSE , fuse);
_(NVKM_SUBDEV_GPIO , gpio);
_(NVKM_SUBDEV_I2C , i2c);
_(NVKM_SUBDEV_IBUS , ibus);
_(NVKM_SUBDEV_ICCSENSE, iccsense);
_(NVKM_SUBDEV_INSTMEM , imem);
_(NVKM_SUBDEV_LTC , ltc);
_(NVKM_SUBDEV_MC , mc);
_(NVKM_SUBDEV_MMU , mmu);
_(NVKM_SUBDEV_MXM , mxm);
_(NVKM_SUBDEV_PCI , pci);
_(NVKM_SUBDEV_PMU , pmu);
_(NVKM_SUBDEV_SECBOOT , secboot);
_(NVKM_SUBDEV_THERM , therm);
_(NVKM_SUBDEV_TIMER , timer);
_(NVKM_SUBDEV_VOLT , volt);
_(NVKM_ENGINE_BSP , bsp);
_(NVKM_ENGINE_CE0 , ce[0]);
_(NVKM_ENGINE_CE1 , ce[1]);
_(NVKM_ENGINE_CE2 , ce[2]);
_(NVKM_ENGINE_CIPHER , cipher);
_(NVKM_ENGINE_DISP , disp);
_(NVKM_ENGINE_DMAOBJ , dma);
_(NVKM_ENGINE_FIFO , fifo);
_(NVKM_ENGINE_GR , gr);
_(NVKM_ENGINE_IFB , ifb);
_(NVKM_ENGINE_ME , me);
_(NVKM_ENGINE_MPEG , mpeg);
_(NVKM_ENGINE_MSENC , msenc);
_(NVKM_ENGINE_MSPDEC , mspdec);
_(NVKM_ENGINE_MSPPP , msppp);
_(NVKM_ENGINE_MSVLD , msvld);
_(NVKM_ENGINE_NVENC0 , nvenc[0]);
_(NVKM_ENGINE_NVENC1 , nvenc[1]);
_(NVKM_ENGINE_NVDEC , nvdec);
_(NVKM_ENGINE_PM , pm);
_(NVKM_ENGINE_SEC , sec);
_(NVKM_ENGINE_SW , sw);
_(NVKM_ENGINE_VIC , vic);
_(NVKM_ENGINE_VP , vp);
default:
WARN_ON(1);
continue;
......
......@@ -1614,7 +1614,7 @@ nvkm_device_pci_func = {
.fini = nvkm_device_pci_fini,
.resource_addr = nvkm_device_pci_resource_addr,
.resource_size = nvkm_device_pci_resource_size,
.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
.cpu_coherent = !IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64),
};
int
......
......@@ -12,6 +12,7 @@
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/ibus.h>
#include <subdev/iccsense.h>
#include <subdev/instmem.h>
#include <subdev/ltc.h>
#include <subdev/mc.h>
......@@ -22,6 +23,7 @@
#include <subdev/therm.h>
#include <subdev/timer.h>
#include <subdev/volt.h>
#include <subdev/secboot.h>
#include <engine/bsp.h>
#include <engine/ce.h>
......@@ -34,9 +36,12 @@
#include <engine/mspdec.h>
#include <engine/msppp.h>
#include <engine/msvld.h>
#include <engine/nvenc.h>
#include <engine/nvdec.h>
#include <engine/pm.h>
#include <engine/sec.h>
#include <engine/sw.h>
#include <engine/vic.h>
#include <engine/vp.h>
int nvkm_device_ctor(const struct nvkm_device_func *,
......
......@@ -255,7 +255,6 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
tdev->func = func;
tdev->pdev = pdev;
tdev->irq = -1;
tdev->vdd = devm_regulator_get(&pdev->dev, "vdd");
if (IS_ERR(tdev->vdd)) {
......@@ -281,6 +280,15 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
goto free;
}
/**
* The IOMMU bit defines the upper limit of the GPU-addressable space.
* This will be refined in nouveau_ttm_init but we need to do it early
* for instmem to behave properly
*/
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(tdev->func->iommu_bit));
if (ret)
goto free;
nvkm_device_tegra_probe_iommu(tdev);
ret = nvkm_device_tegra_power_up(tdev);
......
......@@ -9,7 +9,7 @@ nvkm-y += nvkm/engine/disp/gf119.o
nvkm-y += nvkm/engine/disp/gk104.o
nvkm-y += nvkm/engine/disp/gk110.o
nvkm-y += nvkm/engine/disp/gm107.o
nvkm-y += nvkm/engine/disp/gm204.o
nvkm-y += nvkm/engine/disp/gm200.o
nvkm-y += nvkm/engine/disp/outp.o
nvkm-y += nvkm/engine/disp/outpdp.o
......@@ -18,7 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o
nvkm-y += nvkm/engine/disp/sornv50.o
nvkm-y += nvkm/engine/disp/sorg94.o
nvkm-y += nvkm/engine/disp/sorgf119.o
nvkm-y += nvkm/engine/disp/sorgm204.o
nvkm-y += nvkm/engine/disp/sorgm200.o
nvkm-y += nvkm/engine/disp/dport.o
nvkm-y += nvkm/engine/disp/conn.o
......@@ -43,7 +43,7 @@ nvkm-y += nvkm/engine/disp/rootgf119.o
nvkm-y += nvkm/engine/disp/rootgk104.o
nvkm-y += nvkm/engine/disp/rootgk110.o
nvkm-y += nvkm/engine/disp/rootgm107.o
nvkm-y += nvkm/engine/disp/rootgm204.o
nvkm-y += nvkm/engine/disp/rootgm200.o
nvkm-y += nvkm/engine/disp/channv50.o
nvkm-y += nvkm/engine/disp/changf119.o
......@@ -68,7 +68,7 @@ nvkm-y += nvkm/engine/disp/coregf119.o
nvkm-y += nvkm/engine/disp/coregk104.o
nvkm-y += nvkm/engine/disp/coregk110.o
nvkm-y += nvkm/engine/disp/coregm107.o
nvkm-y += nvkm/engine/disp/coregm204.o
nvkm-y += nvkm/engine/disp/coregm200.o
nvkm-y += nvkm/engine/disp/ovlynv50.o
nvkm-y += nvkm/engine/disp/ovlyg84.o
......
......@@ -27,8 +27,8 @@
#include <nvif/class.h>
const struct nv50_disp_dmac_oclass
gm204_disp_core_oclass = {
.base.oclass = GM204_DISP_CORE_CHANNEL_DMA,
gm200_disp_core_oclass = {
.base.oclass = GM200_DISP_CORE_CHANNEL_DMA,
.base.minver = 0,
.base.maxver = 0,
.ctor = nv50_disp_core_new,
......
......@@ -87,5 +87,5 @@ extern const struct nv50_disp_dmac_oclass gk110_disp_base_oclass;
extern const struct nv50_disp_dmac_oclass gm107_disp_core_oclass;
extern const struct nv50_disp_dmac_oclass gm204_disp_core_oclass;
extern const struct nv50_disp_dmac_oclass gm200_disp_core_oclass;
#endif
......@@ -25,18 +25,18 @@
#include "rootnv50.h"
static const struct nv50_disp_func
gm204_disp = {
gm200_disp = {
.intr = gf119_disp_intr,
.uevent = &gf119_disp_chan_uevent,
.super = gf119_disp_intr_supervisor,
.root = &gm204_disp_root_oclass,
.root = &gm200_disp_root_oclass,
.head.vblank_init = gf119_disp_vblank_init,
.head.vblank_fini = gf119_disp_vblank_fini,
.head.scanoutpos = gf119_disp_root_scanoutpos,
.outp.internal.crt = nv50_dac_output_new,
.outp.internal.tmds = nv50_sor_output_new,
.outp.internal.lvds = nv50_sor_output_new,
.outp.internal.dp = gm204_sor_dp_new,
.outp.internal.dp = gm200_sor_dp_new,
.dac.nr = 3,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense,
......@@ -44,11 +44,11 @@ gm204_disp = {
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl,
.sor.magic = gm204_sor_magic,
.sor.magic = gm200_sor_magic,
};
int
gm204_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
gm200_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
{
return gf119_disp_new_(&gm204_disp, device, index, pdisp);
return gf119_disp_new_(&gm200_disp, device, index, pdisp);
}
......@@ -42,7 +42,7 @@ int nv50_pior_output_new(struct nvkm_disp *, int, struct dcb_output *,
u32 g94_sor_dp_lane_map(struct nvkm_device *, u8 lane);
void gm204_sor_magic(struct nvkm_output *outp);
void gm200_sor_magic(struct nvkm_output *outp);
#define OUTP_MSG(o,l,f,a...) do { \
struct nvkm_output *_outp = (o); \
......
......@@ -63,6 +63,6 @@ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
int gm204_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
#endif
......@@ -27,11 +27,11 @@
#include <nvif/class.h>
static const struct nv50_disp_root_func
gm204_disp_root = {
gm200_disp_root = {
.init = gf119_disp_root_init,
.fini = gf119_disp_root_fini,
.dmac = {
&gm204_disp_core_oclass,
&gm200_disp_core_oclass,
&gk110_disp_base_oclass,
&gk104_disp_ovly_oclass,
},
......@@ -42,17 +42,17 @@ gm204_disp_root = {
};
static int
gm204_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
gm200_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject)
{
return nv50_disp_root_new_(&gm204_disp_root, disp, oclass,
return nv50_disp_root_new_(&gm200_disp_root, disp, oclass,
data, size, pobject);
}
const struct nvkm_disp_oclass
gm204_disp_root_oclass = {
.base.oclass = GM204_DISP,
gm200_disp_root_oclass = {
.base.oclass = GM200_DISP,
.base.minver = -1,
.base.maxver = -1,
.ctor = gm204_disp_root_new,
.ctor = gm200_disp_root_new,
};
......@@ -39,5 +39,5 @@ extern const struct nvkm_disp_oclass gf119_disp_root_oclass;
extern const struct nvkm_disp_oclass gk104_disp_root_oclass;
extern const struct nvkm_disp_oclass gk110_disp_root_oclass;
extern const struct nvkm_disp_oclass gm107_disp_root_oclass;
extern const struct nvkm_disp_oclass gm204_disp_root_oclass;
extern const struct nvkm_disp_oclass gm200_disp_root_oclass;
#endif
......@@ -27,19 +27,19 @@
#include <subdev/timer.h>
static inline u32
gm204_sor_soff(struct nvkm_output_dp *outp)
gm200_sor_soff(struct nvkm_output_dp *outp)
{
return (ffs(outp->base.info.or) - 1) * 0x800;
}
static inline u32
gm204_sor_loff(struct nvkm_output_dp *outp)
gm200_sor_loff(struct nvkm_output_dp *outp)
{
return gm204_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
return gm200_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
}
void
gm204_sor_magic(struct nvkm_output *outp)
gm200_sor_magic(struct nvkm_output *outp)
{
struct nvkm_device *device = outp->disp->engine.subdev.device;
const u32 soff = outp->or * 0x100;
......@@ -51,16 +51,16 @@ gm204_sor_magic(struct nvkm_output *outp)
}
static inline u32
gm204_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
{
return lane * 0x08;
}
static int
gm204_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
{
struct nvkm_device *device = outp->base.disp->engine.subdev.device;
const u32 soff = gm204_sor_soff(outp);
const u32 soff = gm200_sor_soff(outp);
const u32 data = 0x01010101 * pattern;
if (outp->base.info.sorconf.link & 1)
nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
......@@ -70,15 +70,15 @@ gm204_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
}
static int
gm204_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
{
struct nvkm_device *device = outp->base.disp->engine.subdev.device;
const u32 soff = gm204_sor_soff(outp);
const u32 loff = gm204_sor_loff(outp);
const u32 soff = gm200_sor_soff(outp);
const u32 loff = gm200_sor_loff(outp);
u32 mask = 0, i;
for (i = 0; i < nr; i++)
mask |= 1 << (gm204_sor_dp_lane_map(device, i) >> 3);
mask |= 1 << (gm200_sor_dp_lane_map(device, i) >> 3);
nvkm_mask(device, 0x61c130 + loff, 0x0000000f, mask);
nvkm_mask(device, 0x61c034 + soff, 0x80000000, 0x80000000);
......@@ -90,13 +90,13 @@ gm204_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
}
static int
gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
int ln, int vs, int pe, int pc)
{
struct nvkm_device *device = outp->base.disp->engine.subdev.device;
struct nvkm_bios *bios = device->bios;
const u32 shift = gm204_sor_dp_lane_map(device, ln);
const u32 loff = gm204_sor_loff(outp);
const u32 shift = gm200_sor_dp_lane_map(device, ln);
const u32 loff = gm200_sor_loff(outp);
u32 addr, data[4];
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
......@@ -128,16 +128,16 @@ gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
}
static const struct nvkm_output_dp_func
gm204_sor_dp_func = {
.pattern = gm204_sor_dp_pattern,
.lnk_pwr = gm204_sor_dp_lnk_pwr,
gm200_sor_dp_func = {
.pattern = gm200_sor_dp_pattern,
.lnk_pwr = gm200_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gm204_sor_dp_drv_ctl,
.drv_ctl = gm200_sor_dp_drv_ctl,
};
int
gm204_sor_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
gm200_sor_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
struct nvkm_output **poutp)
{
return nvkm_output_dp_new_(&gm204_sor_dp_func, disp, index, dcbE, poutp);
return nvkm_output_dp_new_(&gm200_sor_dp_func, disp, index, dcbE, poutp);
}
......@@ -7,9 +7,11 @@ nvkm-y += nvkm/engine/fifo/nv50.o
nvkm-y += nvkm/engine/fifo/g84.o
nvkm-y += nvkm/engine/fifo/gf100.o
nvkm-y += nvkm/engine/fifo/gk104.o
nvkm-y += nvkm/engine/fifo/gk110.o
nvkm-y += nvkm/engine/fifo/gk208.o
nvkm-y += nvkm/engine/fifo/gk20a.o
nvkm-y += nvkm/engine/fifo/gm204.o
nvkm-y += nvkm/engine/fifo/gm107.o
nvkm-y += nvkm/engine/fifo/gm200.o
nvkm-y += nvkm/engine/fifo/gm20b.o
nvkm-y += nvkm/engine/fifo/chan.o
......@@ -27,4 +29,5 @@ nvkm-y += nvkm/engine/fifo/gpfifonv50.o
nvkm-y += nvkm/engine/fifo/gpfifog84.o
nvkm-y += nvkm/engine/fifo/gpfifogf100.o
nvkm-y += nvkm/engine/fifo/gpfifogk104.o
nvkm-y += nvkm/engine/fifo/gpfifogm204.o
nvkm-y += nvkm/engine/fifo/gpfifogk110.o
nvkm-y += nvkm/engine/fifo/gpfifogm200.o
......@@ -7,7 +7,7 @@
struct gk104_fifo_chan {
struct nvkm_fifo_chan base;
struct gk104_fifo *fifo;
int engine;
int runl;
struct list_head head;
bool killed;
......@@ -25,5 +25,6 @@ int gk104_fifo_gpfifo_new(struct nvkm_fifo *, const struct nvkm_oclass *,
void *data, u32 size, struct nvkm_object **);
extern const struct nvkm_fifo_chan_oclass gk104_fifo_gpfifo_oclass;
extern const struct nvkm_fifo_chan_oclass gm204_fifo_gpfifo_oclass;
extern const struct nvkm_fifo_chan_oclass gk110_fifo_gpfifo_oclass;
extern const struct nvkm_fifo_chan_oclass gm200_fifo_gpfifo_oclass;
#endif
......@@ -54,6 +54,7 @@ gf100_fifo_runlist_commit(struct gf100_fifo *fifo)
struct nvkm_device *device = subdev->device;
struct nvkm_memory *cur;
int nr = 0;
int target;
mutex_lock(&subdev->mutex);
cur = fifo->runlist.mem[fifo->runlist.active];
......@@ -67,7 +68,10 @@ gf100_fifo_runlist_commit(struct gf100_fifo *fifo)
}
nvkm_done(cur);
nvkm_wr32(device, 0x002270, nvkm_memory_addr(cur) >> 12);
target = (nvkm_memory_target(cur) == NVKM_MEM_TARGET_HOST) ? 0x3 : 0x0;
nvkm_wr32(device, 0x002270, (nvkm_memory_addr(cur) >> 12) |
(target << 28));
nvkm_wr32(device, 0x002274, 0x01f00000 | nr);
if (wait_event_timeout(fifo->runlist.wait,
......@@ -130,9 +134,9 @@ gf100_fifo_engine(struct gf100_fifo *fifo, u32 engn)
}
static void
gf100_fifo_recover_work(struct work_struct *work)
gf100_fifo_recover_work(struct work_struct *w)
{
struct gf100_fifo *fifo = container_of(work, typeof(*fifo), fault);
struct gf100_fifo *fifo = container_of(w, typeof(*fifo), recover.work);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_engine *engine;
unsigned long flags;
......@@ -140,15 +144,15 @@ gf100_fifo_recover_work(struct work_struct *work)
u64 mask, todo;
spin_lock_irqsave(&fifo->base.lock, flags);
mask = fifo->mask;
fifo->mask = 0ULL;
mask = fifo->recover.mask;
fifo->recover.mask = 0ULL;
spin_unlock_irqrestore(&fifo->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~BIT_ULL(engn))
engm |= 1 << gf100_fifo_engidx(fifo, engn);
nvkm_mask(device, 0x002630, engm, engm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~BIT_ULL(engn)) {
if ((engine = nvkm_device_engine(device, engn))) {
nvkm_subdev_fini(&engine->subdev, false);
WARN_ON(nvkm_subdev_init(&engine->subdev));
......@@ -176,8 +180,8 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
list_del_init(&chan->head);
chan->killed = true;
fifo->mask |= 1ULL << engine->subdev.index;
schedule_work(&fifo->fault);
fifo->recover.mask |= 1ULL << engine->subdev.index;
schedule_work(&fifo->recover.work);
}
static const struct nvkm_enum
......@@ -330,7 +334,7 @@ gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
}
if (eu) {
if (eu && eu->data2) {
switch (eu->data2) {
case NVKM_SUBDEV_BAR:
nvkm_mask(device, 0x001704, 0x00000000, 0x00000000);
......@@ -544,9 +548,16 @@ static int
gf100_fifo_oneinit(struct nvkm_fifo *base)
{
struct gf100_fifo *fifo = gf100_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
int ret;
/* Determine number of PBDMAs by checking valid enable bits. */
nvkm_wr32(device, 0x002204, 0xffffffff);
fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x002204));
nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr);
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000,
false, &fifo->runlist.mem[0]);
if (ret)
......@@ -576,25 +587,22 @@ static void
gf100_fifo_fini(struct nvkm_fifo *base)
{
struct gf100_fifo *fifo = gf100_fifo(base);
flush_work(&fifo->fault);
flush_work(&fifo->recover.work);
}
static void
gf100_fifo_init(struct nvkm_fifo *base)
{
struct gf100_fifo *fifo = gf100_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_device *device = fifo->base.engine.subdev.device;
int i;
nvkm_wr32(device, 0x000204, 0xffffffff);
nvkm_wr32(device, 0x002204, 0xffffffff);
fifo->spoon_nr = hweight32(nvkm_rd32(device, 0x002204));
nvkm_debug(subdev, "%d PBDMA unit(s)\n", fifo->spoon_nr);
/* Enable PBDMAs. */
nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1);
nvkm_wr32(device, 0x002204, (1 << fifo->pbdma_nr) - 1);
/* assign engines to PBDMAs */
if (fifo->spoon_nr >= 3) {
/* Assign engines to PBDMAs. */
if (fifo->pbdma_nr >= 3) {
nvkm_wr32(device, 0x002208, ~(1 << 0)); /* PGRAPH */
nvkm_wr32(device, 0x00220c, ~(1 << 1)); /* PVP */
nvkm_wr32(device, 0x002210, ~(1 << 1)); /* PMSPP */
......@@ -604,7 +612,7 @@ gf100_fifo_init(struct nvkm_fifo *base)
}
/* PBDMA[n] */
for (i = 0; i < fifo->spoon_nr; i++) {
for (i = 0; i < fifo->pbdma_nr; i++) {
nvkm_mask(device, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
nvkm_wr32(device, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
nvkm_wr32(device, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
......@@ -652,7 +660,7 @@ gf100_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
return -ENOMEM;
INIT_LIST_HEAD(&fifo->chan);
INIT_WORK(&fifo->fault, gf100_fifo_recover_work);
INIT_WORK(&fifo->recover.work, gf100_fifo_recover_work);
*pfifo = &fifo->base;
return nvkm_fifo_ctor(&gf100_fifo, device, index, 128, &fifo->base);
......
......@@ -11,8 +11,12 @@ struct gf100_fifo {
struct list_head chan;
struct work_struct fault;
u64 mask;
struct {
struct work_struct work;
u64 mask;
} recover;
int pbdma_nr;
struct {
struct nvkm_memory *mem[2];
......@@ -24,7 +28,6 @@ struct gf100_fifo {
struct nvkm_memory *mem;
struct nvkm_vma bar;
} user;
int spoon_nr;
};
void gf100_fifo_intr_engine(struct gf100_fifo *);
......
......@@ -47,34 +47,41 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
}
void
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, u32 engine)
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
{
struct gk104_fifo_engn *engn = &fifo->engine[engine];
struct gk104_fifo_chan *chan;
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_memory *cur;
struct nvkm_memory *mem;
int nr = 0;
int target;
mutex_lock(&subdev->mutex);
cur = engn->runlist[engn->cur_runlist];
engn->cur_runlist = !engn->cur_runlist;
mem = fifo->runlist[runl].mem[fifo->runlist[runl].next];
fifo->runlist[runl].next = !fifo->runlist[runl].next;
nvkm_kmap(cur);
list_for_each_entry(chan, &engn->chan, head) {
nvkm_wo32(cur, (nr * 8) + 0, chan->base.chid);
nvkm_wo32(cur, (nr * 8) + 4, 0x00000000);
nvkm_kmap(mem);
list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
nvkm_wo32(mem, (nr * 8) + 0, chan->base.chid);
nvkm_wo32(mem, (nr * 8) + 4, 0x00000000);
nr++;
}
nvkm_done(cur);
nvkm_wr32(device, 0x002270, nvkm_memory_addr(cur) >> 12);
nvkm_wr32(device, 0x002274, (engine << 20) | nr);
if (wait_event_timeout(engn->wait, !(nvkm_rd32(device, 0x002284 +
(engine * 0x08)) & 0x00100000),
msecs_to_jiffies(2000)) == 0)
nvkm_error(subdev, "runlist %d update timeout\n", engine);
nvkm_done(mem);
if (nvkm_memory_target(mem) == NVKM_MEM_TARGET_VRAM)
target = 0;
else
target = 3;
nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
(target << 28));
nvkm_wr32(device, 0x002274, (runl << 20) | nr);
if (wait_event_timeout(fifo->runlist[runl].wait,
!(nvkm_rd32(device, 0x002284 + (runl * 0x08))
& 0x00100000),
msecs_to_jiffies(2000)) == 0)
nvkm_error(subdev, "runlist %d update timeout\n", runl);
mutex_unlock(&subdev->mutex);
}
......@@ -90,58 +97,51 @@ void
gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan)
{
mutex_lock(&fifo->base.engine.subdev.mutex);
list_add_tail(&chan->head, &fifo->engine[chan->engine].chan);
list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan);
mutex_unlock(&fifo->base.engine.subdev.mutex);
}
static inline struct nvkm_engine *
gk104_fifo_engine(struct gk104_fifo *fifo, u32 engn)
{
struct nvkm_device *device = fifo->base.engine.subdev.device;
u64 subdevs = gk104_fifo_engine_subdev(engn);
if (subdevs)
return nvkm_device_engine(device, __ffs(subdevs));
return NULL;
}
static void
gk104_fifo_recover_work(struct work_struct *work)
gk104_fifo_recover_work(struct work_struct *w)
{
struct gk104_fifo *fifo = container_of(work, typeof(*fifo), fault);
struct gk104_fifo *fifo = container_of(w, typeof(*fifo), recover.work);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_engine *engine;
unsigned long flags;
u32 engn, engm = 0;
u64 mask, todo;
u32 engm, runm, todo;
int engn, runl;
spin_lock_irqsave(&fifo->base.lock, flags);
mask = fifo->mask;
fifo->mask = 0ULL;
runm = fifo->recover.runm;
engm = fifo->recover.engm;
fifo->recover.engm = 0;
fifo->recover.runm = 0;
spin_unlock_irqrestore(&fifo->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
engm |= 1 << gk104_fifo_subdev_engine(engn);
nvkm_mask(device, 0x002630, engm, engm);
nvkm_mask(device, 0x002630, runm, runm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
if ((engine = nvkm_device_engine(device, engn))) {
for (todo = engm; engn = __ffs(todo), todo; todo &= ~BIT(engn)) {
if ((engine = fifo->engine[engn].engine)) {
nvkm_subdev_fini(&engine->subdev, false);
WARN_ON(nvkm_subdev_init(&engine->subdev));
}
gk104_fifo_runlist_commit(fifo, gk104_fifo_subdev_engine(engn));
}
nvkm_wr32(device, 0x00262c, engm);
nvkm_mask(device, 0x002630, engm, 0x00000000);
for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
gk104_fifo_runlist_commit(fifo, runl);
nvkm_wr32(device, 0x00262c, runm);
nvkm_mask(device, 0x002630, runm, 0x00000000);
}
static void
gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
struct gk104_fifo_chan *chan)
struct gk104_fifo_chan *chan)
{
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
u32 chid = chan->base.chid;
int engn;
nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n",
nvkm_subdev_name[engine->subdev.index], chid);
......@@ -151,8 +151,15 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
list_del_init(&chan->head);
chan->killed = true;
fifo->mask |= 1ULL << engine->subdev.index;
schedule_work(&fifo->fault);
for (engn = 0; engn < fifo->engine_nr; engn++) {
if (fifo->engine[engn].engine == engine) {
fifo->recover.engm |= BIT(engn);
break;
}
}
fifo->recover.runm |= BIT(chan->runl);
schedule_work(&fifo->recover.work);
}
static const struct nvkm_enum
......@@ -189,32 +196,31 @@ static void
gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
{
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_engine *engine;
struct gk104_fifo_chan *chan;
unsigned long flags;
u32 engn;
spin_lock_irqsave(&fifo->base.lock, flags);
for (engn = 0; engn < ARRAY_SIZE(fifo->engine); engn++) {
for (engn = 0; engn < fifo->engine_nr; engn++) {
struct nvkm_engine *engine = fifo->engine[engn].engine;
int runl = fifo->engine[engn].runl;
u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
u32 busy = (stat & 0x80000000);
u32 next = (stat & 0x07ff0000) >> 16;
u32 next = (stat & 0x0fff0000) >> 16;
u32 chsw = (stat & 0x00008000);
u32 save = (stat & 0x00004000);
u32 load = (stat & 0x00002000);
u32 prev = (stat & 0x000007ff);
u32 prev = (stat & 0x00000fff);
u32 chid = load ? next : prev;
(void)save;
if (busy && chsw) {
list_for_each_entry(chan, &fifo->engine[engn].chan, head) {
if (chan->base.chid == chid) {
engine = gk104_fifo_engine(fifo, engn);
if (!engine)
break;
gk104_fifo_recover(fifo, engine, chan);
break;
}
if (!busy || !chsw)
continue;
list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
if (chan->base.chid == chid && engine) {
gk104_fifo_recover(fifo, engine, chan);
break;
}
}
}
......@@ -395,7 +401,7 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
}
if (eu) {
if (eu && eu->data2) {
switch (eu->data2) {
case NVKM_SUBDEV_BAR:
nvkm_mask(device, 0x001704, 0x00000000, 0x00000000);
......@@ -484,9 +490,10 @@ gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit)
if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data))
show &= ~0x00800000;
}
nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008);
}
nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008);
if (show) {
nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_0, show);
chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags);
......@@ -537,10 +544,10 @@ gk104_fifo_intr_runlist(struct gk104_fifo *fifo)
struct nvkm_device *device = fifo->base.engine.subdev.device;
u32 mask = nvkm_rd32(device, 0x002a00);
while (mask) {
u32 engn = __ffs(mask);
wake_up(&fifo->engine[engn].wait);
nvkm_wr32(device, 0x002a00, 1 << engn);
mask &= ~(1 << engn);
int runl = __ffs(mask);
wake_up(&fifo->runlist[runl].wait);
nvkm_wr32(device, 0x002a00, 1 << runl);
mask &= ~(1 << runl);
}
}
......@@ -647,7 +654,7 @@ gk104_fifo_fini(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
flush_work(&fifo->fault);
flush_work(&fifo->recover.work);
/* allow mmu fault interrupts, even when we're not using fifo */
nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
}
......@@ -656,24 +663,122 @@ int
gk104_fifo_oneinit(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
int ret, i;
u32 *map;
/* Determine number of PBDMAs by checking valid enable bits. */
nvkm_wr32(device, 0x000204, 0xffffffff);
fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x000204));
nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr);
/* Read PBDMA->runlist(s) mapping from HW. */
if (!(map = kzalloc(sizeof(*map) * fifo->pbdma_nr, GFP_KERNEL)))
return -ENOMEM;
for (i = 0; i < fifo->pbdma_nr; i++)
map[i] = nvkm_rd32(device, 0x002390 + (i * 0x04));
/* Read device topology from HW. */
for (i = 0; i < 64; i++) {
int type = -1, pbid = -1, engidx = -1;
int engn = -1, runl = -1, intr = -1, mcen = -1;
int fault = -1, j;
u32 data, addr = 0;
do {
data = nvkm_rd32(device, 0x022700 + (i * 0x04));
nvkm_trace(subdev, "%02x: %08x\n", i, data);
switch (data & 0x00000003) {
case 0x00000000: /* NOT_VALID */
continue;
case 0x00000001: /* DATA */
addr = (data & 0x00fff000);
fault = (data & 0x000000f8) >> 3;
break;
case 0x00000002: /* ENUM */
if (data & 0x00000020)
engn = (data & 0x3c000000) >> 26;
if (data & 0x00000010)
runl = (data & 0x01e00000) >> 21;
if (data & 0x00000008)
intr = (data & 0x000f8000) >> 15;
if (data & 0x00000004)
mcen = (data & 0x00003e00) >> 9;
break;
case 0x00000003: /* ENGINE_TYPE */
type = (data & 0x7ffffffc) >> 2;
break;
}
} while ((data & 0x80000000) && ++i < 64);
if (!data)
continue;
/* Determine which PBDMA handles requests for this engine. */
for (j = 0; runl >= 0 && j < fifo->pbdma_nr; j++) {
if (map[j] & (1 << runl)) {
pbid = j;
break;
}
}
/* Translate engine type to NVKM engine identifier. */
switch (type) {
case 0x00000000: engidx = NVKM_ENGINE_GR; break;
case 0x00000001: engidx = NVKM_ENGINE_CE0; break;
case 0x00000002: engidx = NVKM_ENGINE_CE1; break;
case 0x00000003: engidx = NVKM_ENGINE_CE2; break;
case 0x00000008: engidx = NVKM_ENGINE_MSPDEC; break;
case 0x00000009: engidx = NVKM_ENGINE_MSPPP; break;
case 0x0000000a: engidx = NVKM_ENGINE_MSVLD; break;
case 0x0000000b: engidx = NVKM_ENGINE_MSENC; break;
case 0x0000000c: engidx = NVKM_ENGINE_VIC; break;
case 0x0000000d: engidx = NVKM_ENGINE_SEC; break;
case 0x0000000e: engidx = NVKM_ENGINE_NVENC0; break;
case 0x0000000f: engidx = NVKM_ENGINE_NVENC1; break;
case 0x00000010: engidx = NVKM_ENGINE_NVDEC; break;
break;
default:
break;
}
nvkm_debug(subdev, "%02x (%8s): engine %2d runlist %2d "
"pbdma %2d intr %2d reset %2d "
"fault %2d addr %06x\n", type,
engidx < 0 ? NULL : nvkm_subdev_name[engidx],
engn, runl, pbid, intr, mcen, fault, addr);
/* Mark the engine as supported if everything checks out. */
if (engn >= 0 && runl >= 0) {
fifo->engine[engn].engine = engidx < 0 ? NULL :
nvkm_device_engine(device, engidx);
fifo->engine[engn].runl = runl;
fifo->engine[engn].pbid = pbid;
fifo->engine_nr = max(fifo->engine_nr, engn + 1);
fifo->runlist[runl].engm |= 1 << engn;
fifo->runlist_nr = max(fifo->runlist_nr, runl + 1);
}
}
for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) {
kfree(map);
for (i = 0; i < fifo->runlist_nr; i++) {
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
0x8000, 0x1000, false,
&fifo->engine[i].runlist[0]);
&fifo->runlist[i].mem[0]);
if (ret)
return ret;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
0x8000, 0x1000, false,
&fifo->engine[i].runlist[1]);
&fifo->runlist[i].mem[1]);
if (ret)
return ret;
init_waitqueue_head(&fifo->engine[i].wait);
INIT_LIST_HEAD(&fifo->engine[i].chan);
init_waitqueue_head(&fifo->runlist[i].wait);
INIT_LIST_HEAD(&fifo->runlist[i].chan);
}
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
......@@ -695,24 +800,21 @@ void
gk104_fifo_init(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_device *device = fifo->base.engine.subdev.device;
int i;
/* enable all available PBDMA units */
nvkm_wr32(device, 0x000204, 0xffffffff);
fifo->spoon_nr = hweight32(nvkm_rd32(device, 0x000204));
nvkm_debug(subdev, "%d PBDMA unit(s)\n", fifo->spoon_nr);
/* Enable PBDMAs. */
nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1);
/* PBDMA[n] */
for (i = 0; i < fifo->spoon_nr; i++) {
for (i = 0; i < fifo->pbdma_nr; i++) {
nvkm_mask(device, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
nvkm_wr32(device, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
nvkm_wr32(device, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
}
/* PBDMA[n].HCE */
for (i = 0; i < fifo->spoon_nr; i++) {
for (i = 0; i < fifo->pbdma_nr; i++) {
nvkm_wr32(device, 0x040148 + (i * 0x2000), 0xffffffff); /* INTR */
nvkm_wr32(device, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */
}
......@@ -732,9 +834,9 @@ gk104_fifo_dtor(struct nvkm_fifo *base)
nvkm_vm_put(&fifo->user.bar);
nvkm_memory_del(&fifo->user.mem);
for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) {
nvkm_memory_del(&fifo->engine[i].runlist[1]);
nvkm_memory_del(&fifo->engine[i].runlist[0]);
for (i = 0; i < fifo->runlist_nr; i++) {
nvkm_memory_del(&fifo->runlist[i].mem[1]);
nvkm_memory_del(&fifo->runlist[i].mem[0]);
}
return fifo;
......@@ -748,7 +850,7 @@ gk104_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
return -ENOMEM;
INIT_WORK(&fifo->fault, gk104_fifo_recover_work);
INIT_WORK(&fifo->recover.work, gk104_fifo_recover_work);
*pfifo = &fifo->base;
return nvkm_fifo_ctor(func, device, index, nr, &fifo->base);
......
......@@ -6,25 +6,37 @@
#include <subdev/mmu.h>
struct gk104_fifo_chan;
struct gk104_fifo_engn {
struct nvkm_memory *runlist[2];
int cur_runlist;
wait_queue_head_t wait;
struct list_head chan;
};
struct gk104_fifo {
struct nvkm_fifo base;
struct work_struct fault;
u64 mask;
struct {
struct work_struct work;
u32 engm;
u32 runm;
} recover;
int pbdma_nr;
struct {
struct nvkm_engine *engine;
int runl;
int pbid;
} engine[16];
int engine_nr;
struct {
struct nvkm_memory *mem[2];
int next;
wait_queue_head_t wait;
struct list_head chan;
u32 engm;
} runlist[16];
int runlist_nr;
struct gk104_fifo_engn engine[7];
struct {
struct nvkm_memory *mem;
struct nvkm_vma bar;
} user;
int spoon_nr;
};
int gk104_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *,
......@@ -38,7 +50,7 @@ void gk104_fifo_uevent_init(struct nvkm_fifo *);
void gk104_fifo_uevent_fini(struct nvkm_fifo *);
void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_commit(struct gk104_fifo *, u32 engine);
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl);
static inline u64
gk104_fifo_engine_subdev(int engine)
......@@ -58,23 +70,4 @@ gk104_fifo_engine_subdev(int engine)
return 0;
}
}
static inline int
gk104_fifo_subdev_engine(int subdev)
{
switch (subdev) {
case NVKM_ENGINE_GR:
case NVKM_ENGINE_SW:
case NVKM_ENGINE_CE2 : return 0;
case NVKM_ENGINE_MSPDEC: return 1;
case NVKM_ENGINE_MSPPP : return 2;
case NVKM_ENGINE_MSVLD : return 3;
case NVKM_ENGINE_CE0 : return 4;
case NVKM_ENGINE_CE1 : return 5;
case NVKM_ENGINE_MSENC : return 6;
default:
WARN_ON(1);
return 0;
}
}
#endif
/*
* Copyright 2016 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "gk104.h"
#include "changk104.h"
static const struct nvkm_fifo_func
gk110_fifo = {
.dtor = gk104_fifo_dtor,
.oneinit = gk104_fifo_oneinit,
.init = gk104_fifo_init,
.fini = gk104_fifo_fini,
.intr = gk104_fifo_intr,
.uevent_init = gk104_fifo_uevent_init,
.uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gk110_fifo_gpfifo_oclass,
NULL
},
};
int
gk110_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
return gk104_fifo_new_(&gk110_fifo, device, index, 4096, pfifo);
}
/*
* Copyright 2016 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "gk104.h"
#include "changk104.h"
static const struct nvkm_fifo_func
gm107_fifo = {
.dtor = gk104_fifo_dtor,
.oneinit = gk104_fifo_oneinit,
.init = gk104_fifo_init,
.fini = gk104_fifo_fini,
.intr = gk104_fifo_intr,
.uevent_init = gk104_fifo_uevent_init,
.uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gk110_fifo_gpfifo_oclass,
NULL
},
};
int
gm107_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
return gk104_fifo_new_(&gm107_fifo, device, index, 2048, pfifo);
}
......@@ -25,7 +25,7 @@
#include "changk104.h"
static const struct nvkm_fifo_func
gm204_fifo = {
gm200_fifo = {
.dtor = gk104_fifo_dtor,
.oneinit = gk104_fifo_oneinit,
.init = gk104_fifo_init,
......@@ -34,13 +34,13 @@ gm204_fifo = {
.uevent_init = gk104_fifo_uevent_init,
.uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gm204_fifo_gpfifo_oclass,
&gm200_fifo_gpfifo_oclass,
NULL
},
};
int
gm204_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
gm200_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
return gk104_fifo_new_(&gm204_fifo, device, index, 4096, pfifo);
return gk104_fifo_new_(&gm200_fifo, device, index, 4096, pfifo);
}
......@@ -32,7 +32,7 @@ gm20b_fifo = {
.uevent_init = gk104_fifo_uevent_init,
.uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gm204_fifo_gpfifo_oclass,
&gm200_fifo_gpfifo_oclass,
NULL
},
};
......
......@@ -63,9 +63,15 @@ gk104_fifo_gpfifo_engine_addr(struct nvkm_engine *engine)
case NVKM_ENGINE_CE1 :
case NVKM_ENGINE_CE2 : return 0x0000;
case NVKM_ENGINE_GR : return 0x0210;
case NVKM_ENGINE_SEC : return 0x0220;
case NVKM_ENGINE_MSPDEC: return 0x0250;
case NVKM_ENGINE_MSPPP : return 0x0260;
case NVKM_ENGINE_MSVLD : return 0x0270;
case NVKM_ENGINE_VIC : return 0x0280;
case NVKM_ENGINE_MSENC : return 0x0290;
case NVKM_ENGINE_NVDEC : return 0x02100270;
case NVKM_ENGINE_NVENC0: return 0x02100290;
case NVKM_ENGINE_NVENC1: return 0x0210;
default:
WARN_ON(1);
return 0;
......@@ -76,9 +82,9 @@ static int
gk104_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
struct nvkm_engine *engine, bool suspend)
{
const u32 offset = gk104_fifo_gpfifo_engine_addr(engine);
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
struct nvkm_gpuobj *inst = chan->base.inst;
u32 offset = gk104_fifo_gpfifo_engine_addr(engine);
int ret;
ret = gk104_fifo_gpfifo_kick(chan);
......@@ -87,8 +93,12 @@ gk104_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
if (offset) {
nvkm_kmap(inst);
nvkm_wo32(inst, offset + 0x00, 0x00000000);
nvkm_wo32(inst, offset + 0x04, 0x00000000);
nvkm_wo32(inst, (offset & 0xffff) + 0x00, 0x00000000);
nvkm_wo32(inst, (offset & 0xffff) + 0x04, 0x00000000);
if ((offset >>= 16)) {
nvkm_wo32(inst, offset + 0x00, 0x00000000);
nvkm_wo32(inst, offset + 0x04, 0x00000000);
}
nvkm_done(inst);
}
......@@ -99,15 +109,21 @@ static int
gk104_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
struct nvkm_engine *engine)
{
const u32 offset = gk104_fifo_gpfifo_engine_addr(engine);
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
struct nvkm_gpuobj *inst = chan->base.inst;
u32 offset = gk104_fifo_gpfifo_engine_addr(engine);
if (offset) {
u64 addr = chan->engn[engine->subdev.index].vma.offset;
u64 addr = chan->engn[engine->subdev.index].vma.offset;
u32 datalo = lower_32_bits(addr) | 0x00000004;
u32 datahi = upper_32_bits(addr);
nvkm_kmap(inst);
nvkm_wo32(inst, offset + 0x00, lower_32_bits(addr) | 4);
nvkm_wo32(inst, offset + 0x04, upper_32_bits(addr));
nvkm_wo32(inst, (offset & 0xffff) + 0x00, datalo);
nvkm_wo32(inst, (offset & 0xffff) + 0x04, datahi);
if ((offset >>= 16)) {
nvkm_wo32(inst, offset + 0x00, datalo);
nvkm_wo32(inst, offset + 0x04, datahi);
}
nvkm_done(inst);
}
......@@ -154,7 +170,8 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
if (!list_empty(&chan->head)) {
gk104_fifo_runlist_remove(fifo, chan);
nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800);
gk104_fifo_runlist_commit(fifo, chan->engine);
gk104_fifo_gpfifo_kick(chan);
gk104_fifo_runlist_commit(fifo, chan->runl);
}
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
......@@ -169,13 +186,13 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
u32 addr = chan->base.inst->addr >> 12;
u32 coff = chan->base.chid * 8;
nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->engine << 16);
nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->runl << 16);
nvkm_wr32(device, 0x800000 + coff, 0x80000000 | addr);
if (list_empty(&chan->head) && !chan->killed) {
gk104_fifo_runlist_insert(fifo, chan);
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
gk104_fifo_runlist_commit(fifo, chan->engine);
gk104_fifo_runlist_commit(fifo, chan->runl);
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
}
}
......@@ -201,73 +218,79 @@ gk104_fifo_gpfifo_func = {
.engine_fini = gk104_fifo_gpfifo_engine_fini,
};
int
gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject)
struct gk104_fifo_chan_func {
u32 engine;
u64 subdev;
};
static int
gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func,
struct gk104_fifo *fifo, u32 *engmask, u16 *chid,
u64 vm, u64 ioffset, u64 ilength,
const struct nvkm_oclass *oclass,
struct nvkm_object **pobject)
{
union {
struct kepler_channel_gpfifo_a_v0 v0;
} *args = data;
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_object *parent = oclass->parent;
struct gk104_fifo_chan *chan;
u64 usermem, ioffset, ilength;
u32 engines;
int ret = -ENOSYS, i;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"ioffset %016llx ilength %08x engine %08x\n",
args->v0.version, args->v0.vm, args->v0.ioffset,
args->v0.ilength, args->v0.engine);
} else
return ret;
/* determine which downstream engines are present */
for (i = 0, engines = 0; i < ARRAY_SIZE(fifo->engine); i++) {
u64 subdevs = gk104_fifo_engine_subdev(i);
if (!nvkm_device_engine(device, __ffs64(subdevs)))
continue;
engines |= (1 << i);
int runlist = -1, ret = -ENOSYS, i, j;
u32 engines = 0, present = 0;
u64 subdevs = 0;
u64 usermem;
/* Determine which downstream engines are present */
for (i = 0; i < fifo->engine_nr; i++) {
struct nvkm_engine *engine = fifo->engine[i].engine;
if (engine) {
u64 submask = BIT_ULL(engine->subdev.index);
for (j = 0; func[j].subdev; j++) {
if (func[j].subdev & submask) {
present |= func[j].engine;
break;
}
}
if (!func[j].subdev)
continue;
if (runlist < 0 && (*engmask & present))
runlist = fifo->engine[i].runl;
if (runlist == fifo->engine[i].runl) {
engines |= func[j].engine;
subdevs |= func[j].subdev;
}
}
}
/* if this is an engine mask query, we're done */
if (!args->v0.engine) {
args->v0.engine = engines;
/* Just an engine mask query? All done here! */
if (!*engmask) {
*engmask = present;
return nvkm_object_new(oclass, NULL, 0, pobject);
}
/* check that we support a requested engine - note that the user
* argument is a mask in order to allow the user to request (for
* example) *any* copy engine, but doesn't matter which.
*/
args->v0.engine &= engines;
if (!args->v0.engine) {
nvif_ioctl(parent, "no supported engine\n");
/* No runlist? No supported engines. */
*engmask = present;
if (runlist < 0)
return -ENODEV;
}
*engmask = engines;
/* allocate the channel */
/* Allocate the channel. */
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
chan->fifo = fifo;
chan->engine = __ffs(args->v0.engine);
chan->runl = runlist;
INIT_LIST_HEAD(&chan->head);
ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base,
0x1000, 0x1000, true, args->v0.vm, 0,
gk104_fifo_engine_subdev(chan->engine),
0x1000, 0x1000, true, vm, 0, subdevs,
1, fifo->user.bar.offset, 0x200,
oclass, &chan->base);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
*chid = chan->base.chid;
/* page directory */
/* Page directory. */
ret = nvkm_gpuobj_new(device, 0x10000, 0x1000, false, NULL, &chan->pgd);
if (ret)
return ret;
......@@ -283,10 +306,9 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
if (ret)
return ret;
/* clear channel control registers */
/* Clear channel control registers. */
usermem = chan->base.chid * 0x200;
ioffset = args->v0.ioffset;
ilength = order_base_2(args->v0.ilength / 8);
ilength = order_base_2(ilength / 8);
nvkm_kmap(fifo->user.mem);
for (i = 0; i < 0x200; i += 4)
......@@ -315,6 +337,56 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
return 0;
}
static const struct gk104_fifo_chan_func
gk104_fifo_gpfifo[] = {
{ NVA06F_V0_ENGINE_SW | NVA06F_V0_ENGINE_GR,
BIT_ULL(NVKM_ENGINE_SW) | BIT_ULL(NVKM_ENGINE_GR)
},
{ NVA06F_V0_ENGINE_SEC , BIT_ULL(NVKM_ENGINE_SEC ) },
{ NVA06F_V0_ENGINE_MSVLD , BIT_ULL(NVKM_ENGINE_MSVLD ) },
{ NVA06F_V0_ENGINE_MSPDEC, BIT_ULL(NVKM_ENGINE_MSPDEC) },
{ NVA06F_V0_ENGINE_MSPPP , BIT_ULL(NVKM_ENGINE_MSPPP ) },
{ NVA06F_V0_ENGINE_MSENC , BIT_ULL(NVKM_ENGINE_MSENC ) },
{ NVA06F_V0_ENGINE_VIC , BIT_ULL(NVKM_ENGINE_VIC ) },
{ NVA06F_V0_ENGINE_NVDEC , BIT_ULL(NVKM_ENGINE_NVDEC ) },
{ NVA06F_V0_ENGINE_NVENC0, BIT_ULL(NVKM_ENGINE_NVENC0) },
{ NVA06F_V0_ENGINE_NVENC1, BIT_ULL(NVKM_ENGINE_NVENC1) },
{ NVA06F_V0_ENGINE_CE0 , BIT_ULL(NVKM_ENGINE_CE0 ) },
{ NVA06F_V0_ENGINE_CE1 , BIT_ULL(NVKM_ENGINE_CE1 ) },
{ NVA06F_V0_ENGINE_CE2 , BIT_ULL(NVKM_ENGINE_CE2 ) },
{}
};
int
gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject)
{
struct nvkm_object *parent = oclass->parent;
union {
struct kepler_channel_gpfifo_a_v0 v0;
} *args = data;
struct gk104_fifo *fifo = gk104_fifo(base);
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"ioffset %016llx ilength %08x engine %08x\n",
args->v0.version, args->v0.vm, args->v0.ioffset,
args->v0.ilength, args->v0.engines);
return gk104_fifo_gpfifo_new_(gk104_fifo_gpfifo, fifo,
&args->v0.engines,
&args->v0.chid,
args->v0.vm,
args->v0.ioffset,
args->v0.ilength,
oclass, pobject);
}
return ret;
}
const struct nvkm_fifo_chan_oclass
gk104_fifo_gpfifo_oclass = {
.base.oclass = KEPLER_CHANNEL_GPFIFO_A,
......
/*
* Copyright 2016 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "changk104.h"
#include <nvif/class.h>
const struct nvkm_fifo_chan_oclass
gk110_fifo_gpfifo_oclass = {
.base.oclass = KEPLER_CHANNEL_GPFIFO_B,
.base.minver = 0,
.base.maxver = 0,
.ctor = gk104_fifo_gpfifo_new,
};
......@@ -26,7 +26,7 @@
#include <nvif/class.h>
const struct nvkm_fifo_chan_oclass
gm204_fifo_gpfifo_oclass = {
gm200_fifo_gpfifo_oclass = {
.base.oclass = MAXWELL_CHANNEL_GPFIFO_A,
.base.minver = 0,
.base.maxver = 0,
......
......@@ -29,8 +29,7 @@ nvkm-y += nvkm/engine/gr/gk110b.o
nvkm-y += nvkm/engine/gr/gk208.o
nvkm-y += nvkm/engine/gr/gk20a.o
nvkm-y += nvkm/engine/gr/gm107.o
nvkm-y += nvkm/engine/gr/gm204.o
nvkm-y += nvkm/engine/gr/gm206.o
nvkm-y += nvkm/engine/gr/gm200.o
nvkm-y += nvkm/engine/gr/gm20b.o
nvkm-y += nvkm/engine/gr/ctxnv40.o
......@@ -47,6 +46,5 @@ nvkm-y += nvkm/engine/gr/ctxgk110b.o
nvkm-y += nvkm/engine/gr/ctxgk208.o
nvkm-y += nvkm/engine/gr/ctxgk20a.o
nvkm-y += nvkm/engine/gr/ctxgm107.o
nvkm-y += nvkm/engine/gr/ctxgm204.o
nvkm-y += nvkm/engine/gr/ctxgm206.o
nvkm-y += nvkm/engine/gr/ctxgm200.o
nvkm-y += nvkm/engine/gr/ctxgm20b.o
......@@ -97,12 +97,11 @@ void gm107_grctx_generate_bundle(struct gf100_grctx *);
void gm107_grctx_generate_pagepool(struct gf100_grctx *);
void gm107_grctx_generate_attrib(struct gf100_grctx *);
extern const struct gf100_grctx_func gm204_grctx;
void gm204_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *);
void gm204_grctx_generate_tpcid(struct gf100_gr *);
void gm204_grctx_generate_405b60(struct gf100_gr *);
extern const struct gf100_grctx_func gm200_grctx;
void gm200_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *);
void gm200_grctx_generate_tpcid(struct gf100_gr *);
void gm200_grctx_generate_405b60(struct gf100_gr *);
extern const struct gf100_grctx_func gm206_grctx;
extern const struct gf100_grctx_func gm20b_grctx;
/* context init value lists */
......@@ -210,19 +209,4 @@ extern const struct gf100_gr_init gk208_grctx_init_crstr_0[];
extern const struct gf100_gr_init gm107_grctx_init_gpc_unk_0[];
extern const struct gf100_gr_init gm107_grctx_init_wwdx_0[];
extern const struct gf100_gr_pack gm204_grctx_pack_icmd[];
extern const struct gf100_gr_pack gm204_grctx_pack_mthd[];
extern const struct gf100_gr_pack gm204_grctx_pack_hub[];
extern const struct gf100_gr_init gm204_grctx_init_prop_0[];
extern const struct gf100_gr_init gm204_grctx_init_setup_0[];
extern const struct gf100_gr_init gm204_grctx_init_gpm_0[];
extern const struct gf100_gr_init gm204_grctx_init_gpc_unk_2[];
extern const struct gf100_gr_pack gm204_grctx_pack_tpc[];
extern const struct gf100_gr_pack gm204_grctx_pack_ppc[];
#endif
......@@ -23,43 +23,116 @@
*/
#include "ctxgf100.h"
static const struct gf100_gr_init
gm206_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000007f },
{ 0x418684, 1, 0x04, 0x0000001f },
{ 0x418700, 1, 0x04, 0x00000002 },
{ 0x418704, 1, 0x04, 0x00000080 },
{ 0x418708, 1, 0x04, 0x40000000 },
{ 0x41870c, 2, 0x04, 0x00000000 },
{ 0x418728, 1, 0x04, 0x00300020 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
static const struct gf100_gr_pack
gm206_grctx_pack_gpc[] = {
{ gm107_grctx_init_gpc_unk_0 },
{ gm204_grctx_init_prop_0 },
{ gm206_grctx_init_gpc_unk_1 },
{ gm204_grctx_init_setup_0 },
{ gf100_grctx_init_zcull_0 },
{ gk208_grctx_init_crstr_0 },
{ gm204_grctx_init_gpm_0 },
{ gm204_grctx_init_gpc_unk_2 },
{ gf100_grctx_init_gcc_0 },
{}
};
void
gm200_grctx_generate_tpcid(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
int gpc, tpc, id;
for (tpc = 0, id = 0; tpc < 4; tpc++) {
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
if (tpc < gr->tpc_nr[gpc]) {
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), id);
id++;
}
}
}
}
static void
gm200_grctx_generate_rop_active_fbps(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 fbp_count = nvkm_rd32(device, 0x12006c);
nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
}
void
gm200_grctx_generate_405b60(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 dist_nr = DIV_ROUND_UP(gr->tpc_total, 4);
u32 dist[TPC_MAX / 4] = {};
u32 gpcs[GPC_MAX] = {};
u8 tpcnr[GPC_MAX];
int tpc, gpc, i;
memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr));
/* won't result in the same distribution as the binary driver where
* some of the gpcs have more tpcs than others, but this shall do
* for the moment. the code for earlier gpus has this issue too.
*/
for (gpc = -1, i = 0; i < gr->tpc_total; i++) {
do {
gpc = (gpc + 1) % gr->gpc_nr;
} while(!tpcnr[gpc]);
tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--;
dist[i / 4] |= ((gpc << 4) | tpc) << ((i % 4) * 8);
gpcs[gpc] |= i << (tpc * 8);
}
for (i = 0; i < dist_nr; i++)
nvkm_wr32(device, 0x405b60 + (i * 4), dist[i]);
for (i = 0; i < gr->gpc_nr; i++)
nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]);
}
void
gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
u32 tmp;
int i;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
nvkm_wr32(device, 0x404154, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
grctx->attrib(info);
grctx->unkn(gr);
gm200_grctx_generate_tpcid(gr);
gf100_grctx_generate_r406028(gr);
gk104_grctx_generate_r418bb8(gr);
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x406500, 0x00000000);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
gm200_grctx_generate_rop_active_fbps(gr);
for (tmp = 0, i = 0; i < gr->gpc_nr; i++)
tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4);
nvkm_wr32(device, 0x4041c4, tmp);
gm200_grctx_generate_405b60(gr);
gf100_gr_icmd(gr, gr->fuc_bundle);
nvkm_wr32(device, 0x404154, 0x00000800);
gf100_gr_mthd(gr, gr->fuc_method);
nvkm_mask(device, 0x418e94, 0xffffffff, 0xc4230000);
nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000);
}
const struct gf100_grctx_func
gm206_grctx = {
.main = gm204_grctx_generate_main,
gm200_grctx = {
.main = gm200_grctx_generate_main,
.unkn = gk104_grctx_generate_unkn,
.hub = gm204_grctx_pack_hub,
.gpc = gm206_grctx_pack_gpc,
.zcull = gf100_grctx_pack_zcull,
.tpc = gm204_grctx_pack_tpc,
.ppc = gm204_grctx_pack_ppc,
.icmd = gm204_grctx_pack_icmd,
.mthd = gm204_grctx_pack_mthd,
.bundle = gm107_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0x180,
......
......@@ -54,7 +54,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
grctx->unkn(gr);
gm204_grctx_generate_tpcid(gr);
gm200_grctx_generate_tpcid(gr);
gm20b_grctx_generate_r406028(gr);
gk104_grctx_generate_r418bb8(gr);
......@@ -70,7 +70,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4);
nvkm_wr32(device, 0x4041c4, tmp);
gm204_grctx_generate_405b60(gr);
gm200_grctx_generate_405b60(gr);
gf100_gr_wait_idle(gr);
......
......@@ -322,6 +322,7 @@ main:
// interrupt handler
ih:
push $r0
push $r8
mov $r8 $flags
push $r8
......@@ -358,6 +359,7 @@ ih:
pop $r8
mov $flags $r8
pop $r8
pop $r0
bclr $flags $p0
iret
......
......@@ -382,56 +382,57 @@ uint32_t gf100_grgpc_code[] = {
0xb60412fd,
0x1efd01e4,
0x0018fe05,
0x05b021f5,
0x05b421f5,
/* 0x04eb: main_not_ctx_xfer */
0x94d30ef4,
0xf5f010ef,
0x7e21f501,
0xc60ef403,
/* 0x04f8: ih */
0x88fe80f9,
0xf980f901,
0xf9a0f990,
0xf9d0f9b0,
0xbdf0f9e0,
0x00a7f104,
0x00a3f002,
0xc400aacf,
0x0bf404ab,
0x1cd7f02c,
0x1a00e7f1,
0xcf00e3f0,
0xf7f100ee,
0xf3f01900,
0x00ffcf00,
0xf00421f4,
0x07f101e7,
0x03f01d00,
0x000ed000,
/* 0x0546: ih_no_fifo */
0x07f104bd,
0x03f00100,
0x000ad000,
0xf0fc04bd,
0xd0fce0fc,
0xa0fcb0fc,
0x80fc90fc,
0xfc0088fe,
0x0032f480,
/* 0x056a: hub_barrier_done */
0x80f900f9,
0xf90188fe,
0xf990f980,
0xf9b0f9a0,
0xf9e0f9d0,
0xf104bdf0,
0xf00200a7,
0xaacf00a3,
0x04abc400,
0xf02c0bf4,
0xe7f11cd7,
0xe3f01a00,
0x00eecf00,
0x1900f7f1,
0xcf00f3f0,
0x21f400ff,
0x01e7f004,
0x1d0007f1,
0xd00003f0,
0x04bd000e,
/* 0x0548: ih_no_fifo */
0x010007f1,
0xd00003f0,
0x04bd000a,
0xe0fcf0fc,
0xb0fcd0fc,
0x90fca0fc,
0x88fe80fc,
0xfc80fc00,
0x0032f400,
/* 0x056e: hub_barrier_done */
0xf7f001f8,
0x040e9801,
0xb904febb,
0xe7f102ff,
0xe3f09418,
0x9d21f440,
/* 0x0582: ctx_redswitch */
/* 0x0586: ctx_redswitch */
0xf7f000f8,
0x0007f120,
0x0103f085,
0xbd000fd0,
0x08e7f004,
/* 0x0594: ctx_redswitch_delay */
/* 0x0598: ctx_redswitch_delay */
0xf401e2b6,
0xf5f1fd1b,
0xf5f10800,
......@@ -439,13 +440,13 @@ uint32_t gf100_grgpc_code[] = {
0x03f08500,
0x000fd001,
0x00f804bd,
/* 0x05b0: ctx_xfer */
/* 0x05b4: ctx_xfer */
0x810007f1,
0xd00203f0,
0x04bd000f,
0xf50711f4,
/* 0x05c3: ctx_xfer_not_load */
0xf5058221,
/* 0x05c7: ctx_xfer_not_load */
0xf5058621,
0xbd026a21,
0xfc07f124,
0x0203f047,
......@@ -475,12 +476,11 @@ uint32_t gf100_grgpc_code[] = {
0x6f21f508,
0x5e21f501,
0x0601f402,
/* 0x063b: ctx_xfer_post */
/* 0x063f: ctx_xfer_post */
0xf50712f4,
/* 0x063f: ctx_xfer_done */
/* 0x0643: ctx_xfer_done */
0xf5027f21,
0xf8056a21,
0x00000000,
0xf8056e21,
0x00000000,
0x00000000,
0x00000000,
......
......@@ -408,56 +408,57 @@ uint32_t gf117_grgpc_code[] = {
0x0412fd20,
0xfd01e4b6,
0x18fe051e,
0xfd21f500,
0xd30ef405,
0x0121f500,
0xd30ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
0xfe80f9c6,
0x80f90188,
0xa0f990f9,
0xd0f9b0f9,
0xf0f9e0f9,
0xa7f104bd,
0xa3f00200,
0x00aacf00,
0xf404abc4,
0xd7f02c0b,
0x00e7f124,
0x00e3f01a,
0xf100eecf,
0xf01900f7,
0xffcf00f3,
0x0421f400,
0xf101e7f0,
0xf01d0007,
0x0ed00003,
/* 0x0593: ih_no_fifo */
0xf104bd00,
0xf0010007,
0x0ad00003,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x32f480fc,
/* 0x05b7: hub_barrier_done */
0xf900f9c6,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0x0200a7f1,
0xcf00a3f0,
0xabc400aa,
0x2c0bf404,
0xf124d7f0,
0xf01a00e7,
0xeecf00e3,
0x00f7f100,
0x00f3f019,
0xf400ffcf,
0xe7f00421,
0x0007f101,
0x0003f01d,
0xbd000ed0,
/* 0x0595: ih_no_fifo */
0x0007f104,
0x0003f001,
0xbd000ad0,
0xfcf0fc04,
0xfcd0fce0,
0xfca0fcb0,
0xfe80fc90,
0x80fc0088,
0x32f400fc,
/* 0x05bb: hub_barrier_done */
0xf001f800,
0x0e9801f7,
0x04febb04,
0xf102ffb9,
0xf09418e7,
0x21f440e3,
/* 0x05cf: ctx_redswitch */
/* 0x05d3: ctx_redswitch */
0xf000f89d,
0x07f120f7,
0x03f08500,
0x000fd001,
0xe7f004bd,
/* 0x05e1: ctx_redswitch_delay */
/* 0x05e5: ctx_redswitch_delay */
0x01e2b608,
0xf1fd1bf4,
0xf10800f5,
......@@ -465,13 +466,13 @@ uint32_t gf117_grgpc_code[] = {
0xf0850007,
0x0fd00103,
0xf804bd00,
/* 0x05fd: ctx_xfer */
/* 0x0601: ctx_xfer */
0x0007f100,
0x0203f081,
0xbd000fd0,
0x0711f404,
0x05cf21f5,
/* 0x0610: ctx_xfer_not_load */
0x05d321f5,
/* 0x0614: ctx_xfer_not_load */
0x026a21f5,
0x07f124bd,
0x03f047fc,
......@@ -511,10 +512,10 @@ uint32_t gf117_grgpc_code[] = {
0x21f5016f,
0x01f4025e,
0x0712f406,
/* 0x06ac: ctx_xfer_post */
/* 0x06b0: ctx_xfer_post */
0x027f21f5,
/* 0x06b0: ctx_xfer_done */
0x05b721f5,
/* 0x06b4: ctx_xfer_done */
0x05bb21f5,
0x000000f8,
0x00000000,
0x00000000,
......@@ -533,5 +534,4 @@ uint32_t gf117_grgpc_code[] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
......@@ -408,56 +408,57 @@ uint32_t gk104_grgpc_code[] = {
0x0412fd20,
0xfd01e4b6,
0x18fe051e,
0xfd21f500,
0xd30ef405,
0x0121f500,
0xd30ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
0xfe80f9c6,
0x80f90188,
0xa0f990f9,
0xd0f9b0f9,
0xf0f9e0f9,
0xa7f104bd,
0xa3f00200,
0x00aacf00,
0xf404abc4,
0xd7f02c0b,
0x00e7f124,
0x00e3f01a,
0xf100eecf,
0xf01900f7,
0xffcf00f3,
0x0421f400,
0xf101e7f0,
0xf01d0007,
0x0ed00003,
/* 0x0593: ih_no_fifo */
0xf104bd00,
0xf0010007,
0x0ad00003,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x32f480fc,
/* 0x05b7: hub_barrier_done */
0xf900f9c6,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0x0200a7f1,
0xcf00a3f0,
0xabc400aa,
0x2c0bf404,
0xf124d7f0,
0xf01a00e7,
0xeecf00e3,
0x00f7f100,
0x00f3f019,
0xf400ffcf,
0xe7f00421,
0x0007f101,
0x0003f01d,
0xbd000ed0,
/* 0x0595: ih_no_fifo */
0x0007f104,
0x0003f001,
0xbd000ad0,
0xfcf0fc04,
0xfcd0fce0,
0xfca0fcb0,
0xfe80fc90,
0x80fc0088,
0x32f400fc,
/* 0x05bb: hub_barrier_done */
0xf001f800,
0x0e9801f7,
0x04febb04,
0xf102ffb9,
0xf09418e7,
0x21f440e3,
/* 0x05cf: ctx_redswitch */
/* 0x05d3: ctx_redswitch */
0xf000f89d,
0x07f120f7,
0x03f08500,
0x000fd001,
0xe7f004bd,
/* 0x05e1: ctx_redswitch_delay */
/* 0x05e5: ctx_redswitch_delay */
0x01e2b608,
0xf1fd1bf4,
0xf10800f5,
......@@ -465,13 +466,13 @@ uint32_t gk104_grgpc_code[] = {
0xf0850007,
0x0fd00103,
0xf804bd00,
/* 0x05fd: ctx_xfer */
/* 0x0601: ctx_xfer */
0x0007f100,
0x0203f081,
0xbd000fd0,
0x0711f404,
0x05cf21f5,
/* 0x0610: ctx_xfer_not_load */
0x05d321f5,
/* 0x0614: ctx_xfer_not_load */
0x026a21f5,
0x07f124bd,
0x03f047fc,
......@@ -511,10 +512,10 @@ uint32_t gk104_grgpc_code[] = {
0x21f5016f,
0x01f4025e,
0x0712f406,
/* 0x06ac: ctx_xfer_post */
/* 0x06b0: ctx_xfer_post */
0x027f21f5,
/* 0x06b0: ctx_xfer_done */
0x05b721f5,
/* 0x06b4: ctx_xfer_done */
0x05bb21f5,
0x000000f8,
0x00000000,
0x00000000,
......@@ -533,5 +534,4 @@ uint32_t gk104_grgpc_code[] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
......@@ -408,56 +408,57 @@ uint32_t gk110_grgpc_code[] = {
0x0412fd20,
0xfd01e4b6,
0x18fe051e,
0xfd21f500,
0xd30ef405,
0x0121f500,
0xd30ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
0xfe80f9c6,
0x80f90188,
0xa0f990f9,
0xd0f9b0f9,
0xf0f9e0f9,
0xa7f104bd,
0xa3f00200,
0x00aacf00,
0xf404abc4,
0xd7f02c0b,
0x00e7f124,
0x00e3f01a,
0xf100eecf,
0xf01900f7,
0xffcf00f3,
0x0421f400,
0xf101e7f0,
0xf01d0007,
0x0ed00003,
/* 0x0593: ih_no_fifo */
0xf104bd00,
0xf0010007,
0x0ad00003,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x32f480fc,
/* 0x05b7: hub_barrier_done */
0xf900f9c6,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0x0200a7f1,
0xcf00a3f0,
0xabc400aa,
0x2c0bf404,
0xf124d7f0,
0xf01a00e7,
0xeecf00e3,
0x00f7f100,
0x00f3f019,
0xf400ffcf,
0xe7f00421,
0x0007f101,
0x0003f01d,
0xbd000ed0,
/* 0x0595: ih_no_fifo */
0x0007f104,
0x0003f001,
0xbd000ad0,
0xfcf0fc04,
0xfcd0fce0,
0xfca0fcb0,
0xfe80fc90,
0x80fc0088,
0x32f400fc,
/* 0x05bb: hub_barrier_done */
0xf001f800,
0x0e9801f7,
0x04febb04,
0xf102ffb9,
0xf09418e7,
0x21f440e3,
/* 0x05cf: ctx_redswitch */
/* 0x05d3: ctx_redswitch */
0xf000f89d,
0x07f120f7,
0x03f08500,
0x000fd001,
0xe7f004bd,
/* 0x05e1: ctx_redswitch_delay */
/* 0x05e5: ctx_redswitch_delay */
0x01e2b608,
0xf1fd1bf4,
0xf10800f5,
......@@ -465,13 +466,13 @@ uint32_t gk110_grgpc_code[] = {
0xf0850007,
0x0fd00103,
0xf804bd00,
/* 0x05fd: ctx_xfer */
/* 0x0601: ctx_xfer */
0x0007f100,
0x0203f081,
0xbd000fd0,
0x0711f404,
0x05cf21f5,
/* 0x0610: ctx_xfer_not_load */
0x05d321f5,
/* 0x0614: ctx_xfer_not_load */
0x026a21f5,
0x07f124bd,
0x03f047fc,
......@@ -511,10 +512,10 @@ uint32_t gk110_grgpc_code[] = {
0x21f5016f,
0x01f4025e,
0x0712f406,
/* 0x06ac: ctx_xfer_post */
/* 0x06b0: ctx_xfer_post */
0x027f21f5,
/* 0x06b0: ctx_xfer_done */
0x05b721f5,
/* 0x06b4: ctx_xfer_done */
0x05bb21f5,
0x000000f8,
0x00000000,
0x00000000,
......@@ -533,5 +534,4 @@ uint32_t gk110_grgpc_code[] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
......@@ -360,61 +360,62 @@ uint32_t gk208_grgpc_code[] = {
0xb60412fd,
0x1efd01e4,
0x0018fe05,
0x00051b7e,
0x00051f7e,
/* 0x0477: main_not_ctx_xfer */
0x94d40ef4,
0xf5f010ef,
0x02f87e01,
0xc70ef400,
/* 0x0484: ih */
0x88fe80f9,
0xf980f901,
0xf9a0f990,
0xf9d0f9b0,
0xbdf0f9e0,
0x02004a04,
0xc400aacf,
0x0bf404ab,
0x4e240d1f,
0xeecf1a00,
0x19004f00,
0x7e00ffcf,
0x0e000004,
0x1d004001,
0xbd000ef6,
/* 0x04c1: ih_no_fifo */
0x01004004,
0xbd000af6,
0xfcf0fc04,
0xfcd0fce0,
0xfca0fcb0,
0xfe80fc90,
0x80fc0088,
0x80f900f9,
0xf90188fe,
0xf990f980,
0xf9b0f9a0,
0xf9e0f9d0,
0x4a04bdf0,
0xaacf0200,
0x04abc400,
0x0d1f0bf4,
0x1a004e24,
0x4f00eecf,
0xffcf1900,
0x00047e00,
0x40010e00,
0x0ef61d00,
/* 0x04c3: ih_no_fifo */
0x4004bd00,
0x0af60100,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x00fc80fc,
0xf80032f4,
/* 0x04e1: hub_barrier_done */
/* 0x04e5: hub_barrier_done */
0x98010f01,
0xfebb040e,
0x8effb204,
0x7e409418,
0xf800008f,
/* 0x04f5: ctx_redswitch */
/* 0x04f9: ctx_redswitch */
0x80200f00,
0xf6018500,
0x04bd000f,
/* 0x0502: ctx_redswitch_delay */
/* 0x0506: ctx_redswitch_delay */
0xe2b6080e,
0xfd1bf401,
0x0800f5f1,
0x0200f5f1,
0x01850080,
0xbd000ff6,
/* 0x051b: ctx_xfer */
/* 0x051f: ctx_xfer */
0x8000f804,
0xf6028100,
0x04bd000f,
0x7e0711f4,
/* 0x052b: ctx_xfer_not_load */
0x7e0004f5,
/* 0x052f: ctx_xfer_not_load */
0x7e0004f9,
0xbd000216,
0x47fc8024,
0x0002f602,
......@@ -449,10 +450,10 @@ uint32_t gk208_grgpc_code[] = {
0x7e00013d,
0xf400020a,
0x12f40601,
/* 0x05b5: ctx_xfer_post */
/* 0x05b9: ctx_xfer_post */
0x02277e07,
/* 0x05b9: ctx_xfer_done */
0x04e17e00,
/* 0x05bd: ctx_xfer_done */
0x04e57e00,
0x0000f800,
0x00000000,
0x00000000,
......@@ -469,5 +470,4 @@ uint32_t gk208_grgpc_code[] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
......@@ -438,48 +438,49 @@ uint32_t gm107_grgpc_code[] = {
0x0412fd20,
0xfd01e4b6,
0x18fe051e,
0x06447e00,
0x06487e00,
0xd40ef400,
/* 0x05a0: main_not_ctx_xfer */
0xf010ef94,
0xf87e01f5,
0x0ef40002,
/* 0x05ad: ih */
0xfe80f9c7,
0x80f90188,
0xa0f990f9,
0xd0f9b0f9,
0xf0f9e0f9,
0x004a04bd,
0x00aacf02,
0xf404abc4,
0x240d1f0b,
0xcf1a004e,
0x004f00ee,
0x00ffcf19,
0x0000047e,
0x0040010e,
0x000ef61d,
/* 0x05ea: ih_no_fifo */
0x004004bd,
0x000af601,
0xf0fc04bd,
0xd0fce0fc,
0xa0fcb0fc,
0x80fc90fc,
0xfc0088fe,
0x0032f480,
/* 0x060a: hub_barrier_done */
0xf900f9c7,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0xcf02004a,
0xabc400aa,
0x1f0bf404,
0x004e240d,
0x00eecf1a,
0xcf19004f,
0x047e00ff,
0x010e0000,
0xf61d0040,
0x04bd000e,
/* 0x05ec: ih_no_fifo */
0xf6010040,
0x04bd000a,
0xe0fcf0fc,
0xb0fcd0fc,
0x90fca0fc,
0x88fe80fc,
0xfc80fc00,
0x0032f400,
/* 0x060e: hub_barrier_done */
0x010f01f8,
0xbb040e98,
0xffb204fe,
0x4094188e,
0x00008f7e,
/* 0x061e: ctx_redswitch */
/* 0x0622: ctx_redswitch */
0x200f00f8,
0x01850080,
0xbd000ff6,
/* 0x062b: ctx_redswitch_delay */
/* 0x062f: ctx_redswitch_delay */
0xb6080e04,
0x1bf401e2,
0x00f5f1fd,
......@@ -487,15 +488,15 @@ uint32_t gm107_grgpc_code[] = {
0x85008002,
0x000ff601,
0x00f804bd,
/* 0x0644: ctx_xfer */
/* 0x0648: ctx_xfer */
0x02810080,
0xbd000ff6,
0x1dc48e04,
0x01e5f050,
0x8f7effb2,
0x11f40000,
0x061e7e07,
/* 0x0661: ctx_xfer_not_load */
0x06227e07,
/* 0x0665: ctx_xfer_not_load */
0x02167e00,
0x8024bd00,
0xf60247fc,
......@@ -550,15 +551,15 @@ uint32_t gm107_grgpc_code[] = {
0x7e00020a,
0xf4000314,
0x12f40601,
/* 0x0739: ctx_xfer_post */
/* 0x073d: ctx_xfer_post */
0x02277e1a,
0x8e0d0f00,
0xf0501da8,
0xffb201e5,
0x00008f7e,
0x0003147e,
/* 0x0750: ctx_xfer_done */
0x00060a7e,
/* 0x0754: ctx_xfer_done */
0x00060e7e,
0x000000f8,
0x00000000,
0x00000000,
......@@ -601,5 +602,4 @@ uint32_t gm107_grgpc_code[] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
......@@ -306,6 +306,7 @@ main:
// interrupt handler
ih:
push $r0
push $r8
mov $r8 $flags
push $r8
......@@ -380,6 +381,7 @@ ih:
pop $r8
mov $flags $r8
pop $r8
pop $r0
bclr $flags $p0
iret
......
......@@ -32,12 +32,15 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
struct nvkm_device *device = gr->base.engine.subdev.device;
u32 val;
/* TODO this needs to be removed once secure boot works */
if (1) {
/* Bypass MMU check for non-secure boot */
if (!device->secboot) {
nvkm_wr32(device, 0x100ce4, 0xffffffff);
if (nvkm_rd32(device, 0x100ce4) != 0xffffffff)
nvdev_warn(device,
"cannot bypass secure boot - expect failure soon!\n");
}
/* TODO update once secure boot works */
val = nvkm_rd32(device, 0x100c80);
val &= 0xf000087f;
nvkm_wr32(device, 0x418880, val);
......@@ -61,7 +64,6 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr)
static const struct gf100_gr_func
gm20b_gr = {
.dtor = gk20a_gr_dtor,
.init = gk20a_gr_init,
.init_gpc_mmu = gm20b_gr_init_gpc_mmu,
.set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask,
......@@ -79,5 +81,5 @@ gm20b_gr = {
int
gm20b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gk20a_gr_new_(&gm20b_gr, device, index, pgr);
return gm200_gr_new_(&gm20b_gr, device, index, pgr);
}
......@@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/bios/extdev.o
nvkm-y += nvkm/subdev/bios/fan.o
nvkm-y += nvkm/subdev/bios/gpio.o
nvkm-y += nvkm/subdev/bios/i2c.o
nvkm-y += nvkm/subdev/bios/iccsense.o
nvkm-y += nvkm/subdev/bios/image.o
nvkm-y += nvkm/subdev/bios/init.o
nvkm-y += nvkm/subdev/bios/mxm.o
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册