From beaa0c9a28b30a6ba3292184d04875b6a597e433 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 03:40:43 +1000 Subject: nouveau: Pass channel struct around instead of channel id. --- shared-core/nouveau_drv.h | 391 ++++++++++++++++++++++++---------------------- 1 file changed, 208 insertions(+), 183 deletions(-) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index dd323a0b..8ec91898 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -92,8 +92,11 @@ struct nouveau_gpuobj_ref { int handle; }; -struct nouveau_fifo +struct nouveau_channel { + struct drm_device *dev; + int id; + /* owner of this fifo */ struct drm_file *file_priv; /* mapping of the fifo itself */ @@ -136,57 +139,64 @@ struct nouveau_config { } cmdbuf; }; -struct nouveau_engine_func { - struct { - void *priv; +struct nouveau_instmem_engine { + void *priv; - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); - int (*populate)(struct drm_device *, struct nouveau_gpuobj *, - uint32_t *size); - void (*clear)(struct drm_device *, struct nouveau_gpuobj *); - int (*bind)(struct drm_device *, struct nouveau_gpuobj *); - int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); - } instmem; + int (*populate)(struct drm_device *, struct nouveau_gpuobj *, + uint32_t *size); + void (*clear)(struct drm_device *, struct nouveau_gpuobj *); + int (*bind)(struct drm_device *, struct nouveau_gpuobj *); + int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); +}; - struct { - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - } mc; +struct nouveau_mc_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); +}; - struct { - int (*init)(struct drm_device *dev); - uint64_t (*read)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - } timer; +struct nouveau_timer_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); + uint64_t (*read)(struct drm_device *dev); +}; - struct { - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - } fb; +struct nouveau_fb_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); +}; - struct { - int (*init)(struct drm_device *); - void (*takedown)(struct drm_device *); +struct nouveau_fifo_engine { + void *priv; - int (*create_context)(struct drm_device *, int channel); - void (*destroy_context)(struct drm_device *, int channel); - int (*load_context)(struct drm_device *, int channel); - int (*save_context)(struct drm_device *, int channel); - } graph; + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); - struct { - void *priv; + int (*create_context)(struct nouveau_channel *); + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*save_context)(struct nouveau_channel *); +}; - int (*init)(struct drm_device *); - void (*takedown)(struct drm_device *); +struct nouveau_pgraph_engine { + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); - int (*create_context)(struct drm_device *, int channel); - void (*destroy_context)(struct drm_device *, int channel); - int (*load_context)(struct drm_device *, int channel); - int (*save_context)(struct drm_device *, int channel); - } fifo; + int (*create_context)(struct nouveau_channel *); + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*save_context)(struct nouveau_channel *); +}; + +struct nouveau_engine { + struct nouveau_instmem_engine instmem; + struct nouveau_mc_engine mc; + struct nouveau_timer_engine timer; + struct nouveau_fb_engine fb; + struct nouveau_pgraph_engine graph; + struct nouveau_fifo_engine fifo; }; struct drm_nouveau_private { @@ -207,9 +217,9 @@ struct drm_nouveau_private { drm_local_map_t *ramin; /* NV40 onwards */ int fifo_alloc_count; - struct nouveau_fifo *fifos[NV_MAX_FIFO_NUMBER]; + struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER]; - struct nouveau_engine_func Engine; + struct nouveau_engine Engine; /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ struct nouveau_gpuobj *ramht; @@ -262,93 +272,108 @@ struct drm_nouveau_private { struct nouveau_gpuobj *gpuobj_all; }; +#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \ + struct drm_nouveau_private *nv = dev->dev_private; \ + if (!nouveau_fifo_owner(dev, (cl), (id))) { \ + DRM_ERROR("pid %d doesn't own channel %d\n", \ + DRM_CURRENTPID, (id)); \ + return -EPERM; \ + } \ + (ch) = nv->fifos[(id)]; \ +} while(0) + /* nouveau_state.c */ -extern void nouveau_preclose(struct drm_device * dev, - struct drm_file *file_priv); -extern int nouveau_load(struct drm_device *dev, unsigned long flags); -extern int nouveau_firstopen(struct drm_device *dev); -extern void nouveau_lastclose(struct drm_device *dev); -extern int nouveau_unload(struct drm_device *dev); -extern int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void nouveau_wait_for_idle(struct drm_device *dev); -extern int nouveau_ioctl_card_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); +extern int nouveau_load(struct drm_device *, unsigned long flags); +extern int nouveau_firstopen(struct drm_device *); +extern void nouveau_lastclose(struct drm_device *); +extern int nouveau_unload(struct drm_device *); +extern int nouveau_ioctl_getparam(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_setparam(struct drm_device *, void *data, + struct drm_file *); +extern void nouveau_wait_for_idle(struct drm_device *); +extern int nouveau_ioctl_card_init(struct drm_device *, void *data, + struct drm_file *); /* nouveau_mem.c */ -extern int nouveau_mem_init_heap(struct mem_block **, - uint64_t start, uint64_t size); +extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, + uint64_t size); extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, uint64_t size, int align2, - struct drm_file *file_priv); -extern void nouveau_mem_takedown(struct mem_block **heap); -extern void nouveau_mem_free_block(struct mem_block *); -extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); -extern void nouveau_mem_release(struct drm_file *file_priv, - struct mem_block *heap); -extern int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, + struct drm_file *); +extern void nouveau_mem_takedown(struct mem_block **heap); +extern void nouveau_mem_free_block(struct mem_block *); +extern uint64_t nouveau_mem_fb_amount(struct drm_device *); +extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); +extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_mem_free(struct drm_device *, void *data, + struct drm_file *); +extern struct mem_block* nouveau_mem_alloc(struct drm_device *, int alignment, uint64_t size, - int flags, - struct drm_file *file_priv); -extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*); -extern int nouveau_mem_init(struct drm_device *dev); -extern void nouveau_mem_close(struct drm_device *dev); + int flags, struct drm_file *); +extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*); +extern int nouveau_mem_init(struct drm_device *); +extern void nouveau_mem_close(struct drm_device *); /* nouveau_notifier.c */ -extern int nouveau_notifier_init_channel(struct drm_device *, int channel, - struct drm_file *file_priv); -extern void nouveau_notifier_takedown_channel(struct drm_device *, int channel); -extern int nouveau_notifier_alloc(struct drm_device *, int channel, - uint32_t handle, int cout, uint32_t *offset); -extern int nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int nouveau_notifier_init_channel(struct nouveau_channel *); +extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); +extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, + int cout, uint32_t *offset); +extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, + struct drm_file *); /* nouveau_fifo.c */ -extern int nouveau_fifo_init(struct drm_device *dev); -extern int nouveau_fifo_number(struct drm_device *dev); -extern int nouveau_fifo_ctx_size(struct drm_device *dev); -extern void nouveau_fifo_cleanup(struct drm_device *dev, - struct drm_file *file_priv); -extern int nouveau_fifo_owner(struct drm_device *dev, - struct drm_file *file_priv, int channel); -extern void nouveau_fifo_free(struct drm_device *dev, int channel); +extern int nouveau_fifo_init(struct drm_device *); +extern int nouveau_fifo_number(struct drm_device *); +extern int nouveau_fifo_ctx_size(struct drm_device *); +extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *); +extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, + int channel); +extern void nouveau_fifo_free(struct nouveau_channel *); /* nouveau_object.c */ -extern void nouveau_gpuobj_takedown(struct drm_device *dev); -extern int nouveau_gpuobj_channel_init(struct drm_device *, int channel, +extern void nouveau_gpuobj_takedown(struct drm_device *); +extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, uint32_t vram_h, uint32_t tt_h); -extern void nouveau_gpuobj_channel_takedown(struct drm_device *, int channel); -extern int nouveau_gpuobj_new(struct drm_device *, int channel, int size, int align, - uint32_t flags, struct nouveau_gpuobj **); +extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); +extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, + int size, int align, uint32_t flags, + struct nouveau_gpuobj **); extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **); -extern int nouveau_gpuobj_ref_add(struct drm_device *, int channel, uint32_t handle, - struct nouveau_gpuobj *, +extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, + uint32_t handle, struct nouveau_gpuobj *, + struct nouveau_gpuobj_ref **); +extern int nouveau_gpuobj_ref_del(struct drm_device *, struct nouveau_gpuobj_ref **); -extern int nouveau_gpuobj_ref_del(struct drm_device *, struct nouveau_gpuobj_ref **); -extern int nouveau_gpuobj_new_ref(struct drm_device *, int chan_obj, int chan_ref, +extern int nouveau_gpuobj_new_ref(struct drm_device *, + struct nouveau_channel *alloc_chan, + struct nouveau_channel *ref_chan, uint32_t handle, int size, int align, uint32_t flags, struct nouveau_gpuobj_ref **); extern int nouveau_gpuobj_new_fake(struct drm_device *, uint32_t offset, uint32_t size, uint32_t flags, - struct nouveau_gpuobj**, + struct nouveau_gpuobj **, struct nouveau_gpuobj_ref**); -extern int nouveau_gpuobj_dma_new(struct drm_device *, int channel, int class, - uint64_t offset, uint64_t size, - int access, int target, - struct nouveau_gpuobj **); -extern int nouveau_gpuobj_gart_dma_new(struct drm_device *, int channel, +extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, + uint64_t offset, uint64_t size, int access, + int target, struct nouveau_gpuobj **); +extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, uint64_t offset, uint64_t size, int access, struct nouveau_gpuobj **, uint32_t *o_ret); -extern int nouveau_gpuobj_gr_new(struct drm_device *, int channel, int class, +extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, struct nouveau_gpuobj **); -extern int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, + struct drm_file *); /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); -extern void nouveau_irq_preinstall(struct drm_device*); -extern void nouveau_irq_postinstall(struct drm_device*); -extern void nouveau_irq_uninstall(struct drm_device*); +extern void nouveau_irq_preinstall(struct drm_device *); +extern void nouveau_irq_postinstall(struct drm_device *); +extern void nouveau_irq_uninstall(struct drm_device *); /* nouveau_sgdma.c */ extern int nouveau_sgdma_init(struct drm_device *); @@ -358,131 +383,131 @@ extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); /* nv04_fb.c */ -extern int nv04_fb_init(struct drm_device *dev); -extern void nv04_fb_takedown(struct drm_device *dev); +extern int nv04_fb_init(struct drm_device *); +extern void nv04_fb_takedown(struct drm_device *); /* nv10_fb.c */ -extern int nv10_fb_init(struct drm_device *dev); -extern void nv10_fb_takedown(struct drm_device *dev); +extern int nv10_fb_init(struct drm_device *); +extern void nv10_fb_takedown(struct drm_device *); /* nv40_fb.c */ -extern int nv40_fb_init(struct drm_device *dev); -extern void nv40_fb_takedown(struct drm_device *dev); +extern int nv40_fb_init(struct drm_device *); +extern void nv40_fb_takedown(struct drm_device *); /* nv04_fifo.c */ -extern int nv04_fifo_create_context(struct drm_device *dev, int channel); -extern void nv04_fifo_destroy_context(struct drm_device *dev, int channel); -extern int nv04_fifo_load_context(struct drm_device *dev, int channel); -extern int nv04_fifo_save_context(struct drm_device *dev, int channel); +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_save_context(struct nouveau_channel *); /* nv10_fifo.c */ -extern int nv10_fifo_create_context(struct drm_device *dev, int channel); -extern void nv10_fifo_destroy_context(struct drm_device *dev, int channel); -extern int nv10_fifo_load_context(struct drm_device *dev, int channel); -extern int nv10_fifo_save_context(struct drm_device *dev, int channel); +extern int nv10_fifo_create_context(struct nouveau_channel *); +extern void nv10_fifo_destroy_context(struct nouveau_channel *); +extern int nv10_fifo_load_context(struct nouveau_channel *); +extern int nv10_fifo_save_context(struct nouveau_channel *); /* nv40_fifo.c */ -extern int nv40_fifo_create_context(struct drm_device *, int channel); -extern void nv40_fifo_destroy_context(struct drm_device *, int channel); -extern int nv40_fifo_load_context(struct drm_device *, int channel); -extern int nv40_fifo_save_context(struct drm_device *, int channel); +extern int nv40_fifo_create_context(struct nouveau_channel *); +extern void nv40_fifo_destroy_context(struct nouveau_channel *); +extern int nv40_fifo_load_context(struct nouveau_channel *); +extern int nv40_fifo_save_context(struct nouveau_channel *); /* 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 drm_device *, int channel); -extern void nv50_fifo_destroy_context(struct drm_device *, int channel); -extern int nv50_fifo_load_context(struct drm_device *, int channel); -extern int nv50_fifo_save_context(struct drm_device *, int channel); +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_save_context(struct nouveau_channel *); /* nv04_graph.c */ -extern void nouveau_nv04_context_switch(struct drm_device *dev); -extern int nv04_graph_init(struct drm_device *dev); -extern void nv04_graph_takedown(struct drm_device *dev); -extern int nv04_graph_create_context(struct drm_device *dev, int channel); -extern void nv04_graph_destroy_context(struct drm_device *dev, int channel); -extern int nv04_graph_load_context(struct drm_device *dev, int channel); -extern int nv04_graph_save_context(struct drm_device *dev, int channel); +extern void nouveau_nv04_context_switch(struct drm_device *); +extern int nv04_graph_init(struct drm_device *); +extern void nv04_graph_takedown(struct drm_device *); +extern int nv04_graph_create_context(struct nouveau_channel *); +extern void nv04_graph_destroy_context(struct nouveau_channel *); +extern int nv04_graph_load_context(struct nouveau_channel *); +extern int nv04_graph_save_context(struct nouveau_channel *); /* nv10_graph.c */ -extern void nouveau_nv10_context_switch(struct drm_device *dev); -extern int nv10_graph_init(struct drm_device *dev); -extern void nv10_graph_takedown(struct drm_device *dev); -extern int nv10_graph_create_context(struct drm_device *dev, int channel); -extern void nv10_graph_destroy_context(struct drm_device *dev, int channel); -extern int nv10_graph_load_context(struct drm_device *dev, int channel); -extern int nv10_graph_save_context(struct drm_device *dev, int channel); +extern void nouveau_nv10_context_switch(struct drm_device *); +extern int nv10_graph_init(struct drm_device *); +extern void nv10_graph_takedown(struct drm_device *); +extern int nv10_graph_create_context(struct nouveau_channel *); +extern void nv10_graph_destroy_context(struct nouveau_channel *); +extern int nv10_graph_load_context(struct nouveau_channel *); +extern int nv10_graph_save_context(struct nouveau_channel *); /* nv20_graph.c */ -extern void nouveau_nv20_context_switch(struct drm_device *dev); -extern int nv20_graph_init(struct drm_device *dev); -extern void nv20_graph_takedown(struct drm_device *dev); -extern int nv20_graph_create_context(struct drm_device *dev, int channel); -extern void nv20_graph_destroy_context(struct drm_device *dev, int channel); -extern int nv20_graph_load_context(struct drm_device *dev, int channel); -extern int nv20_graph_save_context(struct drm_device *dev, int channel); +extern void nouveau_nv20_context_switch(struct drm_device *); +extern int nv20_graph_init(struct drm_device *); +extern void nv20_graph_takedown(struct drm_device *); +extern int nv20_graph_create_context(struct nouveau_channel *); +extern void nv20_graph_destroy_context(struct nouveau_channel *); +extern int nv20_graph_load_context(struct nouveau_channel *); +extern int nv20_graph_save_context(struct nouveau_channel *); /* nv30_graph.c */ -extern int nv30_graph_init(struct drm_device *dev); -extern void nv30_graph_takedown(struct drm_device *dev); -extern int nv30_graph_create_context(struct drm_device *, int channel); -extern void nv30_graph_destroy_context(struct drm_device *, int channel); -extern int nv30_graph_load_context(struct drm_device *, int channel); -extern int nv30_graph_save_context(struct drm_device *, int channel); +extern int nv30_graph_init(struct drm_device *); +extern void nv30_graph_takedown(struct drm_device *); +extern int nv30_graph_create_context(struct nouveau_channel *); +extern void nv30_graph_destroy_context(struct nouveau_channel *); +extern int nv30_graph_load_context(struct nouveau_channel *); +extern int nv30_graph_save_context(struct nouveau_channel *); /* nv40_graph.c */ extern int nv40_graph_init(struct drm_device *); extern void nv40_graph_takedown(struct drm_device *); -extern int nv40_graph_create_context(struct drm_device *, int channel); -extern void nv40_graph_destroy_context(struct drm_device *, int channel); -extern int nv40_graph_load_context(struct drm_device *, int channel); -extern int nv40_graph_save_context(struct drm_device *, int channel); +extern int nv40_graph_create_context(struct nouveau_channel *); +extern void nv40_graph_destroy_context(struct nouveau_channel *); +extern int nv40_graph_load_context(struct nouveau_channel *); +extern int nv40_graph_save_context(struct nouveau_channel *); /* nv50_graph.c */ extern int nv50_graph_init(struct drm_device *); extern void nv50_graph_takedown(struct drm_device *); -extern int nv50_graph_create_context(struct drm_device *, int channel); -extern void nv50_graph_destroy_context(struct drm_device *, int channel); -extern int nv50_graph_load_context(struct drm_device *, int channel); -extern int nv50_graph_save_context(struct drm_device *, int channel); +extern int nv50_graph_create_context(struct nouveau_channel *); +extern void nv50_graph_destroy_context(struct nouveau_channel *); +extern int nv50_graph_load_context(struct nouveau_channel *); +extern int nv50_graph_save_context(struct nouveau_channel *); /* nv04_instmem.c */ -extern int nv04_instmem_init(struct drm_device *dev); -extern void nv04_instmem_takedown(struct drm_device *dev); -extern int nv04_instmem_populate(struct drm_device*, struct nouveau_gpuobj*, +extern int nv04_instmem_init(struct drm_device *); +extern void nv04_instmem_takedown(struct drm_device *); +extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, uint32_t *size); -extern void nv04_instmem_clear(struct drm_device*, struct nouveau_gpuobj*); -extern int nv04_instmem_bind(struct drm_device*, struct nouveau_gpuobj*); -extern int nv04_instmem_unbind(struct drm_device*, struct nouveau_gpuobj*); +extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); +extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); /* nv50_instmem.c */ -extern int nv50_instmem_init(struct drm_device *dev); -extern void nv50_instmem_takedown(struct drm_device *dev); -extern int nv50_instmem_populate(struct drm_device*, struct nouveau_gpuobj*, +extern int nv50_instmem_init(struct drm_device *); +extern void nv50_instmem_takedown(struct drm_device *); +extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, uint32_t *size); -extern void nv50_instmem_clear(struct drm_device*, struct nouveau_gpuobj*); -extern int nv50_instmem_bind(struct drm_device*, struct nouveau_gpuobj*); -extern int nv50_instmem_unbind(struct drm_device*, struct nouveau_gpuobj*); +extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); +extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); /* nv04_mc.c */ -extern int nv04_mc_init(struct drm_device *dev); -extern void nv04_mc_takedown(struct drm_device *dev); +extern int nv04_mc_init(struct drm_device *); +extern void nv04_mc_takedown(struct drm_device *); /* nv40_mc.c */ -extern int nv40_mc_init(struct drm_device *dev); -extern void nv40_mc_takedown(struct drm_device *dev); +extern int nv40_mc_init(struct drm_device *); +extern void nv40_mc_takedown(struct drm_device *); /* nv50_mc.c */ -extern int nv50_mc_init(struct drm_device *dev); -extern void nv50_mc_takedown(struct drm_device *dev); +extern int nv50_mc_init(struct drm_device *); +extern void nv50_mc_takedown(struct drm_device *); /* nv04_timer.c */ -extern int nv04_timer_init(struct drm_device *dev); -extern uint64_t nv04_timer_read(struct drm_device *dev); -extern void nv04_timer_takedown(struct drm_device *dev); +extern int nv04_timer_init(struct drm_device *); +extern uint64_t nv04_timer_read(struct drm_device *); +extern void nv04_timer_takedown(struct drm_device *); extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg); + unsigned long arg); #if defined(__powerpc__) #define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) ) -- cgit v1.2.3 From 97770db72040dc032130413e0cdabc1777560a75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 21:45:18 +1000 Subject: nouveau: Various internal and external API changes 1. DRM_NOUVEAU_GPUOBJ_FREE Used to free GPU objects. The obvious usage case is for Gr objects, but notifiers can also be destroyed in the same way. GPU objects gain a destructor method and private data fields with this change, so other specialised cases (like notifiers) can be implemented on top of gpuobjs. 2. DRM_NOUVEAU_CHANNEL_FREE 3. DRM_NOUVEAU_CARD_INIT Ideally we'd do init during module load, but this isn't currently possible. Doing init during firstopen() is bad as X has a love of opening/closing the DRM many times during startup. Once the modesetting-101 branch is merged this can go away. IRQs are enabled in nouveau_card_init() now, rather than having the X server call drmCtlInstHandler(). We'll need this for when we give the kernel module its own channel. 4. DRM_NOUVEAU_GETPARAM Add CHIPSET_ID value, which will return the chipset id derived from NV_PMC_BOOT_0. 4. Use list_* in a few places, rather than home-brewed stuff. --- shared-core/nouveau_drv.h | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 8ec91898..0b173b76 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -34,7 +34,7 @@ #define DRIVER_MAJOR 0 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 9 +#define DRIVER_PATCHLEVEL 10 #define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FLAGS 0xFFFF0000 @@ -67,8 +67,7 @@ enum nouveau_flags { #define NVOBJ_FLAG_ZERO_FREE (1 << 2) #define NVOBJ_FLAG_FAKE (1 << 3) struct nouveau_gpuobj { - struct nouveau_gpuobj *next; - struct nouveau_gpuobj *prev; + struct list_head list; int im_channel; struct mem_block *im_pramin; @@ -80,10 +79,13 @@ struct nouveau_gpuobj { uint32_t engine; uint32_t class; + + void (*dtor)(struct drm_device *, struct nouveau_gpuobj *); + void *priv; }; struct nouveau_gpuobj_ref { - struct nouveau_gpuobj_ref *next; + struct list_head list; struct nouveau_gpuobj *gpuobj; uint32_t instance; @@ -129,7 +131,7 @@ struct nouveau_channel struct nouveau_gpuobj_ref *ramin; /* Private instmem */ struct mem_block *ramin_heap; /* Private PRAMIN heap */ struct nouveau_gpuobj_ref *ramht; /* Hash table */ - struct nouveau_gpuobj_ref *ramht_refs; /* Objects referenced by RAMHT */ + struct list_head ramht_refs; /* Objects referenced by RAMHT */ }; struct nouveau_config { @@ -269,9 +271,17 @@ struct drm_nouveau_private { struct nouveau_config config; - struct nouveau_gpuobj *gpuobj_all; + struct list_head gpuobj_list; }; +#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ + struct drm_nouveau_private *nv = dev->dev_private; \ + if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ + DRM_ERROR("called without init\n"); \ + return -EINVAL; \ + } \ +} while(0) + #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \ struct drm_nouveau_private *nv = dev->dev_private; \ if (!nouveau_fifo_owner(dev, (cl), (id))) { \ @@ -293,6 +303,7 @@ extern int nouveau_ioctl_getparam(struct drm_device *, void *data, extern int nouveau_ioctl_setparam(struct drm_device *, void *data, struct drm_file *); extern void 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 *); @@ -324,6 +335,8 @@ extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int cout, uint32_t *offset); extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, struct drm_file *); +extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, + struct drm_file *); /* nouveau_fifo.c */ extern int nouveau_fifo_init(struct drm_device *); @@ -335,6 +348,7 @@ extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, extern void nouveau_fifo_free(struct nouveau_channel *); /* nouveau_object.c */ +extern int nouveau_gpuobj_init(struct drm_device *); extern void nouveau_gpuobj_takedown(struct drm_device *); extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, uint32_t vram_h, uint32_t tt_h); @@ -348,6 +362,8 @@ extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, struct nouveau_gpuobj_ref **); extern int nouveau_gpuobj_ref_del(struct drm_device *, struct nouveau_gpuobj_ref **); +extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle, + struct nouveau_gpuobj_ref **ref_ret); extern int nouveau_gpuobj_new_ref(struct drm_device *, struct nouveau_channel *alloc_chan, struct nouveau_channel *ref_chan, @@ -368,6 +384,8 @@ extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, struct nouveau_gpuobj **); extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, struct drm_file *); +extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, + struct drm_file *); /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); -- cgit v1.2.3 From cf04641bc61c8bc18101713a8d95ef98e6afae7f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 22:05:31 +1000 Subject: nouveau: Give DRM its own gpu channel If your card doesn't have working context switching, it is now broken. --- shared-core/nouveau_drv.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 0b173b76..10f9149e 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -134,6 +134,22 @@ struct nouveau_channel struct list_head ramht_refs; /* Objects referenced by RAMHT */ }; +struct nouveau_drm_channel { + struct nouveau_channel *chan; + + /* DMA state */ + int max, put, cur, free; + int push_free; + volatile uint32_t *pushbuf; + + /* Notifiers */ + uint32_t notify0_offset; + + /* Buffer moves */ + uint32_t m2mf_dma_source; + uint32_t m2mf_dma_destin; +}; + struct nouveau_config { struct { int location; @@ -222,6 +238,7 @@ struct drm_nouveau_private { struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER]; struct nouveau_engine Engine; + struct nouveau_drm_channel channel; /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ struct nouveau_gpuobj *ramht; @@ -345,6 +362,10 @@ extern int nouveau_fifo_ctx_size(struct drm_device *); extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *); extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, int channel); +extern int nouveau_fifo_alloc(struct drm_device *dev, + struct nouveau_channel **chan, + struct drm_file *file_priv, + uint32_t fb_ctxdma, uint32_t tt_ctxdma); extern void nouveau_fifo_free(struct nouveau_channel *); /* nouveau_object.c */ @@ -400,6 +421,11 @@ extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); +/* nouveau_dma.c */ +extern int nouveau_dma_channel_init(struct drm_device *); +extern void nouveau_dma_channel_takedown(struct drm_device *); +extern int nouveau_dma_wait(struct drm_device *, int size); + /* nv04_fb.c */ extern int nv04_fb_init(struct drm_device *); extern void nv04_fb_takedown(struct drm_device *); -- cgit v1.2.3 From 05633ca3708f48cfbbb77518da4e791d7e1613c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 16:37:55 +1000 Subject: nouveau: Always allocate drm's push buffer in VRAM Fixes #11868 --- shared-core/nouveau_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 10f9149e..572df46e 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -365,6 +365,7 @@ extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, extern int nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan, struct drm_file *file_priv, + struct mem_block *pushbuf, uint32_t fb_ctxdma, uint32_t tt_ctxdma); extern void nouveau_fifo_free(struct nouveau_channel *); -- cgit v1.2.3 From 39907f613b6c84499c34c9a6ece5f5dde64788c0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 10 Aug 2007 13:53:10 +1000 Subject: nouveau: Allow creation of gpuobjs before any other init has taken place. --- shared-core/nouveau_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 572df46e..4d5c7f7e 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -370,8 +370,10 @@ extern int nouveau_fifo_alloc(struct drm_device *dev, extern void nouveau_fifo_free(struct nouveau_channel *); /* nouveau_object.c */ +extern int nouveau_gpuobj_early_init(struct drm_device *); extern int nouveau_gpuobj_init(struct drm_device *); extern void nouveau_gpuobj_takedown(struct drm_device *); +extern void nouveau_gpuobj_late_takedown(struct drm_device *); extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, uint32_t vram_h, uint32_t tt_h); extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); -- cgit v1.2.3 From a46104674f129e873b8dfa29cf8aac9c67bd77be Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 10 Aug 2007 13:54:26 +1000 Subject: nouveau/nv50: demagic instmem setup. --- shared-core/nouveau_drv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 4d5c7f7e..e3d0ff4c 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -393,7 +393,8 @@ extern int nouveau_gpuobj_new_ref(struct drm_device *, struct nouveau_channel *ref_chan, uint32_t handle, int size, int align, uint32_t flags, struct nouveau_gpuobj_ref **); -extern int nouveau_gpuobj_new_fake(struct drm_device *, uint32_t offset, +extern int nouveau_gpuobj_new_fake(struct drm_device *, + uint32_t p_offset, uint32_t b_offset, uint32_t size, uint32_t flags, struct nouveau_gpuobj **, struct nouveau_gpuobj_ref**); -- cgit v1.2.3 From 02c4e0e757b69cd6ae38b8ab2c078b3f06fea661 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Aug 2007 00:56:24 +1000 Subject: nouveau/nv40: Fix channel scheduling. Ensure NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLE gets set, otherwise channels will appear to "freeze" in some circumstances. --- shared-core/nouveau_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index e3d0ff4c..b7459b1b 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -455,6 +455,7 @@ extern int nv10_fifo_load_context(struct nouveau_channel *); extern int nv10_fifo_save_context(struct nouveau_channel *); /* nv40_fifo.c */ +extern int nv40_fifo_init(struct drm_device *); extern int nv40_fifo_create_context(struct nouveau_channel *); extern void nv40_fifo_destroy_context(struct nouveau_channel *); extern int nv40_fifo_load_context(struct nouveau_channel *); -- cgit v1.2.3 From c3faa589b09616acdfd827be1719f6c2706c49ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Aug 2007 13:36:54 +1000 Subject: nouveau: Allow GART notifiers when using sgdma code. --- shared-core/nouveau_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/nouveau_drv.h') diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index b7459b1b..e96c8fad 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -421,6 +421,8 @@ extern void nouveau_irq_uninstall(struct drm_device *); /* nouveau_sgdma.c */ extern int nouveau_sgdma_init(struct drm_device *); extern void nouveau_sgdma_takedown(struct drm_device *); +extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset, + uint32_t *page); extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); -- cgit v1.2.3