Commit aa71fa3c authored by Dave Airlie's avatar Dave Airlie

Merge remote branch 'nouveau/for-airlied' into drm-next-stage

* nouveau/for-airlied: (25 commits)
  drm/nouveau: use ALIGN instead of open coding it
  drm/nouveau: report unknown connector state if lid closed
  drm/nouveau: support version 0x20 displayport tables
  drm/nouveau: Fix noaccel/nofbaccel option descriptions.
  drm/nv50: Implement ctxprog/state generation.
  drm/nouveau: use dcb connector types throughout the driver
  drm/nv50: enable hpd on any connector we know the gpio line for
  drm/nouveau: use dcb connector table for creating drm connectors
  drm/nouveau: construct a connector table for cards that lack a real one
  drm/nouveau: check for known dcb connector types
  drm/nouveau: parse dcb gpio/connector tables after encoders
  drm/nouveau: reorganise bios header, add dcb connector type enums
  drm/nouveau: merge nvbios and nouveau_bios_info
  drm/nouveau: merge parsed_dcb and bios_parsed_dcb into dcb_table
  drm/nouveau: rename parsed_dcb_gpio to dcb_gpio_table
  drm/nouveau: allow retrieval of vbios image from debugfs
  drm/nouveau: fix missing spin_unlock in failure path
  drm/nouveau: fix i2ctable bounds checking
  drm/nouveau: fix nouveau_i2c_find bounds checking
  drm/nouveau: fix pramdac_table range checking
  ...

Conflicts:
	drivers/gpu/drm/nouveau/nouveau_gem.c
