1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4 */ 5 #include <nvif/chan.h> 6 7 void 8 nvif_chan506f_gpfifo_kick(struct nvif_chan *chan) 9 { 10 wmb(); 11 nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); 12 } 13 14 void 15 nvif_chan506f_gpfifo_push(struct nvif_chan *chan, bool main, u64 addr, u32 size, bool no_prefetch) 16 { 17 u32 gpptr = chan->gpfifo.cur << 3; 18 19 if (WARN_ON(!chan->gpfifo.free)) 20 return; 21 22 nvif_wr32(&chan->gpfifo, gpptr + 0, lower_32_bits(addr)); 23 nvif_wr32(&chan->gpfifo, gpptr + 4, upper_32_bits(addr) | 24 (main ? 0 : BIT(9)) | 25 (size >> 2) << 10 | 26 (no_prefetch ? BIT(31) : 0)); 27 28 chan->gpfifo.cur = (chan->gpfifo.cur + 1) & chan->gpfifo.max; 29 chan->gpfifo.free--; 30 if (!chan->gpfifo.free) 31 chan->push.end = chan->push.cur; 32 } 33 34 static u32 35 nvif_chan506f_gpfifo_read_get(struct nvif_chan *chan) 36 { 37 return nvif_rd32(&chan->userd, 0x88); 38 } 39 40 static u32 41 nvif_chan506f_read_get(struct nvif_chan *chan) 42 { 43 u32 tlgetlo = nvif_rd32(&chan->userd, 0x58); 44 u32 tlgethi = nvif_rd32(&chan->userd, 0x5c); 45 struct nvif_push *push = &chan->push; 46 47 /* Update cached GET pointer if TOP_LEVEL_GET is valid. */ 48 if (tlgethi & BIT(31)) { 49 u64 tlget = ((u64)(tlgethi & 0xff) << 32) | tlgetlo; 50 51 push->hw.get = (tlget - push->addr) >> 2; 52 } 53 54 return push->hw.get; 55 } 56 57 static const struct nvif_chan_func 58 nvif_chan506f = { 59 .push.read_get = nvif_chan506f_read_get, 60 .gpfifo.read_get = nvif_chan506f_gpfifo_read_get, 61 .gpfifo.push = nvif_chan506f_gpfifo_push, 62 .gpfifo.kick = nvif_chan506f_gpfifo_kick, 63 }; 64 65 int 66 nvif_chan506f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, 67 void *push, u64 push_addr, u32 push_size) 68 { 69 nvif_chan_gpfifo_ctor(&nvif_chan506f, userd, gpfifo, gpfifo_size, 70 push, push_addr, push_size, chan); 71 return 0; 72 } 73