All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/nouveau: refactor VGA font save/restore
@ 2009-08-02 15:12 Pekka Paalanen
       [not found] ` <1249225972-4655-1-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-02 15:12 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Remove drm_nouveau_private::fb member and map the piece of VRAM only
when accessing VGA fonts.

Collect copied code into the static function nouveau_vga_font_io().

Signed-off-by: Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   17 -------
 drivers/gpu/drm/nouveau/nouveau_hw.c    |   75 +++++++++++++++----------------
 drivers/gpu/drm/nouveau/nouveau_state.c |    8 ---
 3 files changed, 37 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 5477dc0..c6143b8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -461,7 +461,6 @@ struct drm_nouveau_private {
 	int flags;
 
 	void __iomem *mmio;
-	void __iomem *fb;
 	void __iomem *ramin;
 	uint32_t ramin_size;
 
@@ -1014,22 +1013,6 @@ static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val)
 #define nv_wait(reg,mask,val) nouveau_wait_until(dev, 2000000000ULL, (reg),    \
 						 (mask), (val))
 
-/*
- * VRAM access for the first 64kB
- * see nouveau_state.c
- */
-static inline u32 nv_rf32(struct drm_device *dev, unsigned offset)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	return ioread32_native(dev_priv->fb + offset);
-}
-
-static inline void nv_wf32(struct drm_device *dev, unsigned offset, u32 val)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	iowrite32_native(val, dev_priv->fb + offset);
-}
-
 /* PRAMIN access */
 static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
 {
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index 295b876..6f55f55 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -537,13 +537,33 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
  * vga font save/restore
  */
 
+static void nouveau_vga_font_io(struct drm_device *dev,
+				void __iomem *iovram,
+				bool save, unsigned plane)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned i;
+
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane);
+	for (i = 0; i < 16384; i++) {
+		if (save) {
+			dev_priv->saved_vga_font[plane][i] =
+					ioread32_native(iovram + i * 4);
+		} else {
+			iowrite32_native(dev_priv->saved_vga_font[plane][i],
+							iovram + i * 4);
+		}
+	}
+}
+
 void
 nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	uint8_t misc, gr4, gr5, gr6, seq2, seq4;
 	bool graphicsmode;
-	int i;
+	unsigned plane;
+	void __iomem *iovram;
 
 	if (nv_two_heads(dev))
 		NVSetOwner(dev, 0);
@@ -552,10 +572,19 @@ nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
 	graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1;
 	NVSetEnablePalette(dev, 0, false);
 
-	if (graphicsmode)	/* graphics mode => framebuffer => no need to save */
+	if (graphicsmode) /* graphics mode => framebuffer => no need to save */
 		return;
 
 	NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor");
+
+	/* map first 64KiB of VRAM, holds VGA fonts etc */
+	iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536);
+	if (!iovram) {
+		NV_ERROR(dev, "Failed to map VRAM, "
+					"cannot save/restore VGA fonts.\n");
+		return;
+	}
+
 	if (nv_two_heads(dev))
 		NVBlankScreen(dev, 1, true);
 	NVBlankScreen(dev, 0, true);
@@ -573,41 +602,9 @@ nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
 	NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0);
 	NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5);
 
-	/* store font in plane 0 */
-	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x1);
-	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x0);
-	for (i = 0; i < 16384; i++)
-		if (save)
-			dev_priv->saved_vga_font[0][i] = nv_rf32(dev, i * 4);
-		else
-			nv_wf32(dev, i * 4, dev_priv->saved_vga_font[0][i]);
-
-	/* store font in plane 1 */
-	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x2);
-	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x1);
-	for (i = 0; i < 16384; i++)
-		if (save)
-			dev_priv->saved_vga_font[1][i] = nv_rf32(dev, i * 4);
-		else
-			nv_wf32(dev, i * 4, dev_priv->saved_vga_font[1][i]);
-
-	/* store font in plane 2 */
-	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x4);
-	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x2);
-	for (i = 0; i < 16384; i++)
-		if (save)
-			dev_priv->saved_vga_font[2][i] = nv_rf32(dev, i * 4);
-		else
-			nv_wf32(dev, i * 4, dev_priv->saved_vga_font[2][i]);
-
-	/* store font in plane 3 */
-	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x8);
-	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x3);
-	for (i = 0; i < 16384; i++)
-		if (save)
-			dev_priv->saved_vga_font[3][i] = nv_rf32(dev, i * 4);
-		else
-			nv_wf32(dev, i * 4, dev_priv->saved_vga_font[3][i]);
+	/* store font in planes 0..3 */
+	for (plane = 0; plane < 4; plane++)
+		nouveau_vga_font_io(dev, iovram, save, plane);
 
 	/* restore control regs */
 	NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc);
@@ -620,6 +617,8 @@ nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
 	if (nv_two_heads(dev))
 		NVBlankScreen(dev, 1, false);
 	NVBlankScreen(dev, 0, false);
+
+	iounmap(iovram);
 }
 
 /*
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 93d14f3..ace8beb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -590,13 +590,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
 		}
 	}
 
-	/* map first 64KiB of VRAM, holds VGA fonts etc */
-	dev_priv->fb = ioremap(pci_resource_start(dev->pdev, 1), 65536);
-	if (!dev_priv->fb) {
-		NV_ERROR(dev, "Failed to map FB BAR\n");
-		return -ENOMEM;
-	}
-
 	nouveau_OF_copy_vbios_to_ramin(dev);
 
 	/* Special flags */
@@ -648,7 +641,6 @@ int nouveau_unload(struct drm_device *dev)
 
 	iounmap(dev_priv->mmio);
 	iounmap(dev_priv->ramin);
-	iounmap(dev_priv->fb);
 
 	kfree(dev_priv);
 	dev->dev_private = NULL;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] drm/nouveau: cleanup in nouveau_bo_unmap()
       [not found] ` <1249225972-4655-1-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
