nouveau: nuke subchan auto-assign.

It's annoying for several reasons, especially in its current form.  May
possibly be reincarnated later (DDX depends on it these days), but in
not quite the same way.
This commit is contained in:
Ben Skeggs 2007-12-19 19:40:38 +11:00
parent d67c2c1cd5
commit bf2410ca73
10 changed files with 36 additions and 76 deletions

View file

@ -54,6 +54,7 @@ struct nouveau_context {
struct nouveau_grobj *NvM2MF;
struct nouveau_grobj *Nv2D;
uint32_t next_handle;
uint32_t next_subchannel;
uint32_t next_sequence;
/* pipe_surface accel */

View file

@ -126,34 +126,6 @@ nouveau_dma_wait(struct nouveau_channel *chan, int size)
return 0;
}
#ifdef NOUVEAU_DMA_SUBCHAN_LRU
void
nouveau_dma_subc_bind(struct nouveau_grobj *grobj)
{
struct nouveau_channel_priv *nvchan = nouveau_channel(grobj->channel);
int subc = -1, i;
for (i = 0; i < 8; i++) {
if (nvchan->subchannel[i].grobj &&
nvchan->subchannel[i].grobj->bound ==
NOUVEAU_GROBJ_EXPLICIT_BIND)
continue;
if (nvchan->subchannel[i].seq < nvchan->subchannel[subc].seq)
subc = i;
}
assert(subc >= 0);
if (nvchan->subchannel[subc].grobj)
nvchan->subchannel[subc].grobj->bound = 0;
nvchan->subchannel[subc].grobj = grobj;
grobj->subc = subc;
grobj->bound = NOUVEAU_GROBJ_BOUND;
BEGIN_RING_CH(grobj->channel, grobj, 0, 1);
nouveau_dma_out (grobj->channel, grobj->handle);
}
#endif
#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF
static void
nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put)

View file

@ -94,12 +94,6 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
int push_size = size + 1;
#ifdef NOUVEAU_DMA_SUBCHAN_LRU
if (grobj->bound == NOUVEAU_GROBJ_UNBOUND)
nouveau_dma_subc_bind(grobj);
nvchan->subchannel[grobj->subc].seq = nvchan->subc_sequence++;
#endif
#ifdef NOUVEAU_DMA_TRACE
NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel,
grobj->handle, grobj->subc, method, size);
@ -128,26 +122,6 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method);
}
static inline void
nouveau_dma_bind(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
int subc)
{
struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
if (nvchan->subchannel[subc].grobj == grobj)
return;
if (nvchan->subchannel[subc].grobj)
nvchan->subchannel[subc].grobj->bound = NOUVEAU_GROBJ_UNBOUND;
nvchan->subchannel[subc].grobj = grobj;
grobj->subc = subc;
grobj->bound = NOUVEAU_GROBJ_EXPLICIT_BIND;
nouveau_dma_begin(chan, grobj, 0x0000, 1, __FUNCTION__, __LINE__);
nouveau_dma_out (chan, grobj->handle);
}
#define BIND_RING_CH(ch,gr,sc) nouveau_dma_bind((ch), (gr), (sc))
#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ )
#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data))
#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \

View file

