1*862450a8SBen Skeggs /* SPDX-License-Identifier: MIT 2*862450a8SBen Skeggs * 3*862450a8SBen Skeggs * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4*862450a8SBen Skeggs */ 5*862450a8SBen Skeggs #include <nvif/chan.h> 6*862450a8SBen Skeggs #include <nvif/user.h> 7*862450a8SBen Skeggs #include <nvif/push906f.h> 8*862450a8SBen Skeggs 9*862450a8SBen Skeggs #include <nvhw/class/cl906f.h> 10*862450a8SBen Skeggs 11*862450a8SBen Skeggs /* Limits GPFIFO size to 1MiB, and "main" push buffer size to 64KiB. */ 12*862450a8SBen Skeggs #define NVIF_CHAN906F_PBPTR_BITS 15 13*862450a8SBen Skeggs #define NVIF_CHAN906F_PBPTR_MASK ((1 << NVIF_CHAN906F_PBPTR_BITS) - 1) 14*862450a8SBen Skeggs 15*862450a8SBen Skeggs #define NVIF_CHAN906F_GPPTR_SHIFT NVIF_CHAN906F_PBPTR_BITS 16*862450a8SBen Skeggs #define NVIF_CHAN906F_GPPTR_BITS (32 - NVIF_CHAN906F_PBPTR_BITS) 17*862450a8SBen Skeggs #define NVIF_CHAN906F_GPPTR_MASK ((1 << NVIF_CHAN906F_GPPTR_BITS) - 1) 18*862450a8SBen Skeggs 19*862450a8SBen Skeggs #define NVIF_CHAN906F_SEM_RELEASE_SIZE 5 20*862450a8SBen Skeggs 21*862450a8SBen Skeggs static int 22*862450a8SBen Skeggs nvif_chan906f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) 23*862450a8SBen Skeggs { 24*862450a8SBen Skeggs struct nvif_push *push = &chan->push; 25*862450a8SBen Skeggs int ret; 26*862450a8SBen Skeggs 27*862450a8SBen Skeggs ret = PUSH_WAIT(push, NVIF_CHAN906F_SEM_RELEASE_SIZE); 28*862450a8SBen Skeggs if (ret) 29*862450a8SBen Skeggs return ret; 30*862450a8SBen Skeggs 31*862450a8SBen Skeggs PUSH_MTHD(push, NV906F, SEMAPHOREA, 32*862450a8SBen Skeggs NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(addr)), 33*862450a8SBen Skeggs 34*862450a8SBen Skeggs SEMAPHOREB, lower_32_bits(addr), 35*862450a8SBen Skeggs 36*862450a8SBen Skeggs SEMAPHOREC, data, 37*862450a8SBen Skeggs 38*862450a8SBen Skeggs SEMAPHORED, 39*862450a8SBen Skeggs NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) | 40*862450a8SBen Skeggs NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, DIS) | 41*862450a8SBen Skeggs NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE)); 42*862450a8SBen Skeggs 43*862450a8SBen Skeggs return 0; 44*862450a8SBen Skeggs } 45*862450a8SBen Skeggs 46*862450a8SBen Skeggs int 47*862450a8SBen Skeggs nvif_chan906f_gpfifo_post(struct nvif_chan *chan, u32 gpptr, u32 pbptr) 48*862450a8SBen Skeggs { 49*862450a8SBen Skeggs return chan->func->sem.release(chan, chan->sema.addr, 50*862450a8SBen Skeggs (gpptr << NVIF_CHAN906F_GPPTR_SHIFT) | pbptr); 51*862450a8SBen Skeggs } 52*862450a8SBen Skeggs 53*862450a8SBen Skeggs u32 54*862450a8SBen Skeggs nvif_chan906f_gpfifo_read_get(struct nvif_chan *chan) 55*862450a8SBen Skeggs { 56*862450a8SBen Skeggs return nvif_rd32(&chan->sema, 0) >> NVIF_CHAN906F_GPPTR_SHIFT; 57*862450a8SBen Skeggs } 58*862450a8SBen Skeggs 59*862450a8SBen Skeggs u32 60*862450a8SBen Skeggs nvif_chan906f_read_get(struct nvif_chan *chan) 61*862450a8SBen Skeggs { 62*862450a8SBen Skeggs return nvif_rd32(&chan->sema, 0) & NVIF_CHAN906F_PBPTR_MASK; 63*862450a8SBen Skeggs } 64*862450a8SBen Skeggs 65*862450a8SBen Skeggs static const struct nvif_chan_func 66*862450a8SBen Skeggs nvif_chan906f = { 67*862450a8SBen Skeggs .push.read_get = nvif_chan906f_read_get, 68*862450a8SBen Skeggs .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, 69*862450a8SBen Skeggs .gpfifo.push = nvif_chan506f_gpfifo_push, 70*862450a8SBen Skeggs .gpfifo.kick = nvif_chan506f_gpfifo_kick, 71*862450a8SBen Skeggs .gpfifo.post = nvif_chan906f_gpfifo_post, 72*862450a8SBen Skeggs .gpfifo.post_size = NVIF_CHAN906F_SEM_RELEASE_SIZE, 73*862450a8SBen Skeggs .sem.release = nvif_chan906f_sem_release, 74*862450a8SBen Skeggs }; 75*862450a8SBen Skeggs 76*862450a8SBen Skeggs int 77*862450a8SBen Skeggs nvif_chan906f_ctor_(const struct nvif_chan_func *func, void *userd, void *gpfifo, u32 gpfifo_size, 78*862450a8SBen Skeggs void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, 79*862450a8SBen Skeggs struct nvif_chan *chan) 80*862450a8SBen Skeggs { 81*862450a8SBen Skeggs nvif_chan_gpfifo_ctor(func, userd, gpfifo, gpfifo_size, push, push_addr, push_size, chan); 82*862450a8SBen Skeggs chan->sema.map.ptr = sema; 83*862450a8SBen Skeggs chan->sema.addr = sema_addr; 84*862450a8SBen Skeggs return 0; 85*862450a8SBen Skeggs } 86*862450a8SBen Skeggs 87*862450a8SBen Skeggs int 88*862450a8SBen Skeggs nvif_chan906f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, 89*862450a8SBen Skeggs void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr) 90*862450a8SBen Skeggs { 91*862450a8SBen Skeggs return nvif_chan906f_ctor_(&nvif_chan906f, userd, gpfifo, gpfifo_size, 92*862450a8SBen Skeggs push, push_addr, push_size, sema, sema_addr, chan); 93*862450a8SBen Skeggs } 94