Linux Audio

Check our new training course

Loading...
  1/*
  2 * Copyright 2021 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#include "priv.h"
 23
 24#include <subdev/gsp.h>
 25
 26#include <nvif/class.h>
 27
 28static void
 29tu102_vfn_intr_reset(struct nvkm_intr *intr, int leaf, u32 mask)
 30{
 31	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 32
 33	nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1000 + (leaf * 4), mask);
 34}
 35
 36static void
 37tu102_vfn_intr_allow(struct nvkm_intr *intr, int leaf, u32 mask)
 38{
 39	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 40
 41	nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1200 + (leaf * 4), mask);
 42}
 43
 44static void
 45tu102_vfn_intr_block(struct nvkm_intr *intr, int leaf, u32 mask)
 46{
 47	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 48
 49	nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1400 + (leaf * 4), mask);
 50}
 51
 52static void
 53tu102_vfn_intr_rearm(struct nvkm_intr *intr)
 54{
 55	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 56
 57	nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1608, 0x0000000f);
 58}
 59
 60static void
 61tu102_vfn_intr_unarm(struct nvkm_intr *intr)
 62{
 63	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 64
 65	nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1610, 0x0000000f);
 66}
 67
 68static bool
 69tu102_vfn_intr_pending(struct nvkm_intr *intr)
 70{
 71	struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
 72	struct nvkm_device *device = vfn->subdev.device;
 73	u32 intr_top = nvkm_rd32(device, vfn->addr.priv + 0x1600);
 74	int pending = 0, leaf;
 75
 76	for (leaf = 0; leaf < 8; leaf++) {
 77		if (intr_top & BIT(leaf / 2)) {
 78			intr->stat[leaf] = nvkm_rd32(device, vfn->addr.priv + 0x1000 + (leaf * 4));
 79			if (intr->stat[leaf])
 80				pending++;
 81		} else {
 82			intr->stat[leaf] = 0;
 83		}
 84	}
 85
 86	return pending != 0;
 87}
 88
 89const struct nvkm_intr_func
 90tu102_vfn_intr = {
 91	.pending = tu102_vfn_intr_pending,
 92	.unarm = tu102_vfn_intr_unarm,
 93	.rearm = tu102_vfn_intr_rearm,
 94	.block = tu102_vfn_intr_block,
 95	.allow = tu102_vfn_intr_allow,
 96	.reset = tu102_vfn_intr_reset,
 97};
 98
 99static const struct nvkm_vfn_func
100tu102_vfn = {
101	.intr = &tu102_vfn_intr,
102	.user = { 0x030000, 0x010000, { -1, -1, TURING_USERMODE_A } },
103};
104
105int
106tu102_vfn_new(struct nvkm_device *device,
107	      enum nvkm_subdev_type type, int inst, struct nvkm_vfn **pvfn)
108{
109	if (nvkm_gsp_rm(device->gsp))
110		return r535_vfn_new(&tu102_vfn, device, type, inst, 0xb80000, pvfn);
111
112	return nvkm_vfn_new_(&tu102_vfn, device, type, inst, 0xb80000, pvfn);
113}