Skip to content

Commit

Permalink
Merge branch 'drm-nouveau-destage' of git://people.freedesktop.org/~a…
Browse files Browse the repository at this point in the history
…irlied/linux

Pull nouveau destaging + Kelper modesetting support from Dave Airlie:
 "This pull request is unexpected and not something I had mentioned
  previously.

  So NVIDIA announced new Kepler GPUs this morning, and Ben has killed
  himself getting modesetting support for them together to have on
  launch day.  Most of the code to support the new chips has already
  gone in, however this pull contains a few more pieces along with the
  final enables so the driver binds to the new Kepler cards.  Its quite
  amazing that nouveau can support a GPU on its launch day even if its
  just unaccelerated modesetting, and I'd like to have support in the
  next kernel.

  In order to sweeten the deal, Ben has also requested nouveau destage
  and become ABI stable, the only change is the version number bump
  which he prepared userspace for quite a long time ago.  The driver
  hasn't broken ABI since that one big break that caused a lot of fuss.

  It's also quite a small set of code, and not likely to break anything."

* 'drm-nouveau-destage' of git://people.freedesktop.org/~airlied/linux:
  drm/nouveau/dp: support version 4.0 of DP table
  drm/nve0/disp: nvidia randomly decided to move the dithering method
  drm/nve0: initial modesetting support for kepler chipsets
  drm/nouveau: add bios connector type for dms59
  drm/nouveau: move out of staging drivers
  drm/nouveau: bump version to 1.0.0
  drm/nvd0/disp: ignore clock set if no pclk
  drm/nouveau: oops, increase channel dispc_vma to 4
  drm/nouveau: inform userspace of new kernel subchannel requirements
  drm/nouveau: remove m2mf creation on userspace channels
  drm/nvc0-/disp: reimplement flip completion method as fifo method
  drm/nouveau: move fence sequence check to start of loop
  drm/nouveau: remove subchannel names from places where it doesn't matter
  drm/nouveau/ttm: always do buffer moves on kernel channel
  • Loading branch information
torvalds committed Mar 22, 2012
2 parents 09fa302 + 1898f44 commit ba331d5
Show file tree
Hide file tree
Showing 19 changed files with 288 additions and 186 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ config DRM_RADEON

source "drivers/gpu/drm/radeon/Kconfig"

source "drivers/gpu/drm/nouveau/Kconfig"

config DRM_I810
tristate "Intel I810"
# !PREEMPT because of missing ioctl locking
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,8 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
break;
case 1:
case 2:
if (!(entry[5] & cond))
if ((table[0] < 0x40 && !(entry[5] & cond)) ||
(table[0] == 0x40 && !(entry[4] & cond)))
iexec->execute = false;
break;
case 5:
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_bios.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ enum dcb_connector_type {
DCB_CONNECTOR_TV_3 = 0x13,
DCB_CONNECTOR_DVI_I = 0x30,
DCB_CONNECTOR_DVI_D = 0x31,
DCB_CONNECTOR_DMS59_0 = 0x38,
DCB_CONNECTOR_DMS59_1 = 0x39,
DCB_CONNECTOR_LVDS = 0x40,
DCB_CONNECTOR_LVDS_SPWG = 0x41,
DCB_CONNECTOR_DP = 0x46,
Expand Down
11 changes: 3 additions & 8 deletions drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,16 +693,12 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
struct ttm_mem_reg *new_mem)
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
struct nouveau_channel *chan = chan = dev_priv->channel;
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct ttm_mem_reg *old_mem = &bo->mem;
struct nouveau_channel *chan;
int ret;

chan = nvbo->channel;
if (!chan) {
chan = dev_priv->channel;
mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
}
mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);

/* create temporary vmas for the transfer and attach them to the
* old nouveau_mem node, these will get cleaned up after ttm has
Expand Down Expand Up @@ -734,8 +730,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
}

out:
if (chan == dev_priv->channel)
mutex_unlock(&chan->mutex);
mutex_unlock(&chan->mutex);
return ret;
}

Expand Down
34 changes: 18 additions & 16 deletions drivers/gpu/drm/nouveau/nouveau_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
struct nouveau_channel *chan;
unsigned long flags;
int ret;
int ret, i;

/* allocate and lock channel structure */
chan = kzalloc(sizeof(*chan), GFP_KERNEL);
Expand Down Expand Up @@ -184,7 +184,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
return ret;
}

nouveau_dma_pre_init(chan);
nouveau_dma_init(chan);
chan->user_put = 0x40;
chan->user_get = 0x44;
if (dev_priv->card_type >= NV_50)
Expand All @@ -202,9 +202,18 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,

pfifo->reassign(dev, true);

ret = nouveau_dma_init(chan);
if (!ret)
ret = nouveau_fence_channel_init(chan);
/* Insert NOPs for NOUVEAU_DMA_SKIPS */
ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
if (ret) {
nouveau_channel_put(&chan);
return ret;
}