@ 2009-08-02 15:12   ` Pekka Paalanen
       [not found]     ` <1249225972-4655-2-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
  2009-08-03 10:03   ` [PATCH 1/4] drm/nouveau: refactor VGA font save/restore Pekka Paalanen
  1 sibling, 1 reply; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-02 15:12 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

ttm_bo_kunmap() already checks for map->virtual and sets it to NULL.

Signed-off-by: Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 609118c..de4ca71 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -169,10 +169,7 @@ nouveau_bo_map(struct nouveau_bo *nvbo)
 void
 nouveau_bo_unmap(struct nouveau_bo *nvbo)
 {
-	if (nvbo->kmap.virtual) {
-		ttm_bo_kunmap(&nvbo->kmap);
-		nvbo->kmap.virtual = NULL;
-	}
+	ttm_bo_kunmap(&nvbo->kmap);
 }
 
 static struct ttm_backend *
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] drm/nouveau: remove unused arg from nouveau_bo_new()
       [not found]     ` <1249225972-4655-2-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
@ 2009-08-02 15:12       ` Pekka Paalanen
       [not found]         ` <1249225972-4655-3-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-02 15:12 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

nouveau_bo_new() took struct nouveau_channel *chan as a parameter, yet
it was not used (it was set and then reset to NULL). Remove the unused
parameter (which was almost always NULL anyway).

No need to set nvbo->channel = NULL since kzalloc already zeros it.

Signed-off-by: Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c   |    4 +---
 drivers/gpu/drm/nouveau/nouveau_drv.h  |    2 +-
 drivers/gpu/drm/nouveau/nouveau_fifo.c |    2 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c  |    2 +-
 drivers/gpu/drm/nouveau/nv04_crtc.c    |    2 +-
 drivers/gpu/drm/nouveau/nv50_crtc.c    |    2 +-
 drivers/gpu/drm/nouveau/nv50_display.c |    2 +-
 drivers/gpu/drm/nouveau/nv50_instmem.c |    2 +-
 8 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index de4ca71..052ec56 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -52,7 +52,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
 }
 
 int
-nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
+nouveau_bo_new(struct drm_device *dev,
 	       int size, int align, uint32_t flags, uint32_t tile_mode,
 	       uint32_t tile_flags, bool no_vm, bool mappable,
 	       struct nouveau_bo **pnvbo)
@@ -81,11 +81,9 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
 			align = (65536 / PAGE_SIZE);
 	}
 
-	nvbo->channel = chan;
 	ret = ttm_buffer_object_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
 				     ttm_bo_type_device, flags, align,
 				     0, false, NULL, size, nouveau_bo_del_ttm);
