linux/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
<<
>>
Prefs
   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
  25#include <core/os.h>
  26#include <core/class.h>
  27#include <core/engctx.h>
  28#include <core/ramht.h>
  29
  30#include <subdev/instmem.h>
  31#include <subdev/instmem/nv04.h>
  32#include <subdev/fb.h>
  33
  34#include <engine/fifo.h>
  35
  36#include "nv04.h"
  37
  38static struct ramfc_desc
  39nv10_ramfc[] = {
  40        { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
  41        { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
  42        { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
  43        { 16,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
  44        { 16, 16, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
  45        { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_STATE },
  46        { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
  47        { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_ENGINE },
  48        { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_PULL1 },
  49        {}
  50};
  51
  52/*******************************************************************************
  53 * FIFO channel objects
  54 ******************************************************************************/
  55
  56static int
  57nv10_fifo_chan_ctor(struct nouveau_object *parent,
  58                    struct nouveau_object *engine,
  59                    struct nouveau_oclass *oclass, void *data, u32 size,
  60                    struct nouveau_object **pobject)
  61{
  62        struct nv04_fifo_priv *priv = (void *)engine;
  63        struct nv04_fifo_chan *chan;
  64        struct nv03_channel_dma_class *args = data;
  65        int ret;
  66
  67        if (size < sizeof(*args))
  68                return -EINVAL;
  69
  70        ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
  71                                          0x10000, args->pushbuf,
  72                                          (1ULL << NVDEV_ENGINE_DMAOBJ) |
  73                                          (1ULL << NVDEV_ENGINE_SW) |
  74                                          (1ULL << NVDEV_ENGINE_GR), &chan);
  75        *pobject = nv_object(chan);
  76        if (ret)
  77                return ret;
  78
  79        nv_parent(chan)->object_attach = nv04_fifo_object_attach;
  80        nv_parent(chan)->object_detach = nv04_fifo_object_detach;
  81        nv_parent(chan)->context_attach = nv04_fifo_context_attach;
  82        chan->ramfc = chan->base.chid * 32;
  83
  84        nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
  85        nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
  86        nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
  87        nv_wo32(priv->ramfc, chan->ramfc + 0x14,
  88                             NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
  89                             NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
  90#ifdef __BIG_ENDIAN
  91                             NV_PFIFO_CACHE1_BIG_ENDIAN |
  92#endif
  93                             NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
  94        return 0;
  95}
  96
  97static struct nouveau_ofuncs
  98nv10_fifo_ofuncs = {
  99        .ctor = nv10_fifo_chan_ctor,
 100        .dtor = nv04_fifo_chan_dtor,
 101        .init = nv04_fifo_chan_init,
 102        .fini = nv04_fifo_chan_fini,
 103        .rd32 = _nouveau_fifo_channel_rd32,
 104        .wr32 = _nouveau_fifo_channel_wr32,
 105};
 106
 107static struct nouveau_oclass
 108nv10_fifo_sclass[] = {
 109        { NV10_CHANNEL_DMA_CLASS, &nv10_fifo_ofuncs },
 110        {}
 111};
 112
 113/*******************************************************************************
 114 * FIFO context - basically just the instmem reserved for the channel
 115 ******************************************************************************/
 116
 117static struct nouveau_oclass
 118nv10_fifo_cclass = {
 119        .handle = NV_ENGCTX(FIFO, 0x10),
 120        .ofuncs = &(struct nouveau_ofuncs) {
 121                .ctor = nv04_fifo_context_ctor,
 122                .dtor = _nouveau_fifo_context_dtor,
 123                .init = _nouveau_fifo_context_init,
 124                .fini = _nouveau_fifo_context_fini,
 125                .rd32 = _nouveau_fifo_context_rd32,
 126                .wr32 = _nouveau_fifo_context_wr32,
 127        },
 128};
 129
 130/*******************************************************************************
 131 * PFIFO engine
 132 ******************************************************************************/
 133
 134static int
 135nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 136               struct nouveau_oclass *oclass, void *data, u32 size,
 137               struct nouveau_object **pobject)
 138{
 139        struct nv04_instmem_priv *imem = nv04_instmem(parent);
 140        struct nv04_fifo_priv *priv;
 141        int ret;
 142
 143        ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
 144        *pobject = nv_object(priv);
 145        if (ret)
 146                return ret;
 147
 148        nouveau_ramht_ref(imem->ramht, &priv->ramht);
 149        nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
 150        nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
 151
 152        nv_subdev(priv)->unit = 0x00000100;
 153        nv_subdev(priv)->intr = nv04_fifo_intr;
 154        nv_engine(priv)->cclass = &nv10_fifo_cclass;
 155        nv_engine(priv)->sclass = nv10_fifo_sclass;
 156        priv->base.pause = nv04_fifo_pause;
 157        priv->base.start = nv04_fifo_start;
 158        priv->ramfc_desc = nv10_ramfc;
 159        return 0;
 160}
 161
 162struct nouveau_oclass
 163nv10_fifo_oclass = {
 164        .handle = NV_ENGINE(FIFO, 0x10),
 165        .ofuncs = &(struct nouveau_ofuncs) {
 166                .ctor = nv10_fifo_ctor,
 167                .dtor = nv04_fifo_dtor,
 168                .init = nv04_fifo_init,
 169                .fini = _nouveau_fifo_fini,
 170        },
 171};
 172