root/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c

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

DEFINITIONS

This source file includes following definitions.
  1. nv04_instobj_wr32
  2. nv04_instobj_rd32
  3. nv04_instobj_release
  4. nv04_instobj_acquire
  5. nv04_instobj_size
  6. nv04_instobj_addr
  7. nv04_instobj_target
  8. nv04_instobj_dtor
  9. nv04_instobj_new
  10. nv04_instmem_rd32
  11. nv04_instmem_wr32
  12. nv04_instmem_oneinit
  13. nv04_instmem_dtor
  14. nv04_instmem_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 nv04_instmem(p) container_of((p), struct nv04_instmem, base)
  25 #include "priv.h"
  26 
  27 #include <core/ramht.h>
  28 
  29 struct nv04_instmem {
  30         struct nvkm_instmem base;
  31         struct nvkm_mm heap;
  32 };
  33 
  34 /******************************************************************************
  35  * instmem object implementation
  36  *****************************************************************************/
  37 #define nv04_instobj(p) container_of((p), struct nv04_instobj, base.memory)
  38 
  39 struct nv04_instobj {
  40         struct nvkm_instobj base;
  41         struct nv04_instmem *imem;
  42         struct nvkm_mm_node *node;
  43 };
  44 
  45 static void
  46 nv04_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
  47 {
  48         struct nv04_instobj *iobj = nv04_instobj(memory);
  49         struct nvkm_device *device = iobj->imem->base.subdev.device;
  50         nvkm_wr32(device, 0x700000 + iobj->node->offset + offset, data);
  51 }
  52 
  53 static u32
  54 nv04_instobj_rd32(struct nvkm_memory *memory, u64 offset)
  55 {
  56         struct nv04_instobj *iobj = nv04_instobj(memory);
  57         struct nvkm_device *device = iobj->imem->base.subdev.device;
  58         return nvkm_rd32(device, 0x700000 + iobj->node->offset + offset);
  59 }
  60 
  61 static const struct nvkm_memory_ptrs
  62 nv04_instobj_ptrs = {
  63         .rd32 = nv04_instobj_rd32,
  64         .wr32 = nv04_instobj_wr32,
  65 };
  66 
  67 static void
  68 nv04_instobj_release(struct nvkm_memory *memory)
  69 {
  70 }
  71 
  72 static void __iomem *
  73 nv04_instobj_acquire(struct nvkm_memory *memory)
  74 {
  75         struct nv04_instobj *iobj = nv04_instobj(memory);
  76         struct nvkm_device *device = iobj->imem->base.subdev.device;
  77         return device->pri + 0x700000 + iobj->node->offset;
  78 }
  79 
  80 static u64
  81 nv04_instobj_size(struct nvkm_memory *memory)
  82 {
  83         return nv04_instobj(memory)->node->length;
  84 }
  85 
  86 static u64
  87 nv04_instobj_addr(struct nvkm_memory *memory)
  88 {
  89         return nv04_instobj(memory)->node->offset;
  90 }
  91 
  92 static enum nvkm_memory_target
  93 nv04_instobj_target(struct nvkm_memory *memory)
  94 {
  95         return NVKM_MEM_TARGET_INST;
  96 }
  97 
  98 static void *
  99 nv04_instobj_dtor(struct nvkm_memory *memory)
 100 {
 101         struct nv04_instobj *iobj = nv04_instobj(memory);
 102         mutex_lock(&iobj->imem->base.subdev.mutex);
 103         nvkm_mm_free(&iobj->imem->heap, &iobj->node);
 104         mutex_unlock(&iobj->imem->base.subdev.mutex);
 105         nvkm_instobj_dtor(&iobj->imem->base, &iobj->base);
 106         return iobj;
 107 }
 108 
 109 static const struct nvkm_memory_func
 110 nv04_instobj_func = {
 111         .dtor = nv04_instobj_dtor,
 112         .target = nv04_instobj_target,
 113         .size = nv04_instobj_size,
 114         .addr = nv04_instobj_addr,
 115         .acquire = nv04_instobj_acquire,
 116         .release = nv04_instobj_release,
 117 };
 118 
 119 static int
 120 nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
 121                  struct nvkm_memory **pmemory)
 122 {
 123         struct nv04_instmem *imem = nv04_instmem(base);
 124         struct nv04_instobj *iobj;
 125         int ret;
 126 
 127         if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
 128                 return -ENOMEM;
 129         *pmemory = &iobj->base.memory;
 130 
 131         nvkm_instobj_ctor(&nv04_instobj_func, &imem->base, &iobj->base);
 132         iobj->base.memory.ptrs = &nv04_instobj_ptrs;
 133         iobj->imem = imem;
 134 
 135         mutex_lock(&imem->base.subdev.mutex);
 136         ret = nvkm_mm_head(&imem->heap, 0, 1, size, size,
 137                            align ? align : 1, &iobj->node);
 138         mutex_unlock(&imem->base.subdev.mutex);
 139         return ret;
 140 }
 141 
 142 /******************************************************************************
 143  * instmem subdev implementation
 144  *****************************************************************************/
 145 
 146 static u32
 147 nv04_instmem_rd32(struct nvkm_instmem *imem, u32 addr)
 148 {
 149         return nvkm_rd32(imem->subdev.device, 0x700000 + addr);
 150 }
 151 
 152 static void
 153 nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
 154 {
 155         nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
 156 }
 157 
 158 static int
 159 nv04_instmem_oneinit(struct nvkm_instmem *base)
 160 {
 161         struct nv04_instmem *imem = nv04_instmem(base);
 162         struct nvkm_device *device = imem->base.subdev.device;
 163         int ret;
 164 
 165         /* PRAMIN aperture maps over the end of VRAM, reserve it */
 166         imem->base.reserved = 512 * 1024;
 167 
 168         ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1);
 169         if (ret)
 170                 return ret;
 171 
 172         /* 0x00000-0x10000: reserve for probable vbios image */
 173         ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x10000, 0, false,
 174                               &imem->base.vbios);
 175         if (ret)
 176                 return ret;
 177 
 178         /* 0x10000-0x18000: reserve for RAMHT */
 179         ret = nvkm_ramht_new(device, 0x08000, 0, NULL, &imem->base.ramht);
 180         if (ret)
 181                 return ret;
 182 
 183         /* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
 184         ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x00800, 0, true,
 185                               &imem->base.ramfc);
 186         if (ret)
 187                 return ret;
 188 
 189         /* 0x18800-0x18a00: reserve for RAMRO */
 190         ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x00200, 0, false,
 191                               &imem->base.ramro);
 192         if (ret)
 193                 return ret;
 194 
 195         return 0;
 196 }
 197 
 198 static void *
 199 nv04_instmem_dtor(struct nvkm_instmem *base)
 200 {
 201         struct nv04_instmem *imem = nv04_instmem(base);
 202         nvkm_memory_unref(&imem->base.ramfc);
 203         nvkm_memory_unref(&imem->base.ramro);
 204         nvkm_ramht_del(&imem->base.ramht);
 205         nvkm_memory_unref(&imem->base.vbios);
 206         nvkm_mm_fini(&imem->heap);
 207         return imem;
 208 }
 209 
 210 static const struct nvkm_instmem_func
 211 nv04_instmem = {
 212         .dtor = nv04_instmem_dtor,
 213         .oneinit = nv04_instmem_oneinit,
 214         .rd32 = nv04_instmem_rd32,
 215         .wr32 = nv04_instmem_wr32,
 216         .memory_new = nv04_instobj_new,
 217         .zero = false,
 218 };
 219 
 220 int
 221 nv04_instmem_new(struct nvkm_device *device, int index,
 222                  struct nvkm_instmem **pimem)
 223 {
 224         struct nv04_instmem *imem;
 225 
 226         if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
 227                 return -ENOMEM;
 228         nvkm_instmem_ctor(&nv04_instmem, device, index, &imem->base);
 229         *pimem = &imem->base;
 230         return 0;
 231 }

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