-	nvbo->channel = NULL;
 	if (ret) {
 		/* ttm will call nouveau_bo_del_ttm if it fails.. */
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index c6143b8..01c615a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -918,7 +918,7 @@ extern struct nouveau_connector *nouveau_encoder_connector_get(
 
 /* nouveau_bo.c */
 extern struct ttm_bo_driver nouveau_bo_driver;
-extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *,
+extern int nouveau_bo_new(struct drm_device *,
 			  int size, int align, uint32_t flags,
 			  uint32_t tile_mode, uint32_t tile_flags,
 			  bool no_vm, bool mappable, struct nouveau_bo **);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.c b/drivers/gpu/drm/nouveau/nouveau_fifo.c
index 58cef14..9d96ce6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fifo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fifo.c
@@ -256,7 +256,7 @@ nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev)
 	if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size)
 		config->cmdbuf.size = 65536;
 
-	ret = nouveau_bo_new(dev, NULL, config->cmdbuf.size, 0,
+	ret = nouveau_bo_new(dev, config->cmdbuf.size, 0,
 			     config->cmdbuf.location, 0, 0x0000,
 			     false, true, &pushbuf);
 	if (ret) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 670348b..a54fce4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -68,7 +68,7 @@ nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan,
 	struct nouveau_bo *nvbo;
 	int ret;
 
-	ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode,
+	ret = nouveau_bo_new(dev, size, align, flags, tile_mode,
 			     tile_flags, no_vm, mappable, pnvbo);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index c732fbe..860cf0d 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -1118,7 +1118,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
 	drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
 	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
 
-	ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
+	ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
 			     0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
 	if (!ret) {
 		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 81c53c4..32d423d 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -777,7 +777,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
 	}
 	crtc->lut.depth = 0;
 
-	ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM,
+	ret = nouveau_bo_new(dev, 4096, 0x100, TTM_PL_FLAG_VRAM,
 			     0, 0x0000, false, true, &crtc->lut.nvbo);
 	if (!ret) {
 		ret = nouveau_bo_pin(crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 2ab1685..9b22a3d 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -149,7 +149,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
 		return ret;
 	}
 
-	ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
+	ret = nouveau_bo_new(dev, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
 			     false, true, &chan->pushbuf_bo);
 	if (ret == 0)
 		ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM);
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index 062d085..f2401b9 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -368,7 +368,7 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
 	if (*sz == 0)
 		return -EINVAL;
 
-	ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000,
+	ret = nouveau_bo_new(dev, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000,
 			     true, false, &gpuobj->im_backing);
 	if (ret) {
 		NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret);
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] drm/nouveau: detect bad iomem usage in TTM maps
       [not found]         ` <1249225972-4655-3-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
@ 2009-08-02 15:12           ` Pekka Paalanen
       [not found]             ` <1249225972-4655-4-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-02 15:12 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

kmap.virtual should not be used blindly, because it may be a kernel
virtual pointer or an iomem cookie. Iomem cookies may not be
dereferenced directly, they must be used via ioread32() etc. functions.
Unfortunately x86 doesn't care too much, except for caching issues
(barriers). Other arches may fail mysteriously.

Use the TTM API to get the virtual pointer from a map object, and check
if the map type is as expected. This is not the fix but simply shows in
how many places things are wrong.

TTM does not use __iomem attributes in the API and sparse yells its head
off. Seems that TTM would need another set of access wrappers that use
ttm_kmap_obj_virtual() and honour is_iomem.

Signed-off-by: Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_dma.c   |   11 +++++++++--
 drivers/gpu/drm/nouveau/nouveau_fbcon.c |    7 ++++++-
 drivers/gpu/drm/nouveau/nv04_crtc.c     |    9 +++++++--
 drivers/gpu/drm/nouveau/nv50_crtc.c     |    7 ++++++-
 drivers/gpu/drm/nouveau/nv50_display.c  |   11 +++++++++--
 5 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 7766af4..6d26c1e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -36,6 +36,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_gpuobj *m2mf = NULL;
 	int ret, i;
+	bool is_iomem;
 
 	/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
 	ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ?
@@ -56,14 +57,20 @@ 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;
+	chan->dma.pushbuf = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap,
+								&is_iomem);
+	if (is_iomem)
+		NV_WARN(dev, "WARNING: chan->dma.pushbuf is iomem.\n");
 
 	/* Map M2MF notifier object - fbcon. */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		ret = nouveau_bo_map(chan->notifier_bo);
 		if (ret)
 			return ret;
-		chan->m2mf_ntfy_map  = chan->notifier_bo->kmap.virtual;
+		chan->m2mf_ntfy_map = ttm_kmap_obj_virtual(
+					&chan->notifier_bo->kmap, &is_iomem);
+		if (is_iomem)
+			NV_WARN(dev, "WARNING: chan->m2mf_ntfy is iomem.\n");
 		chan->m2mf_ntfy_map += chan->m2mf_ntfy;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 1511d6c..b7e6eb8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -505,6 +505,7 @@ static int nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
 	struct device *device = &dev->pdev->dev;
 	struct fb_fillrect rect;
 	int size, ret;
+	bool is_iomem;
 
 	mode_cmd.width = surface_width;
 	mode_cmd.height = surface_height;
@@ -573,7 +574,11 @@ 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 = ttm_kmap_obj_virtual(&nouveau_fb->nvbo->kmap,
+								&is_iomem);
+	if (!is_iomem)
+		NV_WARN(dev,
+			"WARNING: fbcon info->screen_base is not iomem.\n");
 	info->screen_size = size;
 
 	info->pseudo_palette = fb->pseudo_palette;
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 860cf0d..a038a5f 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -999,6 +999,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
 	struct drm_gem_object *gem;
 	uint32_t *src, *dst, pixel;
 	int ret = 0, alpha, i;
+	bool is_iomem;
 
 	if (width != 64 || height != 64)
 		return -EINVAL;
@@ -1016,8 +1017,12 @@ 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;
+	src = ttm_kmap_obj_virtual(&cursor->kmap, &is_iomem);
+	if (is_iomem)
+		NV_WARN(dev, "WARNING: nv04 cursor src is iomem.\n");
+	dst = ttm_kmap_obj_virtual(&nv_crtc->cursor.nvbo->kmap, &is_iomem);
+	if (is_iomem)
+		NV_WARN(dev, "WARNING: nv04 cursor dst is iomem.\n");
 
 	/* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
 	 * cursors (though NPM in combination with fp dithering may not work on
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 32d423d..66e802b 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -43,10 +43,15 @@ 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;
+	bool is_iomem;
+	void __iomem *lut = ttm_kmap_obj_virtual(&crtc->lut.nvbo->kmap,
+								&is_iomem);
 
 	NV_DEBUG(dev, "\n");
 
+	if (!is_iomem)
+		NV_WARN(dev, "WARNING: nv50 lut is not iomem.\n");
+
 	/* 16 bits, red, green, blue, unused, total of 64 bits per index */
 	/* 10 bits lut, with 14 bits values. */
 	switch (crtc->lut.depth) {
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 9b22a3d..72fce83 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -187,6 +187,7 @@ nv50_display_init(struct drm_device *dev)
 	uint32_t val, ram_amount;
 	uint64_t start;
 	int i;
+	bool is_iomem;
 
 	NV_DEBUG(dev, "\n");
 
@@ -328,7 +329,10 @@ 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;
+	evo->dma.pushbuf = ttm_kmap_obj_virtual(&evo->pushbuf_bo->kmap,
+								&is_iomem);
+	if (is_iomem)
+		NV_WARN(dev, "WARNING: evo->dma.pushbuf is iomem.\n");
 
 	RING_SPACE(evo, NOUVEAU_DMA_SKIPS);
 	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
@@ -638,11 +642,14 @@ nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
 	struct nouveau_channel *chan;
 	struct list_head *entry, *tmp;
 	uint32_t *sem;
+	bool is_iomem;
 
 	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 = ttm_kmap_obj_virtual(&chan->notifier_bo->kmap, &is_iomem);
+		if (is_iomem)
+			NV_WARN(dev, "WARNING: nv50 sem is iomem.\n");
 		sem[chan->nvsw.vblsem_offset] = chan->nvsw.vblsem_rval;
 
 		list_del(&chan->nvsw.vbl_wait);
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/4] drm/nouveau: detect bad iomem usage in TTM maps
       [not found]             ` <1249225972-4655-4-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
