root/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c

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

DEFINITIONS

This source file includes following definitions.
  1. nv44_mpeg_chan_bind
  2. nv44_mpeg_chan_fini
  3. nv44_mpeg_chan_dtor
  4. nv44_mpeg_chan_new
  5. nv44_mpeg_mthd
  6. nv44_mpeg_intr
  7. nv44_mpeg_new

   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 #define nv44_mpeg(p) container_of((p), struct nv44_mpeg, engine)
  25 #include "priv.h"
  26 
  27 #include <core/client.h>
  28 #include <core/gpuobj.h>
  29 #include <engine/fifo.h>
  30 
  31 #include <nvif/class.h>
  32 
  33 struct nv44_mpeg {
  34         struct nvkm_engine engine;
  35         struct list_head chan;
  36 };
  37 
  38 /*******************************************************************************
  39  * PMPEG context
  40  ******************************************************************************/
  41 #define nv44_mpeg_chan(p) container_of((p), struct nv44_mpeg_chan, object)
  42 
  43 struct nv44_mpeg_chan {
  44         struct nvkm_object object;
  45         struct nv44_mpeg *mpeg;
  46         struct nvkm_fifo_chan *fifo;
  47         struct list_head head;
  48         u32 inst;
  49 };
  50 
  51 static int
  52 nv44_mpeg_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent,
  53                     int align, struct nvkm_gpuobj **pgpuobj)
  54 {
  55         struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
  56         int ret = nvkm_gpuobj_new(chan->object.engine->subdev.device, 264 * 4,
  57                                   align, true, parent, pgpuobj);
  58         if (ret == 0) {
  59                 chan->inst = (*pgpuobj)->addr;
  60                 nvkm_kmap(*pgpuobj);
  61                 nvkm_wo32(*pgpuobj, 0x78, 0x02001ec1);
  62                 nvkm_done(*pgpuobj);
  63         }
  64         return ret;
  65 }
  66 
  67 static int
  68 nv44_mpeg_chan_fini(struct nvkm_object *object, bool suspend)
  69 {
  70 
  71         struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
  72         struct nv44_mpeg *mpeg = chan->mpeg;
  73         struct nvkm_device *device = mpeg->engine.subdev.device;
  74         u32 inst = 0x80000000 | (chan->inst >> 4);
  75 
  76         nvkm_mask(device, 0x00b32c, 0x00000001, 0x00000000);
  77         if (nvkm_rd32(device, 0x00b318) == inst)
  78                 nvkm_mask(device, 0x00b318, 0x80000000, 0x00000000);
  79         nvkm_mask(device, 0x00b32c, 0x00000001, 0x00000001);
  80         return 0;
  81 }
  82 
  83 static void *
  84 nv44_mpeg_chan_dtor(struct nvkm_object *object)
  85 {
  86         struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
  87         struct nv44_mpeg *mpeg = chan->mpeg;
  88         unsigned long flags;
  89         spin_lock_irqsave(&mpeg->engine.lock, flags);
  90         list_del(&chan->head);
  91         spin_unlock_irqrestore(&mpeg->engine.lock, flags);
  92         return chan;
  93 }
  94 
  95 static const struct nvkm_object_func
  96 nv44_mpeg_chan = {
  97         .dtor = nv44_mpeg_chan_dtor,
  98         .fini = nv44_mpeg_chan_fini,
  99         .bind = nv44_mpeg_chan_bind,
 100 };
 101 
 102 static int
 103 nv44_mpeg_chan_new(struct nvkm_fifo_chan *fifoch,
 104                    const struct nvkm_oclass *oclass,
 105                    struct nvkm_object **pobject)
 106 {
 107         struct nv44_mpeg *mpeg = nv44_mpeg(oclass->engine);
 108         struct nv44_mpeg_chan *chan;
 109         unsigned long flags;
 110 
 111         if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
 112                 return -ENOMEM;
 113         nvkm_object_ctor(&nv44_mpeg_chan, oclass, &chan->object);
 114         chan->mpeg = mpeg;
 115         chan->fifo = fifoch;
 116         *pobject = &chan->object;
 117 
 118         spin_lock_irqsave(&mpeg->engine.lock, flags);
 119         list_add(&chan->head, &mpeg->chan);
 120         spin_unlock_irqrestore(&mpeg->engine.lock, flags);
 121         return 0;
 122 }
 123 
 124 /*******************************************************************************
 125  * PMPEG engine/subdev functions
 126  ******************************************************************************/
 127 
 128 static bool
 129 nv44_mpeg_mthd(struct nvkm_device *device, u32 mthd, u32 data)
 130 {
 131         switch (mthd) {
 132         case 0x190:
 133         case 0x1a0:
 134         case 0x1b0:
 135                 return nv40_mpeg_mthd_dma(device, mthd, data);
 136         default:
 137                 break;
 138         }
 139         return false;
 140 }
 141 
 142 static void
 143 nv44_mpeg_intr(struct nvkm_engine *engine)
 144 {
 145         struct nv44_mpeg *mpeg = nv44_mpeg(engine);
 146         struct nvkm_subdev *subdev = &mpeg->engine.subdev;
 147         struct nvkm_device *device = subdev->device;
 148         struct nv44_mpeg_chan *temp, *chan = NULL;
 149         unsigned long flags;
 150         u32 inst = nvkm_rd32(device, 0x00b318) & 0x000fffff;
 151         u32 stat = nvkm_rd32(device, 0x00b100);
 152         u32 type = nvkm_rd32(device, 0x00b230);
 153         u32 mthd = nvkm_rd32(device, 0x00b234);
 154         u32 data = nvkm_rd32(device, 0x00b238);
 155         u32 show = stat;
 156 
 157         spin_lock_irqsave(&mpeg->engine.lock, flags);
 158         list_for_each_entry(temp, &mpeg->chan, head) {
 159                 if (temp->inst >> 4 == inst) {
 160                         chan = temp;
 161                         list_del(&chan->head);
 162                         list_add(&chan->head, &mpeg->chan);
 163                         break;
 164                 }
 165         }
 166 
 167         if (stat & 0x01000000) {
 168                 /* happens on initial binding of the object */
 169                 if (type == 0x00000020 && mthd == 0x0000) {
 170                         nvkm_mask(device, 0x00b308, 0x00000000, 0x00000000);
 171                         show &= ~0x01000000;
 172                 }
 173 
 174                 if (type == 0x00000010) {
 175                         if (nv44_mpeg_mthd(subdev->device, mthd, data))
 176                                 show &= ~0x01000000;
 177                 }
 178         }
 179 
 180         nvkm_wr32(device, 0x00b100, stat);
 181         nvkm_wr32(device, 0x00b230, 0x00000001);
 182 
 183         if (show) {
 184                 nvkm_error(subdev, "ch %d [%08x %s] %08x %08x %08x %08x\n",
 185                            chan ? chan->fifo->chid : -1, inst << 4,
 186                            chan ? chan->object.client->name : "unknown",
 187                            stat, type, mthd, data);
 188         }
 189 
 190         spin_unlock_irqrestore(&mpeg->engine.lock, flags);
 191 }
 192 
 193 static const struct nvkm_engine_func
 194 nv44_mpeg = {
 195         .init = nv31_mpeg_init,
 196         .intr = nv44_mpeg_intr,
 197         .tile = nv31_mpeg_tile,
 198         .fifo.cclass = nv44_mpeg_chan_new,
 199         .sclass = {
 200                 { -1, -1, NV31_MPEG, &nv31_mpeg_object },
 201                 {}
 202         }
 203 };
 204 
 205 int
 206 nv44_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg)
 207 {
 208         struct nv44_mpeg *mpeg;
 209 
 210         if (!(mpeg = kzalloc(sizeof(*mpeg), GFP_KERNEL)))
 211                 return -ENOMEM;
 212         INIT_LIST_HEAD(&mpeg->chan);
 213         *pmpeg = &mpeg->engine;
 214 
 215         return nvkm_engine_ctor(&nv44_mpeg, device, index, true, &mpeg->engine);
 216 }

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