Path: blob/master/drivers/gpu/drm/nouveau/nouveau_dma.h
15112 views
/*1* Copyright (C) 2007 Ben Skeggs.2* All Rights Reserved.3*4* Permission is hereby granted, free of charge, to any person obtaining5* a copy of this software and associated documentation files (the6* "Software"), to deal in the Software without restriction, including7* without limitation the rights to use, copy, modify, merge, publish,8* distribute, sublicense, and/or sell copies of the Software, and to9* permit persons to whom the Software is furnished to do so, subject to10* the following conditions:11*12* The above copyright notice and this permission notice (including the13* next paragraph) shall be included in all copies or substantial14* portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,17* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.19* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE20* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION21* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION22* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.23*24*/2526#ifndef __NOUVEAU_DMA_H__27#define __NOUVEAU_DMA_H__2829#ifndef NOUVEAU_DMA_DEBUG30#define NOUVEAU_DMA_DEBUG 031#endif3233void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,34int delta, int length);3536/*37* There's a hw race condition where you can't jump to your PUT offset,38* to avoid this we jump to offset + SKIPS and fill the difference with39* NOPs.40*41* xf86-video-nv configures the DMA fetch size to 32 bytes, and uses42* a SKIPS value of 8. Lets assume that the race condition is to do43* with writing into the fetch area, we configure a fetch size of 12844* bytes so we need a larger SKIPS value.45*/46#define NOUVEAU_DMA_SKIPS (128 / 4)4748/* Hardcoded object assignments to subchannels (subchannel id). */49enum {50NvSubM2MF = 0,51NvSubSw = 1,52NvSub2D = 2,53NvSubCtxSurf2D = 2,54NvSubGdiRect = 3,55NvSubImageBlit = 456};5758/* Object handles. */59enum {60NvM2MF = 0x80000001,61NvDmaFB = 0x80000002,62NvDmaTT = 0x80000003,63NvNotify0 = 0x80000006,64Nv2D = 0x80000007,65NvCtxSurf2D = 0x80000008,66NvRop = 0x80000009,67NvImagePatt = 0x8000000a,68NvClipRect = 0x8000000b,69NvGdiRect = 0x8000000c,70NvImageBlit = 0x8000000d,71NvSw = 0x8000000e,72NvSema = 0x8000000f,73NvEvoSema0 = 0x80000010,74NvEvoSema1 = 0x80000011,7576/* G80+ display objects */77NvEvoVRAM = 0x01000000,78NvEvoFB16 = 0x01000001,79NvEvoFB32 = 0x01000002,80NvEvoVRAM_LP = 0x01000003,81NvEvoSync = 0xcafe000082};8384#define NV_MEMORY_TO_MEMORY_FORMAT 0x0000003985#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x0000000086#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x0000005087#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x0000010088#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x0000010489#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x0000000090#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x0000000191#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x0000018092#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE 0x0000018493#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c9495#define NV50_MEMORY_TO_MEMORY_FORMAT 0x0000503996#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x0000020097#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c98#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x0000023899#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c100101static __must_check inline int102RING_SPACE(struct nouveau_channel *chan, int size)103{104int ret;105106ret = nouveau_dma_wait(chan, 1, size);107if (ret)108return ret;109110chan->dma.free -= size;111return 0;112}113114static inline void115OUT_RING(struct nouveau_channel *chan, int data)116{117if (NOUVEAU_DMA_DEBUG) {118NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n",119chan->id, chan->dma.cur << 2, data);120}121122nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data);123}124125extern void126OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords);127128static inline void129BEGIN_NVC0(struct nouveau_channel *chan, int op, int subc, int mthd, int size)130{131OUT_RING(chan, (op << 28) | (size << 16) | (subc << 13) | (mthd >> 2));132}133134static inline void135BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size)136{137OUT_RING(chan, (subc << 13) | (size << 18) | mthd);138}139140#define WRITE_PUT(val) do { \141DRM_MEMORYBARRIER(); \142nouveau_bo_rd32(chan->pushbuf_bo, 0); \143nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base); \144} while (0)145146static inline void147FIRE_RING(struct nouveau_channel *chan)148{149if (NOUVEAU_DMA_DEBUG) {150NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n",151chan->id, chan->dma.cur << 2);152}153154if (chan->dma.cur == chan->dma.put)155return;156chan->accel_done = true;157158if (chan->dma.ib_max) {159nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,160(chan->dma.cur - chan->dma.put) << 2);161} else {162WRITE_PUT(chan->dma.cur);163}164165chan->dma.put = chan->dma.cur;166}167168static inline void169WIND_RING(struct nouveau_channel *chan)170{171chan->dma.cur = chan->dma.put;172}173174#endif175176177