root/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. g84_fifo_chan_ntfy
  2. g84_fifo_chan_engine
  3. g84_fifo_chan_engine_addr
  4. g84_fifo_chan_engine_fini
  5. g84_fifo_chan_engine_init
  6. g84_fifo_chan_engine_ctor
  7. g84_fifo_chan_object_ctor
  8. g84_fifo_chan_init
  9. g84_fifo_chan_ctor

   1 /*
   2  * Copyright 2012 Red Hat Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: Ben Skeggs
  23  */
  24 #include "channv50.h"
  25 
  26 #include <core/client.h>
  27 #include <core/ramht.h>
  28 #include <subdev/mmu.h>
  29 #include <subdev/timer.h>
  30 
  31 #include <nvif/cl826e.h>
  32 
  33 static int
  34 g84_fifo_chan_ntfy(struct nvkm_fifo_chan *chan, u32 type,
  35                    struct nvkm_event **pevent)
  36 {
  37         switch (type) {
  38         case NV826E_V0_NTFY_NON_STALL_INTERRUPT:
  39                 *pevent = &chan->fifo->uevent;
  40                 return 0;
  41         default:
  42                 break;
  43         }
  44         return -EINVAL;
  45 }
  46 
  47 static int
  48 g84_fifo_chan_engine(struct nvkm_engine *engine)
  49 {
  50         switch (engine->subdev.index) {
  51         case NVKM_ENGINE_GR    : return 0;
  52         case NVKM_ENGINE_MPEG  :
  53         case NVKM_ENGINE_MSPPP : return 1;
  54         case NVKM_ENGINE_CE0   : return 2;
  55         case NVKM_ENGINE_VP    :
  56         case NVKM_ENGINE_MSPDEC: return 3;
  57         case NVKM_ENGINE_CIPHER:
  58         case NVKM_ENGINE_SEC   : return 4;
  59         case NVKM_ENGINE_BSP   :
  60         case NVKM_ENGINE_MSVLD : return 5;
  61         default:
  62                 WARN_ON(1);
  63                 return 0;
  64         }
  65 }
  66 
  67 static int
  68 g84_fifo_chan_engine_addr(struct nvkm_engine *engine)
  69 {
  70         switch (engine->subdev.index) {
  71         case NVKM_ENGINE_DMAOBJ:
  72         case NVKM_ENGINE_SW    : return -1;
  73         case NVKM_ENGINE_GR    : return 0x0020;
  74         case NVKM_ENGINE_VP    :
  75         case NVKM_ENGINE_MSPDEC: return 0x0040;
  76         case NVKM_ENGINE_MPEG  :
  77         case NVKM_ENGINE_MSPPP : return 0x0060;
  78         case NVKM_ENGINE_BSP   :
  79         case NVKM_ENGINE_MSVLD : return 0x0080;
  80         case NVKM_ENGINE_CIPHER:
  81         case NVKM_ENGINE_SEC   : return 0x00a0;
  82         case NVKM_ENGINE_CE0   : return 0x00c0;
  83         default:
  84                 WARN_ON(1);
  85                 return -1;
  86         }
  87 }
  88 
  89 static int
  90 g84_fifo_chan_engine_fini(struct nvkm_fifo_chan *base,
  91                           struct nvkm_engine *engine, bool suspend)
  92 {
  93         struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
  94         struct nv50_fifo *fifo = chan->fifo;
  95         struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  96         struct nvkm_device *device = subdev->device;
  97         u32 engn, save;
  98         int offset;
  99         bool done;
 100 
 101         offset = g84_fifo_chan_engine_addr(engine);
 102         if (offset < 0)
 103                 return 0;
 104 
 105         engn = g84_fifo_chan_engine(engine);
 106         save = nvkm_mask(device, 0x002520, 0x0000003f, 1 << engn);
 107         nvkm_wr32(device, 0x0032fc, chan->base.inst->addr >> 12);
 108         done = nvkm_msec(device, 2000,
 109                 if (nvkm_rd32(device, 0x0032fc) != 0xffffffff)
 110                         break;
 111         ) >= 0;
 112         nvkm_wr32(device, 0x002520, save);
 113         if (!done) {
 114                 nvkm_error(subdev, "channel %d [%s] unload timeout\n",
 115                            chan->base.chid, chan->base.object.client->name);
 116                 if (suspend)
 117                         return -EBUSY;
 118         }
 119 
 120         nvkm_kmap(chan->eng);
 121         nvkm_wo32(chan->eng, offset + 0x00, 0x00000000);
 122         nvkm_wo32(chan->eng, offset + 0x04, 0x00000000);
 123         nvkm_wo32(chan->eng, offset + 0x08, 0x00000000);
 124         nvkm_wo32(chan->eng, offset + 0x0c, 0x00000000);
 125         nvkm_wo32(chan->eng, offset + 0x10, 0x00000000);
 126         nvkm_wo32(chan->eng, offset + 0x14, 0x00000000);
 127         nvkm_done(chan->eng);
 128         return 0;
 129 }
 130 
 131 
 132 static int
 133 g84_fifo_chan_engine_init(struct nvkm_fifo_chan *base,
 134                           struct nvkm_engine *engine)
 135 {
 136         struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
 137         struct nvkm_gpuobj *engn = chan->engn[engine->subdev.index];
 138         u64 limit, start;
 139         int offset;
 140 
 141         offset = g84_fifo_chan_engine_addr(engine);
 142         if (offset < 0)
 143                 return 0;
 144         limit = engn->addr + engn->size - 1;
 145         start = engn->addr;
 146 
 147         nvkm_kmap(chan->eng);
 148         nvkm_wo32(chan->eng, offset + 0x00, 0x00190000);
 149         nvkm_wo32(chan->eng, offset + 0x04, lower_32_bits(limit));
 150         nvkm_wo32(chan->eng, offset + 0x08, lower_32_bits(start));
 151         nvkm_wo32(chan->eng, offset + 0x0c, upper_32_bits(limit) << 24 |
 152                                             upper_32_bits(start));
 153         nvkm_wo32(chan->eng, offset + 0x10, 0x00000000);
 154         nvkm_wo32(chan->eng, offset + 0x14, 0x00000000);
 155         nvkm_done(chan->eng);
 156         return 0;
 157 }
 158 
 159 static int
 160 g84_fifo_chan_engine_ctor(struct nvkm_fifo_chan *base,
 161                           struct nvkm_engine *engine,
 162                           struct nvkm_object *object)
 163 {
 164         struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
 165         int engn = engine->subdev.index;
 166 
 167         if (g84_fifo_chan_engine_addr(engine) < 0)
 168                 return 0;
 169 
 170         return nvkm_object_bind(object, NULL, 0, &chan->engn[engn]);
 171 }
 172 
 173 static int
 174 g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
 175                           struct nvkm_object *object)
 176 {
 177         struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
 178         u32 handle = object->handle;
 179         u32 context;
 180 
 181         switch (object->engine->subdev.index) {
 182         case NVKM_ENGINE_DMAOBJ:
 183         case NVKM_ENGINE_SW    : context = 0x00000000; break;
 184         case NVKM_ENGINE_GR    : context = 0x00100000; break;
 185         case NVKM_ENGINE_MPEG  :
 186         case NVKM_ENGINE_MSPPP : context = 0x00200000; break;
 187         case NVKM_ENGINE_ME    :
 188         case NVKM_ENGINE_CE0   : context = 0x00300000; break;
 189         case NVKM_ENGINE_VP    :
 190         case NVKM_ENGINE_MSPDEC: context = 0x00400000; break;
 191         case NVKM_ENGINE_CIPHER:
 192         case NVKM_ENGINE_SEC   :
 193         case NVKM_ENGINE_VIC   : context = 0x00500000; break;
 194         case NVKM_ENGINE_BSP   :
 195         case NVKM_ENGINE_MSVLD : context = 0x00600000; break;
 196         default:
 197                 WARN_ON(1);
 198                 return -EINVAL;
 199         }
 200 
 201         return nvkm_ramht_insert(chan->ramht, object, 0, 4, handle, context);
 202 }
 203 
 204 static void
 205 g84_fifo_chan_init(struct nvkm_fifo_chan *base)
 206 {
 207         struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
 208         struct nv50_fifo *fifo = chan->fifo;
 209         struct nvkm_device *device = fifo->base.engine.subdev.device;
 210         u64 addr = chan->ramfc->addr >> 8;
 211         u32 chid = chan->base.chid;
 212 
 213         nvkm_wr32(device, 0x002600 + (chid * 4), 0x80000000 | addr);
 214         nv50_fifo_runlist_update(fifo);
 215 }
 216 
 217 static const struct nvkm_fifo_chan_func
 218 g84_fifo_chan_func = {
 219         .dtor = nv50_fifo_chan_dtor,
 220         .init = g84_fifo_chan_init,
 221         .fini = nv50_fifo_chan_fini,
 222         .ntfy = g84_fifo_chan_ntfy,
 223         .engine_ctor = g84_fifo_chan_engine_ctor,
 224         .engine_dtor = nv50_fifo_chan_engine_dtor,
 225         .engine_init = g84_fifo_chan_engine_init,
 226         .engine_fini = g84_fifo_chan_engine_fini,
 227         .object_ctor = g84_fifo_chan_object_ctor,
 228         .object_dtor = nv50_fifo_chan_object_dtor,
 229 };
 230 
 231 int
 232 g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
 233                    const struct nvkm_oclass *oclass,
 234                    struct nv50_fifo_chan *chan)
 235 {
 236         struct nvkm_device *device = fifo->base.engine.subdev.device;
 237         int ret;
 238 
 239         if (!vmm)
 240                 return -EINVAL;
 241 
 242         ret = nvkm_fifo_chan_ctor(&g84_fifo_chan_func, &fifo->base,
 243                                   0x10000, 0x1000, false, vmm, push,
 244                                   (1ULL << NVKM_ENGINE_BSP) |
 245                                   (1ULL << NVKM_ENGINE_CE0) |
 246                                   (1ULL << NVKM_ENGINE_CIPHER) |
 247                                   (1ULL << NVKM_ENGINE_DMAOBJ) |
 248                                   (1ULL << NVKM_ENGINE_GR) |
 249                                   (1ULL << NVKM_ENGINE_ME) |
 250                                   (1ULL << NVKM_ENGINE_MPEG) |
 251                                   (1ULL << NVKM_ENGINE_MSPDEC) |
 252                                   (1ULL << NVKM_ENGINE_MSPPP) |
 253                                   (1ULL << NVKM_ENGINE_MSVLD) |
 254                                   (1ULL << NVKM_ENGINE_SEC) |
 255                                   (1ULL << NVKM_ENGINE_SW) |
 256                                   (1ULL << NVKM_ENGINE_VIC) |
 257                                   (1ULL << NVKM_ENGINE_VP),
 258                                   0, 0xc00000, 0x2000, oclass, &chan->base);
 259         chan->fifo = fifo;
 260         if (ret)
 261                 return ret;
 262 
 263         ret = nvkm_gpuobj_new(device, 0x0200, 0, true, chan->base.inst,
 264                               &chan->eng);
 265         if (ret)
 266                 return ret;
 267 
 268         ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->base.inst,
 269                               &chan->pgd);
 270         if (ret)
 271                 return ret;
 272 
 273         ret = nvkm_gpuobj_new(device, 0x1000, 0x400, true, chan->base.inst,
 274                               &chan->cache);
 275         if (ret)
 276                 return ret;
 277 
 278         ret = nvkm_gpuobj_new(device, 0x100, 0x100, true, chan->base.inst,
 279                               &chan->ramfc);
 280         if (ret)
 281                 return ret;
 282 
 283         return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht);
 284 }

/* [<][>][^][v][top][bottom][index][help] */