Skip to content

Commit

Permalink
Merge branch 'linux-4.4' of git://anongit.freedesktop.org/git/nouveau…
Browse files Browse the repository at this point in the history
…/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
  ...
  • Loading branch information
Dave Airlie committed Nov 3, 2015
2 parents b459004 + 79ef5dc commit 1c431cb
Show file tree
Hide file tree
Showing 74 changed files with 1,312 additions and 381 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvif/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/agp_backend.h>
#include <linux/reset.h>
#include <linux/iommu.h>
#include <linux/of_device.h>

#include <asm/unaligned.h>

Expand Down
13 changes: 12 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <core/mm.h>

struct nvkm_device_tegra {
const struct nvkm_device_tegra_func *func;
struct nvkm_device device;
struct platform_device *pdev;
int irq;
Expand All @@ -28,7 +29,17 @@ struct nvkm_device_tegra {
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,
bool detect, bool mmio, u64 subdev_mask,
struct nvkm_device **);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_VID5 = 0x74,
DCB_GPIO_VID6 = 0x75,
DCB_GPIO_VID7 = 0x76,
DCB_GPIO_VID_PWM = 0x81,
};

#define DCB_GPIO_LOG_DIR 0x02
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ struct nvbios_pmuT {
};

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 {
u8 type;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_timing;
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
union {
struct {
unsigned ramcfg_00_03_01:1;
Expand Down Expand Up @@ -78,7 +79,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
Expand Down
15 changes: 14 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
#ifndef __NVBIOS_VOLT_H__
#define __NVBIOS_VOLT_H__

enum nvbios_volt_type {
NVBIOS_VOLT_GPIO = 0,
NVBIOS_VOLT_PWM,
};

struct nvbios_volt {
u8 vidmask;
enum nvbios_volt_type type;
u32 min;
u32 max;
u32 base;

/* GPIO mode */
u8 vidmask;
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);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_setf(struct nvkm_hwsq *, u8 flag, int data);
void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
void nvkm_hwsq_wait_vblank(struct nvkm_hwsq *);
void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);

int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <core/subdev.h>

int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gf117_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
#endif
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 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 **);
#endif
5 changes: 4 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ struct nvkm_pci {
u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);

int nv04_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 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 **);
#endif
10 changes: 10 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ int nvkm_volt_get(struct nvkm_volt *);
int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);

int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
#endif
84 changes: 62 additions & 22 deletions drivers/gpu/drm/nouveau/nouveau_abi16.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@
#include <nvif/driver.h>
#include <nvif/ioctl.h>
#include <nvif/class.h>
#include <nvif/unpack.h>

#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_gem.h"
#include "nouveau_chan.h"
#include "nouveau_abi16.h"

struct nouveau_abi16 *
nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
static struct nouveau_abi16 *
nouveau_abi16(struct drm_file *file_priv)
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
mutex_lock(&cli->mutex);
if (!cli->abi16) {
struct nouveau_abi16 *abi16;
cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL);
Expand All @@ -51,21 +51,29 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
* device (ie. the one that belongs to the fd it
* opened)
*/
if (nvif_device_init(&cli->base.object,
NOUVEAU_ABI16_DEVICE, NV_DEVICE,
if (nvif_device_init(&cli->base.object, 0, NV_DEVICE,
&args, sizeof(args),
&abi16->device) == 0)
return cli->abi16;

kfree(cli->abi16);
cli->abi16 = NULL;
}

mutex_unlock(&cli->mutex);
}
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
nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
{
Expand Down Expand Up @@ -133,7 +141,6 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,

/* destroy channel object, all children will be killed too */
if (chan->chan) {
abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff));
nouveau_channel_idle(chan->chan);
nouveau_channel_del(&chan->chan);
}
Expand Down Expand Up @@ -238,7 +245,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
struct drm_nouveau_channel_alloc *init = data;
struct nouveau_cli *cli = nouveau_cli(file_priv);
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 nvif_device *device;
int ret;
Expand Down Expand Up @@ -268,26 +275,21 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
return nouveau_abi16_put(abi16, -EINVAL);

/* 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);
if (!chan)
return nouveau_abi16_put(abi16, -ENOMEM);

INIT_LIST_HEAD(&chan->notifiers);
list_add(&chan->head, &abi16->channels);
abi16->handles |= (1ULL << init->channel);

/* create channel object and initialise dma and fence management */
ret = nouveau_channel_new(drm, device,
NOUVEAU_ABI16_CHAN(init->channel),
init->fb_ctxdma_handle,
ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
init->tt_ctxdma_handle, &chan->chan);
if (ret)
goto done;

init->channel = chan->chan->chid;

if (device->info.family >= NV_DEVICE_INFO_V0_TESLA)
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
NOUVEAU_GEM_DOMAIN_GART;
Expand Down Expand Up @@ -338,18 +340,56 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
struct nouveau_abi16_chan *chan;

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 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
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
{
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;

if (unlikely(!abi16))
Expand All @@ -366,7 +406,7 @@ int
nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
{
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_ntfy *ntfy;
struct nvif_client *client;
Expand Down Expand Up @@ -459,7 +499,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
{
struct drm_nouveau_notifierobj_alloc *info = data;
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_ntfy *ntfy;
struct nvif_device *device = &abi16->device;
Expand Down Expand Up @@ -531,7 +571,7 @@ int
nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
{
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_ntfy *ntfy;
int ret = -ENOENT;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/nouveau_abi16.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ struct nouveau_abi16 {
u64 handles;
};

struct nouveau_drm;
struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *, struct drm_device *);
struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *);
int nouveau_abi16_put(struct nouveau_abi16 *, int);
void nouveau_abi16_fini(struct nouveau_abi16 *);
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_GART (1 << 2)
Expand Down
Loading

0 comments on commit 1c431cb

Please sign in to comment.