1/* $NetBSD: nouveau_nvkm_subdev_ltc_base.c,v 1.3 2021/12/18 23:45:40 riastradh Exp $ */ 2 3/* 4 * Copyright 2014 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 <bskeggs@redhat.com> 25 */ 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_ltc_base.c,v 1.3 2021/12/18 23:45:40 riastradh Exp $"); 28 29#include "priv.h" 30 31#include <core/memory.h> 32 33void 34nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count) 35{ 36 struct nvkm_ltc *ltc = device->ltc; 37 const u32 limit = first + count - 1; 38 39 BUG_ON((first > limit) || (limit >= ltc->num_tags)); 40 41 mutex_lock(<c->subdev.mutex); 42 ltc->func->cbc_clear(ltc, first, limit); 43 ltc->func->cbc_wait(ltc); 44 mutex_unlock(<c->subdev.mutex); 45} 46 47int 48nvkm_ltc_zbc_color_get(struct nvkm_ltc *ltc, int index, const u32 color[4]) 49{ 50 memcpy(ltc->zbc_color[index], color, sizeof(ltc->zbc_color[index])); 51 ltc->func->zbc_clear_color(ltc, index, color); 52 return index; 53} 54 55int 56nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth) 57{ 58 ltc->zbc_depth[index] = depth; 59 ltc->func->zbc_clear_depth(ltc, index, depth); 60 return index; 61} 62 63int 64nvkm_ltc_zbc_stencil_get(struct nvkm_ltc *ltc, int index, const u32 stencil) 65{ 66 ltc->zbc_stencil[index] = stencil; 67 ltc->func->zbc_clear_stencil(ltc, index, stencil); 68 return index; 69} 70 71void 72nvkm_ltc_invalidate(struct nvkm_ltc *ltc) 73{ 74 if (ltc->func->invalidate) 75 ltc->func->invalidate(ltc); 76} 77 78void 79nvkm_ltc_flush(struct nvkm_ltc *ltc) 80{ 81 if (ltc->func->flush) 82 ltc->func->flush(ltc); 83} 84 85static void 86nvkm_ltc_intr(struct nvkm_subdev *subdev) 87{ 88 struct nvkm_ltc *ltc = nvkm_ltc(subdev); 89 ltc->func->intr(ltc); 90} 91 92static int 93nvkm_ltc_oneinit(struct nvkm_subdev *subdev) 94{ 95 struct nvkm_ltc *ltc = nvkm_ltc(subdev); 96 return ltc->func->oneinit(ltc); 97} 98 99static int 100nvkm_ltc_init(struct nvkm_subdev *subdev) 101{ 102 struct nvkm_ltc *ltc = nvkm_ltc(subdev); 103 int i; 104 105 for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { 106 ltc->func->zbc_clear_color(ltc, i, ltc->zbc_color[i]); 107 ltc->func->zbc_clear_depth(ltc, i, ltc->zbc_depth[i]); 108 if (ltc->func->zbc_clear_stencil) 109 ltc->func->zbc_clear_stencil(ltc, i, ltc->zbc_stencil[i]); 110 } 111 112 ltc->func->init(ltc); 113 return 0; 114} 115 116static void * 117nvkm_ltc_dtor(struct nvkm_subdev *subdev) 118{ 119 struct nvkm_ltc *ltc = nvkm_ltc(subdev); 120 nvkm_memory_unref(<c->tag_ram); 121 return ltc; 122} 123 124static const struct nvkm_subdev_func 125nvkm_ltc = { 126 .dtor = nvkm_ltc_dtor, 127 .oneinit = nvkm_ltc_oneinit, 128 .init = nvkm_ltc_init, 129 .intr = nvkm_ltc_intr, 130}; 131 132int 133nvkm_ltc_new_(const struct nvkm_ltc_func *func, struct nvkm_device *device, 134 int index, struct nvkm_ltc **pltc) 135{ 136 struct nvkm_ltc *ltc; 137 138 if (!(ltc = *pltc = kzalloc(sizeof(*ltc), GFP_KERNEL))) 139 return -ENOMEM; 140 141 nvkm_subdev_ctor(&nvkm_ltc, device, index, <c->subdev); 142 ltc->func = func; 143 ltc->zbc_min = 1; /* reserve 0 for disabled */ 144 ltc->zbc_max = min(func->zbc, NVKM_LTC_MAX_ZBC_CNT) - 1; 145 return 0; 146} 147