1d1fb887aSBen Skeggs /* SPDX-License-Identifier: MIT 2d1fb887aSBen Skeggs * 3d1fb887aSBen Skeggs * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4d1fb887aSBen Skeggs */ 5d1fb887aSBen Skeggs #include <nvif/chan.h> 6d1fb887aSBen Skeggs #include <nvif/user.h> 7d1fb887aSBen Skeggs 8*862450a8SBen Skeggs #include <nvif/push906f.h> 9*862450a8SBen Skeggs #include <nvhw/class/clc36f.h> 10*862450a8SBen Skeggs 11d1fb887aSBen Skeggs static void 12d1fb887aSBen Skeggs nvif_chanc36f_gpfifo_kick(struct nvif_chan *chan) 13d1fb887aSBen Skeggs { 14d1fb887aSBen Skeggs struct nvif_user *usermode = chan->usermode; 15d1fb887aSBen Skeggs 16d1fb887aSBen Skeggs nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); 17d1fb887aSBen Skeggs 18d1fb887aSBen Skeggs wmb(); /* ensure CPU writes are flushed to BAR1 */ 19d1fb887aSBen Skeggs nvif_rd32(&chan->userd, 0); /* ensure BAR1 writes are flushed to vidmem */ 20d1fb887aSBen Skeggs 21d1fb887aSBen Skeggs usermode->func->doorbell(usermode, chan->doorbell_token); 22d1fb887aSBen Skeggs } 23d1fb887aSBen Skeggs 24*862450a8SBen Skeggs #define NVIF_CHANC36F_SEM_RELEASE_SIZE 6 25*862450a8SBen Skeggs 26*862450a8SBen Skeggs static int 27*862450a8SBen Skeggs nvif_chanc36f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) 28*862450a8SBen Skeggs { 29*862450a8SBen Skeggs struct nvif_push *push = &chan->push; 30*862450a8SBen Skeggs int ret; 31*862450a8SBen Skeggs 32*862450a8SBen Skeggs ret = PUSH_WAIT(push, NVIF_CHANC36F_SEM_RELEASE_SIZE); 33*862450a8SBen Skeggs if (ret) 34*862450a8SBen Skeggs return ret; 35*862450a8SBen Skeggs 36*862450a8SBen Skeggs PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(addr), 37*862450a8SBen Skeggs 38*862450a8SBen Skeggs SEM_ADDR_HI, upper_32_bits(addr), 39*862450a8SBen Skeggs 40*862450a8SBen Skeggs SEM_PAYLOAD_LO, data); 41*862450a8SBen Skeggs 42*862450a8SBen Skeggs PUSH_MTHD(push, NVC36F, SEM_EXECUTE, 43*862450a8SBen Skeggs NVDEF(NVC36F, SEM_EXECUTE, OPERATION, RELEASE) | 44*862450a8SBen Skeggs NVDEF(NVC36F, SEM_EXECUTE, RELEASE_WFI, DIS) | 45*862450a8SBen Skeggs NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT) | 46*862450a8SBen Skeggs NVDEF(NVC36F, SEM_EXECUTE, RELEASE_TIMESTAMP, DIS)); 47*862450a8SBen Skeggs 48*862450a8SBen Skeggs return 0; 49*862450a8SBen Skeggs } 50*862450a8SBen Skeggs 51d1fb887aSBen Skeggs static const struct nvif_chan_func 52d1fb887aSBen Skeggs nvif_chanc36f = { 53*862450a8SBen Skeggs .push.read_get = nvif_chan906f_read_get, 54*862450a8SBen Skeggs .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, 55d1fb887aSBen Skeggs .gpfifo.push = nvif_chan506f_gpfifo_push, 56d1fb887aSBen Skeggs .gpfifo.kick = nvif_chanc36f_gpfifo_kick, 57*862450a8SBen Skeggs .gpfifo.post = nvif_chan906f_gpfifo_post, 58*862450a8SBen Skeggs .gpfifo.post_size = NVIF_CHANC36F_SEM_RELEASE_SIZE, 59*862450a8SBen Skeggs .sem.release = nvif_chanc36f_sem_release, 60d1fb887aSBen Skeggs }; 61d1fb887aSBen Skeggs 62d1fb887aSBen Skeggs int 63d1fb887aSBen Skeggs nvif_chanc36f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, 64*862450a8SBen Skeggs void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, 65d1fb887aSBen Skeggs struct nvif_user *usermode, u32 doorbell_token) 66d1fb887aSBen Skeggs { 67*862450a8SBen Skeggs int ret; 68*862450a8SBen Skeggs 69*862450a8SBen Skeggs ret = nvif_chan906f_ctor_(&nvif_chanc36f, userd, gpfifo, gpfifo_size, 70*862450a8SBen Skeggs push, push_addr, push_size, sema, sema_addr, chan); 71*862450a8SBen Skeggs if (ret) 72*862450a8SBen Skeggs return ret; 73*862450a8SBen Skeggs 74d1fb887aSBen Skeggs chan->usermode = usermode; 75d1fb887aSBen Skeggs chan->doorbell_token = doorbell_token; 76d1fb887aSBen Skeggs return 0; 77d1fb887aSBen Skeggs } 78