Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012 Red Hat Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Ben Skeggs
0023  */
0024 #include "priv.h"
0025 
0026 void
0027 nvkm_bar_flush(struct nvkm_bar *bar)
0028 {
0029     if (bar && bar->func->flush)
0030         bar->func->flush(bar);
0031 }
0032 
0033 struct nvkm_vmm *
0034 nvkm_bar_bar1_vmm(struct nvkm_device *device)
0035 {
0036     return device->bar->func->bar1.vmm(device->bar);
0037 }
0038 
0039 void
0040 nvkm_bar_bar1_reset(struct nvkm_device *device)
0041 {
0042     struct nvkm_bar *bar = device->bar;
0043     if (bar) {
0044         bar->func->bar1.init(bar);
0045         bar->func->bar1.wait(bar);
0046     }
0047 }
0048 
0049 struct nvkm_vmm *
0050 nvkm_bar_bar2_vmm(struct nvkm_device *device)
0051 {
0052     /* Denies access to BAR2 when it's not initialised, used by INSTMEM
0053      * to know when object access needs to go through the BAR0 window.
0054      */
0055     struct nvkm_bar *bar = device->bar;
0056     if (bar && bar->bar2)
0057         return bar->func->bar2.vmm(bar);
0058     return NULL;
0059 }
0060 
0061 void
0062 nvkm_bar_bar2_reset(struct nvkm_device *device)
0063 {
0064     struct nvkm_bar *bar = device->bar;
0065     if (bar && bar->bar2) {
0066         bar->func->bar2.init(bar);
0067         bar->func->bar2.wait(bar);
0068     }
0069 }
0070 
0071 void
0072 nvkm_bar_bar2_fini(struct nvkm_device *device)
0073 {
0074     struct nvkm_bar *bar = device->bar;
0075     if (bar && bar->bar2) {
0076         bar->func->bar2.fini(bar);
0077         bar->bar2 = false;
0078     }
0079 }
0080 
0081 void
0082 nvkm_bar_bar2_init(struct nvkm_device *device)
0083 {
0084     struct nvkm_bar *bar = device->bar;
0085     if (bar && bar->subdev.oneinit && !bar->bar2 && bar->func->bar2.init) {
0086         bar->func->bar2.init(bar);
0087         bar->func->bar2.wait(bar);
0088         bar->bar2 = true;
0089     }
0090 }
0091 
0092 static int
0093 nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
0094 {
0095     struct nvkm_bar *bar = nvkm_bar(subdev);
0096     if (bar->func->bar1.fini)
0097         bar->func->bar1.fini(bar);
0098     return 0;
0099 }
0100 
0101 static int
0102 nvkm_bar_init(struct nvkm_subdev *subdev)
0103 {
0104     struct nvkm_bar *bar = nvkm_bar(subdev);
0105     bar->func->bar1.init(bar);
0106     bar->func->bar1.wait(bar);
0107     if (bar->func->init)
0108         bar->func->init(bar);
0109     return 0;
0110 }
0111 
0112 static int
0113 nvkm_bar_oneinit(struct nvkm_subdev *subdev)
0114 {
0115     struct nvkm_bar *bar = nvkm_bar(subdev);
0116     return bar->func->oneinit(bar);
0117 }
0118 
0119 static void *
0120 nvkm_bar_dtor(struct nvkm_subdev *subdev)
0121 {
0122     struct nvkm_bar *bar = nvkm_bar(subdev);
0123     nvkm_bar_bar2_fini(subdev->device);
0124     return bar->func->dtor(bar);
0125 }
0126 
0127 static const struct nvkm_subdev_func
0128 nvkm_bar = {
0129     .dtor = nvkm_bar_dtor,
0130     .oneinit = nvkm_bar_oneinit,
0131     .init = nvkm_bar_init,
0132     .fini = nvkm_bar_fini,
0133 };
0134 
0135 void
0136 nvkm_bar_ctor(const struct nvkm_bar_func *func, struct nvkm_device *device,
0137           enum nvkm_subdev_type type, int inst, struct nvkm_bar *bar)
0138 {
0139     nvkm_subdev_ctor(&nvkm_bar, device, type, inst, &bar->subdev);
0140     bar->func = func;
0141     spin_lock_init(&bar->lock);
0142 }