@ 2009-08-02 16:11               ` Pekka Paalanen
  0 siblings, 0 replies; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-02 16:11 UTC (permalink / raw)
  To: Ben Skeggs; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Sun,  2 Aug 2009 18:12:52 +0300
Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org> wrote:

> kmap.virtual should not be used blindly, because it may be a kernel
> virtual pointer or an iomem cookie. Iomem cookies may not be
> dereferenced directly, they must be used via ioread32() etc. functions.
> Unfortunately x86 doesn't care too much, except for caching issues
> (barriers). Other arches may fail mysteriously.
> 

From the kernel code purity point of view, this is clearly an error and
should be fixed. OTOH, it does not seem to hurt much, does it?

How do we fix it?

Do we need special routines that take is_iomem into account?
Are some bos such, that they are always iomem or never iomem,
in which case a WARN_ON could suffice?

When I start KMS, g86gl, X, I get the following:

[   84.711009] nouveau 0000:01:00.0: Allocating FIFO number 1
[   84.724325] nouveau 0000:01:00.0: WARNING: chan->m2mf_ntfy is iomem.
[   84.724328] nouveau 0000:01:00.0: nouveau_fifo_alloc: initialised FIFO 1

[   84.726196] nouveau 0000:01:00.0: Detected a DVI-D connector
[   86.002826] nouveau 0000:01:00.0: WARNING: evo->dma.pushbuf is iomem.
[   86.106518] allocated 1440x900 fb: 0x40230000, bo ffff88003d156400

[   86.654361] nouveau 0000:01:00.0: Allocating FIFO number 2
[   86.680615] nouveau 0000:01:00.0: WARNING: chan->m2mf_ntfy is iomem.
[   86.680622] nouveau 0000:01:00.0: nouveau_fifo_alloc: initialised FIFO 2


> Use the TTM API to get the virtual pointer from a map object, and check
> if the map type is as expected. This is not the fix but simply shows in
> how many places things are wrong.
> 
> TTM does not use __iomem attributes in the API and sparse yells its head
> off. Seems that TTM would need another set of access wrappers that use
> ttm_kmap_obj_virtual() and honour is_iomem.
> 
> Signed-off-by: Pekka Paalanen <pq-X3B1VOXEql0@public.gmane.org>
> ---
>  drivers/gpu/drm/nouveau/nouveau_dma.c   |   11 +++++++++--
>  drivers/gpu/drm/nouveau/nouveau_fbcon.c |    7 ++++++-
>  drivers/gpu/drm/nouveau/nv04_crtc.c     |    9 +++++++--
>  drivers/gpu/drm/nouveau/nv50_crtc.c     |    7 ++++++-
>  drivers/gpu/drm/nouveau/nv50_display.c  |   11 +++++++++--
>  5 files changed, 37 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
> index 7766af4..6d26c1e 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dma.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
> @@ -36,6 +36,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
>  	struct drm_nouveau_private *dev_priv = dev->dev_private;
>  	struct nouveau_gpuobj *m2mf = NULL;
>  	int ret, i;
> +	bool is_iomem;
>  
>  	/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
>  	ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ?
> @@ -56,14 +57,20 @@ 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;
> +	chan->dma.pushbuf = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap,
> +								&is_iomem);
> +	if (is_iomem)
> +		NV_WARN(dev, "WARNING: chan->dma.pushbuf is iomem.\n");
>  
>  	/* Map M2MF notifier object - fbcon. */
>  	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
>  		ret = nouveau_bo_map(chan->notifier_bo);
>  		if (ret)
>  			return ret;
> -		chan->m2mf_ntfy_map  = chan->notifier_bo->kmap.virtual;
> +		chan->m2mf_ntfy_map = ttm_kmap_obj_virtual(
> +					&chan->notifier_bo->kmap, &is_iomem);
> +		if (is_iomem)
> +			NV_WARN(dev, "WARNING: chan->m2mf_ntfy is iomem.\n");
>  		chan->m2mf_ntfy_map += chan->m2mf_ntfy;
>  	}
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> index 1511d6c..b7e6eb8 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> @@ -505,6 +505,7 @@ static int nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
>  	struct device *device = &dev->pdev->dev;
>  	struct fb_fillrect rect;
>  	int size, ret;
> +	bool is_iomem;
>  
>  	mode_cmd.width = surface_width;
>  	mode_cmd.height = surface_height;
> @@ -573,7 +574,11 @@ 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 = ttm_kmap_obj_virtual(&nouveau_fb->nvbo->kmap,
> +								&is_iomem);
> +	if (!is_iomem)
> +		NV_WARN(dev,
> +			"WARNING: fbcon info->screen_base is not iomem.\n");
>  	info->screen_size = size;
>  
>  	info->pseudo_palette = fb->pseudo_palette;
> diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
> index 860cf0d..a038a5f 100644
> --- a/drivers/gpu/drm/nouveau/nv04_crtc.c
> +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
> @@ -999,6 +999,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
>  	struct drm_gem_object *gem;
>  	uint32_t *src, *dst, pixel;
>  	int ret = 0, alpha, i;
> +	bool is_iomem;
>  
>  	if (width != 64 || height != 64)
>  		return -EINVAL;
> @@ -1016,8 +1017,12 @@ 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;
> +	src = ttm_kmap_obj_virtual(&cursor->kmap, &is_iomem);
> +	if (is_iomem)
> +		NV_WARN(dev, "WARNING: nv04 cursor src is iomem.\n");
> +	dst = ttm_kmap_obj_virtual(&nv_crtc->cursor.nvbo->kmap, &is_iomem);
> +	if (is_iomem)
> +		NV_WARN(dev, "WARNING: nv04 cursor dst is iomem.\n");
>  
>  	/* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
>  	 * cursors (though NPM in combination with fp dithering may not work on
> diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
> index 32d423d..66e802b 100644
> --- a/drivers/gpu/drm/nouveau/nv50_crtc.c
> +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
> @@ -43,10 +43,15 @@ 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;
> +	bool is_iomem;
> +	void __iomem *lut = ttm_kmap_obj_virtual(&crtc->lut.nvbo->kmap,
> +								&is_iomem);
>  
>  	NV_DEBUG(dev, "\n");
>  
> +	if (!is_iomem)
> +		NV_WARN(dev, "WARNING: nv50 lut is not iomem.\n");
> +
>  	/* 16 bits, red, green, blue, unused, total of 64 bits per index */
>  	/* 10 bits lut, with 14 bits values. */
>  	switch (crtc->lut.depth) {
> diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
> index 9b22a3d..72fce83 100644
> --- a/drivers/gpu/drm/nouveau/nv50_display.c
> +++ b/drivers/gpu/drm/nouveau/nv50_display.c
> @@ -187,6 +187,7 @@ nv50_display_init(struct drm_device *dev)
>  	uint32_t val, ram_amount;
>  	uint64_t start;
>  	int i;
> +	bool is_iomem;
>  
>  	NV_DEBUG(dev, "\n");
>  
> @@ -328,7 +329,10 @@ 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;
> +	evo->dma.pushbuf = ttm_kmap_obj_virtual(&evo->pushbuf_bo->kmap,
> +								&is_iomem);
> +	if (is_iomem)
> +		NV_WARN(dev, "WARNING: evo->dma.pushbuf is iomem.\n");
>  
>  	RING_SPACE(evo, NOUVEAU_DMA_SKIPS);
>  	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
> @@ -638,11 +642,14 @@ nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
>  	struct nouveau_channel *chan;
>  	struct list_head *entry, *tmp;
>  	uint32_t *sem;
> +	bool is_iomem;
>  
>  	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 = ttm_kmap_obj_virtual(&chan->notifier_bo->kmap, &is_iomem);
> +		if (is_iomem)
> +			NV_WARN(dev, "WARNING: nv50 sem is iomem.\n");
>  		sem[chan->nvsw.vblsem_offset] = chan->nvsw.vblsem_rval;
>  
>  		list_del(&chan->nvsw.vbl_wait);
> -- 
> 1.6.3.3

-- 
Pekka Paalanen
http://www.iki.fi/pq/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/4] drm/nouveau: refactor VGA font save/restore
       [not found] ` <1249225972-4655-1-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
  2009-08-02 15:12   ` [PATCH 2/4] drm/nouveau: cleanup in nouveau_bo_unmap() Pekka Paalanen
@ 2009-08-03 10:03   ` Pekka Paalanen
  1 sibling, 0 replies; 6+ messages in thread
