xref: /linux/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c (revision 746680ec6696585e30db3e18c93a63df9cbec39c)
1 /* SPDX-License-Identifier: MIT
2  *
3  * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
4  */
5 #include "wndw.h"
6 #include "atom.h"
7 
8 #include <nvif/pushc97b.h>
9 
10 #include <nvhw/class/clca7e.h>
11 
12 #include <nouveau_bo.h>
13 
14 static int
15 wndwca7e_image_clr(struct nv50_wndw *wndw)
16 {
17 	struct nvif_push *push = &wndw->wndw.push;
18 	int ret;
19 
20 	ret = PUSH_WAIT(push, 4);
21 	if (ret)
22 		return ret;
23 
24 	PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL,
25 		  NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) |
26 		  NVDEF(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING));
27 
28 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0),
29 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, DISABLE));
30 
31 	return 0;
32 }
33 
34 static int
35 wndwca7e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
36 {
37 	const u32 iso0_hi = upper_32_bits(asyw->image.offset[0]);
38 	const u32 iso0_lo = lower_32_bits(asyw->image.offset[0]);
39 	struct nvif_push *push = &wndw->wndw.push;
40 	int ret, kind;
41 
42 	if (asyw->image.kind)
43 		kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_BLOCKLINEAR;
44 	else
45 		kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_PITCH;
46 
47 	ret = PUSH_WAIT(push, 17);
48 	if (ret)
49 		return ret;
50 
51 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ISO(0), iso0_hi);
52 
53 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0),
54 		  NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ADDRESS_LO, iso0_lo >> 4) |
55 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, TARGET, PHYSICAL_NVM) |
56 		  NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, KIND, kind) |
57 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, ENABLE));
58 
59 	PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL,
60 		  NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) |
61 		  NVVAL(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
62 		  NVDEF(NVCA7E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE));
63 
64 	PUSH_MTHD(push, NVCA7E, SET_SIZE,
65 		  NVVAL(NVCA7E, SET_SIZE, WIDTH, asyw->image.w) |
66 		  NVVAL(NVCA7E, SET_SIZE, HEIGHT, asyw->image.h),
67 
68 				SET_STORAGE,
69 		  NVVAL(NVCA7E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh),
70 
71 				SET_PARAMS,
72 		  NVVAL(NVCA7E, SET_PARAMS, FORMAT, asyw->image.format) |
73 		  NVDEF(NVCA7E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) |
74 		  NVDEF(NVCA7E, SET_PARAMS, SWAP_UV, DISABLE) |
75 		  NVDEF(NVCA7E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST),
76 
77 				SET_PLANAR_STORAGE(0),
78 		  NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) |
79 		  NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6));
80 
81 	PUSH_MTHD(push, NVCA7E, SET_POINT_IN(0),
82 		  NVVAL(NVCA7E, SET_POINT_IN, X, asyw->state.src_x >> 16) |
83 		  NVVAL(NVCA7E, SET_POINT_IN, Y, asyw->state.src_y >> 16));
84 
85 	PUSH_MTHD(push, NVCA7E, SET_SIZE_IN,
86 		  NVVAL(NVCA7E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) |
87 		  NVVAL(NVCA7E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16));
88 
89 	PUSH_MTHD(push, NVCA7E, SET_SIZE_OUT,
90 		  NVVAL(NVCA7E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) |
91 		  NVVAL(NVCA7E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h));
92 
93 	return 0;
94 }
95 
96 static int
97 wndwca7e_ilut_clr(struct nv50_wndw *wndw)
98 {
99 	struct nvif_push *push = &wndw->wndw.push;
100 	int ret;
101 
102 	ret = PUSH_WAIT(push, 2);
103 	if (ret)
104 		return ret;
105 
106 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT,
107 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, DISABLE));
108 
109 	return 0;
110 }
111 
112 static int
113 wndwca7e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
114 {
115 	const u32 ilut_hi = upper_32_bits(asyw->xlut.i.offset);
116 	const u32 ilut_lo = lower_32_bits(asyw->xlut.i.offset);
117 	struct nvif_push *push = &wndw->wndw.push;
118 	int ret;
119 
120 	ret = PUSH_WAIT(push, 5);
121 	if (ret)
122 		return ret;
123 
124 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ILUT, ilut_hi,
125 
126 				SET_SURFACE_ADDRESS_LO_ILUT,
127 		  NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ADDRESS_LO, ilut_lo >> 4) |
128 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, TARGET, PHYSICAL_NVM) |
129 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, ENABLE));
130 
131 	PUSH_MTHD(push, NVCA7E, SET_ILUT_CONTROL,
132 		  NVVAL(NVCA7E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) |
133 		  NVVAL(NVCA7E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) |
134 		  NVVAL(NVCA7E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode));
135 
136 	return 0;
137 }
138 
139 static int
140 wndwca7e_ntfy_clr(struct nv50_wndw *wndw)
141 {
142 	struct nvif_push *push = &wndw->wndw.push;
143 	int ret;
144 
145 	ret = PUSH_WAIT(push, 2);
146 	if (ret)
147 		return ret;
148 
149 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER,
150 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, DISABLE));
151 
152 	return 0;
153 }
154 
155 static int
156 wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
157 {
158 	struct nv50_disp *disp = nv50_disp(wndw->plane.dev);
159 	const u64 ntfy_addr = disp->sync->offset + asyw->ntfy.offset;
160 	const u32 ntfy_hi = upper_32_bits(ntfy_addr);
161 	const u32 ntfy_lo = lower_32_bits(ntfy_addr);
162 	struct nvif_push *push = &wndw->wndw.push;
163 	int ret;
164 
165 	ret = PUSH_WAIT(push, 5);
166 	if (ret)
167 		return ret;
168 
169 	PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_NOTIFIER, ntfy_hi,
170 
171 				SET_SURFACE_ADDRESS_LO_NOTIFIER,
172 		  NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ADDRESS_LO, ntfy_lo >> 4) |
173 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, TARGET, PHYSICAL_NVM) |
174 		  NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, ENABLE));
175 
176 	PUSH_MTHD(push, NVCA7E, SET_NOTIFIER_CONTROL,
177 		  NVVAL(NVCA7E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken));
178 
179 	return 0;
180 }
181 
182 static const struct nv50_wndw_func
183 wndwca7e = {
184 	.acquire = wndwc37e_acquire,
185 	.release = wndwc37e_release,
186 	.ntfy_set = wndwca7e_ntfy_set,
187 	.ntfy_clr = wndwca7e_ntfy_clr,
188 	.ntfy_reset = corec37d_ntfy_init,
189 	.ntfy_wait_begun = base507c_ntfy_wait_begun,
190 	.ilut = wndwc57e_ilut,
191 	.ilut_identity = true,
192 	.ilut_size = 1024,
193 	.xlut_set = wndwca7e_ilut_set,
194 	.xlut_clr = wndwca7e_ilut_clr,
195 	.csc = base907c_csc,
196 	.csc_set = wndwc57e_csc_set,
197 	.csc_clr = wndwc57e_csc_clr,
198 	.image_set = wndwca7e_image_set,
199 	.image_clr = wndwca7e_image_clr,
200 	.blend_set = wndwc37e_blend_set,
201 	.update = wndwc37e_update,
202 };
203 
204 int
205 wndwca7e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
206 	     s32 oclass, struct nv50_wndw **pwndw)
207 {
208 	return wndwc37e_new_(&wndwca7e, drm, type, index, oclass, BIT(index >> 1), pwndw);
209 }
210