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
wndwca7e_image_clr(struct nv50_wndw * wndw)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
wndwca7e_image_set(struct nv50_wndw * wndw,struct nv50_wndw_atom * asyw)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
wndwca7e_ilut_clr(struct nv50_wndw * wndw)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
wndwca7e_ilut_set(struct nv50_wndw * wndw,struct nv50_wndw_atom * asyw)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
wndwca7e_ntfy_clr(struct nv50_wndw * wndw)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
wndwca7e_ntfy_set(struct nv50_wndw * wndw,struct nv50_wndw_atom * asyw)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 /****************************************************************
183 * Log2(block height) ----------------------------+ *
184 * Page Kind ----------------------------------+ | *
185 * Gob Height/Page Kind Generation ------+ | | *
186 * Sector layout -------+ | | | *
187 * Compression ------+ | | | | */
188 const u64 wndwca7e_modifiers[] = { /* | | | | | */
189 /* 4cpp+ modifiers */
190 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
191 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
192 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
193 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
194 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
195 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
196 /* 1cpp/8bpp modifiers */
197 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0),
198 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1),
199 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2),
200 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3),
201 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4),
202 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5),
203 /* 2cpp/16bpp modifiers */
204 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0),
205 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1),
206 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2),
207 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3),
208 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4),
209 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5),
210 /* All formats support linear */
211 DRM_FORMAT_MOD_LINEAR,
212 DRM_FORMAT_MOD_INVALID
213 };
214
215 static const struct nv50_wndw_func
216 wndwca7e = {
217 .acquire = wndwc37e_acquire,
218 .release = wndwc37e_release,
219 .ntfy_set = wndwca7e_ntfy_set,
220 .ntfy_clr = wndwca7e_ntfy_clr,
221 .ntfy_reset = corec37d_ntfy_init,
222 .ntfy_wait_begun = base507c_ntfy_wait_begun,
223 .ilut = wndwc57e_ilut,
224 .ilut_identity = true,
225 .ilut_size = 1024,
226 .xlut_set = wndwca7e_ilut_set,
227 .xlut_clr = wndwca7e_ilut_clr,
228 .csc = base907c_csc,
229 .csc_set = wndwc57e_csc_set,
230 .csc_clr = wndwc57e_csc_clr,
231 .image_set = wndwca7e_image_set,
232 .image_clr = wndwca7e_image_clr,
233 .blend_set = wndwc37e_blend_set,
234 .update = wndwc37e_update,
235 };
236
237 int
wndwca7e_new(struct nouveau_drm * drm,enum drm_plane_type type,int index,s32 oclass,struct nv50_wndw ** pwndw)238 wndwca7e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
239 s32 oclass, struct nv50_wndw **pwndw)
240 {
241 return wndwc37e_new_(&wndwca7e, drm, type, index, oclass, BIT(index >> 1), pwndw);
242 }
243