From: Pekka Paalanen @ 2009-08-03 10:03 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Patches 1 and 2 pushed to master, patch 3 NAK'ed by Ben, patch 4 is under
rewrite.

-- 
Pekka Paalanen
http://www.iki.fi/pq/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-08-03 10:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-02 15:12 [PATCH 1/4] drm/nouveau: refactor VGA font save/restore Pekka Paalanen
     [not found] ` <1249225972-4655-1-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
2009-08-02 15:12   ` [PATCH 2/4] drm/nouveau: cleanup in nouveau_bo_unmap() Pekka Paalanen
     [not found]     ` <1249225972-4655-2-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
2009-08-02 15:12       ` [PATCH 3/4] drm/nouveau: remove unused arg from nouveau_bo_new() Pekka Paalanen
     [not found]         ` <1249225972-4655-3-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
2009-08-02 15:12           ` [PATCH 4/4] drm/nouveau: detect bad iomem usage in TTM maps Pekka Paalanen
     [not found]             ` <1249225972-4655-4-git-send-email-pq-X3B1VOXEql0@public.gmane.org>
2009-08-02 16:11               ` Pekka Paalanen
2009-08-03 10:03   ` [PATCH 1/4] drm/nouveau: refactor VGA font save/restore Pekka Paalanen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.