/*
 * Copyright (C) 2007 Ben Skeggs.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef __NOUVEAU_DMA_H__
#define __NOUVEAU_DMA_H__

#ifndef NOUVEAU_DMA_DEBUG
#define NOUVEAU_DMA_DEBUG 0
#endif

void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
		   int delta, int length);

/*
 * There's a hw race condition where you can't jump to your PUT offset,
 * to avoid this we jump to offset + SKIPS and fill the difference with
 * NOPs.
 *
 * xf86-video-nv configures the DMA fetch size to 32 bytes, and uses
 * a SKIPS value of 8.  Lets assume that the race condition is to do
 * with writing into the fetch area, we configure a fetch size of 128
 * bytes so we need a larger SKIPS value.
 */
#define NOUVEAU_DMA_SKIPS (128 / 4)

/* Hardcoded object assignments to subchannels (subchannel id). */
enum {
	NvSubM2MF	= 0,
	NvSubSw		= 1,
	NvSub2D		= 2,
	NvSubCtxSurf2D  = 2,
	NvSubGdiRect    = 3,
	NvSubImageBlit  = 4
};

/* Object handles. */
enum {
	NvM2MF		= 0x80000001,
	NvDmaFB		= 0x80000002,
	NvDmaTT		= 0x80000003,
	NvDmaVRAM	= 0x80000004,
	NvDmaGART	= 0x80000005,
	NvNotify0       = 0x80000006,
	Nv2D		= 0x80000007,
	NvCtxSurf2D	= 0x80000008,
	NvRop		= 0x80000009,
	NvImagePatt	= 0x8000000a,
	NvClipRect	= 0x8000000b,
	NvGdiRect	= 0x8000000c,
	NvImageBlit	= 0x8000000d,
	NvSw		= 0x8000000e,

	/* G80+ display objects */
	NvEvoVRAM	= 0x01000000,
	NvEvoFB16	= 0x01000001,
	NvEvoFB32	= 0x01000002
};

#define NV_MEMORY_TO_MEMORY_FORMAT                                    0x00000039
#define NV_MEMORY_TO_MEMORY_FORMAT_NAME                               0x00000000
#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF                            0x00000050
#define NV_MEMORY_TO_MEMORY_FORMAT_NOP                                0x00000100
#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY                             0x00000104
#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE                 0x00000000
#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN       0x00000001
#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY                         0x00000180
#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE                         0x00000184
#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN                          0x0000030c

#define NV50_MEMORY_TO_MEMORY_FORMAT                                  0x00005039
#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200                           0x00000200
#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C                           0x0000021c
#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH                   0x00000238
#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH                  0x0000023c

static __must_check inline int
RING_SPACE(struct nouveau_channel *chan, int size)
{
	int ret;

	ret = nouveau_dma_wait(chan, 1, size);
	if (ret)
		return ret;

	chan->dma.free -= size;
	return 0;
}

static inline void
OUT_RING(struct nouveau_channel *chan, int data)
{
	if (NOUVEAU_DMA_DEBUG) {
		NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n",
			chan->id, chan->dma.cur << 2, data);
	}

	nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data);
}

extern void
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords);

static inline void
BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size)
{
	OUT_RING(chan, (subc << 13) | (size << 18) | mthd);
}

#define WRITE_PUT(val) do {                                                    \
	DRM_MEMORYBARRIER();                                                   \
	nouveau_bo_rd32(chan->pushbuf_bo, 0);                                  \
	nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base);  \
} while (0)

static inline void
FIRE_RING(struct nouveau_channel *chan)
{
	if (NOUVEAU_DMA_DEBUG) {
		NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n",
			chan->id, chan->dma.cur << 2);
	}

	if (chan->dma.cur == chan->dma.put)
		return;
	chan->accel_done = true;

	if (chan->dma.ib_max) {
		nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
			      (chan->dma.cur - chan->dma.put) << 2);
	} else {
		WRITE_PUT(chan->dma.cur);
	}

	chan->dma.put = chan->dma.cur;
}

static inline void
WIND_RING(struct nouveau_channel *chan)
{
	chan->dma.cur = chan->dma.put;
}

#endif
