Commit cb00f7c1 authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs

drm/nouveau: Pre-G80 tiling support.

Signed-off-by: default avatarFrancisco Jerez <currojerez@riseup.net>
parent 588d7d12
...@@ -277,8 +277,13 @@ struct nouveau_timer_engine { ...@@ -277,8 +277,13 @@ struct nouveau_timer_engine {
}; };
struct nouveau_fb_engine { struct nouveau_fb_engine {
int num_tiles;
int (*init)(struct drm_device *dev); int (*init)(struct drm_device *dev);
void (*takedown)(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 { struct nouveau_fifo_engine {
...@@ -332,6 +337,9 @@ struct nouveau_pgraph_engine { ...@@ -332,6 +337,9 @@ struct nouveau_pgraph_engine {
void (*destroy_context)(struct nouveau_channel *); void (*destroy_context)(struct nouveau_channel *);
int (*load_context)(struct nouveau_channel *); int (*load_context)(struct nouveau_channel *);
int (*unload_context)(struct drm_device *); 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 { struct nouveau_engine {
...@@ -881,10 +889,14 @@ extern void nv04_fb_takedown(struct drm_device *); ...@@ -881,10 +889,14 @@ extern void nv04_fb_takedown(struct drm_device *);
/* nv10_fb.c */ /* nv10_fb.c */
extern int nv10_fb_init(struct drm_device *); extern int nv10_fb_init(struct drm_device *);
extern void nv10_fb_takedown(struct drm_device *); extern void nv10_fb_takedown(struct drm_device *);
extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
/* nv40_fb.c */ /* nv40_fb.c */
extern int nv40_fb_init(struct drm_device *); extern int nv40_fb_init(struct drm_device *);
extern void nv40_fb_takedown(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *);
extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
/* nv04_fifo.c */ /* nv04_fifo.c */
extern int nv04_fifo_init(struct drm_device *); extern int nv04_fifo_init(struct drm_device *);
...@@ -945,6 +957,8 @@ extern void nv10_graph_destroy_context(struct nouveau_channel *); ...@@ -945,6 +957,8 @@ extern void nv10_graph_destroy_context(struct nouveau_channel *);
extern int nv10_graph_load_context(struct nouveau_channel *); extern int nv10_graph_load_context(struct nouveau_channel *);
extern int nv10_graph_unload_context(struct drm_device *); extern int nv10_graph_unload_context(struct drm_device *);
extern void nv10_graph_context_switch(struct drm_device *); extern void nv10_graph_context_switch(struct drm_device *);
extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
/* nv20_graph.c */ /* nv20_graph.c */
extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; extern struct nouveau_pgraph_object_class nv20_graph_grclass[];
...@@ -956,6 +970,8 @@ extern int nv20_graph_unload_context(struct drm_device *); ...@@ -956,6 +970,8 @@ extern int nv20_graph_unload_context(struct drm_device *);
extern int nv20_graph_init(struct drm_device *); extern int nv20_graph_init(struct drm_device *);
extern void nv20_graph_takedown(struct drm_device *); extern void nv20_graph_takedown(struct drm_device *);
extern int nv30_graph_init(struct drm_device *); extern int nv30_graph_init(struct drm_device *);
extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
/* nv40_graph.c */ /* nv40_graph.c */
extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; extern struct nouveau_pgraph_object_class nv40_graph_grclass[];
...@@ -967,6 +983,8 @@ extern void nv40_graph_destroy_context(struct nouveau_channel *); ...@@ -967,6 +983,8 @@ extern void nv40_graph_destroy_context(struct nouveau_channel *);
extern int nv40_graph_load_context(struct nouveau_channel *); extern int nv40_graph_load_context(struct nouveau_channel *);
extern int nv40_graph_unload_context(struct drm_device *); extern int nv40_graph_unload_context(struct drm_device *);
extern void nv40_grctx_init(struct nouveau_grctx *); extern void nv40_grctx_init(struct nouveau_grctx *);
extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
/* nv50_graph.c */ /* nv50_graph.c */
extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; extern struct nouveau_pgraph_object_class nv50_graph_grclass[];
......
...@@ -349,19 +349,19 @@ ...@@ -349,19 +349,19 @@
#define NV04_PGRAPH_BLEND 0x00400824 #define NV04_PGRAPH_BLEND 0x00400824
#define NV04_PGRAPH_STORED_FMT 0x00400830 #define NV04_PGRAPH_STORED_FMT 0x00400830
#define NV04_PGRAPH_PATT_COLORRAM 0x00400900 #define NV04_PGRAPH_PATT_COLORRAM 0x00400900
#define NV40_PGRAPH_TILE0(i) (0x00400900 + (i*16)) #define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16))
#define NV40_PGRAPH_TLIMIT0(i) (0x00400904 + (i*16)) #define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16))
#define NV40_PGRAPH_TSIZE0(i) (0x00400908 + (i*16)) #define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16))
#define NV40_PGRAPH_TSTATUS0(i) (0x0040090C + (i*16)) #define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16))
#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) #define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16))
#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) #define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16))
#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) #define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16))
#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) #define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16))
#define NV04_PGRAPH_U_RAM 0x00400D00 #define NV04_PGRAPH_U_RAM 0x00400D00
#define NV47_PGRAPH_TILE0(i) (0x00400D00 + (i*16)) #define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16))
#define NV47_PGRAPH_TLIMIT0(i) (0x00400D04 + (i*16)) #define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16))
#define NV47_PGRAPH_TSIZE0(i) (0x00400D08 + (i*16)) #define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16))
#define NV47_PGRAPH_TSTATUS0(i) (0x00400D0C + (i*16)) #define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16))
#define NV04_PGRAPH_V_RAM 0x00400D40 #define NV04_PGRAPH_V_RAM 0x00400D40
#define NV04_PGRAPH_W_RAM 0x00400D80 #define NV04_PGRAPH_W_RAM 0x00400D80
#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 #define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40
......
...@@ -102,6 +102,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -102,6 +102,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nv10_fb_init; engine->fb.init = nv10_fb_init;
engine->fb.takedown = nv10_fb_takedown; engine->fb.takedown = nv10_fb_takedown;
engine->fb.set_region_tiling = nv10_fb_set_region_tiling;
engine->graph.grclass = nv10_graph_grclass; engine->graph.grclass = nv10_graph_grclass;
engine->graph.init = nv10_graph_init; engine->graph.init = nv10_graph_init;
engine->graph.takedown = nv10_graph_takedown; engine->graph.takedown = nv10_graph_takedown;
...@@ -111,6 +112,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -111,6 +112,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.fifo_access = nv04_graph_fifo_access;
engine->graph.load_context = nv10_graph_load_context; engine->graph.load_context = nv10_graph_load_context;
engine->graph.unload_context = nv10_graph_unload_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.channels = 32;
engine->fifo.init = nv10_fifo_init; engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown; engine->fifo.takedown = nouveau_stub_takedown;
...@@ -143,6 +145,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -143,6 +145,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nv10_fb_init; engine->fb.init = nv10_fb_init;
engine->fb.takedown = nv10_fb_takedown; engine->fb.takedown = nv10_fb_takedown;
engine->fb.set_region_tiling = nv10_fb_set_region_tiling;
engine->graph.grclass = nv20_graph_grclass; engine->graph.grclass = nv20_graph_grclass;
engine->graph.init = nv20_graph_init; engine->graph.init = nv20_graph_init;
engine->graph.takedown = nv20_graph_takedown; engine->graph.takedown = nv20_graph_takedown;
...@@ -152,6 +155,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -152,6 +155,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.fifo_access = nv04_graph_fifo_access;
engine->graph.load_context = nv20_graph_load_context; engine->graph.load_context = nv20_graph_load_context;
engine->graph.unload_context = nv20_graph_unload_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.channels = 32;
engine->fifo.init = nv10_fifo_init; engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown; engine->fifo.takedown = nouveau_stub_takedown;
...@@ -184,6 +188,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -184,6 +188,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nv10_fb_init; engine->fb.init = nv10_fb_init;
engine->fb.takedown = nv10_fb_takedown; engine->fb.takedown = nv10_fb_takedown;
engine->fb.set_region_tiling = nv10_fb_set_region_tiling;
engine->graph.grclass = nv30_graph_grclass; engine->graph.grclass = nv30_graph_grclass;
engine->graph.init = nv30_graph_init; engine->graph.init = nv30_graph_init;
engine->graph.takedown = nv20_graph_takedown; engine->graph.takedown = nv20_graph_takedown;
...@@ -193,6 +198,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -193,6 +198,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv20_graph_destroy_context; engine->graph.destroy_context = nv20_graph_destroy_context;
engine->graph.load_context = nv20_graph_load_context; engine->graph.load_context = nv20_graph_load_context;
engine->graph.unload_context = nv20_graph_unload_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.channels = 32;
engine->fifo.init = nv10_fifo_init; engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown; engine->fifo.takedown = nouveau_stub_takedown;
...@@ -226,6 +232,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -226,6 +232,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nv40_fb_init; engine->fb.init = nv40_fb_init;
engine->fb.takedown = nv40_fb_takedown; engine->fb.takedown = nv40_fb_takedown;
engine->fb.set_region_tiling = nv40_fb_set_region_tiling;
engine->graph.grclass = nv40_graph_grclass; engine->graph.grclass = nv40_graph_grclass;
engine->graph.init = nv40_graph_init; engine->graph.init = nv40_graph_init;
engine->graph.takedown = nv40_graph_takedown; engine->graph.takedown = nv40_graph_takedown;
...@@ -235,6 +242,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -235,6 +242,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv40_graph_destroy_context; engine->graph.destroy_context = nv40_graph_destroy_context;
engine->graph.load_context = nv40_graph_load_context; engine->graph.load_context = nv40_graph_load_context;
engine->graph.unload_context = nv40_graph_unload_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.channels = 32;
engine->fifo.init = nv40_fifo_init; engine->fifo.init = nv40_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown; engine->fifo.takedown = nouveau_stub_takedown;
......
...@@ -3,17 +3,37 @@ ...@@ -3,17 +3,37 @@
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_drm.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 int
nv10_fb_init(struct drm_device *dev) 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; int i;
fb_bar_size = drm_get_resource_len(dev, 0) - 1; pfb->num_tiles = NV10_PFB_TILE__SIZE;
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
nv_wr32(dev, NV10_PFB_TILE(i), 0); /* Turn all the tiling regions off. */
nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); for (i = 0; i < pfb->num_tiles; i++)
} pfb->set_region_tiling(dev, i, 0, 0, 0);
return 0; return 0;
} }
......
...@@ -807,6 +807,20 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan) ...@@ -807,6 +807,20 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan)
chan->pgraph_ctx = NULL; chan->pgraph_ctx = NULL;
} }
void
nv10_graph_set_region_tiling(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);
}
int nv10_graph_init(struct drm_device *dev) int nv10_graph_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
...@@ -838,17 +852,9 @@ int nv10_graph_init(struct drm_device *dev) ...@@ -838,17 +852,9 @@ int nv10_graph_init(struct drm_device *dev)
} else } else
nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
/* copy tile info from PFB */ /* Turn all the tiling regions off. */
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
nv_wr32(dev, NV10_PGRAPH_TILE(i), nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
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)));
}
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
......
...@@ -514,6 +514,27 @@ nv20_graph_rdi(struct drm_device *dev) ...@@ -514,6 +514,27 @@ nv20_graph_rdi(struct drm_device *dev)
nouveau_wait_for_idle(dev); nouveau_wait_for_idle(dev);
} }
void
nv20_graph_set_region_tiling(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);
}
int int
nv20_graph_init(struct drm_device *dev) nv20_graph_init(struct drm_device *dev)
{ {
...@@ -572,27 +593,10 @@ nv20_graph_init(struct drm_device *dev) ...@@ -572,27 +593,10 @@ nv20_graph_init(struct drm_device *dev)
nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
} }
/* copy tile info from PFB */ /* Turn all the tiling regions off. */
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
nv_wr32(dev, 0x00400904 + i * 0x10, nv20_graph_set_region_tiling(dev, i, 0, 0, 0);
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)));
}
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4));
nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4);
...@@ -704,18 +708,9 @@ nv30_graph_init(struct drm_device *dev) ...@@ -704,18 +708,9 @@ nv30_graph_init(struct drm_device *dev)
nv_wr32(dev, 0x4000c0, 0x00000016); nv_wr32(dev, 0x4000c0, 0x00000016);
/* copy tile info from PFB */ /* Turn all the tiling regions off. */
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
nv_wr32(dev, 0x00400904 + i * 0x10, nv20_graph_set_region_tiling(dev, i, 0, 0, 0);
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) ?? */
}
nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
......
...@@ -3,12 +3,37 @@ ...@@ -3,12 +3,37 @@
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_drm.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 int
nv40_fb_init(struct drm_device *dev) nv40_fb_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t fb_bar_size, tmp; struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
int num_tiles; uint32_t tmp;
int i; int i;
/* This is strictly a NV4x register (don't know about NV5x). */ /* This is strictly a NV4x register (don't know about NV5x). */
...@@ -23,35 +48,23 @@ nv40_fb_init(struct drm_device *dev) ...@@ -23,35 +48,23 @@ nv40_fb_init(struct drm_device *dev)
case 0x45: case 0x45:
tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
num_tiles = NV10_PFB_TILE__SIZE; pfb->num_tiles = NV10_PFB_TILE__SIZE;
break; break;
case 0x46: /* G72 */ case 0x46: /* G72 */
case 0x47: /* G70 */ case 0x47: /* G70 */
case 0x49: /* G71 */ case 0x49: /* G71 */
case 0x4b: /* G73 */ case 0x4b: /* G73 */
case 0x4c: /* C51 (G7X version) */ case 0x4c: /* C51 (G7X version) */
num_tiles = NV40_PFB_TILE__SIZE_1; pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
break; break;
default: default:
num_tiles = NV40_PFB_TILE__SIZE_0; pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
break; break;
} }
fb_bar_size = drm_get_resource_len(dev, 0) - 1; /* Turn all the tiling regions off. */
switch (dev_priv->chipset) { for (i = 0; i < pfb->num_tiles; i++)
case 0x40: pfb->set_region_tiling(dev, i, 0, 0, 0);
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;
}
return 0; return 0;
} }
......
...@@ -181,6 +181,48 @@ nv40_graph_unload_context(struct drm_device *dev) ...@@ -181,6 +181,48 @@ nv40_graph_unload_context(struct drm_device *dev)
return ret; return ret;
} }
void
nv40_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;
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;
}
}
/* /*
* G70 0x47 * G70 0x47
* G71 0x49 * G71 0x49
...@@ -195,7 +237,8 @@ nv40_graph_init(struct drm_device *dev) ...@@ -195,7 +237,8 @@ nv40_graph_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = struct drm_nouveau_private *dev_priv =
(struct drm_nouveau_private *)dev->dev_private; (struct drm_nouveau_private *)dev->dev_private;
uint32_t vramsz, tmp; struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
uint32_t vramsz;
int i, j; int i, j;
nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
...@@ -292,74 +335,9 @@ nv40_graph_init(struct drm_device *dev) ...@@ -292,74 +335,9 @@ nv40_graph_init(struct drm_device *dev)
nv_wr32(dev, 0x400b38, 0x2ffff800); nv_wr32(dev, 0x400b38, 0x2ffff800);
nv_wr32(dev, 0x400b3c, 0x00006000); nv_wr32(dev, 0x400b3c, 0x00006000);
/* copy tile info from PFB */ /* Turn all the tiling regions off. */
switch (dev_priv->chipset) { for (i = 0; i < pfb->num_tiles; i++)
case 0x40: /* vanilla NV40 */ nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
tmp = nv_rd32(dev, NV10_PFB_TILE(i));
nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
tmp = nv_rd32(dev, NV10_PFB_TLIMIT(i));
nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
tmp = nv_rd32(dev, NV10_PFB_TSIZE(i));
nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
tmp = nv_rd32(dev, NV10_PFB_TSTATUS(i));
nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
}
break;
case 0x44:
case 0x4a:
case 0x4e: /* NV44-based cores don't have 0x406900? */
for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) {
tmp = nv_rd32(dev, NV40_PFB_TILE(i));
nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
}
break;
case 0x46:
case 0x47:
case 0x49:
case 0x4b: /* G7X-based cores */
for (i = 0; i < NV40_PFB_TILE__SIZE_1; i++) {
tmp = nv_rd32(dev, NV40_PFB_TILE(i));
nv_wr32(dev, NV47_PGRAPH_TILE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
nv_wr32(dev, NV47_PGRAPH_TLIMIT0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
nv_wr32(dev, NV47_PGRAPH_TSIZE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
nv_wr32(dev, NV47_PGRAPH_TSTATUS0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
}
break;
default: /* everything else */
for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) {
tmp = nv_rd32(dev, NV40_PFB_TILE(i));
nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
}
break;
}
/* begin RAM config */ /* begin RAM config */
vramsz = drm_get_resource_len(dev, 0) - 1; vramsz = drm_get_resource_len(dev, 0) - 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment