linux/drivers/gpu/drm/nouveau/nvkm/core/subdev.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#include <core/subdev.h>
  25#include <core/device.h>
  26#include <core/option.h>
  27#include <subdev/mc.h>
  28
  29static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
  30
  31const char *
  32nvkm_subdev_name[NVKM_SUBDEV_NR] = {
  33        [NVKM_SUBDEV_BAR     ] = "bar",
  34        [NVKM_SUBDEV_VBIOS   ] = "bios",
  35        [NVKM_SUBDEV_BUS     ] = "bus",
  36        [NVKM_SUBDEV_CLK     ] = "clk",
  37        [NVKM_SUBDEV_DEVINIT ] = "devinit",
  38        [NVKM_SUBDEV_FB      ] = "fb",
  39        [NVKM_SUBDEV_FUSE    ] = "fuse",
  40        [NVKM_SUBDEV_GPIO    ] = "gpio",
  41        [NVKM_SUBDEV_I2C     ] = "i2c",
  42        [NVKM_SUBDEV_IBUS    ] = "priv",
  43        [NVKM_SUBDEV_ICCSENSE] = "iccsense",
  44        [NVKM_SUBDEV_INSTMEM ] = "imem",
  45        [NVKM_SUBDEV_LTC     ] = "ltc",
  46        [NVKM_SUBDEV_MC      ] = "mc",
  47        [NVKM_SUBDEV_MMU     ] = "mmu",
  48        [NVKM_SUBDEV_MXM     ] = "mxm",
  49        [NVKM_SUBDEV_PCI     ] = "pci",
  50        [NVKM_SUBDEV_PMU     ] = "pmu",
  51        [NVKM_SUBDEV_SECBOOT ] = "secboot",
  52        [NVKM_SUBDEV_THERM   ] = "therm",
  53        [NVKM_SUBDEV_TIMER   ] = "tmr",
  54        [NVKM_SUBDEV_TOP     ] = "top",
  55        [NVKM_SUBDEV_VOLT    ] = "volt",
  56        [NVKM_ENGINE_BSP     ] = "bsp",
  57        [NVKM_ENGINE_CE0     ] = "ce0",
  58        [NVKM_ENGINE_CE1     ] = "ce1",
  59        [NVKM_ENGINE_CE2     ] = "ce2",
  60        [NVKM_ENGINE_CE3     ] = "ce3",
  61        [NVKM_ENGINE_CE4     ] = "ce4",
  62        [NVKM_ENGINE_CE5     ] = "ce5",
  63        [NVKM_ENGINE_CIPHER  ] = "cipher",
  64        [NVKM_ENGINE_DISP    ] = "disp",
  65        [NVKM_ENGINE_DMAOBJ  ] = "dma",
  66        [NVKM_ENGINE_FIFO    ] = "fifo",
  67        [NVKM_ENGINE_GR      ] = "gr",
  68        [NVKM_ENGINE_IFB     ] = "ifb",
  69        [NVKM_ENGINE_ME      ] = "me",
  70        [NVKM_ENGINE_MPEG    ] = "mpeg",
  71        [NVKM_ENGINE_MSENC   ] = "msenc",
  72        [NVKM_ENGINE_MSPDEC  ] = "mspdec",
  73        [NVKM_ENGINE_MSPPP   ] = "msppp",
  74        [NVKM_ENGINE_MSVLD   ] = "msvld",
  75        [NVKM_ENGINE_NVENC0  ] = "nvenc0",
  76        [NVKM_ENGINE_NVENC1  ] = "nvenc1",
  77        [NVKM_ENGINE_NVENC2  ] = "nvenc2",
  78        [NVKM_ENGINE_NVDEC   ] = "nvdec",
  79        [NVKM_ENGINE_PM      ] = "pm",
  80        [NVKM_ENGINE_SEC     ] = "sec",
  81        [NVKM_ENGINE_SEC2    ] = "sec2",
  82        [NVKM_ENGINE_SW      ] = "sw",
  83        [NVKM_ENGINE_VIC     ] = "vic",
  84        [NVKM_ENGINE_VP      ] = "vp",
  85};
  86
  87void
  88nvkm_subdev_intr(struct nvkm_subdev *subdev)
  89{
  90        if (subdev->func->intr)
  91                subdev->func->intr(subdev);
  92}
  93
  94int
  95nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
  96{
  97        struct nvkm_device *device = subdev->device;
  98        const char *action = suspend ? "suspend" : "fini";
  99        s64 time;
 100
 101        nvkm_trace(subdev, "%s running...\n", action);
 102        time = ktime_to_us(ktime_get());
 103
 104        if (subdev->func->fini) {
 105                int ret = subdev->func->fini(subdev, suspend);
 106                if (ret) {
 107                        nvkm_error(subdev, "%s failed, %d\n", action, ret);
 108                        if (suspend)
 109                                return ret;
 110                }
 111        }
 112
 113        nvkm_mc_reset(device, subdev->index);
 114
 115        time = ktime_to_us(ktime_get()) - time;
 116        nvkm_trace(subdev, "%s completed in %lldus\n", action, time);
 117        return 0;
 118}
 119
 120int
 121nvkm_subdev_preinit(struct nvkm_subdev *subdev)
 122{
 123        s64 time;
 124
 125        nvkm_trace(subdev, "preinit running...\n");
 126        time = ktime_to_us(ktime_get());
 127
 128        if (subdev->func->preinit) {
 129                int ret = subdev->func->preinit(subdev);
 130                if (ret) {
 131                        nvkm_error(subdev, "preinit failed, %d\n", ret);
 132                        return ret;
 133                }
 134        }
 135
 136        time = ktime_to_us(ktime_get()) - time;
 137        nvkm_trace(subdev, "preinit completed in %lldus\n", time);
 138        return 0;
 139}
 140
 141int
 142nvkm_subdev_init(struct nvkm_subdev *subdev)
 143{
 144        s64 time;
 145        int ret;
 146
 147        nvkm_trace(subdev, "init running...\n");
 148        time = ktime_to_us(ktime_get());
 149
 150        if (subdev->func->oneinit && !subdev->oneinit) {
 151                s64 time;
 152                nvkm_trace(subdev, "one-time init running...\n");
 153                time = ktime_to_us(ktime_get());
 154                ret = subdev->func->oneinit(subdev);
 155                if (ret) {
 156                        nvkm_error(subdev, "one-time init failed, %d\n", ret);
 157                        return ret;
 158                }
 159
 160                subdev->oneinit = true;
 161                time = ktime_to_us(ktime_get()) - time;
 162                nvkm_trace(subdev, "one-time init completed in %lldus\n", time);
 163        }
 164
 165        if (subdev->func->init) {
 166                ret = subdev->func->init(subdev);
 167                if (ret) {
 168                        nvkm_error(subdev, "init failed, %d\n", ret);
 169                        return ret;
 170                }
 171        }
 172
 173        time = ktime_to_us(ktime_get()) - time;
 174        nvkm_trace(subdev, "init completed in %lldus\n", time);
 175        return 0;
 176}
 177
 178void
 179nvkm_subdev_del(struct nvkm_subdev **psubdev)
 180{
 181        struct nvkm_subdev *subdev = *psubdev;
 182        s64 time;
 183
 184        if (subdev && !WARN_ON(!subdev->func)) {
 185                nvkm_trace(subdev, "destroy running...\n");
 186                time = ktime_to_us(ktime_get());
 187                if (subdev->func->dtor)
 188                        *psubdev = subdev->func->dtor(subdev);
 189                time = ktime_to_us(ktime_get()) - time;
 190                nvkm_trace(subdev, "destroy completed in %lldus\n", time);
 191                kfree(*psubdev);
 192                *psubdev = NULL;
 193        }
 194}
 195
 196void
 197nvkm_subdev_ctor(const struct nvkm_subdev_func *func,
 198                 struct nvkm_device *device, int index,
 199                 struct nvkm_subdev *subdev)
 200{
 201        const char *name = nvkm_subdev_name[index];
 202        subdev->func = func;
 203        subdev->device = device;
 204        subdev->index = index;
 205
 206        __mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]);
 207        subdev->debug = nvkm_dbgopt(device->dbgopt, name);
 208}
 209