1 /* $NetBSD: nouveau_nvkm_subdev_bar_base.c,v 1.4 2021/12/19 11:34:45 riastradh Exp $ */ 2 3 /* 4 * Copyright 2012 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_bar_base.c,v 1.4 2021/12/19 11:34:45 riastradh Exp $"); 28 29 #include "priv.h" 30 31 void 32 nvkm_bar_flush(struct nvkm_bar *bar) 33 { 34 if (bar && bar->func->flush) 35 bar->func->flush(bar); 36 } 37 38 struct nvkm_vmm * 39 nvkm_bar_bar1_vmm(struct nvkm_device *device) 40 { 41 return device->bar->func->bar1.vmm(device->bar); 42 } 43 44 void 45 nvkm_bar_bar1_reset(struct nvkm_device *device) 46 { 47 struct nvkm_bar *bar = device->bar; 48 if (bar) { 49 bar->func->bar1.init(bar); 50 bar->func->bar1.wait(bar); 51 } 52 } 53 54 struct nvkm_vmm * 55 nvkm_bar_bar2_vmm(struct nvkm_device *device) 56 { 57 /* Denies access to BAR2 when it's not initialised, used by INSTMEM 58 * to know when object access needs to go through the BAR0 window. 59 */ 60 struct nvkm_bar *bar = device->bar; 61 if (bar && bar->bar2) 62 return bar->func->bar2.vmm(bar); 63 return NULL; 64 } 65 66 void 67 nvkm_bar_bar2_reset(struct nvkm_device *device) 68 { 69 struct nvkm_bar *bar = device->bar; 70 if (bar && bar->bar2) { 71 bar->func->bar2.init(bar); 72 bar->func->bar2.wait(bar); 73 } 74 } 75 76 void 77 nvkm_bar_bar2_fini(struct nvkm_device *device) 78 { 79 struct nvkm_bar *bar = device->bar; 80 if (bar && bar->bar2) { 81 bar->func->bar2.fini(bar); 82 bar->bar2 = false; 83 } 84 } 85 86 void 87 nvkm_bar_bar2_init(struct nvkm_device *device) 88 { 89 struct nvkm_bar *bar = device->bar; 90 if (bar && bar->subdev.oneinit && !bar->bar2 && bar->func->bar2.init) { 91 bar->func->bar2.init(bar); 92 bar->func->bar2.wait(bar); 93 bar->bar2 = true; 94 } 95 } 96 97 static int 98 nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) 99 { 100 struct nvkm_bar *bar = nvkm_bar(subdev); 101 if (bar->func->bar1.fini) 102 bar->func->bar1.fini(bar); 103 return 0; 104 } 105 106 static int 107 nvkm_bar_init(struct nvkm_subdev *subdev) 108 { 109 struct nvkm_bar *bar = nvkm_bar(subdev); 110 bar->func->bar1.init(bar); 111 bar->func->bar1.wait(bar); 112 if (bar->func->init) 113 bar->func->init(bar); 114 return 0; 115 } 116 117 static int 118 nvkm_bar_oneinit(struct nvkm_subdev *subdev) 119 { 120 struct nvkm_bar *bar = nvkm_bar(subdev); 121 return bar->func->oneinit(bar); 122 } 123 124 static void * 125 nvkm_bar_dtor(struct nvkm_subdev *subdev) 126 { 127 struct nvkm_bar *bar = nvkm_bar(subdev); 128 nvkm_bar_bar2_fini(subdev->device); 129 spin_lock_destroy(&bar->lock); 130 return bar->func->dtor(bar); 131 } 132 133 static const struct nvkm_subdev_func 134 nvkm_bar = { 135 .dtor = nvkm_bar_dtor, 136 .oneinit = nvkm_bar_oneinit, 137 .init = nvkm_bar_init, 138 .fini = nvkm_bar_fini, 139 }; 140 141 void 142 nvkm_bar_ctor(const struct nvkm_bar_func *func, struct nvkm_device *device, 143 int index, struct nvkm_bar *bar) 144 { 145 nvkm_subdev_ctor(&nvkm_bar, device, index, &bar->subdev); 146 bar->func = func; 147 spin_lock_init(&bar->lock); 148 } 149