root/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c

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

DEFINITIONS

This source file includes following definitions.
  1. gf100_bar_bar1_vmm
  2. gf100_bar_bar1_wait
  3. gf100_bar_bar1_fini
  4. gf100_bar_bar1_init
  5. gf100_bar_bar2_vmm
  6. gf100_bar_bar2_fini
  7. gf100_bar_bar2_init
  8. gf100_bar_oneinit_bar
  9. gf100_bar_oneinit
  10. gf100_bar_dtor
  11. gf100_bar_new_
  12. gf100_bar_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 #include "gf100.h"
  25 
  26 #include <core/memory.h>
  27 #include <core/option.h>
  28 #include <subdev/fb.h>
  29 #include <subdev/mmu.h>
  30 
  31 struct nvkm_vmm *
  32 gf100_bar_bar1_vmm(struct nvkm_bar *base)
  33 {
  34         return gf100_bar(base)->bar[1].vmm;
  35 }
  36 
  37 void
  38 gf100_bar_bar1_wait(struct nvkm_bar *base)
  39 {
  40         /* NFI why it's twice. */
  41         nvkm_bar_flush(base);
  42         nvkm_bar_flush(base);
  43 }
  44 
  45 void
  46 gf100_bar_bar1_fini(struct nvkm_bar *bar)
  47 {
  48         nvkm_mask(bar->subdev.device, 0x001704, 0x80000000, 0x00000000);
  49 }
  50 
  51 void
  52 gf100_bar_bar1_init(struct nvkm_bar *base)
  53 {
  54         struct nvkm_device *device = base->subdev.device;
  55         struct gf100_bar *bar = gf100_bar(base);
  56         const u32 addr = nvkm_memory_addr(bar->bar[1].inst) >> 12;
  57         nvkm_wr32(device, 0x001704, 0x80000000 | addr);
  58 }
  59 
  60 struct nvkm_vmm *
  61 gf100_bar_bar2_vmm(struct nvkm_bar *base)
  62 {
  63         return gf100_bar(base)->bar[0].vmm;
  64 }
  65 
  66 void
  67 gf100_bar_bar2_fini(struct nvkm_bar *bar)
  68 {
  69         nvkm_mask(bar->subdev.device, 0x001714, 0x80000000, 0x00000000);
  70 }
  71 
  72 void
  73 gf100_bar_bar2_init(struct nvkm_bar *base)
  74 {
  75         struct nvkm_device *device = base->subdev.device;
  76         struct gf100_bar *bar = gf100_bar(base);
  77         u32 addr = nvkm_memory_addr(bar->bar[0].inst) >> 12;
  78         if (bar->bar2_halve)
  79                 addr |= 0x40000000;
  80         nvkm_wr32(device, 0x001714, 0x80000000 | addr);
  81 }
  82 
  83 static int
  84 gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm,
  85                       struct lock_class_key *key, int bar_nr)
  86 {
  87         struct nvkm_device *device = bar->base.subdev.device;
  88         resource_size_t bar_len;
  89         int ret;
  90 
  91         ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0, false,
  92                               &bar_vm->inst);
  93         if (ret)
  94                 return ret;
  95 
  96         bar_len = device->func->resource_size(device, bar_nr);
  97         if (!bar_len)
  98                 return -ENOMEM;
  99         if (bar_nr == 3 && bar->bar2_halve)
 100                 bar_len >>= 1;
 101 
 102         ret = nvkm_vmm_new(device, 0, bar_len, NULL, 0, key,
 103                            (bar_nr == 3) ? "bar2" : "bar1", &bar_vm->vmm);
 104         if (ret)
 105                 return ret;
 106 
 107         atomic_inc(&bar_vm->vmm->engref[NVKM_SUBDEV_BAR]);
 108         bar_vm->vmm->debug = bar->base.subdev.debug;
 109 
 110         /*
 111          * Bootstrap page table lookup.
 112          */
 113         if (bar_nr == 3) {
 114                 ret = nvkm_vmm_boot(bar_vm->vmm);
 115                 if (ret)
 116                         return ret;
 117         }
 118 
 119         return nvkm_vmm_join(bar_vm->vmm, bar_vm->inst);
 120 }
 121 
 122 int
 123 gf100_bar_oneinit(struct nvkm_bar *base)
 124 {
 125         static struct lock_class_key bar1_lock;
 126         static struct lock_class_key bar2_lock;
 127         struct gf100_bar *bar = gf100_bar(base);
 128         int ret;
 129 
 130         /* BAR2 */
 131         if (bar->base.func->bar2.init) {
 132                 ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3);
 133                 if (ret)
 134                         return ret;
 135 
 136                 bar->base.subdev.oneinit = true;
 137                 nvkm_bar_bar2_init(bar->base.subdev.device);
 138         }
 139 
 140         /* BAR1 */
 141         ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, 1);
 142         if (ret)
 143                 return ret;
 144 
 145         return 0;
 146 }
 147 
 148 void *
 149 gf100_bar_dtor(struct nvkm_bar *base)
 150 {
 151         struct gf100_bar *bar = gf100_bar(base);
 152 
 153         nvkm_vmm_part(bar->bar[1].vmm, bar->bar[1].inst);
 154         nvkm_vmm_unref(&bar->bar[1].vmm);
 155         nvkm_memory_unref(&bar->bar[1].inst);
 156 
 157         nvkm_vmm_part(bar->bar[0].vmm, bar->bar[0].inst);
 158         nvkm_vmm_unref(&bar->bar[0].vmm);
 159         nvkm_memory_unref(&bar->bar[0].inst);
 160         return bar;
 161 }
 162 
 163 int
 164 gf100_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device,
 165                int index, struct nvkm_bar **pbar)
 166 {
 167         struct gf100_bar *bar;
 168         if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL)))
 169                 return -ENOMEM;
 170         nvkm_bar_ctor(func, device, index, &bar->base);
 171         bar->bar2_halve = nvkm_boolopt(device->cfgopt, "NvBar2Halve", false);
 172         *pbar = &bar->base;
 173         return 0;
 174 }
 175 
 176 static const struct nvkm_bar_func
 177 gf100_bar_func = {
 178         .dtor = gf100_bar_dtor,
 179         .oneinit = gf100_bar_oneinit,
 180         .bar1.init = gf100_bar_bar1_init,
 181         .bar1.fini = gf100_bar_bar1_fini,
 182         .bar1.wait = gf100_bar_bar1_wait,
 183         .bar1.vmm = gf100_bar_bar1_vmm,
 184         .bar2.init = gf100_bar_bar2_init,
 185         .bar2.fini = gf100_bar_bar2_fini,
 186         .bar2.wait = gf100_bar_bar1_wait,
 187         .bar2.vmm = gf100_bar_bar2_vmm,
 188         .flush = g84_bar_flush,
 189 };
 190 
 191 int
 192 gf100_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar)
 193 {
 194         return gf100_bar_new_(&gf100_bar_func, device, index, pbar);
 195 }

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