xref: /linux/drivers/gpu/drm/nouveau/nvif/chanc36f.c (revision b08494a8f7416e5f09907318c5460ad6f6e2a548)
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