parents 79fa9eb7 3bfc7d22
......@@ -16,7 +16,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o \
nv40_grctx.o \
nv40_grctx.o nv50_grctx.o \
nv04_instmem.o nv50_instmem.o \
nv50_crtc.o nv50_dac.o nv50_sor.o \
nv50_cursor.o nv50_display.o nv50_fbcon.o \
......
This diff is collapsed.
......@@ -34,9 +34,67 @@
#define DCB_LOC_ON_CHIP 0
struct dcb_i2c_entry {
uint8_t port_type;
uint8_t read, write;
struct nouveau_i2c_chan *chan;
};
enum dcb_gpio_tag {
DCB_GPIO_TVDAC0 = 0xc,
DCB_GPIO_TVDAC1 = 0x2d,
};
struct dcb_gpio_entry {
enum dcb_gpio_tag tag;
int line;
bool invert;
};
struct dcb_gpio_table {
int entries;
struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
};
enum dcb_connector_type {
DCB_CONNECTOR_VGA = 0x00,
DCB_CONNECTOR_TV_0 = 0x10,
DCB_CONNECTOR_TV_1 = 0x11,
DCB_CONNECTOR_TV_3 = 0x13,
DCB_CONNECTOR_DVI_I = 0x30,
DCB_CONNECTOR_DVI_D = 0x31,
DCB_CONNECTOR_LVDS = 0x40,
DCB_CONNECTOR_DP = 0x46,
DCB_CONNECTOR_eDP = 0x47,
DCB_CONNECTOR_HDMI_0 = 0x60,
DCB_CONNECTOR_HDMI_1 = 0x61,
DCB_CONNECTOR_NONE = 0xff
};
struct dcb_connector_table_entry {
uint32_t entry;
enum dcb_connector_type type;
uint8_t index;
uint8_t gpio_tag;
};
struct dcb_connector_table {
int entries;
struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
};
enum dcb_type {
OUTPUT_ANALOG = 0,
OUTPUT_TV = 1,
OUTPUT_TMDS = 2,
OUTPUT_LVDS = 3,
OUTPUT_DP = 6,
OUTPUT_ANY = -1
};
struct dcb_entry {
int index; /* may not be raw dcb index if merging has happened */
uint8_t type;
enum dcb_type type;
uint8_t i2c_index;
uint8_t heads;
uint8_t connector;
......@@ -71,69 +129,22 @@ struct dcb_entry {
bool i2c_upper_default;
};
struct dcb_i2c_entry {
uint8_t port_type;
uint8_t read, write;
struct nouveau_i2c_chan *chan;
};
struct dcb_table {
uint8_t version;
struct parsed_dcb {
int entries;
struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
};
enum dcb_gpio_tag {
DCB_GPIO_TVDAC0 = 0xc,
DCB_GPIO_TVDAC1 = 0x2d,
};
struct dcb_gpio_entry {
enum dcb_gpio_tag tag;
int line;
bool invert;
};
struct parsed_dcb_gpio {
int entries;
struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
};
struct dcb_connector_table_entry {
uint32_t entry;
uint8_t type;
uint8_t index;
uint8_t gpio_tag;
};
struct dcb_connector_table {
int entries;
struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
};
struct bios_parsed_dcb {
uint8_t version;
struct parsed_dcb dcb;
uint8_t *i2c_table;
uint8_t i2c_default_indices;
struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
uint16_t gpio_table_ptr;
struct parsed_dcb_gpio gpio;
struct dcb_gpio_table gpio;
uint16_t connector_table_ptr;
struct dcb_connector_table connector;
};
enum nouveau_encoder_type {
OUTPUT_ANALOG = 0,
OUTPUT_TV = 1,
OUTPUT_TMDS = 2,
OUTPUT_LVDS = 3,
OUTPUT_DP = 6,
OUTPUT_ANY = -1
};
enum nouveau_or {
OUTPUT_A = (1 << 0),
OUTPUT_B = (1 << 1),
......@@ -190,8 +201,8 @@ struct pll_lims {
int refclk;
};
struct nouveau_bios_info {
struct parsed_dcb *dcb;
struct nvbios {
struct drm_device *dev;
uint8_t chip_version;
......@@ -199,11 +210,6 @@ struct nouveau_bios_info {
uint32_t tvdactestval;
uint8_t digital_min_front_porch;
bool fp_no_ddc;
};
struct nvbios {
struct drm_device *dev;
struct nouveau_bios_info pub;
struct mutex lock;
......@@ -234,7 +240,7 @@ struct nvbios {
uint16_t some_script_ptr; /* BIT I + 14 */
uint16_t init96_tbl_ptr; /* BIT I + 16 */
struct bios_parsed_dcb bdcb;
struct dcb_table dcb;
struct {
int crtchead;
......
......@@ -274,7 +274,7 @@ getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
* returns calculated clock
*/
struct drm_nouveau_private *dev_priv = dev->dev_private;
int cv = dev_priv->vbios->chip_version;
int cv = dev_priv->vbios.chip_version;
int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
......@@ -373,7 +373,7 @@ getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
* returns calculated clock
*/
struct drm_nouveau_private *dev_priv = dev->dev_private;
int chip_version = dev_priv->vbios->chip_version;
int chip_version = dev_priv->vbios.chip_version;
int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
......
......@@ -35,22 +35,27 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_bo *pb = chan->pushbuf_bo;
struct nouveau_gpuobj *pushbuf = NULL;
uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
int ret;
if (dev_priv->card_type >= NV_50) {
ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
dev_priv->vm_end, NV_DMA_ACCESS_RO,
NV_DMA_TARGET_AGP, &pushbuf);
chan->pushbuf_base = pb->bo.offset;
} else
if (pb->bo.mem.mem_type == TTM_PL_TT) {
ret = nouveau_gpuobj_gart_dma_new(chan, 0,
dev_priv->gart_info.aper_size,
NV_DMA_ACCESS_RO, &pushbuf,
NULL);
chan->pushbuf_base = start;
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
} else
if (dev_priv->card_type != NV_04) {
ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
dev_priv->fb_available_size,
NV_DMA_ACCESS_RO,
NV_DMA_TARGET_VIDMEM, &pushbuf);
chan->pushbuf_base = start;
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
} else {
/* NV04 cmdbuf hack, from original ddx.. not sure of it's
* exact reason for existing :) PCI access to cmdbuf in
......@@ -61,7 +66,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
dev_priv->fb_available_size,
NV_DMA_ACCESS_RO,
NV_DMA_TARGET_PCI, &pushbuf);
chan->pushbuf_base = start;
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
}
ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
......@@ -275,9 +280,18 @@ nouveau_channel_free(struct nouveau_channel *chan)
*/
nouveau_fence_fini(chan);
/* Ensure the channel is no longer active on the GPU */
/* This will prevent pfifo from switching channels. */
pfifo->reassign(dev, false);
/* We want to give pgraph a chance to idle and get rid of all potential
* errors. We need to do this before the lock, otherwise the irq handler
* is unable to process them.
*/
if (pgraph->channel(dev) == chan)
nouveau_wait_for_idle(dev);
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);
......@@ -293,6 +307,8 @@ nouveau_channel_free(struct nouveau_channel *chan)
pfifo->reassign(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
/* Release the channel's resources */
nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
if (chan->pushbuf_bo) {
......@@ -369,6 +385,14 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
return ret;
init->channel = chan->id;
if (chan->dma.ib_max)
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
NOUVEAU_GEM_DOMAIN_GART;
else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
else
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
init->subchan[0].handle = NvM2MF;
if (dev_priv->card_type < NV_50)
init->subchan[0].grclass = 0x0039;
......@@ -408,7 +432,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
***********************************/
struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
......@@ -418,13 +441,9 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH),
};
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
This diff is collapsed.
......@@ -49,6 +49,7 @@ static inline struct nouveau_connector *nouveau_connector(
return container_of(con, struct nouveau_connector, base);
}
int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
int nouveau_connector_create(struct drm_device *,
struct dcb_connector_table_entry *);
#endif /* __NOUVEAU_CONNECTOR_H__ */
......@@ -47,12 +47,23 @@ nouveau_debugfs_channel_info(struct seq_file *m, void *data)
seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2);
seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2);
seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2);
if (chan->dma.ib_max) {
seq_printf(m, " ib max: 0x%08x\n", chan->dma.ib_max);
seq_printf(m, " ib put: 0x%08x\n", chan->dma.ib_put);
seq_printf(m, " ib free: 0x%08x\n", chan->dma.ib_free);
}
seq_printf(m, "gpu fifo state:\n");
seq_printf(m, " get: 0x%08x\n",
nvchan_rd32(chan, chan->user_get));
seq_printf(m, " put: 0x%08x\n",
nvchan_rd32(chan, chan->user_put));
if (chan->dma.ib_max) {
seq_printf(m, " ib get: 0x%08x\n",
nvchan_rd32(chan, 0x88));
seq_printf(m, " ib put: 0x%08x\n",
nvchan_rd32(chan, 0x8c));
}
seq_printf(m, "last fence : %d\n", chan->fence.sequence);
seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack);
......@@ -133,9 +144,22 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
return 0;
}
static int
nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private;
int i;
for (i = 0; i < dev_priv->vbios.length; i++)
seq_printf(m, "%c", dev_priv->vbios.data[i]);
return 0;
}
static struct drm_info_list nouveau_debugfs_list[] = {
{ "chipset", nouveau_debugfs_chipset_info, 0, NULL },
{ "memory", nouveau_debugfs_memory_info, 0, NULL },
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
};
#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
......
......@@ -32,7 +32,22 @@
void
nouveau_dma_pre_init(struct nouveau_channel *chan)
{
chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2;
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nouveau_bo *pushbuf = chan->pushbuf_bo;
if (dev_priv->card_type == NV_50) {
const int ib_size = pushbuf->bo.mem.size / 2;
chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2;
chan->dma.ib_max = (ib_size / 8) - 1;
chan->dma.ib_put = 0;
chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put;
chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2;
} else {
chan->dma.max = (pushbuf->bo.mem.size >> 2) - 2;
}
chan->dma.put = 0;
chan->dma.cur = chan->dma.put;
chan->dma.free = chan->dma.max - chan->dma.cur;
......@@ -162,12 +177,101 @@ READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout)
return (val - chan->pushbuf_base) >> 2;
}
void
nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
int delta, int length)
{
struct nouveau_bo *pb = chan->pushbuf_bo;
uint64_t offset = bo->bo.offset + delta;
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
BUG_ON(chan->dma.ib_free < 1);
nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
chan->dma.ib_free--;
}
static int
nv50_dma_push_wait(struct nouveau_channel *chan, int count)
{
uint32_t cnt = 0, prev_get = 0;
while (chan->dma.ib_free < count) {
uint32_t get = nvchan_rd32(chan, 0x88);
if (get != prev_get) {
prev_get = get;
cnt = 0;
}
if ((++cnt & 0xff) == 0) {
DRM_UDELAY(1);
if (cnt > 100000)
return -EBUSY;
}
chan->dma.ib_free = get - chan->dma.ib_put;
if (chan->dma.ib_free <= 0)
chan->dma.ib_free += chan->dma.ib_max + 1;
}
return 0;
}
static int
nv50_dma_wait(struct nouveau_channel *chan, int slots, int count)
{
uint32_t cnt = 0, prev_get = 0;
int ret;
ret = nv50_dma_push_wait(chan, slots + 1);
if (unlikely(ret))
return ret;
while (chan->dma.free < count) {
int get = READ_GET(chan, &prev_get, &cnt);
if (unlikely(get < 0)) {
if (get == -EINVAL)
continue;
return get;
}
if (get <= chan->dma.cur) {
chan->dma.free = chan->dma.max - chan->dma.cur;
if (chan->dma.free >= count)
break;
FIRE_RING(chan);
do {
get = READ_GET(chan, &prev_get, &cnt);
if (unlikely(get < 0)) {
if (get == -EINVAL)
continue;
return get;
}
} while (get == 0);
chan->dma.cur = 0;
chan->dma.put = 0;
}
chan->dma.free = get - chan->dma.cur - 1;
}
return 0;
}
int
nouveau_dma_wait(struct nouveau_channel *chan, int size)
nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size)
{
uint32_t prev_get = 0, cnt = 0;
int get;
if (chan->dma.ib_max)
return nv50_dma_wait(chan, slots, size);
while (chan->dma.free < size) {
get = READ_GET(chan, &prev_get, &cnt);
if (unlikely(get == -EBUSY))
......
......@@ -31,6 +31,9 @@
#define NOUVEAU_DMA_DEBUG 0
#endif
void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
int delta, int length);
/*
* There's a hw race condition where you can't jump to your PUT offset,
* to avoid this we jump to offset + SKIPS and fill the difference with
......@@ -96,13 +99,11 @@ enum {
static __must_check inline int
RING_SPACE(struct nouveau_channel *chan, int size)
{
if (chan->dma.free < size) {
int ret;
ret = nouveau_dma_wait(chan, size);
ret = nouveau_dma_wait(chan, 1, size);
if (ret)
return ret;
}
chan->dma.free -= size;
return 0;
......@@ -146,7 +147,13 @@ FIRE_RING(struct nouveau_channel *chan)
return;
chan->accel_done = true;
if (chan->dma.ib_max) {
nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
(chan->dma.cur - chan->dma.put) << 2);
} else {
WRITE_PUT(chan->dma.cur);
}
chan->dma.put = chan->dma.cur;
}
......
......@@ -75,11 +75,11 @@ MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
int nouveau_ignorelid = 0;
module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
MODULE_PARM_DESC(noagp, "Disable all acceleration");
MODULE_PARM_DESC(noaccel, "Disable all acceleration");
int nouveau_noaccel = 0;
module_param_named(noaccel, nouveau_noaccel, int, 0400);
MODULE_PARM_DESC(noagp, "Disable fbcon acceleration");
MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
int nouveau_nofbaccel = 0;
module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
......
......@@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 15
#define DRIVER_PATCHLEVEL 16
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
......@@ -83,6 +83,7 @@ struct nouveau_bo {
struct drm_file *reserved_by;
struct list_head entry;
int pbbo_index;
bool validate_mapped;
struct nouveau_channel *channel;
......@@ -239,6 +240,11 @@ struct nouveau_channel {
int cur;
int put;
/* access via pushbuf_bo */
int ib_base;
int ib_max;
int ib_free;
int ib_put;
} dma;
uint32_t sw_subchannel[8];
......@@ -533,6 +539,9 @@ struct drm_nouveau_private {
struct nouveau_engine engine;
struct nouveau_channel *channel;
/* For PFIFO and PGRAPH. */
spinlock_t context_switch_lock;
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
struct nouveau_gpuobj *ramht;
uint32_t ramin_rsvd_vram;
......@@ -596,8 +605,7 @@ struct drm_nouveau_private {
struct list_head gpuobj_list;
struct nvbios VBIOS;
struct nouveau_bios_info *vbios;
struct nvbios vbios;
struct nv04_mode_state mode_reg;
struct nv04_mode_state saved_reg;
......@@ -696,12 +704,6 @@ extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
uint32_t reg, uint32_t mask, uint32_t val);
extern bool nouveau_wait_for_idle(struct drm_device *);
extern int nouveau_card_init(struct drm_device *);
extern int nouveau_ioctl_card_init(struct drm_device *, void *data,
struct drm_file *);
extern int nouveau_ioctl_suspend(struct drm_device *, void *data,
struct drm_file *);
extern int nouveau_ioctl_resume(struct drm_device *, void *data,
struct drm_file *);
/* nouveau_mem.c */
extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start,
......@@ -845,7 +847,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
/* nouveau_dma.c */
extern void nouveau_dma_pre_init(struct nouveau_channel *);
extern int nouveau_dma_init(struct nouveau_channel *);
extern int nouveau_dma_wait(struct nouveau_channel *, int size);
extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
/* nouveau_acpi.c */
#ifdef CONFIG_ACPI
......@@ -1027,6 +1029,7 @@ extern void nv50_graph_destroy_context(struct nouveau_channel *);
extern int nv50_graph_load_context(struct nouveau_channel *);
extern int nv50_graph_unload_context(struct drm_device *);
extern void nv50_graph_context_switch(struct drm_device *);
extern int nv50_grctx_init(struct nouveau_grctx *);
/* nouveau_grctx.c */
extern int nouveau_grctx_prog_load(struct drm_device *);
......@@ -1152,16 +1155,6 @@ extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_pin(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_tile(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
......
This diff is collapsed.
......@@ -160,7 +160,7 @@ static void
setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
int chip_version = dev_priv->vbios->chip_version;
int chip_version = dev_priv->vbios.chip_version;
uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
......@@ -216,7 +216,7 @@ setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
struct nouveau_pll_vals *pv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
int chip_version = dev_priv->vbios->chip_version;
int chip_version = dev_priv->vbios.chip_version;
bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
......@@ -374,7 +374,7 @@ nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
struct nouveau_pll_vals *pv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
int cv = dev_priv->vbios->chip_version;
int cv = dev_priv->vbios.chip_version;
if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
cv >= 0x40) {
......
......@@ -254,16 +254,16 @@ struct nouveau_i2c_chan *
nouveau_i2c_find(struct drm_device *dev, int index)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvbios *bios = &dev_priv->VBIOS;
struct nvbios *bios = &dev_priv->vbios;
if (index > DCB_MAX_NUM_I2C_ENTRIES)
if (index >= DCB_MAX_NUM_I2C_ENTRIES)
return NULL;
if (!bios->bdcb.dcb.i2c[index].chan) {
if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
if (!bios->dcb.i2c[index].chan) {
if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index))
return NULL;
}
return bios->bdcb.dcb.i2c[index].chan;
return bios->dcb.i2c[index].chan;
}
......@@ -691,11 +691,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
struct drm_device *dev = (struct drm_device *)arg;
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t status, fbdev_flags = 0;
unsigned long flags;
status = nv_rd32(dev, NV03_PMC_INTR_0);
if (!status)
return IRQ_NONE;
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
if (dev_priv->fbdev_info) {
fbdev_flags = dev_priv->fbdev_info->flags;
dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
......@@ -733,5 +736,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
if (dev_priv->fbdev_info)
dev_priv->fbdev_info->flags = fbdev_flags;
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
return IRQ_HANDLED;
}
......@@ -391,6 +391,7 @@ nouveau_card_init(struct drm_device *dev)
goto out;
engine = &dev_priv->engine;
dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
spin_lock_init(&dev_priv->context_switch_lock);
/* Parse BIOS tables / Run init tables if card not POSTed */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
......@@ -776,13 +777,6 @@ int nouveau_unload(struct drm_device *dev)
return 0;
}
int
nouveau_ioctl_card_init(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
return nouveau_card_init(dev);
}
int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
......
......@@ -230,13 +230,13 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
if (dcb->type == OUTPUT_TV) {
testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
if (dev_priv->vbios->tvdactestval)
testval = dev_priv->vbios->tvdactestval;
if (dev_priv->vbios.tvdactestval)
testval = dev_priv->vbios.tvdactestval;
} else {
testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
if (dev_priv->vbios->dactestval)
testval = dev_priv->vbios->dactestval;
if (dev_priv->vbios.dactestval)
testval = dev_priv->vbios.dactestval;
}
saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
......
......@@ -269,10 +269,10 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
if (!nv_gf4_disp_arch(dev) ||
(output_mode->hsync_start - output_mode->hdisplay) >=
dev_priv->vbios->digital_min_front_porch)
dev_priv->vbios.digital_min_front_porch)
regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
else
regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1;
regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1;
regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
......
......@@ -93,10 +93,9 @@ int
nv04_display_create(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct parsed_dcb *dcb = dev_priv->vbios->dcb;
struct dcb_table *dcb = &dev_priv->vbios.dcb;
struct drm_encoder *encoder;
struct drm_crtc *crtc;
uint16_t connector[16] = { 0 };
int i, ret;
NV_DEBUG_KMS(dev, "\n");
......@@ -154,52 +153,10 @@ nv04_display_create(struct drm_device *dev)
if (ret)
continue;
connector[dcbent->connector] |= (1 << dcbent->type);
}
for (i = 0; i < dcb->entries; i++) {
struct dcb_entry *dcbent = &dcb->entry[i];
uint16_t encoders;
int type;
encoders = connector[dcbent->connector];
if (!(encoders & (1 << dcbent->type)))
continue;
connector[dcbent->connector] = 0;
switch (dcbent->type) {
case OUTPUT_ANALOG:
if (!MULTIPLE_ENCODERS(encoders))
type = DRM_MODE_CONNECTOR_VGA;
else
type = DRM_MODE_CONNECTOR_DVII;
break;
case OUTPUT_TMDS:
if (!MULTIPLE_ENCODERS(encoders))
type = DRM_MODE_CONNECTOR_DVID;
else
type = DRM_MODE_CONNECTOR_DVII;
break;
case OUTPUT_LVDS:
type = DRM_MODE_CONNECTOR_LVDS;
#if 0
/* don't create i2c adapter when lvds ddc not allowed */
if (dcbent->lvdsconf.use_straps_for_mode ||
dev_priv->vbios->fp_no_ddc)
i2c_index = 0xf;
#endif
break;
case OUTPUT_TV:
type = DRM_MODE_CONNECTOR_TV;
break;
default:
type = DRM_MODE_CONNECTOR_Unknown;
continue;
}
nouveau_connector_create(dev, dcbent->connector, type);
}
for (i = 0; i < dcb->connector.entries; i++)
nouveau_connector_create(dev, &dcb->connector.entry[i]);
/* Save previous state */
NVLockVgaCrtcs(dev, false);
......
......@@ -118,7 +118,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
return;
}
width = (image->width + 31) & ~31;
width = ALIGN(image->width, 32);
dsize = (width * image->height) >> 5;
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
......
......@@ -117,6 +117,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned long flags;
int ret;
ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0,
......@@ -127,6 +128,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
if (ret)
return ret;
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
/* Setup initial state */
dev_priv->engine.instmem.prepare_access(dev, true);
RAMFC_WR(DMA_PUT, chan->pushbuf_base);
......@@ -144,6 +147,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
/* enable the fifo dma operation */
nv_wr32(dev, NV04_PFIFO_MODE,
nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
return 0;
}
......
......@@ -262,7 +262,7 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
nv_encoder->or = ffs(entry->or) - 1;
/* Run the slave-specific initialization */
adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter;
adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter;
was_locked = NVLockVgaCrtcs(dev, false);
......
......@@ -45,8 +45,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
if (dev_priv->vbios->tvdactestval)
testval = dev_priv->vbios->tvdactestval;
if (dev_priv->vbios.tvdactestval)
testval = dev_priv->vbios.tvdactestval;
dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
head = (dacclk & 0x100) >> 8;
......@@ -367,7 +367,7 @@ static void nv17_tv_prepare(struct drm_encoder *encoder)
!enc->crtc &&
nv04_dfp_get_bound_head(dev, dcb) == head) {
nv04_dfp_bind_head(dev, dcb, head ^ 1,
dev_priv->VBIOS.fp.dual_link);
dev_priv->vbios.fp.dual_link);
}
}
......
......@@ -37,6 +37,7 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t fc = NV40_RAMFC(chan->id);
unsigned long flags;
int ret;
ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0,
......@@ -45,6 +46,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
if (ret)
return ret;
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wi32(dev, fc + 0, chan->pushbuf_base);
nv_wi32(dev, fc + 4, chan->pushbuf_base);
......@@ -63,6 +66,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
/* enable the fifo dma operation */
nv_wr32(dev, NV04_PFIFO_MODE,
nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
return 0;
}
......
......@@ -79,8 +79,8 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
}
/* Use bios provided value if possible. */
if (dev_priv->vbios->dactestval) {
load_pattern = dev_priv->vbios->dactestval;
if (dev_priv->vbios.dactestval) {
load_pattern = dev_priv->vbios.dactestval;
NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n",
load_pattern);
} else {
......
......@@ -370,9 +370,7 @@ nv50_display_init(struct drm_device *dev)
struct nouveau_connector *conn = nouveau_connector(connector);
struct dcb_gpio_entry *gpio;
if (connector->connector_type != DRM_MODE_CONNECTOR_DVII &&
connector->connector_type != DRM_MODE_CONNECTOR_DVID &&
connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
if (conn->dcb->gpio_tag == 0xff)
continue;
gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
......@@ -465,8 +463,7 @@ static int nv50_display_disable(struct drm_device *dev)
int nv50_display_create(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct parsed_dcb *dcb = dev_priv->vbios->dcb;
uint32_t connector[16] = {};
struct dcb_table *dcb = &dev_priv->vbios.dcb;
int ret, i;
NV_DEBUG_KMS(dev, "\n");
......@@ -522,44 +519,13 @@ int nv50_display_create(struct drm_device *dev)
NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
continue;
}
connector[entry->connector] |= (1 << entry->type);
}
/* It appears that DCB 3.0+ VBIOS has a connector table, however,
* I'm not 100% certain how to decode it correctly yet so just
* look at what encoders are present on each connector index and
* attempt to derive the connector type from that.
*/
for (i = 0 ; i < dcb->entries; i++) {
struct dcb_entry *entry = &dcb->entry[i];
uint16_t encoders;
int type;
encoders = connector[entry->connector];
if (!(encoders & (1 << entry->type)))
continue;
connector[entry->connector] = 0;
if (encoders & (1 << OUTPUT_DP)) {
type = DRM_MODE_CONNECTOR_DisplayPort;
} else if (encoders & (1 << OUTPUT_TMDS)) {
if (encoders & (1 << OUTPUT_ANALOG))
type = DRM_MODE_CONNECTOR_DVII;
else
type = DRM_MODE_CONNECTOR_DVID;
} else if (encoders & (1 << OUTPUT_ANALOG)) {
type = DRM_MODE_CONNECTOR_VGA;
} else if (encoders & (1 << OUTPUT_LVDS)) {
type = DRM_MODE_CONNECTOR_LVDS;
} else {
type = DRM_MODE_CONNECTOR_Unknown;
}
if (type == DRM_MODE_CONNECTOR_Unknown)
for (i = 0 ; i < dcb->connector.entries; i++) {
if (i != 0 && dcb->connector.entry[i].index ==
dcb->connector.entry[i - 1].index)
continue;
nouveau_connector_create(dev, entry->connector, type);
nouveau_connector_create(dev, &dcb->connector.entry[i]);
}
ret = nv50_display_init(dev);
......@@ -667,8 +633,8 @@ nv50_display_irq_head(struct drm_device *dev, int *phead,
return -1;
}
for (i = 0; i < dev_priv->vbios->dcb->entries; i++) {
struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i];
for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i];
if (dcbent->type != type)
continue;
......@@ -692,7 +658,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_connector *nv_connector = NULL;
struct drm_encoder *encoder;
struct nvbios *bios = &dev_priv->VBIOS;
struct nvbios *bios = &dev_priv->vbios;
uint32_t mc, script = 0, or;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
......@@ -710,7 +676,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
switch (dcbent->type) {
case OUTPUT_LVDS:
script = (mc >> 8) & 0xf;
if (bios->pub.fp_no_ddc) {
if (bios->fp_no_ddc) {
if (bios->fp.dual_link)
script |= 0x0100;
if (bios->fp.if_is_24bit)
......
......@@ -109,7 +109,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
return;
}
width = (image->width + 31) & ~31;
width = ALIGN(image->width, 32);
dwords = (width * image->height) >> 5;
BEGIN_RING(chan, NvSub2D, 0x0814, 2);
......
......@@ -243,6 +243,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *ramfc = NULL;
unsigned long flags;
int ret;
NV_DEBUG(dev, "ch%d\n", chan->id);
......@@ -278,19 +279,21 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
return ret;
}
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base);
nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base);
nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
nv_wo32(dev, ramfc, 0x3c/4, 0x00086078);
nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
nv_wo32(dev, ramfc, 0x7c/4, 0x30000001);
nv_wo32(dev, ramfc, 0x78/4, 0x00000000);
nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff);
nv_wo32(dev, ramfc, 0x3c/4, 0x403f6078);
nv_wo32(dev, ramfc, 0x50/4, chan->pushbuf_base +
chan->dma.ib_base * 4);
nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16);
if (!IS_G80) {
nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
......@@ -306,10 +309,12 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
ret = nv50_fifo_channel_enable(dev, chan->id, false);
if (ret) {
NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
return ret;
}
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
return 0;
}
......
......@@ -28,30 +28,7 @@
#include "drm.h"
#include "nouveau_drv.h"
MODULE_FIRMWARE("nouveau/nv50.ctxprog");
MODULE_FIRMWARE("nouveau/nv50.ctxvals");
MODULE_FIRMWARE("nouveau/nv84.ctxprog");
MODULE_FIRMWARE("nouveau/nv84.ctxvals");
MODULE_FIRMWARE("nouveau/nv86.ctxprog");
MODULE_FIRMWARE("nouveau/nv86.ctxvals");
MODULE_FIRMWARE("nouveau/nv92.ctxprog");
MODULE_FIRMWARE("nouveau/nv92.ctxvals");
MODULE_FIRMWARE("nouveau/nv94.ctxprog");
MODULE_FIRMWARE("nouveau/nv94.ctxvals");
MODULE_FIRMWARE("nouveau/nv96.ctxprog");
MODULE_FIRMWARE("nouveau/nv96.ctxvals");
MODULE_FIRMWARE("nouveau/nv98.ctxprog");
MODULE_FIRMWARE("nouveau/nv98.ctxvals");
MODULE_FIRMWARE("nouveau/nva0.ctxprog");
MODULE_FIRMWARE("nouveau/nva0.ctxvals");
MODULE_FIRMWARE("nouveau/nva5.ctxprog");
MODULE_FIRMWARE("nouveau/nva5.ctxvals");
MODULE_FIRMWARE("nouveau/nva8.ctxprog");
MODULE_FIRMWARE("nouveau/nva8.ctxvals");
MODULE_FIRMWARE("nouveau/nvaa.ctxprog");
MODULE_FIRMWARE("nouveau/nvaa.ctxvals");
MODULE_FIRMWARE("nouveau/nvac.ctxprog");
MODULE_FIRMWARE("nouveau/nvac.ctxvals");
#include "nouveau_grctx.h"
#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
......@@ -111,9 +88,34 @@ nv50_graph_init_ctxctl(struct drm_device *dev)
NV_DEBUG(dev, "\n");
if (nouveau_ctxfw) {
nouveau_grctx_prog_load(dev);
if (!dev_priv->engine.graph.ctxprog)
dev_priv->engine.graph.grctx_size = 0x70000;
}
if (!dev_priv->engine.graph.ctxprog) {
struct nouveau_grctx ctx = {};
uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL);
int i;
if (!cp) {
NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n");
dev_priv->engine.graph.accel_blocked = true;
return 0;
}
ctx.dev = dev;
ctx.mode = NOUVEAU_GRCTX_PROG;
ctx.data = cp;
ctx.ctxprog_max = 512;
if (!nv50_grctx_init(&ctx)) {
dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
} else {
dev_priv->engine.graph.accel_blocked = true;
}
kfree(cp);
}
nv_wr32(dev, 0x400320, 4);
nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
......@@ -193,13 +195,13 @@ nv50_graph_create_context(struct nouveau_channel *chan)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
struct nouveau_gpuobj *ctx;
uint32_t grctx_size = 0x70000;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
int hdr, ret;
NV_DEBUG(dev, "ch%d\n", chan->id);
ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC |
ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
0x1000, NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
if (ret)
return ret;
......@@ -209,7 +211,7 @@ nv50_graph_create_context(struct nouveau_channel *chan)
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
grctx_size - 1);
pgraph->grctx_size - 1);
nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance);
nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
......@@ -217,7 +219,15 @@ nv50_graph_create_context(struct nouveau_channel *chan)
dev_priv->engine.instmem.finish_access(dev);
dev_priv->engine.instmem.prepare_access(dev, true);
if (!pgraph->ctxprog) {
struct nouveau_grctx ctx = {};
ctx.dev = chan->dev;
ctx.mode = NOUVEAU_GRCTX_VALS;
ctx.data = chan->ramin_grctx->gpuobj;
nv50_grctx_init(&ctx);
} else {
nouveau_grctx_vals_load(dev, ctx);
}
nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
if ((dev_priv->chipset & 0xf0) == 0xa0)
nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
......
This diff is collapsed.
......@@ -390,7 +390,7 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
if (gpuobj->im_backing)
return -EINVAL;
*sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1);
*sz = ALIGN(*sz, NV50_INSTMEM_PAGE_SIZE);
if (*sz == 0)
return -EINVAL;
......
......@@ -25,13 +25,14 @@
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 16
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
uint32_t tt_ctxdma_handle;
int channel;
uint32_t pushbuf_domains;
/* Notifier memory */
uint32_t notifier_handle;
......@@ -109,68 +110,58 @@ struct drm_nouveau_gem_new {
uint32_t align;
};
#define NOUVEAU_GEM_MAX_BUFFERS 1024
struct drm_nouveau_gem_pushbuf_bo_presumed {
uint32_t valid;
uint32_t domain;
uint64_t offset;
};
struct drm_nouveau_gem_pushbuf_bo {
uint64_t user_priv;
uint32_t handle;
uint32_t read_domains;
uint32_t write_domains;
uint32_t valid_domains;
uint32_t presumed_ok;
uint32_t presumed_domain;
uint64_t presumed_offset;
struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
};
#define NOUVEAU_GEM_RELOC_LOW (1 << 0)
#define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
#define NOUVEAU_GEM_RELOC_OR (1 << 2)
#define NOUVEAU_GEM_MAX_RELOCS 1024
struct drm_nouveau_gem_pushbuf_reloc {
uint32_t reloc_bo_index;
uint32_t reloc_bo_offset;
uint32_t bo_index;
uint32_t reloc_index;
uint32_t flags;
uint32_t data;
uint32_t vor;
uint32_t tor;
};
#define NOUVEAU_GEM_MAX_BUFFERS 1024
#define NOUVEAU_GEM_MAX_RELOCS 1024
#define NOUVEAU_GEM_MAX_PUSH 512
struct drm_nouveau_gem_pushbuf_push {
uint32_t bo_index;
uint32_t pad;
uint64_t offset;
uint64_t length;
};
struct drm_nouveau_gem_pushbuf {
uint32_t channel;
uint32_t nr_dwords;
uint32_t nr_buffers;
uint32_t nr_relocs;
uint64_t dwords;
uint64_t buffers;
uint64_t relocs;
};
struct drm_nouveau_gem_pushbuf_call {
uint32_t channel;
uint32_t handle;
uint32_t offset;
uint32_t nr_buffers;
uint32_t nr_relocs;
uint32_t nr_dwords;
uint64_t buffers;
uint32_t nr_push;
uint64_t relocs;
uint64_t push;
uint32_t suffix0;
uint32_t suffix1;
/* below only accessed for CALL2 */
uint64_t vram_available;
uint64_t gart_available;
};
struct drm_nouveau_gem_pin {
uint32_t handle;
uint32_t domain;
uint64_t offset;
};
struct drm_nouveau_gem_unpin {
uint32_t handle;
};
#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
......@@ -183,14 +174,6 @@ struct drm_nouveau_gem_cpu_fini {
uint32_t handle;
};
struct drm_nouveau_gem_tile {
uint32_t handle;
uint32_t offset;
uint32_t size;
uint32_t tile_mode;
uint32_t tile_flags;
};
enum nouveau_bus_type {
NV_AGP = 0,
NV_PCI = 1,
......@@ -200,22 +183,17 @@ enum nouveau_bus_type {
struct drm_nouveau_sarea {
};
#define DRM_NOUVEAU_CARD_INIT 0x00
#define DRM_NOUVEAU_GETPARAM 0x01
#define DRM_NOUVEAU_SETPARAM 0x02
#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03
#define DRM_NOUVEAU_CHANNEL_FREE 0x04
#define DRM_NOUVEAU_GROBJ_ALLOC 0x05
#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06
#define DRM_NOUVEAU_GPUOBJ_FREE 0x07
#define DRM_NOUVEAU_GETPARAM 0x00
#define DRM_NOUVEAU_SETPARAM 0x01
#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02
#define DRM_NOUVEAU_CHANNEL_FREE 0x03
#define DRM_NOUVEAU_GROBJ_ALLOC 0x04
#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05
#define DRM_NOUVEAU_GPUOBJ_FREE 0x06
#define DRM_NOUVEAU_GEM_NEW 0x40
#define DRM_NOUVEAU_GEM_PUSHBUF 0x41
#define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42
#define DRM_NOUVEAU_GEM_PIN 0x43 /* !KMS only */
#define DRM_NOUVEAU_GEM_UNPIN 0x44 /* !KMS only */
#define DRM_NOUVEAU_GEM_CPU_PREP 0x45
#define DRM_NOUVEAU_GEM_CPU_FINI 0x46
#define DRM_NOUVEAU_GEM_INFO 0x47
#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48
#define DRM_NOUVEAU_GEM_CPU_PREP 0x42
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
#endif /* __NOUVEAU_DRM_H__ */
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