for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
OUT_RING (chan, 0x00000000);
FIRE_RING(chan);

ret = nouveau_fence_channel_init(chan);
if (ret) {
nouveau_channel_put(&chan);
return ret;
Expand Down Expand Up @@ -427,18 +436,11 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
}

if (dev_priv->card_type < NV_C0) {
init->subchan[0].handle = NvM2MF;
if (dev_priv->card_type < NV_50)
init->subchan[0].grclass = 0x0039;
else
init->subchan[0].grclass = 0x5039;
init->subchan[1].handle = NvSw;
init->subchan[1].grclass = NV_SW;
init->nr_subchan = 2;
} else {
init->subchan[0].handle = 0x9039;
init->subchan[0].grclass = 0x9039;
init->subchan[0].handle = NvSw;
init->subchan[0].grclass = NV_SW;
init->nr_subchan = 1;
} else {
init->nr_subchan = 0;
}

/* Named memory object area */
Expand Down
13 changes: 6 additions & 7 deletions drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,8 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
case DCB_CONNECTOR_TV_0 :
case DCB_CONNECTOR_TV_1 :
case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV;
case DCB_CONNECTOR_DMS59_0 :
case DCB_CONNECTOR_DMS59_1 :
case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII;
case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID;
case DCB_CONNECTOR_LVDS :
Expand Down Expand Up @@ -1013,13 +1015,10 @@ nouveau_connector_create(struct drm_device *dev, int index)

/* Add overscan compensation options to digital outputs */
if (disp->underscan_property &&
(nv_connector->type == DCB_CONNECTOR_DVI_D ||
nv_connector->type == DCB_CONNECTOR_DVI_I ||
nv_connector->type == DCB_CONNECTOR_HDMI_0 ||
nv_connector->type == DCB_CONNECTOR_HDMI_1 ||
nv_connector->type == DCB_CONNECTOR_DP ||
nv_connector->type == DCB_CONNECTOR_DMS59_DP0 ||
nv_connector->type == DCB_CONNECTOR_DMS59_DP1)) {
(type == DRM_MODE_CONNECTOR_DVID ||
type == DRM_MODE_CONNECTOR_DVII ||
type == DRM_MODE_CONNECTOR_HDMIA ||
type == DRM_MODE_CONNECTOR_DisplayPort)) {
drm_connector_attach_property(connector,
disp->underscan_property,
UNDERSCAN_OFF);
Expand Down
14 changes: 9 additions & 5 deletions drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,15 +441,19 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
goto fail;

/* Emit the pageflip */
ret = RING_SPACE(chan, 2);
ret = RING_SPACE(chan, 3);
if (ret)
goto fail;

if (dev_priv->card_type < NV_C0)
if (dev_priv->card_type < NV_C0) {
BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
else
BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
OUT_RING (chan, 0);
OUT_RING (chan, 0x00000000);
OUT_RING (chan, 0x00000000);
} else {
BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1);
OUT_RING (chan, ++chan->fence.sequence);
BEGIN_NVC0(chan, 8, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000);
}
FIRE_RING (chan);

ret = nouveau_fence_new(chan, pfence, true);
Expand Down
61 changes: 1 addition & 60 deletions drivers/gpu/drm/nouveau/nouveau_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "nouveau_ramht.h"

void
nouveau_dma_pre_init(struct nouveau_channel *chan)
nouveau_dma_init(struct nouveau_channel *chan)
{
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nouveau_bo *pushbuf = chan->pushbuf_bo;
Expand All @@ -54,65 +54,6 @@ nouveau_dma_pre_init(struct nouveau_channel *chan)
chan->dma.free = chan->dma.max - chan->dma.cur;
}

int
nouveau_dma_init(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
int ret, i;

if (dev_priv->card_type >= NV_C0) {
ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
if (ret)
return ret;

ret = RING_SPACE(chan, 2);
if (ret)
return ret;

BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1);
OUT_RING (chan, 0x00009039);
FIRE_RING (chan);
return 0;
}

/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
ret = nouveau_gpuobj_gr_new(chan, NvM2MF, dev_priv->card_type < NV_50 ?
0x0039 : 0x5039);
if (ret)
return ret;

/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
&chan->m2mf_ntfy);
if (ret)
return ret;

/* Insert NOPS for NOUVEAU_DMA_SKIPS */
ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
if (ret)
return ret;

for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
OUT_RING(chan, 0);

/* Initialise NV_MEMORY_TO_MEMORY_FORMAT */
ret = RING_SPACE(chan, 6);
if (ret)
return ret;
BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
OUT_RING (chan, NvM2MF);
BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
OUT_RING (chan, NvNotify0);
OUT_RING (chan, chan->vram_handle);
OUT_RING (chan, chan->gart_handle);

