diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-05-01 20:48:08 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-05-24 16:56:11 +1000 |
commit | c420b2dc8dc3cdd507214f4df5c5f96f08812cbe (patch) | |
tree | 6dca9f0aba3de22a2bda5fe647d6945d4f4e986e | |
parent | a226c32a386bca0426e500954b79e3fd46afc0d9 (diff) |
drm/nouveau/fifo: turn all fifo modules into engine modules
Been tested on each major revision that's relevant here, but I'm sure there
are still bugs waiting to be ironed out.
This is a *very* invasive change.
There's a couple of pieces left that I don't like much (eg. other engines
using fifo_priv for the channel count), but that's an artefact of there
being a master channel list still. This is changing, slowly.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
30 files changed, 1374 insertions, 1386 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index ce222eb0a31..fe5267d06ab 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -16,8 +16,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \ nv50_fb.o nvc0_fb.o \ - nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \ - nve0_fifo.o \ + nv04_fifo.o nv10_fifo.o nv17_fifo.o nv40_fifo.o nv50_fifo.o \ + nv84_fifo.o nvc0_fifo.o nve0_fifo.o \ nv04_fence.o nv10_fence.o nv84_fence.o nvc0_fence.o \ nv04_software.o nv50_software.o nvc0_software.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a1f566758e7..9420538d237 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -27,6 +27,7 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" #include "nouveau_dma.h" +#include "nouveau_fifo.h" #include "nouveau_ramht.h" #include "nouveau_fence.h" #include "nouveau_software.h" @@ -120,8 +121,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, uint32_t vram_handle, uint32_t gart_handle) { struct nouveau_exec_engine *fence = nv_engine(dev, NVOBJ_ENGINE_FENCE); + struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); struct nouveau_channel *chan; unsigned long flags; @@ -189,20 +190,13 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, if (dev_priv->card_type >= NV_50) chan->user_get_hi = 0x60; - /* disable the fifo caches */ - if (dev_priv->card_type < NV_50) - nv_wr32(dev, NV03_PFIFO_CACHES, 0); - - /* Construct initial RAMFC for new channel */ - ret = pfifo->create_context(chan); + /* create fifo context */ + ret = pfifo->base.context_new(chan, NVOBJ_ENGINE_FIFO); if (ret) { nouveau_channel_put(&chan); return ret; } - if (dev_priv->card_type < NV_50) - nv_wr32(dev, NV03_PFIFO_CACHES, 1); - /* Insert NOPs for NOUVEAU_DMA_SKIPS */ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); if (ret) { @@ -288,7 +282,6 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) struct nouveau_channel *chan = *pchan; struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; unsigned long flags; int i; @@ -305,22 +298,12 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) /* give it chance to idle */ nouveau_channel_idle(chan); - /* boot it off the hardware */ - if (dev_priv->card_type < NV_50) - nv_wr32(dev, NV03_PFIFO_CACHES, 0); - /* destroy the engine specific contexts */ for (i = NVOBJ_ENGINE_NR - 1; i >= 0; i--) { if (chan->engctx[i]) dev_priv->eng[i]->context_del(chan, i); - /*XXX: clean this up later, order is important */ - if (i == NVOBJ_ENGINE_FENCE) - pfifo->destroy_context(chan); } - if (dev_priv->card_type < NV_50) - nv_wr32(dev, NV03_PFIFO_CACHES, 1); - /* aside from its resources, the channel should now be dead, * remove it from the channel list */ @@ -393,13 +376,15 @@ nouveau_channel_idle(struct nouveau_channel *chan) void nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; + struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); struct nouveau_channel *chan; int i; + if (!pfifo) + return; + NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); - for (i = 0; i < engine->fifo.channels; i++) { + for (i = 0; i < pfifo->channels; i++) { chan = nouveau_channel_get(file_priv, i); if (IS_ERR(chan)) continue; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 910b97e813f..cad254c8e38 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -33,6 +33,7 @@ #include "nouveau_fb.h" #include "nouveau_fbcon.h" #include "nouveau_pm.h" +#include "nouveau_fifo.h" #include "nv50_display.h" #include "drm_pciids.h" @@ -175,7 +176,7 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) struct drm_device *dev = pci_get_drvdata(pdev); struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); struct nouveau_channel *chan; struct drm_crtc *crtc; int ret, i, e; @@ -214,21 +215,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); NV_INFO(dev, "Idling channels...\n"); - for (i = 0; i < pfifo->channels; i++) { + for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) { chan = dev_priv->channels.ptr[i]; if (chan && chan->pushbuf_bo) nouveau_channel_idle(chan); } - if (dev_priv->card_type < NV_50) { - nv_wr32(dev, NV03_PFIFO_CACHES, 0); - nv_mask(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0); - nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0); - } - pfifo->unload_context(dev); - for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { if (!dev_priv->eng[e]) continue; @@ -269,11 +262,6 @@ out_abort: if (dev_priv->eng[e]) dev_priv->eng[e]->init(dev, e); } - if (dev_priv->card_type < NV_50) { - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); - nv_wr32(dev, NV03_PFIFO_CACHES, 1); - } return ret; } @@ -281,6 +269,7 @@ int nouveau_pci_resume(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; struct drm_crtc *crtc; @@ -328,7 +317,6 @@ nouveau_pci_resume(struct pci_dev *pdev) if (dev_priv->eng[i]) dev_priv->eng[i]->init(dev, i); } - engine->fifo.init(dev); nouveau_irq_postinstall(dev); @@ -337,7 +325,7 @@ nouveau_pci_resume(struct pci_dev *pdev) struct nouveau_channel *chan; int j; - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) { chan = dev_priv->channels.ptr[i]; if (!chan || !chan->pushbuf_bo) continue; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9943ccf764c..1ede35491f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -165,9 +165,10 @@ enum nouveau_flags { #define NVOBJ_ENGINE_PPP NVOBJ_ENGINE_MPEG #define NVOBJ_ENGINE_BSP 6 #define NVOBJ_ENGINE_VP 7 -#define NVOBJ_ENGINE_FENCE 14 -#define NVOBJ_ENGINE_DISPLAY 15 +#define NVOBJ_ENGINE_FIFO 14 +#define NVOBJ_ENGINE_FENCE 15 #define NVOBJ_ENGINE_NR 16 +#define NVOBJ_ENGINE_DISPLAY (NVOBJ_ENGINE_NR + 0) /*XXX*/ #define NVOBJ_FLAG_DONT_MAP (1 << 0) #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) @@ -248,8 +249,6 @@ struct nouveau_channel { /* PFIFO context */ struct nouveau_gpuobj *ramfc; - struct nouveau_gpuobj *cache; - void *fifo_priv; /* Execution engine contexts */ void *engctx[NVOBJ_ENGINE_NR]; @@ -283,8 +282,6 @@ struct nouveau_channel { int ib_put; } dma; - uint32_t sw_subchannel[8]; - struct { bool active; char name[32]; @@ -347,23 +344,6 @@ struct nouveau_fb_engine { void (*free_tile_region)(struct drm_device *dev, int i); }; -struct nouveau_fifo_engine { - void *priv; - int channels; - - struct nouveau_gpuobj *playlist[2]; - int cur_playlist; - - int (*init)(struct drm_device *); - void (*takedown)(struct drm_device *); - - int (*create_context)(struct nouveau_channel *); - void (*destroy_context)(struct nouveau_channel *); - int (*load_context)(struct nouveau_channel *); - int (*unload_context)(struct drm_device *); - void (*tlb_flush)(struct drm_device *dev); -}; - struct nouveau_display_engine { void *priv; int (*early_init)(struct drm_device *); @@ -571,7 +551,6 @@ struct nouveau_engine { struct nouveau_mc_engine mc; struct nouveau_timer_engine timer; struct nouveau_fb_engine fb; - struct nouveau_fifo_engine fifo; struct nouveau_display_engine display; struct nouveau_gpio_engine gpio; struct nouveau_pm_engine pm; @@ -1183,52 +1162,6 @@ extern void nv50_fb_vm_trap(struct drm_device *, int display); extern int nvc0_fb_init(struct drm_device *); extern void nvc0_fb_takedown(struct drm_device *); -/* nv04_fifo.c */ -extern int nv04_fifo_init(struct drm_device *); -extern void nv04_fifo_fini(struct drm_device *); -extern int nv04_fifo_create_context(struct nouveau_channel *); -extern void nv04_fifo_destroy_context(struct nouveau_channel *); -extern int nv04_fifo_load_context(struct nouveau_channel *); -extern int nv04_fifo_unload_context(struct drm_device *); -extern void nv04_fifo_isr(struct drm_device *); -bool nv04_fifo_cache_pull(struct drm_device *, bool enable); - -/* nv10_fifo.c */ -extern int nv10_fifo_init(struct drm_device *); -extern int nv10_fifo_create_context(struct nouveau_channel *); -extern int nv10_fifo_load_context(struct nouveau_channel *); -extern int nv10_fifo_unload_context(struct drm_device *); - -/* nv40_fifo.c */ -extern int nv40_fifo_init(struct drm_device *); -extern int nv40_fifo_create_context(struct nouveau_channel *); -extern int nv40_fifo_load_context(struct nouveau_channel *); -extern int nv40_fifo_unload_context(struct drm_device *); - -/* nv50_fifo.c */ -extern int nv50_fifo_init(struct drm_device *); -extern void nv50_fifo_takedown(struct drm_device *); -extern int nv50_fifo_create_context(struct nouveau_channel *); -extern void nv50_fifo_destroy_context(struct nouveau_channel *); -extern int nv50_fifo_load_context(struct nouveau_channel *); -extern int nv50_fifo_unload_context(struct drm_device *); -extern void nv50_fifo_tlb_flush(struct drm_device *dev); - -/* nvc0_fifo.c */ -extern int nvc0_fifo_init(struct drm_device *); -extern void nvc0_fifo_takedown(struct drm_device *); -extern int nvc0_fifo_create_context(struct nouveau_channel *); -extern void nvc0_fifo_destroy_context(struct nouveau_channel *); -extern int nvc0_fifo_load_context(struct nouveau_channel *); -extern int nvc0_fifo_unload_context(struct drm_device *); - -/* nve0_fifo.c */ -extern int nve0_fifo_init(struct drm_device *); -extern void nve0_fifo_takedown(struct drm_device *); -extern int nve0_fifo_create_context(struct nouveau_channel *); -extern void nve0_fifo_destroy_context(struct nouveau_channel *); -extern int nve0_fifo_unload_context(struct drm_device *); - /* nv04_graph.c */ extern int nv04_graph_create(struct drm_device *); extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.h b/drivers/gpu/drm/nouveau/nouveau_fifo.h new file mode 100644 index 00000000000..ce99cab2f25 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_fifo.h @@ -0,0 +1,32 @@ +#ifndef __NOUVEAU_FIFO_H__ +#define __NOUVEAU_FIFO_H__ + +struct nouveau_fifo_priv { + struct nouveau_exec_engine base; + u32 channels; +}; + +struct nouveau_fifo_chan { +}; + +bool nv04_fifo_cache_pull(struct drm_device *, bool); +void nv04_fifo_context_del(struct nouveau_channel *, int); +int nv04_fifo_fini(struct drm_device *, int, bool); +int nv04_fifo_init(struct drm_device *, int); +void nv04_fifo_isr(struct drm_device *); +void nv04_fifo_destroy(struct drm_device *, int); + +void nv50_fifo_playlist_update(struct drm_device *); +void nv50_fifo_destroy(struct drm_device *, int); +void nv50_fifo_tlb_flush(struct drm_device *, int); + +int nv04_fifo_create(struct drm_device *); +int nv10_fifo_create(struct drm_device *); +int nv17_fifo_create(struct drm_device *); +int nv40_fifo_create(struct drm_device *); +int nv50_fifo_create(struct drm_device *); +int nv84_fifo_create(struct drm_device *); +int nvc0_fifo_create(struct drm_device *); +int nve0_fifo_create(struct drm_device *); + +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index fd7273459ad..5b498ea32e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -39,6 +39,7 @@ #include "nouveau_pm.h" #include "nouveau_mm.h" #include "nouveau_vm.h" +#include "nouveau_fifo.h" #include "nouveau_fence.h" /* diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 8e0b38f3597..d7e56ce410b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -34,6 +34,7 @@ #include "drm.h" #include "nouveau_drv.h" #include "nouveau_drm.h" +#include "nouveau_fifo.h" #include "nouveau_ramht.h" #include "nouveau_software.h" #include "nouveau_vm.h" @@ -120,12 +121,13 @@ nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid, u32 class, u32 mthd, u32 data) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); struct nouveau_channel *chan = NULL; unsigned long flags; int ret = -EINVAL; spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (chid >= 0 && chid < dev_priv->engine.fifo.channels) + if (chid >= 0 && chid < pfifo->channels) chan = dev_priv->channels.ptr[chid]; if (chan) ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 660a033b6dd..e4e73a13a2b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -39,6 +39,7 @@ #include "nouveau_gpio.h" #include "nouveau_pm.h" #include "nv50_display.h" +#include "nouveau_fifo.h" #include "nouveau_fence.h" #include "nouveau_software.h" @@ -68,13 +69,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv04_fb_init; engine->fb.takedown = nv04_fb_takedown; - engine->fifo.channels = 16; - engine->fifo.init = nv04_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.create_context = nv04_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv04_fifo_load_context; - engine->fifo.unload_context = nv04_fifo_unload_context; engine->display.early_init = nv04_display_early_init; engine->display.late_takedown = nv04_display_late_takedown; engine->display.create = nv04_display_create; @@ -108,13 +102,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv10_fb_init_tile_region; engine->fb.set_tile_region = nv10_fb_set_tile_region; engine->fb.free_tile_region = nv10_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; engine->display.late_takedown = nv04_display_late_takedown; engine->display.create = nv04_display_create; @@ -154,13 +141,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv20_fb_init_tile_region; engine->fb.set_tile_region = nv20_fb_set_tile_region; engine->fb.free_tile_region = nv20_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; engine->display.late_takedown = nv04_display_late_takedown; engine->display.create = nv04_display_create; @@ -196,13 +176,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv30_fb_init_tile_region; engine->fb.set_tile_region = nv10_fb_set_tile_region; engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; engine->display.late_takedown = nv04_display_late_takedown; engine->display.create = nv04_display_create; @@ -241,13 +214,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv30_fb_init_tile_region; engine->fb.set_tile_region = nv40_fb_set_tile_region; engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv40_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.create_context = nv40_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv40_fifo_load_context; - engine->fifo.unload_context = nv40_fifo_unload_context; engine->display.early_init = nv04_display_early_init; engine->display.late_takedown = nv04_display_late_takedown; engine->display.create = nv04_display_create; @@ -294,14 +260,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv50_fb_init; engine->fb.takedown = nv50_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nv50_fifo_init; - engine->fifo.takedown = nv50_fifo_takedown; - engine->fifo.create_context = nv50_fifo_create_context; - engine->fifo.destroy_context = nv50_fifo_destroy_context; - engine->fifo.load_context = nv50_fifo_load_context; - engine->fifo.unload_context = nv50_fifo_unload_context; - engine->fifo.tlb_flush = nv50_fifo_tlb_flush; engine->display.early_init = nv50_display_early_init; engine->display.late_takedown = nv50_display_late_takedown; engine->display.create = nv50_display_create; @@ -365,13 +323,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_fifo_unload_context; engine->display.early_init = nv50_display_early_init; engine->display.late_takedown = nv50_display_late_takedown; engine->display.create = nv50_display_create; @@ -414,13 +365,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_fifo_unload_context; engine->display.early_init = nouveau_stub_init; engine->display.late_takedown = nouveau_stub_takedown; engine->display.create = nvd0_display_create; @@ -461,13 +405,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 4096; - engine->fifo.init = nve0_fifo_init; - engine->fifo.takedown = nve0_fifo_takedown; - engine->fifo.create_context = nve0_fifo_create_context; - engine->fifo.destroy_context = nve0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nve0_fifo_unload_context; engine->display.early_init = nouveau_stub_init; engine->display.late_takedown = nouveau_stub_takedown; engine->display.create = nvd0_display_create; @@ -728,6 +665,38 @@ nouveau_card_init(struct drm_device *dev) if (!dev_priv->noaccel) { switch (dev_priv->card_type) { case NV_04: + nv04_fifo_create(dev); + break; + case NV_10: + case NV_20: + case NV_30: + if (dev_priv->chipset < 0x17) + nv10_fifo_create(dev); + else + nv17_fifo_create(dev); + break; + case NV_40: + nv40_fifo_create(dev); + break; + case NV_50: + if (dev_priv->chipset == 0x50) + nv50_fifo_create(dev); + else + nv84_fifo_create(dev); + break; + case NV_C0: + case NV_D0: + nvc0_fifo_create(dev); + break; + case NV_E0: + nve0_fifo_create(dev); + break; + default: + break; + } + + switch (dev_priv->card_type) { + case NV_04: nv04_fence_create(dev); break; case NV_10: @@ -859,16 +828,11 @@ nouveau_card_init(struct drm_device *dev) goto out_engine; } } - - /* PFIFO */ - ret = engine->fifo.init(dev); - if (ret) - goto out_engine; } ret = nouveau_irq_init(dev); if (ret) - goto out_fifo; + goto out_engine; ret = nouveau_display_create(dev); if (ret) @@ -901,9 +865,6 @@ out_pm: nouveau_display_destroy(dev); out_irq: nouveau_irq_fini(dev); -out_fifo: - if (!dev_priv->noaccel) - engine->fifo.takedown(dev); out_engine: if (!dev_priv->noaccel) { for (e = e - 1; e >= 0; e--) { @@ -956,7 +917,6 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_display_destroy(dev); if (!dev_priv->noaccel) { - engine->fifo.takedown(dev); for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { if (dev_priv->eng[e]) { dev_priv->eng[e]->fini(dev, e, false); diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 584c24d457f..a6295cd00ec 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Ben Skeggs. + * Copyright (C) 2012 Ben Skeggs. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining @@ -27,21 +27,38 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_ramht.h" +#include "nouveau_fifo.h" #include "nouveau_util.h" - -#define NV04_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV04_RAMFC__SIZE)) -#define NV04_RAMFC__SIZE 32 -#define NV04_RAMFC_DMA_PUT 0x00 -#define NV04_RAMFC_DMA_GET 0x04 -#define NV04_RAMFC_DMA_INSTANCE 0x08 -#define NV04_RAMFC_DMA_STATE 0x0C -#define NV04_RAMFC_DMA_FETCH 0x10 -#define NV04_RAMFC_ENGINE 0x14 -#define NV04_RAMFC_PULL1_ENGINE 0x18 - -#define RAMFC_WR(offset, val) nv_wo32(chan->ramfc, NV04_RAMFC_##offset, (val)) -#define RAMFC_RD(offset) nv_ro32(chan->ramfc, NV04_RAMFC_##offset) +#include "nouveau_ramht.h" +#include "nouveau_software.h" + +static struct ramfc_desc { + unsigned bits:6; + unsigned ctxs:5; + unsigned ctxp:8; + unsigned regs:5; + unsigned regp; +} nv04_ramfc[] = { + { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT }, + { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET }, + { 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE }, + { 16, 16, 0x08, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT }, + { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_STATE }, + { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_FETCH }, + { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_ENGINE }, + { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_PULL1 }, + {} +}; + +struct nv04_fifo_priv { + struct nouveau_fifo_priv base; + struct ramfc_desc *ramfc_desc; +}; + +struct nv04_fifo_chan { + struct nouveau_fifo_chan base; + struct nouveau_gpuobj *ramfc; +}; bool nv04_fifo_cache_pull(struct drm_device *dev, bool enable) @@ -58,13 +75,13 @@ nv04_fifo_cache_pull(struct drm_device *dev, bool enable) * invalidate the most recently calculated instance. */ if (!nv_wait(dev, NV04_PFIFO_CACHE1_PULL0, - NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0)) + NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0)) NV_ERROR(dev, "Timeout idling the PFIFO puller.\n"); if (nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0) & - NV04_PFIFO_CACHE1_PULL0_HASH_FAILED) + NV04_PFIFO_CACHE1_PULL0_HASH_FAILED) nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_CACHE_ERROR); + NV_PFIFO_INTR_CACHE_ERROR); nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); } @@ -72,238 +89,182 @@ nv04_fifo_cache_pull(struct drm_device *dev, bool enable) return pull & 1; } -#ifdef __BIG_ENDIAN -#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN -#else -#define DMA_FETCH_ENDIANNESS 0 -#endif - -int -nv04_fifo_create_context(struct nouveau_channel *chan) +static int +nv04_fifo_context_new(struct nouveau_channel *chan, int engine) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv04_fifo_priv *priv = nv_engine(dev, engine); + struct nv04_fifo_chan *fctx; unsigned long flags; int ret; - ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, - NV04_RAMFC__SIZE, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, - &chan->ramfc); - if (ret) - return ret; + fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL); + if (!fctx) + return -ENOMEM; + /* map channel control registers */ chan->user = ioremap(pci_resource_start(dev->pdev, 0) + NV03_USER(chan->id), PAGE_SIZE); - if (!chan->user) - return -ENOMEM; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - /* Setup initial state */ - RAMFC_WR(DMA_PUT, chan->pushbuf_base); - RAMFC_WR(DMA_GET, chan->pushbuf_base); - RAMFC_WR(DMA_INSTANCE, chan->pushbuf->pinst >> 4); - RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | - DMA_FETCH_ENDIANNESS)); + if (!chan->user) { + ret = -ENOMEM; + goto error; + } - /* enable the fifo dma operation */ - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); + /* initialise default fifo context */ + ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst + + chan->id * 32, ~0, 32, + NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc); + if (ret) + goto error; |