drm/nouveau: Allocate a per-channel instance of NV_SW.
It will be useful for various synchronization purposes, mostly stolen from "[PATCH] drm/nv50: synchronize user channel after buffer object move on kernel channel" by Maarten Maathuis. Signed-off-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
Родитель
0a2d090f99
Коммит
ca4362adb4
|
@ -414,7 +414,9 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
|
|||
init->subchan[0].grclass = 0x0039;
|
||||
else
|
||||
init->subchan[0].grclass = 0x5039;
|
||||
init->nr_subchan = 1;
|
||||
init->subchan[1].handle = NvSw;
|
||||
init->subchan[1].grclass = NV_SW;
|
||||
init->nr_subchan = 2;
|
||||
|
||||
/* Named memory object area */
|
||||
ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
|
||||
|
|
|
@ -35,6 +35,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
|
|||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_gpuobj *m2mf = NULL;
|
||||
struct nouveau_gpuobj *nvsw = NULL;
|
||||
int ret, i;
|
||||
|
||||
/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
|
||||
|
@ -47,6 +48,15 @@ nouveau_dma_init(struct nouveau_channel *chan)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Create an NV_SW object for various sync purposes */
|
||||
ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
|
||||
ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy);
|
||||
if (ret)
|
||||
|
@ -87,6 +97,13 @@ nouveau_dma_init(struct nouveau_channel *chan)
|
|||
BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
|
||||
OUT_RING(chan, NvNotify0);
|
||||
|
||||
/* Initialise NV_SW */
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
BEGIN_RING(chan, NvSubSw, 0, 1);
|
||||
OUT_RING(chan, NvSw);
|
||||
|
||||
/* Sit back and pray the channel works.. */
|
||||
FIRE_RING(chan);
|
||||
|
||||
|
|
|
@ -46,10 +46,11 @@
|
|||
/* Hardcoded object assignments to subchannels (subchannel id). */
|
||||
enum {
|
||||
NvSubM2MF = 0,
|
||||
NvSub2D = 1,
|
||||
NvSubCtxSurf2D = 1,
|
||||
NvSubGdiRect = 2,
|
||||
NvSubImageBlit = 3
|
||||
NvSubSw = 1,
|
||||
NvSub2D = 2,
|
||||
NvSubCtxSurf2D = 2,
|
||||
NvSubGdiRect = 3,
|
||||
NvSubImageBlit = 4
|
||||
};
|
||||
|
||||
/* Object handles. */
|
||||
|
@ -67,6 +68,7 @@ enum {
|
|||
NvClipRect = 0x8000000b,
|
||||
NvGdiRect = 0x8000000c,
|
||||
NvImageBlit = 0x8000000d,
|
||||
NvSw = 0x8000000e,
|
||||
|
||||
/* G80+ display objects */
|
||||
NvEvoVRAM = 0x01000000,
|
||||
|
|
|
@ -788,6 +788,8 @@ extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
|
|||
uint32_t *o_ret);
|
||||
extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
|
||||
struct nouveau_gpuobj **);
|
||||
extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class,
|
||||
struct nouveau_gpuobj **);
|
||||
extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
|
||||
struct drm_file *);
|
||||
extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
|
||||
|
@ -1330,14 +1332,14 @@ nv_two_reg_pll(struct drm_device *dev)
|
|||
return false;
|
||||
}
|
||||
|
||||
#define NV50_NVSW 0x0000506e
|
||||
#define NV50_NVSW_DMA_SEMAPHORE 0x00000060
|
||||
#define NV50_NVSW_SEMAPHORE_OFFSET 0x00000064
|
||||
#define NV50_NVSW_SEMAPHORE_ACQUIRE 0x00000068
|
||||
#define NV50_NVSW_SEMAPHORE_RELEASE 0x0000006c
|
||||
#define NV50_NVSW_DMA_VBLSEM 0x0000018c
|
||||
#define NV50_NVSW_VBLSEM_OFFSET 0x00000400
|
||||
#define NV50_NVSW_VBLSEM_RELEASE_VALUE 0x00000404
|
||||
#define NV50_NVSW_VBLSEM_RELEASE 0x00000408
|
||||
#define NV_SW 0x0000506e
|
||||
#define NV_SW_DMA_SEMAPHORE 0x00000060
|
||||
#define NV_SW_SEMAPHORE_OFFSET 0x00000064
|
||||
#define NV_SW_SEMAPHORE_ACQUIRE 0x00000068
|
||||
#define NV_SW_SEMAPHORE_RELEASE 0x0000006c
|
||||
#define NV_SW_DMA_VBLSEM 0x0000018c
|
||||
#define NV_SW_VBLSEM_OFFSET 0x00000400
|
||||
#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
|
||||
#define NV_SW_VBLSEM_RELEASE 0x00000408
|
||||
|
||||
#endif /* __NOUVEAU_DRV_H__ */
|
||||
|
|
|
@ -881,7 +881,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
|
||||
struct nouveau_gpuobj **gpuobj_ret)
|
||||
{
|
||||
|
|
|
@ -184,6 +184,7 @@ nv04_fbcon_accel_init(struct fb_info *info)
|
|||
struct drm_device *dev = par->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_channel *chan = dev_priv->channel;
|
||||
const int sub = NvSubCtxSurf2D;
|
||||
int surface_fmt, pattern_fmt, rect_fmt;
|
||||
int ret;
|
||||
|
||||
|
@ -247,25 +248,25 @@ nv04_fbcon_accel_init(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, 1, 0x0000, 1);
|
||||
BEGIN_RING(chan, sub, 0x0000, 1);
|
||||
OUT_RING(chan, NvCtxSurf2D);
|
||||
BEGIN_RING(chan, 1, 0x0184, 2);
|
||||
BEGIN_RING(chan, sub, 0x0184, 2);
|
||||
OUT_RING(chan, NvDmaFB);
|
||||
OUT_RING(chan, NvDmaFB);
|
||||
BEGIN_RING(chan, 1, 0x0300, 4);
|
||||
BEGIN_RING(chan, sub, 0x0300, 4);
|
||||
OUT_RING(chan, surface_fmt);
|
||||
OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16));
|
||||
OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
|
||||
OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
|
||||
|
||||
BEGIN_RING(chan, 1, 0x0000, 1);
|
||||
BEGIN_RING(chan, sub, 0x0000, 1);
|
||||
OUT_RING(chan, NvRop);
|
||||
BEGIN_RING(chan, 1, 0x0300, 1);
|
||||
BEGIN_RING(chan, sub, 0x0300, 1);
|
||||
OUT_RING(chan, 0x55);
|
||||
|
||||
BEGIN_RING(chan, 1, 0x0000, 1);
|
||||
BEGIN_RING(chan, sub, 0x0000, 1);
|
||||
OUT_RING(chan, NvImagePatt);
|
||||
BEGIN_RING(chan, 1, 0x0300, 8);
|
||||
BEGIN_RING(chan, sub, 0x0300, 8);
|
||||
OUT_RING(chan, pattern_fmt);
|
||||
#ifdef __BIG_ENDIAN
|
||||
OUT_RING(chan, 2);
|
||||
|
@ -279,9 +280,9 @@ nv04_fbcon_accel_init(struct fb_info *info)
|
|||
OUT_RING(chan, ~0);
|
||||
OUT_RING(chan, ~0);
|
||||
|
||||
BEGIN_RING(chan, 1, 0x0000, 1);
|
||||
BEGIN_RING(chan, sub, 0x0000, 1);
|
||||
OUT_RING(chan, NvClipRect);
|
||||
BEGIN_RING(chan, 1, 0x0300, 2);
|
||||
BEGIN_RING(chan, sub, 0x0300, 2);
|
||||
OUT_RING(chan, 0);
|
||||
OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче