Commit 1c431cb4 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'linux-4.4' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next

- Vast improvements to gk20a instmem handling.
- Improved PGOB detection + GK107 support.
- Compatibility between old/new interfaces added, final missing piece to
finally enabling userspace to start using them.
- Kepler GDDR5 PLL stability improvements
- Support for non-GPIO (PWM) voltage controllers
- G8x/GT2xx memory clock improvements
- Misc other fixes

* 'linux-4.4' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (45 commits)
  drm/nouveau: bump patchlevel to indicate availability of abi16/nvif interop
  drm/nouveau/abi16: implement limited interoperability with usif/nvif
  drm/nouveau/abi16: introduce locked variant of nouveau_abi16_get()
  drm/nouveau/abi16: remove unused argument from nouveau_abi16_get()
  drm/nouveau/pci: enable c800 magic for Medion Erazer X7827
  drm/nouveau/pci: enable c800 magic for Lenovo Y510P
  drm/nouveau/pll/gk104: fix PLL instability due to bad configuration with gddr5
  drm/nouveau/clk/g84: Enable reclocking for GDDR3 G94-G200
  drm/nouveau/bus/hwsq: Implement VBLANK waiting heuristic
  drm/nouveau/fb/ramnv50: Script changes for G94 and up
  drm/nouveau/fb/ramnv50: Deal with cards without timing entries
  drm/nouveau/fb/ramnv50: Voltage GPIOs
  drm/nouveau/fb/ramgt215: Restructure r111100 calculation for DDR2
  drm/nouveau/fb/ramgt215: Change FBVDD/Q when BIOS asks for it
  drm/nouveau/fb/ramgt215: Transform GPIO ramfuc method from FBVREF-specific to generic
  drm/nouveau/bios/rammap: Identify DLLoff for >= GF100
  drm/nouveau/pci: Handle 5-bit and 8-bit tag field
  drm/nouveau/disp,pm: constify nvkm_object_func structures
  drm/nouveau/gr: add FERMI_COMPUTE_B class to GF110+
  drm/nouveau/gr: document mp error 0x10
  ...