@ -161,12 +161,6 @@ struct nouveau_channel_priv {
struct drm_nouveau_channel_alloc drm;
struct {
struct nouveau_grobj *grobj;
uint32_t seq;
} subchannel[8];
uint32_t subc_sequence;
uint32_t *pushbuf;
void *notifier_block;

View file

@ -108,8 +108,15 @@ nouveau_fence_emit(struct nouveau_fence *fence)
if (nvfence->sequence == 0xffffffff)
NOUVEAU_ERR("AII wrap unhandled\n");
BEGIN_RING_CH(&nvchan->base, nvchan->subchannel[0].grobj, 0x50, 1);
OUT_RING_CH (&nvchan->base, nvfence->sequence);
/*XXX: assumes subc 0 is populated */
if (nvchan->dma.free < 2)
WAIT_RING_CH(&nvchan->base, 2);
nvchan->dma.free -= 2;
#ifdef NOUVEAU_DMA_DEBUG
nvchan->dma.push_free += 2;
#endif
OUT_RING_CH(&nvchan->base, 0x00040050);
OUT_RING_CH(&nvchan->base, nvfence->sequence);
if (nvchan->fence_tail) {
nouveau_fence(nvchan->fence_tail)->next = fence;

View file

@ -20,7 +20,6 @@
//#define NOUVEAU_DMA_TRACE
//#define NOUVEAU_DMA_DEBUG
//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF
#define NOUVEAU_DMA_SUBCHAN_LRU
#define NOUVEAU_DMA_BARRIER
#define NOUVEAU_DMA_TIMEOUT 2000
@ -29,6 +28,10 @@
nv->pushbuf = nouveau_pipe_dma_beginp(nv->obj, (mthd), (size)); \
} while(0)
#define BEGIN_RING_GR(obj,mthd,size) do { \
nv->pushbuf = nouveau_pipe_dma_beginp(obj, (mthd), (size)); \
} while(0)
#define OUT_RING(data) do { \
(*nv->pushbuf++) = (data); \
} while(0)
@ -48,6 +51,12 @@
nouveau_pipe_dma_kickoff(nv->channel); \
} while(0)
#define BIND_RING(o,s) do { \
nv->o->subc = (s); \
BEGIN_RING(o, 0x0000, 1); \
OUT_RING (nv->o->handle); \
} while(0)
#define OUT_RELOC(bo,data,flags,vor,tor) do { \
nouveau_pushbuf_emit_reloc(nv->channel, nv->pushbuf, (void*)(bo), \
(data), (flags), (vor), (tor)); \

View file

@ -20,9 +20,18 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
struct nouveau_grobj **grobj)
{
struct nouveau_context *nv = nvws->nv;
int ret;
return nouveau_grobj_alloc(nv->channel, nv->next_handle++,
grclass, grobj);
ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++,
grclass, grobj);
if (ret)
return ret;
(*grobj)->subc = nv->next_subchannel++;
assert((*grobj)->subc <= 7);
BEGIN_RING_GR(*grobj, 0x0000, 1);
OUT_RING ((*grobj)->handle);
return 0;
}
uint32_t *
@ -34,10 +43,6 @@ nouveau_pipe_dma_beginp(struct nouveau_grobj *grobj, int mthd, int size)
if (!nvchan->pb_tail || nvchan->pb_tail->remaining < (size + 1))
nouveau_pushbuf_flush(grobj->channel);
if (grobj->bound == NOUVEAU_GROBJ_UNBOUND)
nouveau_dma_subc_bind(grobj);
nvchan->subchannel[grobj->subc].seq = nvchan->subc_sequence++;
pushbuf = nvchan->pb_tail->cur;
nvchan->pb_tail->cur += (size + 1);
nvchan->pb_tail->remaining -= (size + 1);

View file

@ -178,6 +178,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
NOUVEAU_ERR("Error creating m2mf object: %d\n", ret);
return 1;
}
BIND_RING (NvM2MF, nv->next_subchannel++);
BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
OUT_RING (nv->sync_notifier->handle);
@ -188,6 +189,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret);
return 1;
}
BIND_RING (NvCtxSurf2D, nv->next_subchannel++);
BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
OUT_RING (nv->channel->vram->handle);
OUT_RING (nv->channel->vram->handle);
@ -199,6 +201,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
NOUVEAU_ERR("Error creating blit object: %d\n", ret);
return 1;
}
BIND_RING (NvImageBlit, nv->next_subchannel++);
BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
OUT_RING (nv->sync_notifier->handle);
BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
@ -212,6 +215,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
NOUVEAU_ERR("Error creating rect object: %d\n", ret);
return 1;
}
BIND_RING (NvGdiRect, nv->next_subchannel++);
BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
OUT_RING (nv->sync_notifier->handle);
BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);

View file

@ -151,7 +151,7 @@ nouveau_surface_init_nv50(struct nouveau_context *nv)
&nv->Nv2D);
if (ret)
return ret;
BIND_RING (Nv2D, 0);
BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1);
OUT_RING (nv->sync_notifier->handle);
BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);

View file

@ -29,12 +29,6 @@ struct nouveau_grobj {
struct nouveau_channel *channel;
int grclass;
uint32_t handle;
enum {
NOUVEAU_GROBJ_UNBOUND = 0,
NOUVEAU_GROBJ_BOUND = 1,
NOUVEAU_GROBJ_EXPLICIT_BIND = 2,
} bound;
int subc;
};