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