parents b4590047 79ef5dca
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/iommu.h> #include <linux/iommu.h>
#include <linux/of_device.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <core/mm.h> #include <core/mm.h>
struct nvkm_device_tegra { struct nvkm_device_tegra {
const struct nvkm_device_tegra_func *func;
struct nvkm_device device; struct nvkm_device device;
struct platform_device *pdev; struct platform_device *pdev;
int irq; int irq;
...@@ -28,7 +29,17 @@ struct nvkm_device_tegra { ...@@ -28,7 +29,17 @@ struct nvkm_device_tegra {
int gpu_speedo; int gpu_speedo;
}; };
int nvkm_device_tegra_new(struct platform_device *, struct nvkm_device_tegra_func {
/*
* If an IOMMU is used, indicates which address bit will trigger a
* IOMMU translation when set (when this bit is not set, IOMMU is
* bypassed). A value of 0 means an IOMMU is never used.
*/
u8 iommu_bit;
};
int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
struct platform_device *,
const char *cfg, const char *dbg, const char *cfg, const char *dbg,
bool detect, bool mmio, u64 subdev_mask, bool detect, bool mmio, u64 subdev_mask,
struct nvkm_device **); struct nvkm_device **);
......
...@@ -15,6 +15,7 @@ enum dcb_gpio_func_name { ...@@ -15,6 +15,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_VID5 = 0x74, DCB_GPIO_VID5 = 0x74,
DCB_GPIO_VID6 = 0x75, DCB_GPIO_VID6 = 0x75,
DCB_GPIO_VID7 = 0x76, DCB_GPIO_VID7 = 0x76,
DCB_GPIO_VID_PWM = 0x81,
}; };
#define DCB_GPIO_LOG_DIR 0x02 #define DCB_GPIO_LOG_DIR 0x02
......
...@@ -4,8 +4,6 @@ struct nvbios_pmuT { ...@@ -4,8 +4,6 @@ struct nvbios_pmuT {
}; };
u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_pmuTp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_pmuT *);
struct nvbios_pmuE { struct nvbios_pmuE {
u8 type; u8 type;
......
...@@ -39,6 +39,7 @@ struct nvbios_ramcfg { ...@@ -39,6 +39,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_timing; unsigned ramcfg_timing;
unsigned ramcfg_DLLoff; unsigned ramcfg_DLLoff;
unsigned ramcfg_RON; unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
union { union {
struct { struct {
unsigned ramcfg_00_03_01:1; unsigned ramcfg_00_03_01:1;
...@@ -78,7 +79,6 @@ struct nvbios_ramcfg { ...@@ -78,7 +79,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1; unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1; unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1; unsigned ramcfg_11_01_10:1;
unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1; unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1; unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2; unsigned ramcfg_11_02_03:2;
......
#ifndef __NVBIOS_VOLT_H__ #ifndef __NVBIOS_VOLT_H__
#define __NVBIOS_VOLT_H__ #define __NVBIOS_VOLT_H__
enum nvbios_volt_type {
NVBIOS_VOLT_GPIO = 0,
NVBIOS_VOLT_PWM,
};
struct nvbios_volt { struct nvbios_volt {
u8 vidmask; enum nvbios_volt_type type;
u32 min; u32 min;
u32 max; u32 max;
u32 base; u32 base;
/* GPIO mode */
u8 vidmask;
s16 step; s16 step;
/* PWM mode */
u32 pwm_freq;
u32 pwm_range;
}; };
u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
......
...@@ -14,6 +14,7 @@ int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec); ...@@ -14,6 +14,7 @@ int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data); void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data); void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data); void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
void nvkm_hwsq_wait_vblank(struct nvkm_hwsq *);
void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec); void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **); int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <core/subdev.h> #include <core/subdev.h>
int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **); 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 gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **); int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
#endif #endif
...@@ -30,7 +30,11 @@ void nvkm_ltc_tags_clear(struct nvkm_ltc *, u32 first, u32 count); ...@@ -30,7 +30,11 @@ void nvkm_ltc_tags_clear(struct nvkm_ltc *, u32 first, u32 count);
int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]); int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32); int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32);
void nvkm_ltc_invalidate(struct nvkm_ltc *);
void nvkm_ltc_flush(struct nvkm_ltc *);
int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gk104_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 gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
#endif #endif
...@@ -24,11 +24,14 @@ struct nvkm_pci { ...@@ -24,11 +24,14 @@ struct nvkm_pci {
u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr); u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data); void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data); void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow); void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int nv46_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int nv50_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int g84_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
#endif #endif
...@@ -59,6 +59,16 @@ void nvkm_timer_alarm_cancel(struct nvkm_timer *, struct nvkm_alarm *); ...@@ -59,6 +59,16 @@ void nvkm_timer_alarm_cancel(struct nvkm_timer *, struct nvkm_alarm *);
#define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond) #define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond)
#define nvkm_msec(d,m,cond...) nvkm_usec((d), (m) * 1000, ##cond) #define nvkm_msec(d,m,cond...) nvkm_usec((d), (m) * 1000, ##cond)
#define nvkm_wait_nsec(d,n,addr,mask,data) \
nvkm_nsec(d, n, \
if ((nvkm_rd32(d, (addr)) & (mask)) == (data)) \
break; \
)
#define nvkm_wait_usec(d,u,addr,mask,data) \
nvkm_wait_nsec((d), (u) * 1000, (addr), (mask), (data))
#define nvkm_wait_msec(d,m,addr,mask,data) \
nvkm_wait_usec((d), (m) * 1000, (addr), (mask), (data))
int nv04_timer_new(struct nvkm_device *, int, struct nvkm_timer **); int nv04_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
int nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **); int nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **); int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
......
...@@ -18,5 +18,6 @@ int nvkm_volt_get(struct nvkm_volt *); ...@@ -18,5 +18,6 @@ int nvkm_volt_get(struct nvkm_volt *);
int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition); int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **); 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 gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
#endif #endif
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <nvif/driver.h> #include <nvif/driver.h>
#include <nvif/ioctl.h> #include <nvif/ioctl.h>
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/unpack.h>
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nouveau_dma.h" #include "nouveau_dma.h"
...@@ -32,11 +33,10 @@ ...@@ -32,11 +33,10 @@
#include "nouveau_chan.h" #include "nouveau_chan.h"
#include "nouveau_abi16.h" #include "nouveau_abi16.h"
struct nouveau_abi16 * static struct nouveau_abi16 *
nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) nouveau_abi16(struct drm_file *file_priv)
{ {
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
mutex_lock(&cli->mutex);
if (!cli->abi16) { if (!cli->abi16) {
struct nouveau_abi16 *abi16; struct nouveau_abi16 *abi16;
cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL); cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL);
...@@ -51,8 +51,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) ...@@ -51,8 +51,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
* device (ie. the one that belongs to the fd it * device (ie. the one that belongs to the fd it
* opened) * opened)
*/ */
if (nvif_device_init(&cli->base.object, if (nvif_device_init(&cli->base.object, 0, NV_DEVICE,
NOUVEAU_ABI16_DEVICE, NV_DEVICE,
&args, sizeof(args), &args, sizeof(args),
&abi16->device) == 0) &abi16->device) == 0)
return cli->abi16; return cli->abi16;
...@@ -60,12 +59,21 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) ...@@ -60,12 +59,21 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
kfree(cli->abi16); kfree(cli->abi16);
cli->abi16 = NULL; cli->abi16 = NULL;
} }
mutex_unlock(&cli->mutex);
} }
return cli->abi16; return cli->abi16;
} }
struct nouveau_abi16 *
nouveau_abi16_get(struct drm_file *file_priv)
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
mutex_lock(&cli->mutex);
if (nouveau_abi16(file_priv))
return cli->abi16;
mutex_unlock(&cli->mutex);
return NULL;
}
int int
nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret) nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
{ {
...@@ -133,7 +141,6 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, ...@@ -133,7 +141,6 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
/* destroy channel object, all children will be killed too */ /* destroy channel object, all children will be killed too */
if (chan->chan) { if (chan->chan) {
abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff));
nouveau_channel_idle(chan->chan); nouveau_channel_idle(chan->chan);
nouveau_channel_del(&chan->chan); nouveau_channel_del(&chan->chan);
} }
...@@ -238,7 +245,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -238,7 +245,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
struct drm_nouveau_channel_alloc *init = data; struct drm_nouveau_channel_alloc *init = data;
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
struct nvif_device *device; struct nvif_device *device;
int ret; int ret;
...@@ -268,26 +275,21 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -268,26 +275,21 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
return nouveau_abi16_put(abi16, -EINVAL); return nouveau_abi16_put(abi16, -EINVAL);
/* allocate "abi16 channel" data and make up a handle for it */ /* allocate "abi16 channel" data and make up a handle for it */
init->channel = __ffs64(~abi16->handles);
if (~abi16->handles == 0)
return nouveau_abi16_put(abi16, -ENOSPC);
chan = kzalloc(sizeof(*chan), GFP_KERNEL); chan = kzalloc(sizeof(*chan), GFP_KERNEL);
if (!chan) if (!chan)
return nouveau_abi16_put(abi16, -ENOMEM); return nouveau_abi16_put(abi16, -ENOMEM);
INIT_LIST_HEAD(&chan->notifiers); INIT_LIST_HEAD(&chan->notifiers);
list_add(&chan->head, &abi16->channels); list_add(&chan->head, &abi16->channels);
abi16->handles |= (1ULL << init->channel);
/* create channel object and initialise dma and fence management */ /* create channel object and initialise dma and fence management */
ret = nouveau_channel_new(drm, device, ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
NOUVEAU_ABI16_CHAN(init->channel),
init->fb_ctxdma_handle,
init->tt_ctxdma_handle, &chan->chan); init->tt_ctxdma_handle, &chan->chan);
if (ret) if (ret)
goto done; goto done;
init->channel = chan->chan->chid;
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) if (device->info.family >= NV_DEVICE_INFO_V0_TESLA)
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
NOUVEAU_GEM_DOMAIN_GART; NOUVEAU_GEM_DOMAIN_GART;
...@@ -338,18 +340,56 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel) ...@@ -338,18 +340,56 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
list_for_each_entry(chan, &abi16->channels, head) { list_for_each_entry(chan, &abi16->channels, head) {
if (chan->chan->user.handle == NOUVEAU_ABI16_CHAN(channel)) if (chan->chan->chid == channel)
return chan; return chan;
} }
return NULL; return NULL;
} }
int
nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
{
union {
struct nvif_ioctl_v0 v0;
} *args = data;
struct nouveau_abi16_chan *chan;
struct nouveau_abi16 *abi16;
int ret;
if (nvif_unpack(args->v0, 0, 0, true)) {
switch (args->v0.type) {
case NVIF_IOCTL_V0_NEW:
case NVIF_IOCTL_V0_MTHD:
case NVIF_IOCTL_V0_SCLASS:
break;
default:
return -EACCES;
}
} else
return ret;
if (!(abi16 = nouveau_abi16(file_priv)))
return -ENOMEM;
if (args->v0.token != ~0ULL) {
if (!(chan = nouveau_abi16_chan(abi16, args->v0.token)))
return -EINVAL;
args->v0.object = nvif_handle(&chan->chan->user);
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
return 0;
}
args->v0.object = nvif_handle(&abi16->device.object);
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
return 0;
}
int int
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
{ {
struct drm_nouveau_channel_free *req = data; struct drm_nouveau_channel_free *req = data;
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
if (unlikely(!abi16)) if (unlikely(!abi16))
...@@ -366,7 +406,7 @@ int ...@@ -366,7 +406,7 @@ int
nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
{ {
struct drm_nouveau_grobj_alloc *init = data; struct drm_nouveau_grobj_alloc *init = data;
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
struct nouveau_abi16_ntfy *ntfy; struct nouveau_abi16_ntfy *ntfy;
struct nvif_client *client; struct nvif_client *client;
...@@ -459,7 +499,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) ...@@ -459,7 +499,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
{ {
struct drm_nouveau_notifierobj_alloc *info = data; struct drm_nouveau_notifierobj_alloc *info = data;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
struct nouveau_abi16_ntfy *ntfy; struct nouveau_abi16_ntfy *ntfy;
struct nvif_device *device = &abi16->device; struct nvif_device *device = &abi16->device;
...@@ -531,7 +571,7 @@ int ...@@ -531,7 +571,7 @@ int
nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
{ {
struct drm_nouveau_gpuobj_free *fini = data; struct drm_nouveau_gpuobj_free *fini = data;
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
struct nouveau_abi16_ntfy *ntfy; struct nouveau_abi16_ntfy *ntfy;
int ret = -ENOENT; int ret = -ENOENT;
......
...@@ -33,11 +33,11 @@ struct nouveau_abi16 { ...@@ -33,11 +33,11 @@ struct nouveau_abi16 {
u64 handles; u64 handles;
}; };
struct nouveau_drm; struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *);
struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *, struct drm_device *);
int nouveau_abi16_put(struct nouveau_abi16 *, int); int nouveau_abi16_put(struct nouveau_abi16 *, int);
void nouveau_abi16_fini(struct nouveau_abi16 *); void nouveau_abi16_fini(struct nouveau_abi16 *);
s32 nouveau_abi16_swclass(struct nouveau_drm *); s32 nouveau_abi16_swclass(struct nouveau_drm *);
int nouveau_abi16_usif(struct drm_file *, void *data, u32 size);
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) #define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
......
...@@ -55,10 +55,8 @@ nouveau_channel_idle(struct nouveau_channel *chan) ...@@ -55,10 +55,8 @@ nouveau_channel_idle(struct nouveau_channel *chan)
} }
if (ret) { if (ret) {
NV_PRINTK(err, cli, "failed to idle channel " NV_PRINTK(err, cli, "failed to idle channel %d [%s]\n",
"0x%08x [%s]\n", chan->chid, nvxx_client(&cli->base)->name);
chan->user.handle,
nvxx_client(&cli->base)->name);
return ret; return ret;
} }
} }
...@@ -89,7 +87,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) ...@@ -89,7 +87,7 @@ nouveau_channel_del(struct nouveau_channel **pchan)
static int static int
nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, u32 size, struct nouveau_channel **pchan) u32 size, struct nouveau_channel **pchan)
{ {
struct nouveau_cli *cli = (void *)device->object.client; struct nouveau_cli *cli = (void *)device->object.client;
struct nvkm_mmu *mmu = nvxx_mmu(device); struct nvkm_mmu *mmu = nvxx_mmu(device);
...@@ -174,8 +172,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -174,8 +172,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
} }
} }
ret = nvif_object_init(&device->object, NVDRM_PUSH | ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
(handle & 0xffff), NV_DMA_FROM_MEMORY,
&args, sizeof(args), &chan->push.ctxdma); &args, sizeof(args), &chan->push.ctxdma);
if (ret) { if (ret) {
nouveau_channel_del(pchan); nouveau_channel_del(pchan);
...@@ -187,7 +184,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -187,7 +184,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
static int static int
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, u32 engine, struct nouveau_channel **pchan) u32 engine, struct nouveau_channel **pchan)
{ {
static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A, static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A,
KEPLER_CHANNEL_GPFIFO_A, KEPLER_CHANNEL_GPFIFO_A,
...@@ -206,7 +203,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -206,7 +203,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
int ret; int ret;
/* allocate dma push buffer */ /* allocate dma push buffer */
ret = nouveau_channel_prep(drm, device, handle, 0x12000, &chan); ret = nouveau_channel_prep(drm, device, 0x12000, &chan);
*pchan = chan; *pchan = chan;
if (ret) if (ret)
return ret; return ret;
...@@ -236,7 +233,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -236,7 +233,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
size = sizeof(args.nv50); size = sizeof(args.nv50);
} }
ret = nvif_object_init(&device->object, handle, *oclass++, ret = nvif_object_init(&device->object, 0, *oclass++,
&args, size, &chan->user); &args, size, &chan->user);
if (ret == 0) { if (ret == 0) {
if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A)
...@@ -256,7 +253,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -256,7 +253,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
static int static int
nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, struct nouveau_channel **pchan) struct nouveau_channel **pchan)
{ {
static const u16 oclasses[] = { NV40_CHANNEL_DMA, static const u16 oclasses[] = { NV40_CHANNEL_DMA,
NV17_CHANNEL_DMA, NV17_CHANNEL_DMA,
...@@ -269,7 +266,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -269,7 +266,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
int ret; int ret;
/* allocate dma push buffer */ /* allocate dma push buffer */
ret = nouveau_channel_prep(drm, device, handle, 0x10000, &chan); ret = nouveau_channel_prep(drm, device, 0x10000, &chan);
*pchan = chan; *pchan = chan;
if (ret) if (ret)
return ret; return ret;
...@@ -280,7 +277,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -280,7 +277,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
args.offset = chan->push.vma.offset; args.offset = chan->push.vma.offset;
do { do {
ret = nvif_object_init(&device->object, handle, *oclass++, ret = nvif_object_init(&device->object, 0, *oclass++,
&args, sizeof(args), &chan->user); &args, sizeof(args), &chan->user);
if (ret == 0) { if (ret == 0) {
chan->chid = args.chid; chan->chid = args.chid;
...@@ -401,8 +398,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) ...@@ -401,8 +398,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
int int
nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, u32 arg0, u32 arg1, u32 arg0, u32 arg1, struct nouveau_channel **pchan)
struct nouveau_channel **pchan)
{ {
struct nouveau_cli *cli = (void *)device->object.client; struct nouveau_cli *cli = (void *)device->object.client;
bool super; bool super;
...@@ -412,10 +408,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -412,10 +408,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
super = cli->base.super; super = cli->base.super;
cli->base.super = true; cli->base.super = true;
ret = nouveau_channel_ind(drm, device, handle, arg0, pchan); ret = nouveau_channel_ind(drm, device, arg0, pchan);
if (ret) { if (ret) {
NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret); NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
ret = nouveau_channel_dma(drm, device, handle, pchan); ret = nouveau_channel_dma(drm, device, pchan);
if (ret) { if (ret) {
NV_PRINTK(dbg, cli, "dma channel create, %d\n", ret); NV_PRINTK(dbg, cli, "dma channel create, %d\n", ret);
goto done; goto done;
......
...@@ -42,8 +42,7 @@ struct nouveau_channel { ...@@ -42,8 +42,7 @@ struct nouveau_channel {
int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
u32 handle, u32 arg0, u32 arg1, u32 arg0, u32 arg1, struct nouveau_channel **);
struct nouveau_channel **);
void nouveau_channel_del(struct nouveau_channel **); void nouveau_channel_del(struct nouveau_channel **);
int nouveau_channel_idle(struct nouveau_channel *); int nouveau_channel_idle(struct nouveau_channel *);
......
...@@ -509,9 +509,8 @@ nouveau_display_create(struct drm_device *dev) ...@@ -509,9 +509,8 @@ nouveau_display_create(struct drm_device *dev)
int i; int i;
for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) {
ret = nvif_object_init(&drm->device.object, ret = nvif_object_init(&drm->device.object, 0,
NVDRM_DISPLAY, oclass[i], oclass[i], NULL, 0, &disp->disp);
NULL, 0, &disp->disp);
} }
if (ret == 0) { if (ret == 0) {
......
...@@ -208,7 +208,7 @@ nouveau_accel_init(struct nouveau_drm *drm) ...@@ -208,7 +208,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
} }
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, ret = nouveau_channel_new(drm, &drm->device,
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0| KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0|
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1, KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1,
0, &drm->cechan); 0, &drm->cechan);
...@@ -221,7 +221,7 @@ nouveau_accel_init(struct nouveau_drm *drm) ...@@ -221,7 +221,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
if (device->info.chipset >= 0xa3 && if (device->info.chipset >= 0xa3 &&
device->info.chipset != 0xaa && device->info.chipset != 0xaa &&
device->info.chipset != 0xac) { device->info.chipset != 0xac) {
ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, ret = nouveau_channel_new(drm, &drm->device,
NvDmaFB, NvDmaTT, &drm->cechan); NvDmaFB, NvDmaTT, &drm->cechan);
if (ret) if (ret)
NV_ERROR(drm, "failed to create ce channel, %d\n", ret); NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
...@@ -233,8 +233,7 @@ nouveau_accel_init(struct nouveau_drm *drm) ...@@ -233,8 +233,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
arg1 = NvDmaTT; arg1 = NvDmaTT;
} }
ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN, arg0, arg1, ret = nouveau_channel_new(drm, &drm->device, arg0, arg1, &drm->channel);
&drm->channel);
if (ret) { if (ret) {
NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
nouveau_accel_fini(drm); nouveau_accel_fini(drm);
...@@ -403,8 +402,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -403,8 +402,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
nouveau_get_hdmi_dev(drm); nouveau_get_hdmi_dev(drm);
ret = nvif_device_init(&drm->client.base.object, ret = nvif_device_init(&drm->client.base.object, 0, NV_DEVICE,
NVDRM_DEVICE, NV_DEVICE,
&(struct nv_device_v0) { &(struct nv_device_v0) {
.device = ~0, .device = ~0,
}, sizeof(struct nv_device_v0), }, sizeof(struct nv_device_v0),
...@@ -1030,13 +1028,14 @@ nouveau_drm_pci_driver = { ...@@ -1030,13 +1028,14 @@ nouveau_drm_pci_driver = {
}; };
struct drm_device * struct drm_device *
nouveau_platform_device_create(struct platform_device *pdev, nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
struct platform_device *pdev,
struct nvkm_device **pdevice) struct nvkm_device **pdevice)
{ {
struct drm_device *drm; struct drm_device *drm;
int err; int err;
err = nvkm_device_tegra_new(pdev, nouveau_config, nouveau_debug, err = nvkm_device_tegra_new(func, pdev, nouveau_config, nouveau_debug,
true, true, ~0ULL, pdevice); true, true, ~0ULL, pdevice);
if (err) if (err)
goto err_free; goto err_free;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 3 #define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 1
/* /*
* 1.1.1: * 1.1.1:
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
* 1.3.0: * 1.3.0:
* - NVIF ABI modified, safe because only (current) users are test * - NVIF ABI modified, safe because only (current) users are test
* programs that get directly linked with NVKM. * programs that get directly linked with NVKM.
* 1.3.1:
* - implemented limited ABI16/NVIF interop
*/ */
#include <nvif/client.h> #include <nvif/client.h>
...@@ -74,11 +76,6 @@ enum nouveau_drm_notify_route { ...@@ -74,11 +76,6 @@ enum nouveau_drm_notify_route {
}; };
enum nouveau_drm_handle { enum nouveau_drm_handle {
NVDRM_CLIENT = 0xffffffff,
NVDRM_DEVICE = 0xdddddddd,
NVDRM_CONTROL = 0xdddddddc,
NVDRM_DISPLAY = 0xd1500000,
NVDRM_PUSH = 0xbbbb0000, /* |= client chid */
NVDRM_CHAN = 0xcccc0000, /* |= client chid */ NVDRM_CHAN = 0xcccc0000, /* |= client chid */
NVDRM_NVSW = 0x55550000, NVDRM_NVSW = 0x55550000,
}; };
...@@ -183,8 +180,11 @@ nouveau_drm(struct drm_device *dev) ...@@ -183,8 +180,11 @@ nouveau_drm(struct drm_device *dev)
int nouveau_pmops_suspend(struct device *); int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *); int nouveau_pmops_resume(struct device *);
#include <nvkm/core/tegra.h>
struct drm_device * struct drm_device *
nouveau_platform_device_create(struct platform_device *, struct nvkm_device **); nouveau_platform_device_create(const struct nvkm_device_tegra_func *,
struct platform_device *, struct nvkm_device **);
void nouveau_drm_device_remove(struct drm_device *dev); void nouveau_drm_device_remove(struct drm_device *dev);
#define NV_PRINTK(l,c,f,a...) do { \ #define NV_PRINTK(l,c,f,a...) do { \
......
...@@ -84,8 +84,10 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -84,8 +84,10 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
} }
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0 && ret != -EACCES) if (ret < 0 && ret != -EACCES) {
kfree(vma);
goto out; goto out;
}
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
if (ret) if (ret)
...@@ -227,11 +229,12 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, ...@@ -227,11 +229,12 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nvkm_vma *vma; struct nvkm_vma *vma;
if (nvbo->bo.mem.mem_type == TTM_PL_TT) if (is_power_of_2(nvbo->valid_domains))
rep->domain = nvbo->valid_domains;
else if (nvbo->bo.mem.mem_type == TTM_PL_TT)
rep->domain = NOUVEAU_GEM_DOMAIN_GART; rep->domain = NOUVEAU_GEM_DOMAIN_GART;
else else
rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
rep->offset = nvbo->bo.offset; rep->offset = nvbo->bo.offset;
if (cli->vm) { if (cli->vm) {
vma = nouveau_bo_vma_find(nvbo, cli->vm); vma = nouveau_bo_vma_find(nvbo, cli->vm);
...@@ -665,7 +668,7 @@ int ...@@ -665,7 +668,7 @@ int
nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_abi16_chan *temp; struct nouveau_abi16_chan *temp;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
...@@ -681,7 +684,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ...@@ -681,7 +684,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
return -ENOMEM; return -ENOMEM;
list_for_each_entry(temp, &abi16->channels, head) { list_for_each_entry(temp, &abi16->channels, head) {
if (temp->chan->user.handle == (NVDRM_CHAN | req->channel)) { if (temp->chan->chid == req->channel) {
chan = temp->chan; chan = temp->chan;
break; break;
} }
......
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
static int nouveau_platform_probe(struct platform_device *pdev) static int nouveau_platform_probe(struct platform_device *pdev)
{ {
const struct nvkm_device_tegra_func *func;
struct nvkm_device *device; struct nvkm_device *device;
struct drm_device *drm; struct drm_device *drm;
int ret; int ret;
drm = nouveau_platform_device_create(pdev, &device); func = of_device_get_match_data(&pdev->dev);
drm = nouveau_platform_device_create(func, pdev, &device);
if (IS_ERR(drm)) if (IS_ERR(drm))
return PTR_ERR(drm); return PTR_ERR(drm);
...@@ -48,9 +51,19 @@ static int nouveau_platform_remove(struct platform_device *pdev) ...@@ -48,9 +51,19 @@ static int nouveau_platform_remove(struct platform_device *pdev)
} }
#if IS_ENABLED(CONFIG_OF) #if IS_ENABLED(CONFIG_OF)
static const struct nvkm_device_tegra_func gk20a_platform_data = {
.iommu_bit = 34,
};
static const struct of_device_id nouveau_platform_match[] = { static const struct of_device_id nouveau_platform_match[] = {
{ .compatible = "nvidia,gk20a" }, {
{ .compatible = "nvidia,gm20b" }, .compatible = "nvidia,gk20a",
.data = &gk20a_platform_data,
},
{
.compatible = "nvidia,gm20b",
.data = &gk20a_platform_data,
},
{ } { }
}; };
......
...@@ -188,9 +188,8 @@ nouveau_sysfs_init(struct drm_device *dev) ...@@ -188,9 +188,8 @@ nouveau_sysfs_init(struct drm_device *dev)
if (!sysfs) if (!sysfs)
return -ENOMEM; return -ENOMEM;
ret = nvif_object_init(&device->object, NVDRM_CONTROL, ret = nvif_object_init(&device->object, 0, NVIF_IOCTL_NEW_V0_CONTROL,
NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, NULL, 0, &sysfs->ctrl);
&sysfs->ctrl);
if (ret == 0) if (ret == 0)
device_create_file(nvxx_device(device)->dev, &dev_attr_pstate); device_create_file(nvxx_device(device)->dev, &dev_attr_pstate);
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include "nouveau_gem.h" #include "nouveau_gem.h"
#include "drm_legacy.h" #include "drm_legacy.h"
#include <core/tegra.h>
static int static int
nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
{ {
...@@ -338,7 +341,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) ...@@ -338,7 +341,7 @@ nouveau_ttm_init(struct nouveau_drm *drm)
struct nvkm_device *device = nvxx_device(&drm->device); struct nvkm_device *device = nvxx_device(&drm->device);
struct nvkm_pci *pci = device->pci; struct nvkm_pci *pci = device->pci;
struct drm_device *dev = drm->dev; struct drm_device *dev = drm->dev;
u32 bits; u8 bits;
int ret; int ret;
if (pci && pci->agp.bridge) { if (pci && pci->agp.bridge) {
...@@ -351,20 +354,28 @@ nouveau_ttm_init(struct nouveau_drm *drm) ...@@ -351,20 +354,28 @@ nouveau_ttm_init(struct nouveau_drm *drm)
bits = nvxx_mmu(&drm->device)->dma_bits; bits = nvxx_mmu(&drm->device)->dma_bits;
if (nvxx_device(&drm->device)->func->pci) { if (nvxx_device(&drm->device)->func->pci) {
if (drm->agp.bridge || if (drm->agp.bridge ||
!pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits))) !dma_supported(dev->dev, DMA_BIT_MASK(bits)))
bits = 32; bits = 32;
} else if (device->func->tegra) {
struct nvkm_device_tegra *tegra = device->func->tegra(device);
ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); /*
if (ret) * If the platform can use a IOMMU, then the addressable DMA
return ret; * space is constrained by the IOMMU bit
*/
if (tegra->func->iommu_bit)
bits = min(bits, tegra->func->iommu_bit);
ret = pci_set_consistent_dma_mask(dev->pdev,
DMA_BIT_MASK(bits));
if (ret)
pci_set_consistent_dma_mask(dev->pdev,
DMA_BIT_MASK(32));
} }
ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits));
if (ret)
return ret;
ret = dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(bits));
if (ret)
dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(32));
ret = nouveau_ttm_global_init(drm); ret = nouveau_ttm_global_init(drm);
if (ret) if (ret)
return ret; return ret;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nouveau_usif.h" #include "nouveau_usif.h"
#include "nouveau_abi16.h"
#include <nvif/notify.h> #include <nvif/notify.h>
#include <nvif/unpack.h> #include <nvif/unpack.h>
...@@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc) ...@@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
} else } else
goto done; goto done;
/* USIF slightly abuses some return-only ioctl members in order
* to provide interoperability with the older ABI16 objects
*/
mutex_lock(&cli->mutex); mutex_lock(&cli->mutex);
if (argv->v0.route) {
if (ret = -EINVAL, argv->v0.route == 0xff)
ret = nouveau_abi16_usif(filp, argv, argc);
if (ret) {
mutex_unlock(&cli->mutex);
goto done;
}
}
switch (argv->v0.type) { switch (argv->v0.type) {
case NVIF_IOCTL_V0_NEW: case NVIF_IOCTL_V0_NEW:
/* ... except if we're creating children */
argv->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
ret = usif_object_new(filp, data, size, argv, argc); ret = usif_object_new(filp, data, size, argv, argc);
break; break;
case NVIF_IOCTL_V0_NTFY_NEW: case NVIF_IOCTL_V0_NTFY_NEW:
......
...@@ -68,7 +68,6 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -68,7 +68,6 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
const s32 *oclass, u8 head, void *data, u32 size, const s32 *oclass, u8 head, void *data, u32 size,
struct nv50_chan *chan) struct nv50_chan *chan)
{ {
const u32 handle = (oclass[0] << 16) | head;
struct nvif_sclass *sclass; struct nvif_sclass *sclass;
int ret, i, n; int ret, i, n;
...@@ -81,7 +80,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -81,7 +80,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
while (oclass[0]) { while (oclass[0]) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (sclass[i].oclass == oclass[0]) { if (sclass[i].oclass == oclass[0]) {
ret = nvif_object_init(disp, handle, oclass[0], ret = nvif_object_init(disp, 0, oclass[0],
data, size, &chan->user); data, size, &chan->user);
if (ret == 0) if (ret == 0)
nvif_object_map(&chan->user); nvif_object_map(&chan->user);
...@@ -231,8 +230,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -231,8 +230,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
if (!dmac->ptr) if (!dmac->ptr)
return -ENOMEM; return -ENOMEM;
ret = nvif_object_init(&device->object, 0xd0000000, ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) { &(struct nv_dma_v0) {
.target = NV_DMA_V0_TARGET_PCI_US, .target = NV_DMA_V0_TARGET_PCI_US,
.access = NV_DMA_V0_ACCESS_RD, .access = NV_DMA_V0_ACCESS_RD,
.start = dmac->handle + 0x0000, .start = dmac->handle + 0x0000,
......
...@@ -637,7 +637,7 @@ nv46_chipset = { ...@@ -637,7 +637,7 @@ nv46_chipset = {
.imem = nv40_instmem_new, .imem = nv40_instmem_new,
.mc = nv44_mc_new, .mc = nv44_mc_new,
.mmu = nv44_mmu_new, .mmu = nv44_mmu_new,
.pci = nv4c_pci_new, .pci = nv46_pci_new,
.therm = nv40_therm_new, .therm = nv40_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -822,7 +822,7 @@ nv50_chipset = { ...@@ -822,7 +822,7 @@ nv50_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv50_pci_new, .pci = nv46_pci_new,
.therm = nv50_therm_new, .therm = nv50_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -929,7 +929,7 @@ nv84_chipset = { ...@@ -929,7 +929,7 @@ nv84_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv50_pci_new, .pci = g84_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -961,7 +961,7 @@ nv86_chipset = { ...@@ -961,7 +961,7 @@ nv86_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv50_pci_new, .pci = g84_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -993,7 +993,7 @@ nv92_chipset = { ...@@ -993,7 +993,7 @@ nv92_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv50_pci_new, .pci = g84_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1025,7 +1025,7 @@ nv94_chipset = { ...@@ -1025,7 +1025,7 @@ nv94_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1057,7 +1057,7 @@ nv96_chipset = { ...@@ -1057,7 +1057,7 @@ nv96_chipset = {
.mc = nv50_mc_new, .mc = nv50_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1089,7 +1089,7 @@ nv98_chipset = { ...@@ -1089,7 +1089,7 @@ nv98_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1121,7 +1121,7 @@ nva0_chipset = { ...@@ -1121,7 +1121,7 @@ nva0_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1153,7 +1153,7 @@ nva3_chipset = { ...@@ -1153,7 +1153,7 @@ nva3_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gt215_pmu_new, .pmu = gt215_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1187,7 +1187,7 @@ nva5_chipset = { ...@@ -1187,7 +1187,7 @@ nva5_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gt215_pmu_new, .pmu = gt215_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1220,7 +1220,7 @@ nva8_chipset = { ...@@ -1220,7 +1220,7 @@ nva8_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gt215_pmu_new, .pmu = gt215_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1253,7 +1253,7 @@ nvaa_chipset = { ...@@ -1253,7 +1253,7 @@ nvaa_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1285,7 +1285,7 @@ nvac_chipset = { ...@@ -1285,7 +1285,7 @@ nvac_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = g84_therm_new, .therm = g84_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = nv40_volt_new,
...@@ -1317,7 +1317,7 @@ nvaf_chipset = { ...@@ -1317,7 +1317,7 @@ nvaf_chipset = {
.mc = g98_mc_new, .mc = g98_mc_new,
.mmu = nv50_mmu_new, .mmu = nv50_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gt215_pmu_new, .pmu = gt215_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1388,7 +1388,7 @@ nvc1_chipset = { ...@@ -1388,7 +1388,7 @@ nvc1_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gf100_pmu_new, .pmu = gf100_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1423,7 +1423,7 @@ nvc3_chipset = { ...@@ -1423,7 +1423,7 @@ nvc3_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gf100_pmu_new, .pmu = gf100_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1566,7 +1566,7 @@ nvcf_chipset = { ...@@ -1566,7 +1566,7 @@ nvcf_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gf100_pmu_new, .pmu = gf100_pmu_new,
.therm = gt215_therm_new, .therm = gt215_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1595,13 +1595,13 @@ nvd7_chipset = { ...@@ -1595,13 +1595,13 @@ nvd7_chipset = {
.fuse = gf100_fuse_new, .fuse = gf100_fuse_new,
.gpio = gf119_gpio_new, .gpio = gf119_gpio_new,
.i2c = gf117_i2c_new, .i2c = gf117_i2c_new,
.ibus = gf100_ibus_new, .ibus = gf117_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
.ltc = gf100_ltc_new, .ltc = gf100_ltc_new,
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.ce[0] = gf100_ce_new, .ce[0] = gf100_ce_new,
...@@ -1628,13 +1628,13 @@ nvd9_chipset = { ...@@ -1628,13 +1628,13 @@ nvd9_chipset = {
.fuse = gf100_fuse_new, .fuse = gf100_fuse_new,
.gpio = gf119_gpio_new, .gpio = gf119_gpio_new,
.i2c = gf119_i2c_new, .i2c = gf119_i2c_new,
.ibus = gf100_ibus_new, .ibus = gf117_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
.ltc = gf100_ltc_new, .ltc = gf100_ltc_new,
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gf119_pmu_new, .pmu = gf119_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
...@@ -1669,11 +1669,11 @@ nve4_chipset = { ...@@ -1669,11 +1669,11 @@ nve4_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk104_pmu_new, .pmu = gk104_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1706,11 +1706,11 @@ nve6_chipset = { ...@@ -1706,11 +1706,11 @@ nve6_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk104_pmu_new, .pmu = gk104_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1743,11 +1743,11 @@ nve7_chipset = { ...@@ -1743,11 +1743,11 @@ nve7_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gf119_pmu_new, .pmu = gk104_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1804,11 +1804,11 @@ nvf0_chipset = { ...@@ -1804,11 +1804,11 @@ nvf0_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk110_pmu_new, .pmu = gk110_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1840,11 +1840,11 @@ nvf1_chipset = { ...@@ -1840,11 +1840,11 @@ nvf1_chipset = {
.mc = gf100_mc_new, .mc = gf100_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk110_pmu_new, .pmu = gk110_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1876,11 +1876,11 @@ nv106_chipset = { ...@@ -1876,11 +1876,11 @@ nv106_chipset = {
.mc = gk20a_mc_new, .mc = gk20a_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk208_pmu_new, .pmu = gk208_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1912,11 +1912,11 @@ nv108_chipset = { ...@@ -1912,11 +1912,11 @@ nv108_chipset = {
.mc = gk20a_mc_new, .mc = gk20a_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gk208_pmu_new, .pmu = gk208_pmu_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = nv40_volt_new, .volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new, .ce[1] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
...@@ -1948,10 +1948,11 @@ nv117_chipset = { ...@@ -1948,10 +1948,11 @@ nv117_chipset = {
.mc = gk20a_mc_new, .mc = gk20a_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gm107_pmu_new, .pmu = gm107_pmu_new,
.therm = gm107_therm_new, .therm = gm107_therm_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new, .ce[0] = gk104_ce_new,
.ce[2] = gk104_ce_new, .ce[2] = gk104_ce_new,
.disp = gm107_disp_new, .disp = gm107_disp_new,
...@@ -1978,9 +1979,10 @@ nv124_chipset = { ...@@ -1978,9 +1979,10 @@ nv124_chipset = {
.mc = gk20a_mc_new, .mc = gk20a_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gm107_pmu_new, .pmu = gm107_pmu_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gm204_ce_new, .ce[0] = gm204_ce_new,
.ce[1] = gm204_ce_new, .ce[1] = gm204_ce_new,
.ce[2] = gm204_ce_new, .ce[2] = gm204_ce_new,
...@@ -2008,9 +2010,10 @@ nv126_chipset = { ...@@ -2008,9 +2010,10 @@ nv126_chipset = {
.mc = gk20a_mc_new, .mc = gk20a_mc_new,
.mmu = gf100_mmu_new, .mmu = gf100_mmu_new,
.mxm = nv50_mxm_new, .mxm = nv50_mxm_new,
.pci = nv40_pci_new, .pci = g94_pci_new,
.pmu = gm107_pmu_new, .pmu = gm107_pmu_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.volt = gk104_volt_new,
.ce[0] = gm204_ce_new, .ce[0] = gm204_ce_new,
.ce[1] = gm204_ce_new, .ce[1] = gm204_ce_new,
.ce[2] = gm204_ce_new, .ce[2] = gm204_ce_new,
......
...@@ -258,6 +258,12 @@ nvkm_device_pci_10de_0df4[] = { ...@@ -258,6 +258,12 @@ nvkm_device_pci_10de_0df4[] = {
{} {}
}; };
static const struct nvkm_device_pci_vendor
nvkm_device_pci_10de_0fcd[] = {
{ 0x17aa, 0x3801, NULL, { .War00C800_0 = true } }, /* Lenovo Y510P */
{}
};
static const struct nvkm_device_pci_vendor static const struct nvkm_device_pci_vendor
nvkm_device_pci_10de_0fd2[] = { nvkm_device_pci_10de_0fd2[] = {
{ 0x1028, 0x0595, "GeForce GT 640M LE" }, { 0x1028, 0x0595, "GeForce GT 640M LE" },
...@@ -678,6 +684,7 @@ nvkm_device_pci_10de_1189[] = { ...@@ -678,6 +684,7 @@ nvkm_device_pci_10de_1189[] = {
static const struct nvkm_device_pci_vendor static const struct nvkm_device_pci_vendor
nvkm_device_pci_10de_1199[] = { nvkm_device_pci_10de_1199[] = {
{ 0x1458, 0xd001, "GeForce GTX 760" }, { 0x1458, 0xd001, "GeForce GTX 760" },
{ 0x1462, 0x1106, "GeForce GTX 780M", { .War00C800_0 = true } }, /* Medion Erazer X7827 */
{} {}
}; };
...@@ -1349,7 +1356,7 @@ nvkm_device_pci_10de[] = { ...@@ -1349,7 +1356,7 @@ nvkm_device_pci_10de[] = {
{ 0x0fc6, "GeForce GTX 650" }, { 0x0fc6, "GeForce GTX 650" },
{ 0x0fc8, "GeForce GT 740" }, { 0x0fc8, "GeForce GT 740" },
{ 0x0fc9, "GeForce GT 730" }, { 0x0fc9, "GeForce GT 730" },
{ 0x0fcd, "GeForce GT 755M" }, { 0x0fcd, "GeForce GT 755M", nvkm_device_pci_10de_0fcd },
{ 0x0fce, "GeForce GT 640M LE" }, { 0x0fce, "GeForce GT 640M LE" },
{ 0x0fd1, "GeForce GT 650M" }, { 0x0fd1, "GeForce GT 650M" },
{ 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 }, { 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 },
......
...@@ -85,6 +85,9 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) ...@@ -85,6 +85,9 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
unsigned long pgsize_bitmap; unsigned long pgsize_bitmap;
int ret; int ret;
if (!tdev->func->iommu_bit)
return;
mutex_init(&tdev->iommu.mutex); mutex_init(&tdev->iommu.mutex);
if (iommu_present(&platform_bus_type)) { if (iommu_present(&platform_bus_type)) {
...@@ -114,7 +117,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) ...@@ -114,7 +117,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
goto free_domain; goto free_domain;
ret = nvkm_mm_init(&tdev->iommu.mm, 0, ret = nvkm_mm_init(&tdev->iommu.mm, 0,
(1ULL << 40) >> tdev->iommu.pgshift, 1); (1ULL << tdev->func->iommu_bit) >>
tdev->iommu.pgshift, 1);
if (ret) if (ret)
goto detach_device; goto detach_device;
} }
...@@ -237,7 +241,8 @@ nvkm_device_tegra_func = { ...@@ -237,7 +241,8 @@ nvkm_device_tegra_func = {
}; };
int int
nvkm_device_tegra_new(struct platform_device *pdev, nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
struct platform_device *pdev,
const char *cfg, const char *dbg, const char *cfg, const char *dbg,
bool detect, bool mmio, u64 subdev_mask, bool detect, bool mmio, u64 subdev_mask,
struct nvkm_device **pdevice) struct nvkm_device **pdevice)
...@@ -248,6 +253,7 @@ nvkm_device_tegra_new(struct platform_device *pdev, ...@@ -248,6 +253,7 @@ nvkm_device_tegra_new(struct platform_device *pdev,
if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
*pdevice = &tdev->device; *pdevice = &tdev->device;
tdev->func = func;
tdev->pdev = pdev; tdev->pdev = pdev;
tdev->irq = -1; tdev->irq = -1;
...@@ -285,7 +291,8 @@ nvkm_device_tegra_new(struct platform_device *pdev, ...@@ -285,7 +291,8 @@ nvkm_device_tegra_new(struct platform_device *pdev,
} }
#else #else
int int
nvkm_device_tegra_new(struct platform_device *pdev, nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
struct platform_device *pdev,
const char *cfg, const char *dbg, const char *cfg, const char *dbg,
bool detect, bool mmio, u64 subdev_mask, bool detect, bool mmio, u64 subdev_mask,
struct nvkm_device **pdevice) struct nvkm_device **pdevice)
......
...@@ -109,7 +109,7 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) ...@@ -109,7 +109,7 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return -EINVAL; return -EINVAL;
} }
static struct nvkm_object_func static const struct nvkm_object_func
nv04_disp_root = { nv04_disp_root = {
.mthd = nv04_disp_mthd, .mthd = nv04_disp_mthd,
.ntfy = nvkm_disp_ntfy, .ntfy = nvkm_disp_ntfy,
......
...@@ -882,6 +882,7 @@ static const struct nvkm_enum gf100_mp_warp_error[] = { ...@@ -882,6 +882,7 @@ static const struct nvkm_enum gf100_mp_warp_error[] = {
{ 0x0d, "GPR_OUT_OF_BOUNDS" }, { 0x0d, "GPR_OUT_OF_BOUNDS" },
{ 0x0e, "MEM_OUT_OF_BOUNDS" }, { 0x0e, "MEM_OUT_OF_BOUNDS" },
{ 0x0f, "UNALIGNED_MEM_ACCESS" }, { 0x0f, "UNALIGNED_MEM_ACCESS" },
{ 0x10, "INVALID_ADDR_SPACE" },
{ 0x11, "INVALID_PARAM" }, { 0x11, "INVALID_PARAM" },
{} {}
}; };
......
...@@ -98,6 +98,7 @@ gf110_gr = { ...@@ -98,6 +98,7 @@ gf110_gr = {
{ -1, -1, FERMI_B, &gf100_fermi }, { -1, -1, FERMI_B, &gf100_fermi },
{ -1, -1, FERMI_C, &gf100_fermi }, { -1, -1, FERMI_C, &gf100_fermi },
{ -1, -1, FERMI_COMPUTE_A }, { -1, -1, FERMI_COMPUTE_A },
{ -1, -1, FERMI_COMPUTE_B },
{} {}
} }
}; };
......
...@@ -135,6 +135,7 @@ gf117_gr = { ...@@ -135,6 +135,7 @@ gf117_gr = {
{ -1, -1, FERMI_B, &gf100_fermi }, { -1, -1, FERMI_B, &gf100_fermi },
{ -1, -1, FERMI_C, &gf100_fermi }, { -1, -1, FERMI_C, &gf100_fermi },
{ -1, -1, FERMI_COMPUTE_A }, { -1, -1, FERMI_COMPUTE_A },
{ -1, -1, FERMI_COMPUTE_B },
{} {}
} }
}; };
......
...@@ -189,6 +189,7 @@ gf119_gr = { ...@@ -189,6 +189,7 @@ gf119_gr = {
{ -1, -1, FERMI_B, &gf100_fermi }, { -1, -1, FERMI_B, &gf100_fermi },
{ -1, -1, FERMI_C, &gf100_fermi }, { -1, -1, FERMI_C, &gf100_fermi },
{ -1, -1, FERMI_COMPUTE_A }, { -1, -1, FERMI_COMPUTE_A },
{ -1, -1, FERMI_COMPUTE_B },
{} {}
} }
}; };
......
...@@ -633,7 +633,7 @@ nvkm_perfmon_dtor(struct nvkm_object *object) ...@@ -633,7 +633,7 @@ nvkm_perfmon_dtor(struct nvkm_object *object)
return perfmon; return perfmon;
} }
static struct nvkm_object_func static const struct nvkm_object_func
nvkm_perfmon = { nvkm_perfmon = {
.dtor = nvkm_perfmon_dtor, .dtor = nvkm_perfmon_dtor,
.mthd = nvkm_perfmon_mthd, .mthd = nvkm_perfmon_mthd,
......
...@@ -61,19 +61,6 @@ nvbios_pmuTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) ...@@ -61,19 +61,6 @@ nvbios_pmuTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
return data; return data;
} }
u32
nvbios_pmuTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_pmuT *info)
{
u32 data = nvbios_pmuTe(bios, ver, hdr, cnt, len);
memset(info, 0x00, sizeof(*info));
switch (!!data * *ver) {
default:
break;
}
return data;
}
u32 u32
nvbios_pmuEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr) nvbios_pmuEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
{ {
......
...@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx, ...@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2; p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2;
p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3; p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3; p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3;
p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7;
p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1; p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2; p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2;
p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5; p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
...@@ -205,6 +206,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data, ...@@ -205,6 +206,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6; p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0; p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0; p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0;
p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
p->ramcfg_10_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0; p->ramcfg_10_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0;
p->ramcfg_10_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0; p->ramcfg_10_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
p->ramcfg_10_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0; p->ramcfg_10_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0;
...@@ -219,7 +221,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data, ...@@ -219,7 +221,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2; p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2;
p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3; p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3;
p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4; p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4;
p->ramcfg_11_01_20 = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5; p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5;
p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6; p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7; p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0; p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
......
...@@ -73,15 +73,19 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, ...@@ -73,15 +73,19 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
memset(info, 0x00, sizeof(*info)); memset(info, 0x00, sizeof(*info));
switch (!!volt * *ver) { switch (!!volt * *ver) {
case 0x12: case 0x12:
info->type = NVBIOS_VOLT_GPIO;
info->vidmask = nvbios_rd08(bios, volt + 0x04); info->vidmask = nvbios_rd08(bios, volt + 0x04);
break; break;
case 0x20: case 0x20:
info->type = NVBIOS_VOLT_GPIO;
info->vidmask = nvbios_rd08(bios, volt + 0x05); info->vidmask = nvbios_rd08(bios, volt + 0x05);
break; break;
case 0x30: case 0x30:
info->type = NVBIOS_VOLT_GPIO;
info->vidmask = nvbios_rd08(bios, volt + 0x04); info->vidmask = nvbios_rd08(bios, volt + 0x04);
break; break;
case 0x40: case 0x40:
info->type = NVBIOS_VOLT_GPIO;
info->base = nvbios_rd32(bios, volt + 0x04); info->base = nvbios_rd32(bios, volt + 0x04);
info->step = nvbios_rd16(bios, volt + 0x08); info->step = nvbios_rd16(bios, volt + 0x08);
info->vidmask = nvbios_rd08(bios, volt + 0x0b); info->vidmask = nvbios_rd08(bios, volt + 0x0b);
...@@ -90,11 +94,20 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, ...@@ -90,11 +94,20 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
info->max = info->base; info->max = info->base;
break; break;
case 0x50: case 0x50:
info->vidmask = nvbios_rd08(bios, volt + 0x06);
info->min = nvbios_rd32(bios, volt + 0x0a); info->min = nvbios_rd32(bios, volt + 0x0a);
info->max = nvbios_rd32(bios, volt + 0x0e); info->max = nvbios_rd32(bios, volt + 0x0e);
info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;
info->step = nvbios_rd16(bios, volt + 0x16);
/* offset 4 seems to be a flag byte */
if (nvbios_rd32(bios, volt + 0x4) & 1) {
info->type = NVBIOS_VOLT_PWM;
info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000;
info->pwm_range = nvbios_rd32(bios, volt + 0x16);
} else {
info->type = NVBIOS_VOLT_GPIO;
info->vidmask = nvbios_rd08(bios, volt + 0x06);
info->step = nvbios_rd16(bios, volt + 0x16);
}
break; break;
} }
return volt; return volt;
......
...@@ -131,6 +131,38 @@ nvkm_hwsq_wait(struct nvkm_hwsq *hwsq, u8 flag, u8 data) ...@@ -131,6 +131,38 @@ nvkm_hwsq_wait(struct nvkm_hwsq *hwsq, u8 flag, u8 data)
hwsq_cmd(hwsq, 3, (u8[]){ 0x5f, flag, data }); hwsq_cmd(hwsq, 3, (u8[]){ 0x5f, flag, data });
} }
void
nvkm_hwsq_wait_vblank(struct nvkm_hwsq *hwsq)
{
struct nvkm_subdev *subdev = hwsq->subdev;
struct nvkm_device *device = subdev->device;
u32 heads, x, y, px = 0;
int i, head_sync;
heads = nvkm_rd32(device, 0x610050);
for (i = 0; i < 2; i++) {
/* Heuristic: sync to head with biggest resolution */
if (heads & (2 << (i << 3))) {
x = nvkm_rd32(device, 0x610b40 + (0x540 * i));
y = (x & 0xffff0000) >> 16;
x &= 0x0000ffff;
if ((x * y) > px) {
px = (x * y);
head_sync = i;
}
}
}
if (px == 0) {
nvkm_debug(subdev, "WAIT VBLANK !NO ACTIVE HEAD\n");
return;
}
nvkm_debug(subdev, "WAIT VBLANK HEAD%d\n", head_sync);
nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x0);
nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x1);
}
void void
nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec) nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec)
{ {
......
...@@ -133,6 +133,12 @@ hwsq_wait(struct hwsq *ram, u8 flag, u8 data) ...@@ -133,6 +133,12 @@ hwsq_wait(struct hwsq *ram, u8 flag, u8 data)
nvkm_hwsq_wait(ram->hwsq, flag, data); nvkm_hwsq_wait(ram->hwsq, flag, data);
} }
static inline void
hwsq_wait_vblank(struct hwsq *ram)
{
nvkm_hwsq_wait_vblank(ram->hwsq);
}
static inline void static inline void
hwsq_nsec(struct hwsq *ram, u32 nsec) hwsq_nsec(struct hwsq *ram, u32 nsec)
{ {
......
...@@ -44,5 +44,5 @@ int ...@@ -44,5 +44,5 @@ int
g84_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk) g84_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
{ {
return nv50_clk_new_(&g84_clk, device, index, return nv50_clk_new_(&g84_clk, device, index,
(device->chipset == 0xa0), pclk); (device->chipset >= 0x94), pclk);
} }
...@@ -63,7 +63,7 @@ ramgddr3_wr_lo[] = { ...@@ -63,7 +63,7 @@ ramgddr3_wr_lo[] = {
{ 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 }, { 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
{ 11, 0 }, { 13 , 1 }, { 11, 0 }, { 13 , 1 },
/* the below are mentioned in some, but not all, gddr3 docs */ /* the below are mentioned in some, but not all, gddr3 docs */
{ 4, 1 }, { 6, 3 }, { 12, 1 }, { 4, 0 }, { 6, 3 }, { 12, 1 },
{ -1 } { -1 }
}; };
...@@ -87,15 +87,17 @@ nvkm_gddr3_calc(struct nvkm_ram *ram) ...@@ -87,15 +87,17 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16; WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
/* XXX: Get these values from the VBIOS instead */ /* XXX: Get these values from the VBIOS instead */
DLL = !(ram->mr[1] & 0x1); DLL = !(ram->mr[1] & 0x1);
ODT = (ram->mr[1] & 0x004) >> 2 |
(ram->mr[1] & 0x040) >> 5 |
(ram->mr[1] & 0x200) >> 7;
RON = !(ram->mr[1] & 0x300) >> 8; RON = !(ram->mr[1] & 0x300) >> 8;
break; break;
default: default:
return -ENOSYS; return -ENOSYS;
} }
if (ram->next->bios.timing_ver == 0x20 ||
ram->next->bios.ramcfg_timing == 0xff) {
ODT = (ram->mr[1] & 0xc) >> 2;
}
hi = ram->mr[2] & 0x1; hi = ram->mr[2] & 0x1;
CL = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL); CL = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL);
WR = ramxlat(ramgddr3_wr_lo, WR); WR = ramxlat(ramgddr3_wr_lo, WR);
......
...@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts) ...@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
int WL, CL, WR, at[2], dt, ds; int WL, CL, WR, at[2], dt, ds;
int rq = ram->freq < 1000000; /* XXX */ int rq = ram->freq < 1000000; /* XXX */
xd = !ram->next->bios.ramcfg_DLLoff;
switch (ram->next->bios.ramcfg_ver) { switch (ram->next->bios.ramcfg_ver) {
case 0x11: case 0x11:
pd = ram->next->bios.ramcfg_11_01_80; pd = ram->next->bios.ramcfg_11_01_80;
lf = ram->next->bios.ramcfg_11_01_40; lf = ram->next->bios.ramcfg_11_01_40;
xd = !ram->next->bios.ramcfg_11_01_20;
vh = ram->next->bios.ramcfg_11_02_10; vh = ram->next->bios.ramcfg_11_02_10;
vr = ram->next->bios.ramcfg_11_02_04; vr = ram->next->bios.ramcfg_11_02_04;
vo = ram->next->bios.ramcfg_11_06; vo = ram->next->bios.ramcfg_11_06;
......
...@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct gk104_ram *ram, u32 freq) ...@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct gk104_ram *ram, u32 freq)
* DDR3 * DDR3
******************************************************************************/ ******************************************************************************/
static void
nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
{
ram_nuke(fuc, mr[0]);
ram_mask(fuc, mr[0], 0x100, 0x100);
ram_mask(fuc, mr[0], 0x100, 0x000);
}
static void
nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
{
u32 mr1_old = ram_rd32(fuc, mr[1]);
if (!(mr1_old & 0x1)) {
ram_mask(fuc, mr[1], 0x1, 0x1);
ram_nsec(fuc, 1000);
}
}
static int static int
gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq) gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
{ {
...@@ -702,6 +721,10 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq) ...@@ -702,6 +721,10 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000); ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
if (next->bios.ramcfg_DLLoff)
nvkm_sddr3_dll_disable(fuc);
ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */ ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
...@@ -879,17 +902,20 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq) ...@@ -879,17 +902,20 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
ram_nsec(fuc, 1000); ram_nsec(fuc, 1000);
ram_nuke(fuc, mr[0]); if (!next->bios.ramcfg_DLLoff) {
ram_mask(fuc, mr[0], 0x100, 0x100); ram_mask(fuc, mr[1], 0x1, 0x0);
ram_mask(fuc, mr[0], 0x100, 0x000); nvkm_sddr3_dll_reset(fuc);
}
ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]); ram_mask(fuc, mr[2], 0x00000fff, ram->base.mr[2]);
ram_mask(fuc, mr[1], 0xffffffff, ram->base.mr[1]);
ram_wr32(fuc, mr[0], ram->base.mr[0]); ram_wr32(fuc, mr[0], ram->base.mr[0]);
ram_nsec(fuc, 1000); ram_nsec(fuc, 1000);
ram_nuke(fuc, mr[0]); if (!next->bios.ramcfg_DLLoff) {
ram_mask(fuc, mr[0], 0x100, 0x100); nvkm_sddr3_dll_reset(fuc);
ram_mask(fuc, mr[0], 0x100, 0x000); ram_nsec(fuc, 1000);
}
if (vc == 0 && ram_have(fuc, gpio2E)) { if (vc == 0 && ram_have(fuc, gpio2E)) {
u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]); u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
...@@ -944,6 +970,67 @@ gk104_ram_calc_data(struct gk104_ram *ram, u32 khz, struct nvkm_ram_data *data) ...@@ -944,6 +970,67 @@ gk104_ram_calc_data(struct gk104_ram *ram, u32 khz, struct nvkm_ram_data *data)
return -EINVAL; return -EINVAL;
} }
static int
gk104_calc_pll_output(int fN, int M, int N, int P, int clk)
{
return ((clk * N) + (((u16)(fN + 4096) * clk) >> 13)) / (M * P);
}
static int
gk104_pll_calc_hiclk(int target_khz, int crystal,
int *N1, int *fN1, int *M1, int *P1,
int *N2, int *M2, int *P2)
{
int best_clk = 0, best_err = target_khz, p_ref, n_ref;
bool upper = false;
*M1 = 1;
/* M has to be 1, otherwise it gets unstable */
*M2 = 1;
/* can be 1 or 2, sticking with 1 for simplicity */
*P2 = 1;
for (p_ref = 0x7; p_ref >= 0x5; --p_ref) {
for (n_ref = 0x25; n_ref <= 0x2b; ++n_ref) {
int cur_N, cur_clk, cur_err;
cur_clk = gk104_calc_pll_output(0, 1, n_ref, p_ref, crystal);
cur_N = target_khz / cur_clk;
cur_err = target_khz
- gk104_calc_pll_output(0xf000, 1, cur_N, 1, cur_clk);
/* we found a better combination */
if (cur_err < best_err) {
best_err = cur_err;
best_clk = cur_clk;
*N2 = cur_N;
*N1 = n_ref;
*P1 = p_ref;
upper = false;
}
cur_N += 1;
cur_err = gk104_calc_pll_output(0xf000, 1, cur_N, 1, cur_clk)
- target_khz;
if (cur_err < best_err) {
best_err = cur_err;
best_clk = cur_clk;
*N2 = cur_N;
*N1 = n_ref;
*P1 = p_ref;
upper = true;
}
}
}
/* adjust fN to get closer to the target clock */
*fN1 = (u16)((((best_err / *N2 * *P2) * (*P1 * *M1)) << 13) / crystal);
if (upper)
*fN1 = (u16)(1 - *fN1);
return gk104_calc_pll_output(*fN1, 1, *N1, *P1, crystal);
}
static int static int
gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next) gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next)
{ {
...@@ -968,31 +1055,24 @@ gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next) ...@@ -968,31 +1055,24 @@ gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next)
* kepler boards, no idea how/why they're chosen. * kepler boards, no idea how/why they're chosen.
*/ */
refclk = next->freq; refclk = next->freq;
if (ram->mode == 2)
refclk = fuc->mempll.refclk;
/* calculate refpll coefficients */
ret = gt215_pll_calc(subdev, &fuc->refpll, refclk, &ram->N1,
&ram->fN1, &ram->M1, &ram->P1);
fuc->mempll.refclk = ret;
if (ret <= 0) {
nvkm_error(subdev, "unable to calc refpll\n");
return -EINVAL;
}
/* calculate mempll coefficients, if we're using it */
if (ram->mode == 2) { if (ram->mode == 2) {
/* post-divider doesn't work... the reg takes the values but ret = gk104_pll_calc_hiclk(next->freq, subdev->device->crystal,
* appears to completely ignore it. there *is* a bit at &ram->N1, &ram->fN1, &ram->M1, &ram->P1,
* bit 28 that appears to divide the clock by 2 if set. &ram->N2, &ram->M2, &ram->P2);
*/ fuc->mempll.refclk = ret;
fuc->mempll.min_p = 1; if (ret <= 0) {
fuc->mempll.max_p = 2; nvkm_error(subdev, "unable to calc plls\n");
return -EINVAL;
ret = gt215_pll_calc(subdev, &fuc->mempll, next->freq, }
&ram->N2, NULL, &ram->M2, &ram->P2); nvkm_debug(subdev, "sucessfully calced PLLs for clock %i kHz"
" (refclock: %i kHz)\n", next->freq, ret);
} else {
/* calculate refpll coefficients */
ret = gt215_pll_calc(subdev, &fuc->refpll, refclk, &ram->N1,
&ram->fN1, &ram->M1, &ram->P1);
fuc->mempll.refclk = ret;
if (ret <= 0) { if (ret <= 0) {
nvkm_error(subdev, "unable to calc mempll\n"); nvkm_error(subdev, "unable to calc refpll\n");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1600,6 +1680,7 @@ gk104_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ...@@ -1600,6 +1680,7 @@ gk104_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
break; break;
case NVKM_RAM_TYPE_DDR3: case NVKM_RAM_TYPE_DDR3:
ram->fuc.r_mr[0] = ramfuc_reg(0x10f300); ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
ram->fuc.r_mr[1] = ramfuc_reg(0x10f304);
ram->fuc.r_mr[2] = ramfuc_reg(0x10f320); ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
break; break;
default: default:
......
...@@ -34,9 +34,6 @@ ...@@ -34,9 +34,6 @@
#include <subdev/clk/gt215.h> #include <subdev/clk/gt215.h>
#include <subdev/gpio.h> #include <subdev/gpio.h>
/* XXX: Remove when memx gains GPIO support */
extern int nv50_gpio_location(int line, u32 *reg, u32 *shift);
struct gt215_ramfuc { struct gt215_ramfuc {
struct ramfuc base; struct ramfuc base;
struct ramfuc_reg r_0x001610; struct ramfuc_reg r_0x001610;
...@@ -75,7 +72,7 @@ struct gt215_ramfuc { ...@@ -75,7 +72,7 @@ struct gt215_ramfuc {
struct ramfuc_reg r_0x111400; struct ramfuc_reg r_0x111400;
struct ramfuc_reg r_0x611200; struct ramfuc_reg r_0x611200;
struct ramfuc_reg r_mr[4]; struct ramfuc_reg r_mr[4];
struct ramfuc_reg r_gpioFBVREF; struct ramfuc_reg r_gpio[4];
}; };
struct gt215_ltrain { struct gt215_ltrain {
...@@ -466,24 +463,27 @@ gt215_ram_lock_pll(struct gt215_ramfuc *fuc, struct gt215_clk_info *mclk) ...@@ -466,24 +463,27 @@ gt215_ram_lock_pll(struct gt215_ramfuc *fuc, struct gt215_clk_info *mclk)
} }
static void static void
gt215_ram_fbvref(struct gt215_ramfuc *fuc, u32 val) gt215_ram_gpio(struct gt215_ramfuc *fuc, u8 tag, u32 val)
{ {
struct nvkm_gpio *gpio = fuc->base.fb->subdev.device->gpio; struct nvkm_gpio *gpio = fuc->base.fb->subdev.device->gpio;
struct dcb_gpio_func func; struct dcb_gpio_func func;
u32 reg, sh, gpio_val; u32 reg, sh, gpio_val;
int ret; int ret;
if (nvkm_gpio_get(gpio, 0, 0x2e, DCB_GPIO_UNUSED) != val) { if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func); ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
if (ret) if (ret)
return; return;
nv50_gpio_location(func.line, &reg, &sh); reg = func.line >> 3;
gpio_val = ram_rd32(fuc, gpioFBVREF); sh = (func.line & 0x7) << 2;
gpio_val = ram_rd32(fuc, gpio[reg]);
if (gpio_val & (8 << sh)) if (gpio_val & (8 << sh))
val = !val; val = !val;
if (!(func.log[1] & 1))
val = !val;
ram_mask(fuc, gpioFBVREF, (0x3 << sh), ((val | 0x2) << sh)); ram_mask(fuc, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
ram_nsec(fuc, 20000); ram_nsec(fuc, 20000);
} }
} }
...@@ -498,6 +498,7 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -498,6 +498,7 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
struct nvkm_bios *bios = device->bios; struct nvkm_bios *bios = device->bios;
struct gt215_clk_info mclk; struct gt215_clk_info mclk;
struct nvkm_gpio *gpio = device->gpio;
struct nvkm_ram_data *next; struct nvkm_ram_data *next;
u8 ver, hdr, cnt, len, strap; u8 ver, hdr, cnt, len, strap;
u32 data; u32 data;
...@@ -642,8 +643,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -642,8 +643,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
break; break;
} }
if (fuc->r_gpioFBVREF.addr && next->bios.timing_10_ODT) if (next->bios.timing_10_ODT)
gt215_ram_fbvref(fuc, 0); gt215_ram_gpio(fuc, 0x2e, 1);
/* Brace RAM for impact */ /* Brace RAM for impact */
ram_wr32(fuc, 0x1002d4, 0x00000001); ram_wr32(fuc, 0x1002d4, 0x00000001);
...@@ -656,6 +657,23 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -656,6 +657,23 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
if (device->chipset == 0xa3 && freq <= 500000) if (device->chipset == 0xa3 && freq <= 500000)
ram_mask(fuc, 0x100700, 0x00000006, 0x00000006); ram_mask(fuc, 0x100700, 0x00000006, 0x00000006);
/* Alter FBVDD/Q, apparently must be done with PLL disabled, thus
* set it to bypass */
if (nvkm_gpio_get(gpio, 0, 0x18, DCB_GPIO_UNUSED) ==
next->bios.ramcfg_FBVDDQ) {
data = ram_rd32(fuc, 0x004000) & 0x9;
if (data == 0x1)
ram_mask(fuc, 0x004000, 0x8, 0x8);
if (data & 0x1)
ram_mask(fuc, 0x004000, 0x1, 0x0);
gt215_ram_gpio(fuc, 0x18, !next->bios.ramcfg_FBVDDQ);
if (data & 0x1)
ram_mask(fuc, 0x004000, 0x1, 0x1);
}
/* Fiddle with clocks */ /* Fiddle with clocks */
/* There's 4 scenario's /* There's 4 scenario's
* pll->pll: first switch to a 324MHz clock, set up new PLL, switch * pll->pll: first switch to a 324MHz clock, set up new PLL, switch
...@@ -753,39 +771,43 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -753,39 +771,43 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100; unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100;
r111100 = ram_rd32(fuc, 0x111100) & ~0x3a800000; r111100 = ram_rd32(fuc, 0x111100) & ~0x3a800000;
if (next->bios.ramcfg_10_02_04) { /* NVA8 seems to skip various bits related to ramcfg_10_02_04 */
switch (ram->base.type) { if (device->chipset == 0xa8) {
case NVKM_RAM_TYPE_DDR3: r111100 |= 0x08000000;
if (device->chipset != 0xa8) if (!next->bios.ramcfg_10_02_04)
r111100 |= 0x00000004;
/* no break */
case NVKM_RAM_TYPE_DDR2:
r111100 |= 0x08000000;
break;
default:
break;
}
} else {
switch (ram->base.type) {
case NVKM_RAM_TYPE_DDR2:
r111100 |= 0x1a800000;
unk714 |= 0x00000010; unk714 |= 0x00000010;
break; } else {
case NVKM_RAM_TYPE_DDR3: if (next->bios.ramcfg_10_02_04) {
if (device->chipset == 0xa8) { switch (ram->base.type) {
r111100 |= 0x08000000; case NVKM_RAM_TYPE_DDR2:
} else { case NVKM_RAM_TYPE_DDR3:
r111100 &= ~0x00000004; r111100 &= ~0x00000020;
if (next->bios.ramcfg_10_02_10)
r111100 |= 0x08000004;
else
r111100 |= 0x00000024;
break;
default:
break;
}
} else {
switch (ram->base.type) {
case NVKM_RAM_TYPE_DDR2:
case NVKM_RAM_TYPE_DDR3:
r111100 &= ~0x00000024;
r111100 |= 0x12800000; r111100 |= 0x12800000;
if (next->bios.ramcfg_10_02_10)
r111100 |= 0x08000000;
unk714 |= 0x00000010;
break;
case NVKM_RAM_TYPE_GDDR3:
r111100 |= 0x30000000;
unk714 |= 0x00000020;
break;
default:
break;
} }
unk714 |= 0x00000010;
break;
case NVKM_RAM_TYPE_GDDR3:
r111100 |= 0x30000000;
unk714 |= 0x00000020;
break;
default:
break;
} }
} }
...@@ -809,8 +831,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -809,8 +831,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(fuc, 0x100718, 0xffffffff, unk718); ram_mask(fuc, 0x100718, 0xffffffff, unk718);
ram_mask(fuc, 0x111100, 0xffffffff, r111100); ram_mask(fuc, 0x111100, 0xffffffff, r111100);
if (fuc->r_gpioFBVREF.addr && !next->bios.timing_10_ODT) if (!next->bios.timing_10_ODT)
gt215_ram_fbvref(fuc, 1); gt215_ram_gpio(fuc, 0x2e, 0);
/* Reset DLL */ /* Reset DLL */
if (!next->bios.ramcfg_DLLoff) if (!next->bios.ramcfg_DLLoff)
...@@ -919,10 +941,7 @@ gt215_ram_func = { ...@@ -919,10 +941,7 @@ gt215_ram_func = {
int int
gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{ {
struct nvkm_gpio *gpio = fb->subdev.device->gpio;
struct dcb_gpio_func func;
struct gt215_ram *ram; struct gt215_ram *ram;
u32 reg, shift;
int ret, i; int ret, i;
if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
...@@ -981,12 +1000,10 @@ gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ...@@ -981,12 +1000,10 @@ gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0); ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0);
ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4); ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
} }
ram->fuc.r_gpio[0] = ramfuc_reg(0x00e104);
ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func); ram->fuc.r_gpio[1] = ramfuc_reg(0x00e108);
if (ret == 0) { ram->fuc.r_gpio[2] = ramfuc_reg(0x00e120);
nv50_gpio_location(func.line, &reg, &shift); ram->fuc.r_gpio[3] = ramfuc_reg(0x00e124);
ram->fuc.r_gpioFBVREF = ramfuc_reg(reg);
}
return 0; return 0;
} }
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <subdev/bios/rammap.h> #include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h> #include <subdev/bios/timing.h>
#include <subdev/clk/pll.h> #include <subdev/clk/pll.h>
#include <subdev/gpio.h>
struct nv50_ramseq { struct nv50_ramseq {
struct hwsq base; struct hwsq base;
...@@ -59,6 +60,7 @@ struct nv50_ramseq { ...@@ -59,6 +60,7 @@ struct nv50_ramseq {
struct hwsq_reg r_0x611200; struct hwsq_reg r_0x611200;
struct hwsq_reg r_timing[9]; struct hwsq_reg r_timing[9];
struct hwsq_reg r_mr[4]; struct hwsq_reg r_mr[4];
struct hwsq_reg r_gpio[4];
}; };
struct nv50_ram { struct nv50_ram {
...@@ -144,6 +146,38 @@ nv50_ram_timing_calc(struct nv50_ram *ram, u32 *timing) ...@@ -144,6 +146,38 @@ nv50_ram_timing_calc(struct nv50_ram *ram, u32 *timing)
nvkm_debug(subdev, " 240: %08x\n", timing[8]); nvkm_debug(subdev, " 240: %08x\n", timing[8]);
return 0; return 0;
} }
static int
nv50_ram_timing_read(struct nv50_ram *ram, u32 *timing)
{
unsigned int i;
struct nvbios_ramcfg *cfg = &ram->base.target.bios;
struct nvkm_subdev *subdev = &ram->base.fb->subdev;
struct nvkm_device *device = subdev->device;
for (i = 0; i <= 8; i++)
timing[i] = nvkm_rd32(device, 0x100220 + (i * 4));
/* Derive the bare minimum for the MR calculation to succeed */
cfg->timing_ver = 0x10;
T(CL) = (timing[3] & 0xff) + 1;
switch (ram->base.type) {
case NVKM_RAM_TYPE_DDR2:
T(CWL) = T(CL) - 1;
break;
case NVKM_RAM_TYPE_GDDR3:
T(CWL) = ((timing[2] & 0xff000000) >> 24) + 1;
break;
default:
return -ENOSYS;
break;
}
T(WR) = ((timing[1] >> 24) & 0xff) - 1 - T(CWL);
return 0;
}
#undef T #undef T
static void static void
...@@ -154,6 +188,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq) ...@@ -154,6 +188,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
ram_nsec(hwsq, 24000); ram_nsec(hwsq, 24000);
} }
static void
nv50_ram_gpio(struct nv50_ramseq *hwsq, u8 tag, u32 val)
{
struct nvkm_gpio *gpio = hwsq->base.subdev->device->gpio;
struct dcb_gpio_func func;
u32 reg, sh, gpio_val;
int ret;
if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
if (ret)
return;
reg = func.line >> 3;
sh = (func.line & 0x7) << 2;
gpio_val = ram_rd32(hwsq, gpio[reg]);
if (gpio_val & (8 << sh))
val = !val;
if (!(func.log[1] & 1))
val = !val;
ram_mask(hwsq, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
ram_nsec(hwsq, 20000);
}
}
static int static int
nv50_ram_calc(struct nvkm_ram *base, u32 freq) nv50_ram_calc(struct nvkm_ram *base, u32 freq)
{ {
...@@ -213,10 +274,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -213,10 +274,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
strap, data, ver, hdr); strap, data, ver, hdr);
return -EINVAL; return -EINVAL;
} }
nv50_ram_timing_calc(ram, timing);
} else {
nv50_ram_timing_read(ram, timing);
} }
nv50_ram_timing_calc(ram, timing);
ret = ram_init(hwsq, subdev); ret = ram_init(hwsq, subdev);
if (ret) if (ret)
return ret; return ret;
...@@ -235,14 +297,18 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -235,14 +297,18 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
break; break;
} }
if (ret) if (ret) {
nvkm_error(subdev, "Could not calculate MR\n");
return ret; return ret;
}
if (subdev->device->chipset <= 0x96 && !next->bios.ramcfg_00_03_02)
ram_mask(hwsq, 0x100710, 0x00000200, 0x00000000);
/* Always disable this bit during reclock */ /* Always disable this bit during reclock */
ram_mask(hwsq, 0x100200, 0x00000800, 0x00000000); ram_mask(hwsq, 0x100200, 0x00000800, 0x00000000);
ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */ ram_wait_vblank(hwsq);
ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
ram_wr32(hwsq, 0x611200, 0x00003300); ram_wr32(hwsq, 0x611200, 0x00003300);
ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */ ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */
ram_nsec(hwsq, 8000); ram_nsec(hwsq, 8000);
...@@ -250,6 +316,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -250,6 +316,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */ ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
ram_nsec(hwsq, 2000); ram_nsec(hwsq, 2000);
if (next->bios.timing_10_ODT)
nv50_ram_gpio(hwsq, 0x2e, 1);
ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */ ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
...@@ -286,8 +355,12 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -286,8 +355,12 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
next->bios.rammap_00_16_40 << 14); next->bios.rammap_00_16_40 << 14);
ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1); ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
ram_mask(hwsq, 0x004008, 0x91ff0000, r004008); ram_mask(hwsq, 0x004008, 0x91ff0000, r004008);
if (subdev->device->chipset >= 0x96)
/* XXX: GDDR3 only? */
if (subdev->device->chipset >= 0x92)
ram_wr32(hwsq, 0x100da0, r100da0); ram_wr32(hwsq, 0x100da0, r100da0);
nv50_ram_gpio(hwsq, 0x18, !next->bios.ramcfg_FBVDDQ);
ram_nsec(hwsq, 64000); /*XXX*/ ram_nsec(hwsq, 64000); /*XXX*/
ram_nsec(hwsq, 32000); /*XXX*/ ram_nsec(hwsq, 32000); /*XXX*/
...@@ -329,19 +402,33 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -329,19 +402,33 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x100200, 0x00001000, !next->bios.ramcfg_00_04_02 << 12); ram_mask(hwsq, 0x100200, 0x00001000, !next->bios.ramcfg_00_04_02 << 12);
/* XXX: A lot of this could be "chipset"/"ram type" specific stuff */ /* XXX: A lot of this could be "chipset"/"ram type" specific stuff */
unk710 = ram_rd32(hwsq, 0x100710) & ~0x00000101; unk710 = ram_rd32(hwsq, 0x100710) & ~0x00000100;
unk714 = ram_rd32(hwsq, 0x100714) & ~0xf0000020; unk714 = ram_rd32(hwsq, 0x100714) & ~0xf0000020;
unk718 = ram_rd32(hwsq, 0x100718) & ~0x00000100; unk718 = ram_rd32(hwsq, 0x100718) & ~0x00000100;
unk71c = ram_rd32(hwsq, 0x10071c) & ~0x00000100; unk71c = ram_rd32(hwsq, 0x10071c) & ~0x00000100;
if (subdev->device->chipset <= 0x96) {
unk710 &= ~0x0000006e;
unk714 &= ~0x00000100;
if (!next->bios.ramcfg_00_03_08)
unk710 |= 0x00000060;
if (!next->bios.ramcfg_FBVDDQ)
unk714 |= 0x00000100;
if ( next->bios.ramcfg_00_04_04)
unk710 |= 0x0000000e;
} else {
unk710 &= ~0x00000001;
if (!next->bios.ramcfg_00_03_08)
unk710 |= 0x00000001;
}
if ( next->bios.ramcfg_00_03_01) if ( next->bios.ramcfg_00_03_01)
unk71c |= 0x00000100; unk71c |= 0x00000100;
if ( next->bios.ramcfg_00_03_02) if ( next->bios.ramcfg_00_03_02)
unk710 |= 0x00000100; unk710 |= 0x00000100;
if (!next->bios.ramcfg_00_03_08) { if (!next->bios.ramcfg_00_03_08)
unk710 |= 0x1; unk714 |= 0x00000020;
unk714 |= 0x20;
}
if ( next->bios.ramcfg_00_04_04) if ( next->bios.ramcfg_00_04_04)
unk714 |= 0x70000000; unk714 |= 0x70000000;
if ( next->bios.ramcfg_00_04_20) if ( next->bios.ramcfg_00_04_20)
...@@ -352,6 +439,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -352,6 +439,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x100718, 0xffffffff, unk718); ram_mask(hwsq, 0x100718, 0xffffffff, unk718);
ram_mask(hwsq, 0x100710, 0xffffffff, unk710); ram_mask(hwsq, 0x100710, 0xffffffff, unk710);
/* XXX: G94 does not even test these regs in trace. Harmless we do it,
* but why is it omitted? */
if (next->bios.rammap_00_16_20) { if (next->bios.rammap_00_16_20) {
ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 | ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 |
next->bios.ramcfg_00_06 << 8 | next->bios.ramcfg_00_06 << 8 |
...@@ -364,6 +453,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -364,6 +453,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
} }
ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]); ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]);
if (!next->bios.timing_10_ODT)
nv50_ram_gpio(hwsq, 0x2e, 0);
/* Reset DLL */ /* Reset DLL */
if (!next->bios.ramcfg_DLLoff) if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(hwsq); nvkm_sddr2_dll_reset(hwsq);
...@@ -379,6 +471,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -379,6 +471,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x004008, 0x00004000, 0x00000000); ram_mask(hwsq, 0x004008, 0x00004000, 0x00000000);
if (next->bios.ramcfg_00_03_02) if (next->bios.ramcfg_00_03_02)
ram_mask(hwsq, 0x10021c, 0x00010000, 0x00010000); ram_mask(hwsq, 0x10021c, 0x00010000, 0x00010000);
if (subdev->device->chipset <= 0x96 && next->bios.ramcfg_00_03_02)
ram_mask(hwsq, 0x100710, 0x00000200, 0x00000200);
return 0; return 0;
} }
...@@ -634,5 +728,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ...@@ -634,5 +728,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4); ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
} }
ram->hwsq.r_gpio[0] = hwsq_reg(0x00e104);
ram->hwsq.r_gpio[1] = hwsq_reg(0x00e108);
ram->hwsq.r_gpio[2] = hwsq_reg(0x00e120);
ram->hwsq.r_gpio[3] = hwsq_reg(0x00e124);
return 0; return 0;
} }
...@@ -11,5 +11,6 @@ ...@@ -11,5 +11,6 @@
#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d)) #define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d)) #define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d)) #define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
#define ram_wait_vblank(s) hwsq_wait_vblank(&(s)->base)
#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n)) #define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n))
#endif #endif
...@@ -76,6 +76,12 @@ nvkm_sddr2_calc(struct nvkm_ram *ram) ...@@ -76,6 +76,12 @@ nvkm_sddr2_calc(struct nvkm_ram *ram)
return -ENOSYS; return -ENOSYS;
} }
if (ram->next->bios.timing_ver == 0x20 ||
ram->next->bios.ramcfg_timing == 0xff) {
ODT = (ram->mr[1] & 0x004) >> 2 |
(ram->mr[1] & 0x040) >> 5;
}
CL = ramxlat(ramddr2_cl, CL); CL = ramxlat(ramddr2_cl, CL);
WR = ramxlat(ramddr2_wr, WR); WR = ramxlat(ramddr2_wr, WR);
if (CL < 0 || WR < 0) if (CL < 0 || WR < 0)
......
...@@ -70,6 +70,8 @@ nvkm_sddr3_calc(struct nvkm_ram *ram) ...@@ -70,6 +70,8 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
{ {
int CWL, CL, WR, DLL = 0, ODT = 0; int CWL, CL, WR, DLL = 0, ODT = 0;
DLL = !ram->next->bios.ramcfg_DLLoff;
switch (ram->next->bios.timing_ver) { switch (ram->next->bios.timing_ver) {
case 0x10: case 0x10:
if (ram->next->bios.timing_hdr < 0x17) { if (ram->next->bios.timing_hdr < 0x17) {
...@@ -79,7 +81,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram) ...@@ -79,7 +81,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
CWL = ram->next->bios.timing_10_CWL; CWL = ram->next->bios.timing_10_CWL;
CL = ram->next->bios.timing_10_CL; CL = ram->next->bios.timing_10_CL;
WR = ram->next->bios.timing_10_WR; WR = ram->next->bios.timing_10_WR;
DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT; ODT = ram->next->bios.timing_10_ODT;
break; break;
case 0x20: case 0x20:
...@@ -87,7 +88,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram) ...@@ -87,7 +88,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
CL = (ram->next->bios.timing[1] & 0x0000001f) >> 0; CL = (ram->next->bios.timing[1] & 0x0000001f) >> 0;
WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16; WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
/* XXX: Get these values from the VBIOS instead */ /* XXX: Get these values from the VBIOS instead */
DLL = !(ram->mr[1] & 0x1);
ODT = (ram->mr[1] & 0x004) >> 2 | ODT = (ram->mr[1] & 0x004) >> 2 |
(ram->mr[1] & 0x040) >> 5 | (ram->mr[1] & 0x040) >> 5 |
(ram->mr[1] & 0x200) >> 7; (ram->mr[1] & 0x200) >> 7;
......
...@@ -54,7 +54,7 @@ nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match) ...@@ -54,7 +54,7 @@ nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
} }
} }
int static int
nv50_gpio_location(int line, u32 *reg, u32 *shift) nv50_gpio_location(int line, u32 *reg, u32 *shift)
{ {
const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
......
nvkm-y += nvkm/subdev/ibus/gf100.o nvkm-y += nvkm/subdev/ibus/gf100.o
nvkm-y += nvkm/subdev/ibus/gf117.o
nvkm-y += nvkm/subdev/ibus/gk104.o nvkm-y += nvkm/subdev/ibus/gk104.o
nvkm-y += nvkm/subdev/ibus/gk20a.o nvkm-y += nvkm/subdev/ibus/gk20a.o
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <subdev/ibus.h> #include "priv.h"
static void static void
gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i)
...@@ -56,7 +56,7 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) ...@@ -56,7 +56,7 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i)
nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000); nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000);
} }
static void void
gf100_ibus_intr(struct nvkm_subdev *ibus) gf100_ibus_intr(struct nvkm_subdev *ibus)
{ {
struct nvkm_device *device = ibus->device; struct nvkm_device *device = ibus->device;
...@@ -92,8 +92,21 @@ gf100_ibus_intr(struct nvkm_subdev *ibus) ...@@ -92,8 +92,21 @@ gf100_ibus_intr(struct nvkm_subdev *ibus)
} }
} }
static int
gf100_ibus_init(struct nvkm_subdev *ibus)
{
struct nvkm_device *device = ibus->device;
nvkm_mask(device, 0x122310, 0x0003ffff, 0x00000800);
nvkm_wr32(device, 0x12232c, 0x00100064);
nvkm_wr32(device, 0x122330, 0x00100064);
nvkm_wr32(device, 0x122334, 0x00100064);
nvkm_mask(device, 0x122348, 0x0003ffff, 0x00000100);
return 0;
}
static const struct nvkm_subdev_func static const struct nvkm_subdev_func
gf100_ibus = { gf100_ibus = {
.init = gf100_ibus_init,
.intr = gf100_ibus_intr, .intr = gf100_ibus_intr,
}; };
......
/*
* Copyright 2015 Samuel Pitosiet
*
* 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: Samuel Pitoiset
*/
#include "priv.h"
static int
gf117_ibus_init(struct nvkm_subdev *ibus)
{
struct nvkm_device *device = ibus->device;
nvkm_mask(device, 0x122310, 0x0003ffff, 0x00000800);
nvkm_mask(device, 0x122348, 0x0003ffff, 0x00000100);
nvkm_mask(device, 0x1223b0, 0x0003ffff, 0x00000fff);
return 0;
}
static const struct nvkm_subdev_func
gf117_ibus = {
.init = gf117_ibus_init,
.intr = gf100_ibus_intr,
};
int
gf117_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev **pibus)
{
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
nvkm_subdev_ctor(&gf117_ibus, device, index, 0, ibus);
return 0;
}
#ifndef __NVKM_IBUS_PRIV_H__
#define __NVKM_IBUS_PRIV_H__
#include <subdev/ibus.h>
void gf100_ibus_intr(struct nvkm_subdev *);
#endif
...@@ -67,6 +67,20 @@ nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth) ...@@ -67,6 +67,20 @@ nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth)
return index; return index;
} }
void
nvkm_ltc_invalidate(struct nvkm_ltc *ltc)
{
if (ltc->func->invalidate)
ltc->func->invalidate(ltc);
}
void
nvkm_ltc_flush(struct nvkm_ltc *ltc)
{
if (ltc->func->flush)
ltc->func->flush(ltc);
}
static void static void
nvkm_ltc_intr(struct nvkm_subdev *subdev) nvkm_ltc_intr(struct nvkm_subdev *subdev)
{ {
......
...@@ -122,6 +122,36 @@ gf100_ltc_intr(struct nvkm_ltc *ltc) ...@@ -122,6 +122,36 @@ gf100_ltc_intr(struct nvkm_ltc *ltc)
} }
} }
void
gf100_ltc_invalidate(struct nvkm_ltc *ltc)
{
struct nvkm_device *device = ltc->subdev.device;
s64 taken;
nvkm_wr32(device, 0x70004, 0x00000001);
taken = nvkm_wait_msec(device, 2, 0x70004, 0x00000003, 0x00000000);
if (taken < 0)
nvkm_warn(&ltc->subdev, "LTC invalidate timeout\n");
if (taken > 0)
nvkm_debug(&ltc->subdev, "LTC invalidate took %lld ns\n", taken);
}
void
gf100_ltc_flush(struct nvkm_ltc *ltc)
{
struct nvkm_device *device = ltc->subdev.device;
s64 taken;
nvkm_wr32(device, 0x70010, 0x00000001);
taken = nvkm_wait_msec(device, 2, 0x70010, 0x00000003, 0x00000000);
if (taken < 0)
nvkm_warn(&ltc->subdev, "LTC flush timeout\n");
if (taken > 0)
nvkm_debug(&ltc->subdev, "LTC flush took %lld ns\n", taken);
}
/* TODO: Figure out tag memory details and drop the over-cautious allocation. /* TODO: Figure out tag memory details and drop the over-cautious allocation.
*/ */
int int
...@@ -215,6 +245,8 @@ gf100_ltc = { ...@@ -215,6 +245,8 @@ gf100_ltc = {
.zbc = 16, .zbc = 16,
.zbc_clear_color = gf100_ltc_zbc_clear_color, .zbc_clear_color = gf100_ltc_zbc_clear_color,
.zbc_clear_depth = gf100_ltc_zbc_clear_depth, .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
.invalidate = gf100_ltc_invalidate,
.flush = gf100_ltc_flush,
}; };
int int
......
...@@ -45,6 +45,8 @@ gk104_ltc = { ...@@ -45,6 +45,8 @@ gk104_ltc = {
.zbc = 16, .zbc = 16,
.zbc_clear_color = gf100_ltc_zbc_clear_color, .zbc_clear_color = gf100_ltc_zbc_clear_color,
.zbc_clear_depth = gf100_ltc_zbc_clear_depth, .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
.invalidate = gf100_ltc_invalidate,
.flush = gf100_ltc_flush,
}; };
int int
......
...@@ -138,6 +138,8 @@ gm107_ltc = { ...@@ -138,6 +138,8 @@ gm107_ltc = {
.zbc = 16, .zbc = 16,
.zbc_clear_color = gm107_ltc_zbc_clear_color, .zbc_clear_color = gm107_ltc_zbc_clear_color,
.zbc_clear_depth = gm107_ltc_zbc_clear_depth, .zbc_clear_depth = gm107_ltc_zbc_clear_depth,
.invalidate = gf100_ltc_invalidate,
.flush = gf100_ltc_flush,
}; };
int int
......
...@@ -17,6 +17,9 @@ struct nvkm_ltc_func { ...@@ -17,6 +17,9 @@ struct nvkm_ltc_func {
int zbc; int zbc;
void (*zbc_clear_color)(struct nvkm_ltc *, int, const u32[4]); void (*zbc_clear_color)(struct nvkm_ltc *, int, const u32[4]);
void (*zbc_clear_depth)(struct nvkm_ltc *, int, const u32); void (*zbc_clear_depth)(struct nvkm_ltc *, int, const u32);
void (*invalidate)(struct nvkm_ltc *);
void (*flush)(struct nvkm_ltc *);
}; };
int gf100_ltc_oneinit(struct nvkm_ltc *); int gf100_ltc_oneinit(struct nvkm_ltc *);
...@@ -26,4 +29,6 @@ void gf100_ltc_cbc_clear(struct nvkm_ltc *, u32, u32); ...@@ -26,4 +29,6 @@ void gf100_ltc_cbc_clear(struct nvkm_ltc *, u32, u32);
void gf100_ltc_cbc_wait(struct nvkm_ltc *); void gf100_ltc_cbc_wait(struct nvkm_ltc *);
void gf100_ltc_zbc_clear_color(struct nvkm_ltc *, int, const u32[4]); void gf100_ltc_zbc_clear_color(struct nvkm_ltc *, int, const u32[4]);
void gf100_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32); void gf100_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32);
void gf100_ltc_invalidate(struct nvkm_ltc *);
void gf100_ltc_flush(struct nvkm_ltc *);
#endif #endif
...@@ -2,6 +2,8 @@ nvkm-y += nvkm/subdev/pci/agp.o ...@@ -2,6 +2,8 @@ nvkm-y += nvkm/subdev/pci/agp.o
nvkm-y += nvkm/subdev/pci/base.o nvkm-y += nvkm/subdev/pci/base.o
nvkm-y += nvkm/subdev/pci/nv04.o nvkm-y += nvkm/subdev/pci/nv04.o
nvkm-y += nvkm/subdev/pci/nv40.o nvkm-y += nvkm/subdev/pci/nv40.o
nvkm-y += nvkm/subdev/pci/nv46.o
nvkm-y += nvkm/subdev/pci/nv4c.o nvkm-y += nvkm/subdev/pci/nv4c.o
nvkm-y += nvkm/subdev/pci/nv50.o nvkm-y += nvkm/subdev/pci/g84.o
nvkm-y += nvkm/subdev/pci/g94.o
nvkm-y += nvkm/subdev/pci/gf100.o nvkm-y += nvkm/subdev/pci/gf100.o
...@@ -46,6 +46,14 @@ nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) ...@@ -46,6 +46,14 @@ nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data)
pci->func->wr32(pci, addr, data); pci->func->wr32(pci, addr, data);
} }
u32
nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value)
{
u32 data = pci->func->rd32(pci, addr);
pci->func->wr32(pci, addr, (data & ~mask) | value);
return data;
}
void void
nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow) nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow)
{ {
...@@ -111,6 +119,9 @@ nvkm_pci_init(struct nvkm_subdev *subdev) ...@@ -111,6 +119,9 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
return ret; return ret;
} }
if (pci->func->init)
pci->func->init(pci);
ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci);
if (ret) if (ret)
return ret; return ret;
......
/*
* Copyright 2015 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 <bskeggs@redhat.com>
*/
#include "priv.h"
#include <core/pci.h>
void
g84_pci_init(struct nvkm_pci *pci)
{
/* The following only concerns PCIe cards. */
if (!pci_is_pcie(pci->pdev))
return;
/* Tag field is 8-bit long, regardless of EXT_TAG.
* However, if EXT_TAG is disabled, only the lower 5 bits of the tag
* field should be used, limiting the number of request to 32.
*
* Apparently, 0x041c stores some limit on the number of requests
* possible, so if EXT_TAG is disabled, limit that requests number to
* 32
*
* Fixes fdo#86537
*/
if (nvkm_pci_rd32(pci, 0x007c) & 0x00000020)
nvkm_pci_mask(pci, 0x0080, 0x00000100, 0x00000100);
else
nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000);
}
static const struct nvkm_pci_func
g84_pci_func = {
.init = g84_pci_init,
.rd32 = nv40_pci_rd32,
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv46_pci_msi_rearm,
};
int
g84_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
{
return nvkm_pci_new_(&g84_pci_func, device, index, ppci);
}
/*
* Copyright 2015 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 <bskeggs@redhat.com>
*/
#include "priv.h"
static const struct nvkm_pci_func
g94_pci_func = {
.init = g84_pci_init,
.rd32 = nv40_pci_rd32,
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
};
int
g94_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
{
return nvkm_pci_new_(&g94_pci_func, device, index, ppci);
}
...@@ -31,6 +31,7 @@ gf100_pci_msi_rearm(struct nvkm_pci *pci) ...@@ -31,6 +31,7 @@ gf100_pci_msi_rearm(struct nvkm_pci *pci)
static const struct nvkm_pci_func static const struct nvkm_pci_func
gf100_pci_func = { gf100_pci_func = {
.init = g84_pci_init,
.rd32 = nv40_pci_rd32, .rd32 = nv40_pci_rd32,
.wr08 = nv40_pci_wr08, .wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32, .wr32 = nv40_pci_wr32,
......
...@@ -44,7 +44,7 @@ nv40_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) ...@@ -44,7 +44,7 @@ nv40_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data)
nvkm_wr32(device, 0x088000 + addr, data); nvkm_wr32(device, 0x088000 + addr, data);
} }
static void void
nv40_pci_msi_rearm(struct nvkm_pci *pci) nv40_pci_msi_rearm(struct nvkm_pci *pci)
{ {
nvkm_pci_wr08(pci, 0x0068, 0xff); nvkm_pci_wr08(pci, 0x0068, 0xff);
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
#include <core/pci.h> #include <core/pci.h>
/* MSI re-arm through the PRI appears to be broken on the original G80, /* MSI re-arm through the PRI appears to be broken on NV46/NV50/G84/G86/G92,
* so we access it via alternate PCI config space mechanisms. * so we access it via alternate PCI config space mechanisms.
*/ */
static void void
nv50_pci_msi_rearm(struct nvkm_pci *pci) nv46_pci_msi_rearm(struct nvkm_pci *pci)
{ {
struct nvkm_device *device = pci->subdev.device; struct nvkm_device *device = pci->subdev.device;
struct pci_dev *pdev = device->func->pci(device)->pdev; struct pci_dev *pdev = device->func->pci(device)->pdev;
...@@ -37,15 +37,15 @@ nv50_pci_msi_rearm(struct nvkm_pci *pci) ...@@ -37,15 +37,15 @@ nv50_pci_msi_rearm(struct nvkm_pci *pci)
} }
static const struct nvkm_pci_func static const struct nvkm_pci_func
nv50_pci_func = { nv46_pci_func = {
.rd32 = nv40_pci_rd32, .rd32 = nv40_pci_rd32,
.wr08 = nv40_pci_wr08, .wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32, .wr32 = nv40_pci_wr32,
.msi_rearm = nv50_pci_msi_rearm, .msi_rearm = nv46_pci_msi_rearm,
}; };
int int
nv50_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci) nv46_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
{ {
return nvkm_pci_new_(&nv50_pci_func, device, index, ppci); return nvkm_pci_new_(&nv46_pci_func, device, index, ppci);
} }
...@@ -7,6 +7,7 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *, ...@@ -7,6 +7,7 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *,
int index, struct nvkm_pci **); int index, struct nvkm_pci **);
struct nvkm_pci_func { struct nvkm_pci_func {
void (*init)(struct nvkm_pci *);
u32 (*rd32)(struct nvkm_pci *, u16 addr); u32 (*rd32)(struct nvkm_pci *, u16 addr);
void (*wr08)(struct nvkm_pci *, u16 addr, u8 data); void (*wr08)(struct nvkm_pci *, u16 addr, u8 data);
void (*wr32)(struct nvkm_pci *, u16 addr, u32 data); void (*wr32)(struct nvkm_pci *, u16 addr, u32 data);
...@@ -16,4 +17,9 @@ struct nvkm_pci_func { ...@@ -16,4 +17,9 @@ struct nvkm_pci_func {
u32 nv40_pci_rd32(struct nvkm_pci *, u16); u32 nv40_pci_rd32(struct nvkm_pci *, u16);
void nv40_pci_wr08(struct nvkm_pci *, u16, u8); void nv40_pci_wr08(struct nvkm_pci *, u16, u8);
void nv40_pci_wr32(struct nvkm_pci *, u16, u32); void nv40_pci_wr32(struct nvkm_pci *, u16, u32);
void nv40_pci_msi_rearm(struct nvkm_pci *);
void nv46_pci_msi_rearm(struct nvkm_pci *);
void g84_pci_init(struct nvkm_pci *pci);
#endif #endif
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
void void
nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable) nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
{ {
if (pmu->func->pgob) if (pmu && pmu->func->pgob)
pmu->func->pgob(pmu, enable); pmu->func->pgob(pmu, enable);
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "fuc/gf119.fuc4.h" #include "fuc/gf119.fuc4.h"
#include <core/option.h> #include <core/option.h>
#include <subdev/fuse.h>
#include <subdev/timer.h> #include <subdev/timer.h>
static void static void
...@@ -57,6 +58,9 @@ gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable) ...@@ -57,6 +58,9 @@ gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
{ {
struct nvkm_device *device = pmu->subdev.device; struct nvkm_device *device = pmu->subdev.device;
if (!(nvkm_fuse_read(device->fuse, 0x31c) & 0x00000001))
return;
nvkm_mask(device, 0x000200, 0x00001000, 0x00000000); nvkm_mask(device, 0x000200, 0x00001000, 0x00000000);
nvkm_rd32(device, 0x000200); nvkm_rd32(device, 0x000200);
nvkm_mask(device, 0x000200, 0x08000000, 0x08000000); nvkm_mask(device, 0x000200, 0x08000000, 0x08000000);
......
nvkm-y += nvkm/subdev/volt/base.o nvkm-y += nvkm/subdev/volt/base.o
nvkm-y += nvkm/subdev/volt/gpio.o nvkm-y += nvkm/subdev/volt/gpio.o
nvkm-y += nvkm/subdev/volt/nv40.o nvkm-y += nvkm/subdev/volt/nv40.o
nvkm-y += nvkm/subdev/volt/gk104.o
nvkm-y += nvkm/subdev/volt/gk20a.o nvkm-y += nvkm/subdev/volt/gk20a.o
...@@ -30,7 +30,12 @@ ...@@ -30,7 +30,12 @@
int int
nvkm_volt_get(struct nvkm_volt *volt) nvkm_volt_get(struct nvkm_volt *volt)
{ {
int ret = volt->func->vid_get(volt), i; int ret, i;
if (volt->func->volt_get)
return volt->func->volt_get(volt);
ret = volt->func->vid_get(volt);
if (ret >= 0) { if (ret >= 0) {
for (i = 0; i < volt->vid_nr; i++) { for (i = 0; i < volt->vid_nr; i++) {
if (volt->vid[i].vid == ret) if (volt->vid[i].vid == ret)
...@@ -46,6 +51,10 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv) ...@@ -46,6 +51,10 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
{ {
struct nvkm_subdev *subdev = &volt->subdev; struct nvkm_subdev *subdev = &volt->subdev;
int i, ret = -EINVAL; int i, ret = -EINVAL;
if (volt->func->volt_set)
return volt->func->volt_set(volt, uv);
for (i = 0; i < volt->vid_nr; i++) { for (i = 0; i < volt->vid_nr; i++) {
if (volt->vid[i].uv == uv) { if (volt->vid[i].uv == uv) {
ret = volt->func->vid_set(volt, volt->vid[i].vid); ret = volt->func->vid_set(volt, volt->vid[i].vid);
......
/*
* Copyright 2015 Martin Peres
*
* 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: Martin Peres
*/
#include "priv.h"
#include <subdev/volt.h>
#include <subdev/gpio.h>
#include <subdev/bios.h>
#include <subdev/bios/volt.h>
#define gk104_volt(p) container_of((p), struct gk104_volt, base)
struct gk104_volt {
struct nvkm_volt base;
struct nvbios_volt bios;
};
int
gk104_volt_get(struct nvkm_volt *base)
{
struct nvbios_volt *bios = &gk104_volt(base)->bios;
struct nvkm_device *device = base->subdev.device;
u32 div, duty;
div = nvkm_rd32(device, 0x20340);
duty = nvkm_rd32(device, 0x20344);
return bios->base + bios->pwm_range * duty / div;
}
int
gk104_volt_set(struct nvkm_volt *base, u32 uv)
{
struct nvbios_volt *bios = &gk104_volt(base)->bios;
struct nvkm_device *device = base->subdev.device;
u32 div, duty;
/* the blob uses this crystal frequency, let's use it too. */
div = 27648000 / bios->pwm_freq;
duty = (uv - bios->base) * div / bios->pwm_range;
nvkm_wr32(device, 0x20340, div);
nvkm_wr32(device, 0x20344, 0x8000000 | duty);
return 0;
}
static const struct nvkm_volt_func
gk104_volt_pwm = {
.volt_get = gk104_volt_get,
.volt_set = gk104_volt_set,
}, gk104_volt_gpio = {
.vid_get = nvkm_voltgpio_get,
.vid_set = nvkm_voltgpio_set,
};
int
gk104_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
{
const struct nvkm_volt_func *volt_func = &gk104_volt_gpio;
struct dcb_gpio_func gpio;
struct nvbios_volt bios;
struct gk104_volt *volt;
u8 ver, hdr, cnt, len;
const char *mode;
if (!nvbios_volt_parse(device->bios, &ver, &hdr, &cnt, &len, &bios))
return 0;
if (!nvkm_gpio_find(device->gpio, 0, DCB_GPIO_VID_PWM, 0xff, &gpio) &&
bios.type == NVBIOS_VOLT_PWM) {
volt_func = &gk104_volt_pwm;
}
if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL)))
return -ENOMEM;
nvkm_volt_ctor(volt_func, device, index, &volt->base);
*pvolt = &volt->base;
volt->bios = bios;
/* now that we have a subdev, we can show an error if we found through
* the voltage table that we were supposed to use the PWN mode but we
* did not find the right GPIO for it.
*/
if (bios.type == NVBIOS_VOLT_PWM && volt_func != &gk104_volt_pwm) {
nvkm_error(&volt->base.subdev,
"Type mismatch between the voltage table type and "
"the GPIO table. Fallback to GPIO mode.\n");
}
if (volt_func == &gk104_volt_gpio) {
nvkm_voltgpio_init(&volt->base);
mode = "GPIO";
} else
mode = "PWM";
nvkm_debug(&volt->base.subdev, "Using %s mode\n", mode);
return 0;
}
...@@ -9,6 +9,8 @@ int nvkm_volt_new_(const struct nvkm_volt_func *, struct nvkm_device *, ...@@ -9,6 +9,8 @@ int nvkm_volt_new_(const struct nvkm_volt_func *, struct nvkm_device *,
int index, struct nvkm_volt **); int index, struct nvkm_volt **);
struct nvkm_volt_func { struct nvkm_volt_func {
int (*volt_get)(struct nvkm_volt *);
int (*volt_set)(struct nvkm_volt *, u32 uv);
int (*vid_get)(struct nvkm_volt *); int (*vid_get)(struct nvkm_volt *);
int (*vid_set)(struct nvkm_volt *, u8 vid); int (*vid_set)(struct nvkm_volt *, u8 vid);
int (*set_id)(struct nvkm_volt *, u8 id, int condition); int (*set_id)(struct nvkm_volt *, u8 id, int condition);
...@@ -17,4 +19,8 @@ struct nvkm_volt_func { ...@@ -17,4 +19,8 @@ struct nvkm_volt_func {
int nvkm_voltgpio_init(struct nvkm_volt *); int nvkm_voltgpio_init(struct nvkm_volt *);
int nvkm_voltgpio_get(struct nvkm_volt *); int nvkm_voltgpio_get(struct nvkm_volt *);
int nvkm_voltgpio_set(struct nvkm_volt *, u8); int nvkm_voltgpio_set(struct nvkm_volt *, u8);
int nvkm_voltpwm_init(struct nvkm_volt *volt);
int nvkm_voltpwm_get(struct nvkm_volt *volt);
int nvkm_voltpwm_set(struct nvkm_volt *volt, u32 uv);
#endif #endif
...@@ -27,14 +27,6 @@ ...@@ -27,14 +27,6 @@
#define DRM_NOUVEAU_EVENT_NVIF 0x80000000 #define DRM_NOUVEAU_EVENT_NVIF 0x80000000
/* reserved object handles when using deprecated object APIs - these
* are here so that libdrm can allow interoperability with the new
* object APIs
*/
#define NOUVEAU_ABI16_CLIENT 0xffffffff
#define NOUVEAU_ABI16_DEVICE 0xdddddddd
#define NOUVEAU_ABI16_CHAN(n) (0xcccc0000 | (n))
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0) #define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) #define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment