Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 1/6] drm/nouveau: bo read/write wrappers for nv04_crtc.c
Introduce accessors for TTM buffer object memory that has been mapped into the kernel virtual address space or as IO memory. IO memory needs to be accessed via special accessor functions, not by dereferencing the iomem cookie. The wrappers hide the details of 32-bit access and honour the TTM map type. nv04_crtc_cursor_set() is changed to use the new wrappers. 'cursor' is received from user space, which means we cannot assume that it is or is not iomem. 'nv_crtc->cursor.nvbo' should always be iomem, and as such the access is relatively slow. Therefore using the wrappers for it, too, should not cost much. Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nouveau_bo.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 2 ++ drivers/gpu/drm/nouveau/nv04_crtc.c | 7 ++----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d59ffc4..442bab7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -172,6 +172,29 @@ nouveau_bo_unmap(struct nouveau_bo *nvbo) ttm_bo_kunmap(&nvbo->kmap); } +u32 +nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index) +{ + bool is_iomem; + u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); + mem = &mem[index]; + if (is_iomem) + return ioread32_native((void __force __iomem *)mem); + else + return *mem; +} + +void +nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val) +{ + bool is_iomem; + u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); + mem = &mem[index]; + if (is_iomem) + iowrite32_native(val, (void __force __iomem *)mem); + else + *mem = val; +} static struct ttm_backend * nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c6143b8..44a7ab5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -926,6 +926,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); extern int nouveau_bo_unpin(struct nouveau_bo *); extern int nouveau_bo_map(struct nouveau_bo *); extern void nouveau_bo_unmap(struct nouveau_bo *); +extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); +extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); /* nouveau_fence.c */ struct nouveau_fence; diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 103e28c..f4fc5b7 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -1005,7 +1005,6 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_bo *cursor = NULL; struct drm_gem_object *gem; - uint32_t *src, *dst, pixel; int ret = 0, alpha, i; if (width != 64 || height != 64) @@ -1024,8 +1023,6 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ret = nouveau_bo_map(cursor); if (ret) goto out; - src = cursor->kmap.virtual; - dst = nv_crtc->cursor.nvbo->kmap.virtual; /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha * cursors (though NPM in combination with fp dithering may not work on @@ -1034,7 +1031,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, * blob uses, however we get given PM cursors so we use PM mode */ for (i = 0; i < 64 * 64; i++) { - pixel = *src++; + uint32_t pixel = nouveau_bo_rd32(cursor, i); /* hw gets unhappy if alpha <= rgb values. for a PM image "less * than" shouldn't happen; fix "equal to" case by adding one to @@ -1054,7 +1051,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, } #endif - *dst++ = pixel; + nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, pixel); } nouveau_bo_unmap(cursor); -- 1.6.3.3
Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 2/6] drm/nv50: proper notifier_bo access in nv50_display_vblank_crtc_handler()
Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nv50_display.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index ee3905d..b81dc16 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -639,14 +639,12 @@ nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan; struct list_head *entry, *tmp; - uint32_t *sem; list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) { chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait); - sem = chan->notifier_bo->kmap.virtual; - sem[chan->nvsw.vblsem_offset] = chan->nvsw.vblsem_rval; - + nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset, + chan->nvsw.vblsem_rval); list_del(&chan->nvsw.vbl_wait); } } -- 1.6.3.3
Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 3/6] drm/nouveau: use bo accessors for push buffers
Since push buffers may reside in system memory or VRAM (iomem), they must be accessed via the proper functions instead of just dereferencing a pointer which might be an iomem cookie. Remove the redundant member nouveau_channel::dma.pushbuf. Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nouveau_dma.c | 1 - drivers/gpu/drm/nouveau/nouveau_dma.h | 5 ++--- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +-- drivers/gpu/drm/nouveau/nv50_display.c | 1 - 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 7766af4..e315f01 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -56,7 +56,6 @@ nouveau_dma_init(struct nouveau_channel *chan) ret = nouveau_bo_map(chan->pushbuf_bo); if (ret) return ret; - chan->dma.pushbuf = chan->pushbuf_bo->kmap.virtual; /* Map M2MF notifier object - fbcon. */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index f15873f..c8674f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -102,7 +102,7 @@ OUT_RING(struct nouveau_channel *chan, int data) NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n", chan->id, chan->dma.cur << 2, data); #endif - chan->dma.pushbuf[chan->dma.cur++] = data; + nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data); } static inline void @@ -114,9 +114,8 @@ BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) #define READ_GET() ((nvchan_rd32(chan->user_get) - chan->pushbuf_base) >> 2) #define WRITE_PUT(val) do { \ - volatile uint32_t tmp; \ DRM_MEMORYBARRIER(); \ - tmp = chan->dma.pushbuf[0]; \ + nouveau_bo_rd32(chan->pushbuf_bo, 0); \ nvchan_wr32(chan->user_put, ((val) << 2) + chan->pushbuf_base); \ chan->dma.put = (val); \ } while (0) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 44a7ab5..eb32532 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -226,8 +226,7 @@ struct nouveau_channel int free; int cur; int put; - - volatile uint32_t *pushbuf; + /* access via pushbuf_bo */ } dma; uint32_t sw_subchannel[8]; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index b81dc16..99feea7 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -328,7 +328,6 @@ nv50_display_init(struct drm_device *dev) evo->dma.put = 0; evo->dma.cur = evo->dma.put; evo->dma.free = evo->dma.max - evo->dma.cur; - evo->dma.pushbuf = evo->pushbuf_bo->kmap.virtual; RING_SPACE(evo, NOUVEAU_DMA_SKIPS); for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) -- 1.6.3.3
Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 4/6] drm/nouveau: access fbcon notifier via bo accessors
Notifier can live in system memory or VRAM, hence they must be accessed using the bo wrapper functions. Remove the redundant member nouveau_channel::m2mf_ntfy_map. Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nouveau_dma.c | 2 -- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 - drivers/gpu/drm/nouveau/nouveau_fbcon.c | 5 +++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index e315f01..a555a5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -62,8 +62,6 @@ nouveau_dma_init(struct nouveau_channel *chan) ret = nouveau_bo_map(chan->notifier_bo); if (ret) return ret; - chan->m2mf_ntfy_map = chan->notifier_bo->kmap.virtual; - chan->m2mf_ntfy_map += chan->m2mf_ntfy; } /* Initialise DMA vars */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index eb32532..9d71ff5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -215,7 +215,6 @@ struct nouveau_channel /* GPU object info for stuff used in-kernel (mm_enabled) */ uint32_t m2mf_ntfy; - volatile uint32_t *m2mf_ntfy_map; uint32_t vram_handle; uint32_t gart_handle; bool accel_done; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index d6b4dd2..c72bcc4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -73,12 +73,13 @@ nouveau_fbcon_sync(struct fb_info *info) OUT_RING (chan, 0); BEGIN_RING(chan, 0, 0x0100, 1); OUT_RING (chan, 0); - chan->m2mf_ntfy_map[3] = 0xffffffff; + nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); FIRE_RING (chan); ret = -EBUSY; for (i = 0; i < 100000; i++) { - if (chan->m2mf_ntfy_map[3] == 0) { + if (nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3) + == 0) { ret = 0; break; } -- 1.6.3.3
Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 5/6] drm/nouveau: screen_base and lut must be iomem
This introduces nvbo_kmap_obj_iovirtual() for cases where the bo memory is guaranteed (or supposed) to be iomem. Fbcon assumes screen_base is iomem, and the crtc color LUT must reside in iomem. Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nouveau_drv.h | 11 +++++++++++ drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/nouveau/nv50_crtc.c | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9d71ff5..25510b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -101,6 +101,17 @@ nouveau_gem_object(struct drm_gem_object *gem) return gem ? gem->driver_private : NULL; } +/* TODO: submit equivalent to TTM generic API upstream? */ +static inline void __iomem * +nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) +{ + bool is_iomem; + void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual( + &nvbo->kmap, &is_iomem); + WARN_ON_ONCE(ioptr && !is_iomem); + return ioptr; +} + struct mem_block { struct mem_block *next; struct mem_block *prev; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index c72bcc4..601eabe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -582,7 +582,7 @@ static int nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; - info->screen_base = nouveau_fb->nvbo->kmap.virtual; + info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); info->screen_size = size; info->pseudo_palette = fb->pseudo_palette; diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index b169f9b..bb6847a 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -43,7 +43,7 @@ nv50_crtc_lut_load(struct nouveau_crtc *crtc) { struct drm_device *dev = crtc->base.dev; uint32_t index = 0, i; - void __iomem *lut = crtc->lut.nvbo->kmap.virtual; + void __iomem *lut = nvbo_kmap_obj_iovirtual(crtc->lut.nvbo); NV_DEBUG(dev, "\n"); -- 1.6.3.3
Pekka Paalanen
2009-Aug-04 18:22 UTC
[Nouveau] [PATCH 6/6] drm/nouveau: remove redundant check in nouveau_bo_del_ttm()
ttm_bo_kunmap() already checks if the bo is not mapped. Signed-off-by: Pekka Paalanen <pq at iki.fi> --- drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 442bab7..dc6c3a6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -39,8 +39,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); - if (unlikely(nvbo->kmap.virtual)) - ttm_bo_kunmap(&nvbo->kmap); + ttm_bo_kunmap(&nvbo->kmap); if (unlikely(nvbo->gem)) DRM_ERROR("bo %p still attached to GEM object\n", bo); -- 1.6.3.3
Maybe Matching Threads
- drm bo accessors etc. v2
- [PATCH 1/2] drm/nv50: align size of buffer object to the right boundaries.
- [PATCH] nvc0: Add and enable vblank support
- [PATCH] drm/nv50: synchronize user channel after buffer object move on kernel channel
- [PATCH 1/4] drm/nouveau: refactor nouveau_dma_wait()