/* Sit back and pray the channel works.. */
FIRE_RING(chan);

return 0;
}

void
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
{
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/nouveau_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,

/* Hardcoded object assignments to subchannels (subchannel id). */
enum {
NvSubM2MF = 0,
NvSubSw = 1,
NvSubSw = 0,
NvSubM2MF = 1,
NvSub2D = 2,
NvSubCtxSurf2D = 2,
NvSubGdiRect = 3,
Expand Down
11 changes: 11 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
case 0x20:
case 0x21:
case 0x30:
case 0x40:
break;
default:
NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
Expand Down Expand Up @@ -366,6 +367,10 @@ dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable)
if (table[0] >= 0x20 && table[0] <= 0x30) {
if (enable) script = ROM16(entry[12]);
else script = ROM16(entry[14]);
} else
if (table[0] == 0x40) {
if (enable) script = ROM16(entry[11]);
else script = ROM16(entry[13]);
}
}

Expand All @@ -380,6 +385,9 @@ dp_link_train_init(struct drm_device *dev, struct dp_state *dp)
if (table) {
if (table[0] >= 0x20 && table[0] <= 0x30)
script = ROM16(entry[6]);
else
if (table[0] == 0x40)
script = ROM16(entry[5]);
}

nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
Expand All @@ -393,6 +401,9 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
if (table) {
if (table[0] >= 0x20 && table[0] <= 0x30)
script = ROM16(entry[8]);
else
if (table[0] == 0x40)
script = ROM16(entry[7]);
}

nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
Expand Down
40 changes: 26 additions & 14 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
#define __NOUVEAU_DRV_H__

#define DRIVER_AUTHOR "Stephane Marchesin"
#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net"
#define DRIVER_EMAIL "nouveau@lists.freedesktop.org"

#define DRIVER_NAME "nouveau"
#define DRIVER_DESC "nVidia Riva/TNT/GeForce"
#define DRIVER_DATE "20090420"
#define DRIVER_DATE "20120316"

#define DRIVER_MAJOR 0
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 16
#define DRIVER_PATCHLEVEL 0

#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
Expand Down Expand Up @@ -113,8 +113,6 @@ struct nouveau_bo {
int pbbo_index;
bool validate_mapped;

struct nouveau_channel *channel;

struct list_head vma_list;
unsigned page_shift;

Expand Down Expand Up @@ -296,7 +294,7 @@ struct nouveau_channel {

uint32_t sw_subchannel[8];

struct nouveau_vma dispc_vma[2];
struct nouveau_vma dispc_vma[4];
struct {
struct nouveau_gpuobj *vblsem;
uint32_t vblsem_head;
Expand Down Expand Up @@ -703,6 +701,7 @@ enum nouveau_card_type {
NV_50 = 0x50,
NV_C0 = 0xc0,
NV_D0 = 0xd0,
NV_E0 = 0xe0,
};

struct drm_nouveau_private {
Expand Down Expand Up @@ -1091,8 +1090,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
#endif

/* nouveau_dma.c */
extern void nouveau_dma_pre_init(struct nouveau_channel *);
extern int nouveau_dma_init(struct nouveau_channel *);
extern void nouveau_dma_init(struct nouveau_channel *);
extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);

/* nouveau_acpi.c */
Expand Down Expand Up @@ -1765,13 +1763,27 @@ nv44_graph_class(struct drm_device *dev)
#define NV_MEM_TYPE_VM 0x7f
#define NV_MEM_COMP_VM 0x03

/* FIFO methods */
#define NV01_SUBCHAN_OBJECT 0x00000000
#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH 0x00000010
#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_LOW 0x00000014
#define NV84_SUBCHAN_SEMAPHORE_SEQUENCE 0x00000018
#define NV84_SUBCHAN_SEMAPHORE_TRIGGER 0x0000001c
#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL 0x00000001
#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002
#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004
#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020
#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024
#define NV10_SUBCHAN_REF_CNT 0x00000050
#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054
#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060
#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064
#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068
#define NV11_SUBCHAN_SEMAPHORE_RELEASE 0x0000006c
#define NV40_SUBCHAN_YIELD 0x00000080

/* NV_SW object class */
#define NV_SW 0x0000506e
#define NV_SW_DMA_SEMAPHORE 0x00000060
#define NV_SW_SEMAPHORE_OFFSET 0x00000064
#define NV_SW_SEMAPHORE_ACQUIRE 0x00000068
#define NV_SW_SEMAPHORE_RELEASE 0x0000006c
#define NV_SW_YIELD 0x00000080
#define NV_SW_DMA_VBLSEM 0x0000018c
#define NV_SW_VBLSEM_OFFSET 0x00000400
#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
Expand Down
Loading

0 comments on commit ba331d5

Please sign in to comment.