[Nouveau] [PATCH 1/3] drm/nouveau: Pre-G80 tiling support.
Jimmy Rentz
jb17bsome at gmail.com
Fri Dec 11 12:18:20 PST 2009
On Fri, 11 Dec 2009 19:33:22 +0100
Francisco Jerez <currojerez at riseup.net> wrote:
> Signed-off-by: Francisco Jerez <currojerez at riseup.net>
> ---
> drivers/gpu/drm/nouveau/nouveau_drv.h | 23 +++++
> drivers/gpu/drm/nouveau/nouveau_reg.h | 16 ++--
> drivers/gpu/drm/nouveau/nouveau_state.c | 8 ++
> drivers/gpu/drm/nouveau/nv10_fb.c | 32 ++++++--
> drivers/gpu/drm/nouveau/nv10_graph.c | 47 ++++++++---
> drivers/gpu/drm/nouveau/nv20_graph.c | 80 +++++++++++--------
> drivers/gpu/drm/nouveau/nv40_fb.c | 53 ++++++++-----
> drivers/gpu/drm/nouveau/nv40_graph.c | 135
> +++++++++++++++---------------- 8 files changed, 247 insertions(+),
> 147 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h
> b/drivers/gpu/drm/nouveau/nouveau_drv.h index 88b4c7b..2730497 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drv.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
> @@ -276,8 +276,13 @@ struct nouveau_timer_engine {
> };
>
> struct nouveau_fb_engine {
> + int num_tiles;
> +
> int (*init)(struct drm_device *dev);
> void (*takedown)(struct drm_device *dev);
> +
> + void (*set_region_tiling)(struct drm_device *dev, int i,
> uint32_t addr,
> + uint32_t size, uint32_t pitch);
> };
>
> struct nouveau_fifo_engine {
> @@ -328,6 +333,9 @@ struct nouveau_pgraph_engine {
> void (*destroy_context)(struct nouveau_channel *);
> int (*load_context)(struct nouveau_channel *);
> int (*unload_context)(struct drm_device *);
> +
> + void (*set_region_tiling)(struct drm_device *dev, int i,
> uint32_t addr,
> + uint32_t size, uint32_t pitch);
> };
>
> struct nouveau_engine {
> @@ -876,10 +884,16 @@ extern void nv04_fb_takedown(struct drm_device
> *); /* nv10_fb.c */
> extern int nv10_fb_init(struct drm_device *);
> extern void nv10_fb_takedown(struct drm_device *);
> +extern void nv10_fb_set_region_tiling(struct drm_device *dev, int i,
> + uint32_t addr, uint32_t size,
> + uint32_t pitch);
>
> /* nv40_fb.c */
> extern int nv40_fb_init(struct drm_device *);
> extern void nv40_fb_takedown(struct drm_device *);
> +extern void nv40_fb_set_region_tiling(struct drm_device *dev, int i,
> + uint32_t addr, uint32_t size,
> + uint32_t pitch);
>
> /* nv04_fifo.c */
> extern int nv04_fifo_init(struct drm_device *);
> @@ -938,6 +952,9 @@ extern void nv10_graph_destroy_context(struct
> nouveau_channel *); extern int nv10_graph_load_context(struct
> nouveau_channel *); extern int nv10_graph_unload_context(struct
> drm_device *); extern void nv10_graph_context_switch(struct
> drm_device *); +extern void nv10_graph_set_region_tiling(struct
> drm_device *dev, int i,
> + uint32_t addr, uint32_t
> size,
> + uint32_t pitch);
>
> /* nv20_graph.c */
> extern struct nouveau_pgraph_object_class nv20_graph_grclass[];
> @@ -949,6 +966,9 @@ extern int nv20_graph_unload_context(struct
> drm_device *); extern int nv20_graph_init(struct drm_device *);
> extern void nv20_graph_takedown(struct drm_device *);
> extern int nv30_graph_init(struct drm_device *);
> +extern void nv20_graph_set_region_tiling(struct drm_device *dev, int
> i,
> + uint32_t addr, uint32_t
> size,
> + uint32_t pitch);
>
> /* nv40_graph.c */
> extern struct nouveau_pgraph_object_class nv40_graph_grclass[];
> @@ -962,6 +982,9 @@ extern int nv40_graph_unload_context(struct
> drm_device *); extern int nv40_grctx_init(struct drm_device *);
> extern void nv40_grctx_fini(struct drm_device *);
> extern void nv40_grctx_vals_load(struct drm_device *, struct
> nouveau_gpuobj *); +extern void nv40_graph_set_region_tiling(struct
> drm_device *dev, int i,
> + uint32_t addr, uint32_t
> size,
> + uint32_t pitch);
>
> /* nv50_graph.c */
> extern struct nouveau_pgraph_object_class nv50_graph_grclass[];
> diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h
> b/drivers/gpu/drm/nouveau/nouveau_reg.h index fa1b0e7..251f1b3 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_reg.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
> @@ -349,19 +349,19 @@
> #define NV04_PGRAPH_BLEND 0x00400824
> #define NV04_PGRAPH_STORED_FMT 0x00400830
> #define NV04_PGRAPH_PATT_COLORRAM 0x00400900
> -#define NV40_PGRAPH_TILE0(i)
> (0x00400900 + (i*16)) -#define
> NV40_PGRAPH_TLIMIT0(i) (0x00400904 +
> (i*16)) -#define NV40_PGRAPH_TSIZE0(i)
> (0x00400908 + (i*16)) -#define
> NV40_PGRAPH_TSTATUS0(i) (0x0040090C +
> (i*16)) +#define NV20_PGRAPH_TILE(i)
> (0x00400900 + (i*16)) +#define
> NV20_PGRAPH_TLIMIT(i) (0x00400904 +
> (i*16)) +#define NV20_PGRAPH_TSIZE(i)
> (0x00400908 + (i*16)) +#define
> NV20_PGRAPH_TSTATUS(i) (0x0040090C +
> (i*16)) #define NV10_PGRAPH_TILE(i)
> (0x00400B00 + (i*16)) #define
> NV10_PGRAPH_TLIMIT(i) (0x00400B04 +
> (i*16)) #define NV10_PGRAPH_TSIZE(i)
> (0x00400B08 + (i*16)) #define
> NV10_PGRAPH_TSTATUS(i) (0x00400B0C +
> (i*16)) #define NV04_PGRAPH_U_RAM
> 0x00400D00 -#define
> NV47_PGRAPH_TILE0(i) (0x00400D00 +
> (i*16)) -#define NV47_PGRAPH_TLIMIT0(i)
> (0x00400D04 + (i*16)) -#define
> NV47_PGRAPH_TSIZE0(i) (0x00400D08 +
> (i*16)) -#define NV47_PGRAPH_TSTATUS0(i)
> (0x00400D0C + (i*16)) +#define
> NV47_PGRAPH_TILE(i) (0x00400D00 +
> (i*16)) +#define NV47_PGRAPH_TLIMIT(i)
> (0x00400D04 + (i*16)) +#define
> NV47_PGRAPH_TSIZE(i) (0x00400D08 +
> (i*16)) +#define NV47_PGRAPH_TSTATUS(i)
> (0x00400D0C + (i*16)) #define
> NV04_PGRAPH_V_RAM 0x00400D40 #define
> NV04_PGRAPH_W_RAM 0x00400D80 #define
> NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 diff
> --git a/drivers/gpu/drm/nouveau/nouveau_state.c
> b/drivers/gpu/drm/nouveau/nouveau_state.c index 2ed41d3..4342867
> 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++
> b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -100,6 +100,7 @@ static
> int nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->timer.takedown = nv04_timer_takedown;
> engine->fb.init = nv10_fb_init;
> engine->fb.takedown = nv10_fb_takedown;
> + engine->fb.set_region_tiling =
> nv10_fb_set_region_tiling; engine->graph.grclass =
> nv10_graph_grclass; engine->graph.init =
> nv10_graph_init; engine->graph.takedown =
> nv10_graph_takedown; @@ -109,6 +110,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->graph.fifo_access = nv04_graph_fifo_access;
> engine->graph.load_context = nv10_graph_load_context;
> engine->graph.unload_context = nv10_graph_unload_context;
> + engine->graph.set_region_tiling =
> nv10_graph_set_region_tiling; engine->fifo.channels =
> 32; engine->fifo.init = nv10_fifo_init;
> engine->fifo.takedown =
> nouveau_stub_takedown; @@ -139,6 +141,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->timer.takedown = nv04_timer_takedown;
> engine->fb.init = nv10_fb_init;
> engine->fb.takedown = nv10_fb_takedown;
> + engine->fb.set_region_tiling =
> nv10_fb_set_region_tiling; engine->graph.grclass =
> nv20_graph_grclass; engine->graph.init =
> nv20_graph_init; engine->graph.takedown =
> nv20_graph_takedown; @@ -148,6 +151,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->graph.fifo_access = nv04_graph_fifo_access;
> engine->graph.load_context = nv20_graph_load_context;
> engine->graph.unload_context = nv20_graph_unload_context;
> + engine->graph.set_region_tiling =
> nv20_graph_set_region_tiling; engine->fifo.channels =
> 32; engine->fifo.init = nv10_fifo_init;
> engine->fifo.takedown =
> nouveau_stub_takedown; @@ -178,6 +182,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->timer.takedown = nv04_timer_takedown;
> engine->fb.init = nv10_fb_init;
> engine->fb.takedown = nv10_fb_takedown;
> + engine->fb.set_region_tiling =
> nv10_fb_set_region_tiling; engine->graph.grclass =
> nv30_graph_grclass; engine->graph.init =
> nv30_graph_init; engine->graph.takedown =
> nv20_graph_takedown; @@ -187,6 +192,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->graph.destroy_context = nv20_graph_destroy_context;
> engine->graph.load_context = nv20_graph_load_context;
> engine->graph.unload_context = nv20_graph_unload_context;
> + engine->graph.set_region_tiling =
> nv20_graph_set_region_tiling; engine->fifo.channels =
> 32; engine->fifo.init = nv10_fifo_init;
> engine->fifo.takedown =
> nouveau_stub_takedown; @@ -218,6 +224,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->timer.takedown = nv04_timer_takedown;
> engine->fb.init = nv40_fb_init;
> engine->fb.takedown = nv40_fb_takedown;
> + engine->fb.set_region_tiling =
> nv40_fb_set_region_tiling; engine->graph.grclass =
> nv40_graph_grclass; engine->graph.init =
> nv40_graph_init; engine->graph.takedown =
> nv40_graph_takedown; @@ -227,6 +234,7 @@ static int
> nouveau_init_engine_ptrs(struct drm_device *dev)
> engine->graph.destroy_context = nv40_graph_destroy_context;
> engine->graph.load_context = nv40_graph_load_context;
> engine->graph.unload_context = nv40_graph_unload_context;
> + engine->graph.set_region_tiling =
> nv40_graph_set_region_tiling; engine->fifo.channels =
> 32; engine->fifo.init = nv40_fifo_init;
> engine->fifo.takedown =
> nouveau_stub_takedown; diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c
> b/drivers/gpu/drm/nouveau/nv10_fb.c index 79e2d10..cc5cda4 100644
> --- a/drivers/gpu/drm/nouveau/nv10_fb.c
> +++ b/drivers/gpu/drm/nouveau/nv10_fb.c
> @@ -3,17 +3,37 @@
> #include "nouveau_drv.h"
> #include "nouveau_drm.h"
>
> +void
> +nv10_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t
> addr,
> + uint32_t size, uint32_t pitch)
> +{
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + uint32_t limit = max(1u, addr + size) - 1;
> +
> + if (pitch) {
> + if (dev_priv->card_type >= NV_20)
> + addr |= 1;
> + else
> + addr |= 1 << 31;
> + }
> +
> + nv_wr32(dev, NV10_PFB_TLIMIT(i), limit);
> + nv_wr32(dev, NV10_PFB_TSIZE(i), pitch);
> + nv_wr32(dev, NV10_PFB_TILE(i), addr);
> +}
> +
> int
> nv10_fb_init(struct drm_device *dev)
> {
> - uint32_t fb_bar_size;
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
> int i;
>
> - fb_bar_size = drm_get_resource_len(dev, 0) - 1;
> - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
> - nv_wr32(dev, NV10_PFB_TILE(i), 0);
> - nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size);
> - }
> + pfb->num_tiles = NV10_PFB_TILE__SIZE;
> +
> + /* Turn all the tiling regions off. */
> + for (i = 0; i < pfb->num_tiles; i++)
> + pfb->set_region_tiling(dev, i, 0, 0, 0);
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c
> b/drivers/gpu/drm/nouveau/nv10_graph.c index 6bf6804..2aeac8b 100644
> --- a/drivers/gpu/drm/nouveau/nv10_graph.c
> +++ b/drivers/gpu/drm/nouveau/nv10_graph.c
> @@ -808,6 +808,39 @@ void nv10_graph_destroy_context(struct
> nouveau_channel *chan) chan->pgraph_ctx = NULL;
> }
>
> +static void
> +nv10_graph_write_tile(struct drm_device *dev, int i, uint32_t addr,
> + uint32_t size, uint32_t pitch)
> +{
> + uint32_t limit = max(1u, addr + size) - 1;
> +
> + if (pitch)
> + addr |= 1 << 31;
> +
> + nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit);
> + nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch);
> + nv_wr32(dev, NV10_PGRAPH_TILE(i), addr);
> +}
> +
> +void
> +nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t
> addr,
> + uint32_t size, uint32_t pitch)
> +{
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
> + struct nouveau_pgraph_engine *pgraph =
> &dev_priv->engine.graph; +
> + pfifo->reassign(dev, false);
> + pgraph->fifo_access(dev, false);
> +
> + nouveau_wait_for_idle(dev);
> +
> + nv10_graph_write_tile(dev, i, addr, size, pitch);
> +
> + pgraph->fifo_access(dev, true);
> + pfifo->reassign(dev, true);
> +}
> +
> int nv10_graph_init(struct drm_device *dev)
> {
> struct drm_nouveau_private *dev_priv = dev->dev_private;
> @@ -836,17 +869,9 @@ int nv10_graph_init(struct drm_device *dev)
> } else
> nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
>
> - /* copy tile info from PFB */
> - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
> - nv_wr32(dev, NV10_PGRAPH_TILE(i),
> - nv_rd32(dev,
> NV10_PFB_TILE(i)));
> - nv_wr32(dev, NV10_PGRAPH_TLIMIT(i),
> - nv_rd32(dev,
> NV10_PFB_TLIMIT(i)));
> - nv_wr32(dev, NV10_PGRAPH_TSIZE(i),
> - nv_rd32(dev,
> NV10_PFB_TSIZE(i)));
> - nv_wr32(dev, NV10_PGRAPH_TSTATUS(i),
> - nv_rd32(dev,
> NV10_PFB_TSTATUS(i)));
> - }
> + /* Turn all the tiling regions off. */
> + for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
> + nv10_graph_write_tile(dev, i, 0, 0, 0);
>
> nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
> nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
> diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c
> b/drivers/gpu/drm/nouveau/nv20_graph.c index 18ba74f..55d1a8e 100644
> --- a/drivers/gpu/drm/nouveau/nv20_graph.c
> +++ b/drivers/gpu/drm/nouveau/nv20_graph.c
> @@ -514,6 +514,46 @@ nv20_graph_rdi(struct drm_device *dev)
> nouveau_wait_for_idle(dev);
> }
>
> +static void
> +nv20_graph_write_tile(struct drm_device *dev, int i, uint32_t addr,
> + uint32_t size, uint32_t pitch)
> +{
> + uint32_t limit = max(1u, addr + size) - 1;
> +
> + if (pitch)
> + addr |= 1;
> +
> + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
> + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
> + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
> +
> + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i);
> + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, limit);
> + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i);
> + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, pitch);
> + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i);
> + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, addr);
> +}
> +
> +void
> +nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t
> addr,
> + uint32_t size, uint32_t pitch)
> +{
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
> + struct nouveau_pgraph_engine *pgraph =
> &dev_priv->engine.graph; +
> + pfifo->reassign(dev, false);
> + pgraph->fifo_access(dev, false);
> +
> + nouveau_wait_for_idle(dev);
> +
> + nv20_graph_write_tile(dev, i, addr, size, pitch);
> +
> + pgraph->fifo_access(dev, true);
> + pfifo->reassign(dev, true);
> +}
> +
> int
> nv20_graph_init(struct drm_device *dev)
> {
> @@ -572,27 +612,10 @@ nv20_graph_init(struct drm_device *dev)
> nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
> }
>
> - /* copy tile info from PFB */
> - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
> - nv_wr32(dev, 0x00400904 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TLIMIT(i)));
> - /* which is NV40_PGRAPH_TLIMIT0(i) ?? */
> - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + i *
> 4);
> - nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
> - nv_rd32(dev,
> NV10_PFB_TLIMIT(i)));
> - nv_wr32(dev, 0x00400908 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TSIZE(i)));
> - /* which is NV40_PGRAPH_TSIZE0(i) ?? */
> - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + i *
> 4);
> - nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
> - nv_rd32(dev,
> NV10_PFB_TSIZE(i)));
> - nv_wr32(dev, 0x00400900 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TILE(i)));
> - /* which is NV40_PGRAPH_TILE0(i) ?? */
> - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + i *
> 4);
> - nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
> - nv_rd32(dev,
> NV10_PFB_TILE(i)));
> - }
> + /* Turn all the tiling regions off. */
> + for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
> + nv20_graph_write_tile(dev, i, 0, 0, 0);
> +
> for (i = 0; i < 8; i++) {
> nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300
> + i * 4)); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4);
> @@ -704,18 +727,9 @@ nv30_graph_init(struct drm_device *dev)
>
> nv_wr32(dev, 0x4000c0, 0x00000016);
>
> - /* copy tile info from PFB */
> - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
> - nv_wr32(dev, 0x00400904 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TLIMIT(i)));
> - /* which is NV40_PGRAPH_TLIMIT0(i) ?? */
> - nv_wr32(dev, 0x00400908 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TSIZE(i)));
> - /* which is NV40_PGRAPH_TSIZE0(i) ?? */
> - nv_wr32(dev, 0x00400900 + i * 0x10,
> - nv_rd32(dev,
> NV10_PFB_TILE(i)));
> - /* which is NV40_PGRAPH_TILE0(i) ?? */
> - }
> + /* Turn all the tiling regions off. */
> + for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
> + nv20_graph_write_tile(dev, i, 0, 0, 0);
>
> nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
> nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
> diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c
> b/drivers/gpu/drm/nouveau/nv40_fb.c index ca1d271..3cd07d8 100644
> --- a/drivers/gpu/drm/nouveau/nv40_fb.c
> +++ b/drivers/gpu/drm/nouveau/nv40_fb.c
> @@ -3,12 +3,37 @@
> #include "nouveau_drv.h"
> #include "nouveau_drm.h"
>
> +void
> +nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t
> addr,
> + uint32_t size, uint32_t pitch)
> +{
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + uint32_t limit = max(1u, addr + size) - 1;
> +
> + if (pitch)
> + addr |= 1;
> +
> + switch (dev_priv->chipset) {
> + case 0x40:
> + nv_wr32(dev, NV10_PFB_TLIMIT(i), limit);
> + nv_wr32(dev, NV10_PFB_TSIZE(i), pitch);
> + nv_wr32(dev, NV10_PFB_TILE(i), addr);
> + break;
> +
> + default:
> + nv_wr32(dev, NV40_PFB_TLIMIT(i), limit);
> + nv_wr32(dev, NV40_PFB_TSIZE(i), pitch);
> + nv_wr32(dev, NV40_PFB_TILE(i), addr);
> + break;
> + }
> +}
> +
> int
> nv40_fb_init(struct drm_device *dev)
> {
> struct drm_nouveau_private *dev_priv = dev->dev_private;
> - uint32_t fb_bar_size, tmp;
> - int num_tiles;
> + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
> + uint32_t tmp;
> int i;
>
> /* This is strictly a NV4x register (don't know about NV5x).
> */ @@ -23,35 +48,23 @@ nv40_fb_init(struct drm_device *dev)
> case 0x45:
> tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
> nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
> - num_tiles = NV10_PFB_TILE__SIZE;
> + pfb->num_tiles = NV10_PFB_TILE__SIZE;
> break;
> case 0x46: /* G72 */
> case 0x47: /* G70 */
> case 0x49: /* G71 */
> case 0x4b: /* G73 */
> case 0x4c: /* C51 (G7X version) */
> - num_tiles = NV40_PFB_TILE__SIZE_1;
> + pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
> break;
> default:
> - num_tiles = NV40_PFB_TILE__SIZE_0;
> + pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
> break;
> }
>
> - fb_bar_size = drm_get_resource_len(dev, 0) - 1;
> - switch (dev_priv->chipset) {
> - case 0x40:
> - for (i = 0; i < num_tiles; i++) {
> - nv_wr32(dev, NV10_PFB_TILE(i), 0);
> - nv_wr32(dev, NV10_PFB_TLIMIT(i),
> fb_bar_size);
> - }
> - break;
> - default:
> - for (i = 0; i < num_tiles; i++) {
> - nv_wr32(dev, NV40_PFB_TILE(i), 0);
> - nv_wr32(dev, NV40_PFB_TLIMIT(i),
> fb_bar_size);
> - }
> - break;
> - }
> + /* Turn all the tiling regions off. */
> + for (i = 0; i < pfb->num_tiles; i++)
> + pfb->set_region_tiling(dev, i, 0, 0, 0);
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c
> b/drivers/gpu/drm/nouveau/nv40_graph.c index d3e0a2a..2435d49 100644
> --- a/drivers/gpu/drm/nouveau/nv40_graph.c
> +++ b/drivers/gpu/drm/nouveau/nv40_graph.c
> @@ -333,6 +333,67 @@ nv40_grctx_vals_load(struct drm_device *dev,
> struct nouveau_gpuobj *ctx) nv_wo32(dev, ctx, cv->data[i].offset,
> cv->data[i].value); }
>
> +static void
> +nv40_graph_write_tile(struct drm_device *dev, int i, uint32_t addr,
> + uint32_t size, uint32_t pitch)
> +{
> + struct drm_nouveau_private *dev_priv = dev->dev_private;
> + uint32_t limit = max(1u, addr + size) - 1;
> +
> + if (pitch)
> + addr |= 1;
> +
> + switch (dev_priv->chipset) {
> + case 0x44:
> + case 0x4a:
> + case 0x4e:
> + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
> + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
> + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
> + break;
> +
> + case 0x46:
> + case 0x47:
> + case 0x49:
> + case 0x4b:
> + nv_wr32(dev, NV47_PGRAPH_TSIZE(i), pitch);
> + nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), limit);
> + nv_wr32(dev, NV47_PGRAPH_TILE(i), addr);
> + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch);
> + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit);
> + nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr);
> + break;
> +
> + default:
> + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
> + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
> + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
> + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch);
> + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit);
> + nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr);
> + break;
> + }
> +}
> +
Have you looked at 0xB000, 0xB004, 0xB008 by chance?
I noticed that nv uses these tiling regs (what looks like) on nv4a/nv4e (NV44 core) cards but not any others at startup. I thought is was because 0x406900 regs are missing.
+#define NV40_PFB_TILE2(i) (0x0000B000 + (i*12))
+#define NV40_PFB_TILE__SIZE_2 12
+#define NV40_PFB_TLIMIT2(i) (0x0000B004 + (i*12))
+#define NV40_PFB_TSIZE2(i) (0x0000B008 + (i*12))
More information about the Nouveau
mailing list