1/* 2 * Copyright (C) 2007 Ben Skeggs. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27#include "drmP.h" 28#include "drm.h" 29#include "nouveau_drv.h" 30 31#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE)) 32#define NV04_RAMFC__SIZE 32 33#define NV04_RAMFC_DMA_PUT 0x00 34#define NV04_RAMFC_DMA_GET 0x04 35#define NV04_RAMFC_DMA_INSTANCE 0x08 36#define NV04_RAMFC_DMA_STATE 0x0C 37#define NV04_RAMFC_DMA_FETCH 0x10 38#define NV04_RAMFC_ENGINE 0x14 39#define NV04_RAMFC_PULL1_ENGINE 0x18 40 41#define RAMFC_WR(offset, val) nv_wo32(dev, chan->ramfc->gpuobj, \ 42 NV04_RAMFC_##offset/4, (val)) 43#define RAMFC_RD(offset) nv_ro32(dev, chan->ramfc->gpuobj, \ 44 NV04_RAMFC_##offset/4) 45 46void 47nv04_fifo_disable(struct drm_device *dev) 48{ 49 uint32_t tmp; 50 51 tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH); 52 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, tmp & ~1); 53 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0); 54 tmp = nv_rd32(dev, NV03_PFIFO_CACHE1_PULL1); 55 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, tmp & ~1); 56} 57 58void 59nv04_fifo_enable(struct drm_device *dev) 60{ 61 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1); 62 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); 63} 64 65bool 66nv04_fifo_reassign(struct drm_device *dev, bool enable) 67{ 68 uint32_t reassign = nv_rd32(dev, NV03_PFIFO_CACHES); 69 70 nv_wr32(dev, NV03_PFIFO_CACHES, enable ? 1 : 0); 71 return (reassign == 1); 72} 73 74bool 75nv04_fifo_cache_flush(struct drm_device *dev) 76{ 77 struct drm_nouveau_private *dev_priv = dev->dev_private; 78 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; 79 uint64_t start = ptimer->read(dev); 80 81 do { 82 if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) == 83 nv_rd32(dev, NV03_PFIFO_CACHE1_PUT)) 84 return true; 85 86 } while (ptimer->read(dev) - start < 100000000); 87 88 NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n"); 89 90 return false; 91} 92 93bool 94nv04_fifo_cache_pull(struct drm_device *dev, bool enable) 95{ 96 uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0); 97 98 if (enable) { 99 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1); 100 } else { 101 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1); 102 nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); 103 } 104 105 return !!(pull & 1); 106} 107 108int 109nv04_fifo_channel_id(struct drm_device *dev) 110{ 111 return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & 112 NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; 113} 114 115#ifdef __BIG_ENDIAN 116#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN 117#else 118#define DMA_FETCH_ENDIANNESS 0 119#endif 120 121int 122nv04_fifo_create_context(struct nouveau_channel *chan) 123{ 124 struct drm_device *dev = chan->dev; 125 struct drm_nouveau_private *dev_priv = dev->dev_private; 126 unsigned long flags; 127 int ret; 128 129 ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, 130 NV04_RAMFC__SIZE, 131 NVOBJ_FLAG_ZERO_ALLOC | 132 NVOBJ_FLAG_ZERO_FREE, 133 NULL, &chan->ramfc); 134 if (ret) 135 return ret; 136 137 spin_lock_irqsave(&dev_priv->context_switch_lock, flags); 138 139 /* Setup initial state */ 140 RAMFC_WR(DMA_PUT, chan->pushbuf_base); 141 RAMFC_WR(DMA_GET, chan->pushbuf_base); 142 RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); 143 RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | 144 NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | 145 NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | 146 DMA_FETCH_ENDIANNESS)); 147 148 /* enable the fifo dma operation */ 149 nv_wr32(dev, NV04_PFIFO_MODE, 150 nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); 151 152 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); 153 return 0; 154} 155 156void 157nv04_fifo_destroy_context(struct nouveau_channel *chan) 158{ 159 struct drm_device *dev = chan->dev; 160 161 nv_wr32(dev, NV04_PFIFO_MODE, 162 nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); 163 164 nouveau_gpuobj_ref_del(dev, &chan->ramfc); 165} 166 167static void 168nv04_fifo_do_load_context(struct drm_device *dev, int chid) 169{ 170 struct drm_nouveau_private *dev_priv = dev->dev_private; 171 uint32_t fc = NV04_RAMFC(chid), tmp; 172 173 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); 174 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); 175 tmp = nv_ri32(dev, fc + 8); 176 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); 177 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); 178 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 12)); 179 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 16)); 180 nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); 181 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); 182 183 nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); 184 nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); 185} 186 187int 188nv04_fifo_load_context(struct nouveau_channel *chan) 189{ 190 uint32_t tmp; 191 192 nv_wr32(chan->dev, NV03_PFIFO_CACHE1_PUSH1, 193 NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); 194 nv04_fifo_do_load_context(chan->dev, chan->id); 195 nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); 196 197 /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ 198 tmp = nv_rd32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); 199 nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); 200 201 return 0; 202} 203 204int 205nv04_fifo_unload_context(struct drm_device *dev) 206{ 207 struct drm_nouveau_private *dev_priv = dev->dev_private; 208 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 209 struct nouveau_channel *chan = NULL; 210 uint32_t tmp; 211 int chid; 212 213 chid = pfifo->channel_id(dev); 214 if (chid < 0 || chid >= dev_priv->engine.fifo.channels) 215 return 0; 216 217 chan = dev_priv->fifos[chid]; 218 if (!chan) { 219 NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); 220 return -EINVAL; 221 } 222 223 RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); 224 RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); 225 tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; 226 tmp |= nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE); 227 RAMFC_WR(DMA_INSTANCE, tmp); 228 RAMFC_WR(DMA_STATE, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); 229 RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); 230 RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); 231 RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); 232 233 nv04_fifo_do_load_context(dev, pfifo->channels - 1); 234 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); 235 return 0; 236} 237 238static void 239nv04_fifo_init_reset(struct drm_device *dev) 240{ 241 nv_wr32(dev, NV03_PMC_ENABLE, 242 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); 243 nv_wr32(dev, NV03_PMC_ENABLE, 244 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); 245 246 nv_wr32(dev, 0x003224, 0x000f0078); 247 nv_wr32(dev, 0x002044, 0x0101ffff); 248 nv_wr32(dev, 0x002040, 0x000000ff); 249 nv_wr32(dev, 0x002500, 0x00000000); 250 nv_wr32(dev, 0x003000, 0x00000000); 251 nv_wr32(dev, 0x003050, 0x00000000); 252 nv_wr32(dev, 0x003200, 0x00000000); 253 nv_wr32(dev, 0x003250, 0x00000000); 254 nv_wr32(dev, 0x003220, 0x00000000); 255 256 nv_wr32(dev, 0x003250, 0x00000000); 257 nv_wr32(dev, 0x003270, 0x00000000); 258 nv_wr32(dev, 0x003210, 0x00000000); 259} 260 261static void 262nv04_fifo_init_ramxx(struct drm_device *dev) 263{ 264 struct drm_nouveau_private *dev_priv = dev->dev_private; 265 266 nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | 267 ((dev_priv->ramht_bits - 9) << 16) | 268 (dev_priv->ramht_offset >> 8)); 269 nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); 270 nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); 271} 272 273static void 274nv04_fifo_init_intr(struct drm_device *dev) 275{ 276 nv_wr32(dev, 0x002100, 0xffffffff); 277 nv_wr32(dev, 0x002140, 0xffffffff); 278} 279 280int 281nv04_fifo_init(struct drm_device *dev) 282{ 283 struct drm_nouveau_private *dev_priv = dev->dev_private; 284 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 285 int i; 286 287 nv04_fifo_init_reset(dev); 288 nv04_fifo_init_ramxx(dev); 289 290 nv04_fifo_do_load_context(dev, pfifo->channels - 1); 291 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); 292 293 nv04_fifo_init_intr(dev); 294 pfifo->enable(dev); 295 pfifo->reassign(dev, true); 296 297 for (i = 0; i < dev_priv->engine.fifo.channels; i++) { 298 if (dev_priv->fifos[i]) { 299 uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); 300 nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); 301 } 302 } 303 304 return 0; 305} 306