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 NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE)) 32#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) 33 34int 35nv10_fifo_channel_id(struct drm_device *dev) 36{ 37 return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & 38 NV10_PFIFO_CACHE1_PUSH1_CHID_MASK; 39} 40 41int 42nv10_fifo_create_context(struct nouveau_channel *chan) 43{ 44 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 45 struct drm_device *dev = chan->dev; 46 uint32_t fc = NV10_RAMFC(chan->id); 47 int ret; 48 49 ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, 50 NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | 51 NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc); 52 if (ret) 53 return ret; 54 55 /* Fill entries that are seen filled in dumps of nvidia driver just 56 * after channel's is put into DMA mode 57 */ 58 nv_wi32(dev, fc + 0, chan->pushbuf_base); 59 nv_wi32(dev, fc + 4, chan->pushbuf_base); 60 nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); 61 nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | 62 NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | 63 NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | 64#ifdef __BIG_ENDIAN 65 NV_PFIFO_CACHE1_BIG_ENDIAN | 66#endif 67 0); 68 69 /* enable the fifo dma operation */ 70 nv_wr32(dev, NV04_PFIFO_MODE, 71 nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); 72 return 0; 73} 74 75void 76nv10_fifo_destroy_context(struct nouveau_channel *chan) 77{ 78 struct drm_device *dev = chan->dev; 79 80 nv_wr32(dev, NV04_PFIFO_MODE, 81 nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); 82 83 nouveau_gpuobj_ref_del(dev, &chan->ramfc); 84} 85 86static void 87nv10_fifo_do_load_context(struct drm_device *dev, int chid) 88{ 89 struct drm_nouveau_private *dev_priv = dev->dev_private; 90 uint32_t fc = NV10_RAMFC(chid), tmp; 91 92 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); 93 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); 94 nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); 95 96 tmp = nv_ri32(dev, fc + 12); 97 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); 98 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); 99 100 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 16)); 101 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 20)); 102 nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 24)); 103 nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 28)); 104 105 if (dev_priv->chipset < 0x17) 106 goto out; 107 108 nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 32)); 109 tmp = nv_ri32(dev, fc + 36); 110 nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp); 111 nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 40)); 112 nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 44)); 113 nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); 114 115out: 116 nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); 117 nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); 118} 119 120int 121nv10_fifo_load_context(struct nouveau_channel *chan) 122{ 123 struct drm_device *dev = chan->dev; 124 uint32_t tmp; 125 126 nv10_fifo_do_load_context(dev, chan->id); 127 128 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 129 NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); 130 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); 131 132 /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ 133 tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); 134 nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); 135 136 return 0; 137} 138 139int 140nv10_fifo_unload_context(struct drm_device *dev) 141{ 142 struct drm_nouveau_private *dev_priv = dev->dev_private; 143 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 144 uint32_t fc, tmp; 145 int chid; 146 147 chid = pfifo->channel_id(dev); 148 if (chid < 0 || chid >= dev_priv->engine.fifo.channels) 149 return 0; 150 fc = NV10_RAMFC(chid); 151 152 nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); 153 nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); 154 nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); 155 tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF; 156 tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16); 157 nv_wi32(dev, fc + 12, tmp); 158 nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); 159 nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); 160 nv_wi32(dev, fc + 24, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); 161 nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); 162 163 if (dev_priv->chipset < 0x17) 164 goto out; 165 166 nv_wi32(dev, fc + 32, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); 167 tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); 168 nv_wi32(dev, fc + 36, tmp); 169 nv_wi32(dev, fc + 40, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); 170 nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE)); 171 nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); 172 173out: 174 nv10_fifo_do_load_context(dev, pfifo->channels - 1); 175 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); 176 return 0; 177} 178 179static void 180nv10_fifo_init_reset(struct drm_device *dev) 181{ 182 nv_wr32(dev, NV03_PMC_ENABLE, 183 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); 184 nv_wr32(dev, NV03_PMC_ENABLE, 185 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); 186 187 nv_wr32(dev, 0x003224, 0x000f0078); 188 nv_wr32(dev, 0x002044, 0x0101ffff); 189 nv_wr32(dev, 0x002040, 0x000000ff); 190 nv_wr32(dev, 0x002500, 0x00000000); 191 nv_wr32(dev, 0x003000, 0x00000000); 192 nv_wr32(dev, 0x003050, 0x00000000); 193 194 nv_wr32(dev, 0x003258, 0x00000000); 195 nv_wr32(dev, 0x003210, 0x00000000); 196 nv_wr32(dev, 0x003270, 0x00000000); 197} 198 199static void 200nv10_fifo_init_ramxx(struct drm_device *dev) 201{ 202 struct drm_nouveau_private *dev_priv = dev->dev_private; 203 204 nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | 205 ((dev_priv->ramht_bits - 9) << 16) | 206 (dev_priv->ramht_offset >> 8)); 207 nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); 208 209 if (dev_priv->chipset < 0x17) { 210 nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); 211 } else { 212 nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) | 213 (1 << 16) /* 64 Bytes entry*/); 214 } 215} 216 217static void 218nv10_fifo_init_intr(struct drm_device *dev) 219{ 220 nv_wr32(dev, 0x002100, 0xffffffff); 221 nv_wr32(dev, 0x002140, 0xffffffff); 222} 223 224int 225nv10_fifo_init(struct drm_device *dev) 226{ 227 struct drm_nouveau_private *dev_priv = dev->dev_private; 228 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 229 int i; 230 231 nv10_fifo_init_reset(dev); 232 nv10_fifo_init_ramxx(dev); 233 234 nv10_fifo_do_load_context(dev, pfifo->channels - 1); 235 nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); 236 237 nv10_fifo_init_intr(dev); 238 pfifo->enable(dev); 239 pfifo->reassign(dev, true); 240 241 for (i = 0; i < dev_priv->engine.fifo.channels; i++) { 242 if (dev_priv->fifos[i]) { 243 uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); 244 nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); 245 } 246 } 247 248 return 0; 249} 250