1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #ifndef __NVKMS_EVO_3_H__
25 #define __NVKMS_EVO_3_H__
26
27 #include "nvkms-types.h"
28 #include "nv-float.h"
29 #include "nvkms-softfloat.h"
30 #include <class/clc57d.h> // NVC57D_CORE_CHANNEL_DMA
31
32 #define NV_EVO3_X_EMULATED_SURFACE_MEMORY_FORMATS_C6 \
33 (NVBIT64(NvKmsSurfaceMemoryFormatRF16GF16BF16XF16) | \
34 NVBIT64(NvKmsSurfaceMemoryFormatX2B10G10R10))
35
36 #define NV_EVO3_SUPPORTED_DITHERING_MODES \
37 ((1 << NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_AUTO) | \
38 (1 << NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_DYNAMIC_2X2) | \
39 (1 << NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_STATIC_2X2) | \
40 (1 << NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_TEMPORAL))
41
42 #define NV_EVO3_SUPPORTED_CURSOR_COMP_BLEND_MODES \
43 ((1 << NVKMS_COMPOSITION_BLENDING_MODE_OPAQUE) | \
44 (1 << NVKMS_COMPOSITION_BLENDING_MODE_NON_PREMULT_ALPHA) | \
45 (1 << NVKMS_COMPOSITION_BLENDING_MODE_PREMULT_ALPHA) | \
46 (1 << NVKMS_COMPOSITION_BLENDING_MODE_NON_PREMULT_SURFACE_ALPHA) | \
47 (1 << NVKMS_COMPOSITION_BLENDING_MODE_PREMULT_SURFACE_ALPHA))
48
49 #define NV_EVO3_DEFAULT_WINDOW_USAGE_BOUNDS_C5 \
50 (DRF_DEF(C57D, _WINDOW_SET_WINDOW_USAGE_BOUNDS, _ILUT_ALLOWED, _TRUE) | \
51 DRF_DEF(C57D, _WINDOW_SET_WINDOW_USAGE_BOUNDS, _TMO_LUT_ALLOWED, _TRUE))
52
53 // HW supports ratio = 1, 2 (downscaling), 4 (downscaling)
54 #define NUM_SCALER_RATIOS 3
55
56 // There are 16 phases stored in matrix, but HW can derive the values of phase
57 // +16 and -16 from phase 0. Therefore, SW loads phase +16/-16 in phase 0 coeff
58 // values.
59 // coeff values in phase 0.
60 #define NUM_TAPS5_COEFF_PHASES 16
61
62 // There are 5 coefficient values per phase (or matrix row), but SW doesn't need
63 // to upload c2. So, the value here is set to 4.
64 #define NUM_TAPS5_COEFF_VALUES 4
65
66 extern const NvU32 scalerTaps5Coeff[NUM_SCALER_RATIOS][NUM_TAPS5_COEFF_PHASES][NUM_TAPS5_COEFF_VALUES];
67
68 struct EvoClampRangeC5 {
69 NvU32 green, red_blue;
70 };
71
72 /*
73 * Converts FP32 to fixed point S5.14 coefficient format
74 */
nvCscCoefConvertS514(float32_t x)75 static inline NvU32 nvCscCoefConvertS514(float32_t x)
76 {
77 /* more concisely, (NvS32)floor(x * 65536.0 + 2.0) */
78 const NvS32 y = f32_to_i32(f32_mulAdd(x,
79 NvU32viewAsF32(NV_FLOAT_65536),
80 NvU32viewAsF32(NV_FLOAT_TWO)),
81 softfloat_round_min, FALSE);
82 return (NvU32)(0x001ffffc & clamp_S32(y, -0x100000, 0xfffff));
83 }
84
85 NvBool nvComputeMinFrameIdle(
86 const NVHwModeTimingsEvo *pTimings,
87 NvU16 *pLeadingRasterLines,
88 NvU16 *pTrailingRasterLines);
89
90 void nvEvoSetControlC3(NVDevEvoPtr pDevEvo, int sd);
91
92 void nvEvoORSetControlC3(NVDevEvoPtr pDevEvo,
93 const NVConnectorEvoRec *pConnectorEvo,
94 const enum nvKmsTimingsProtocol protocol,
95 const NvU32 orIndex,
96 const NvU32 headMask,
97 NVEvoUpdateState *updateState);
98
99 NvU32 nvEvoGetPixelDepthC3(const enum nvKmsPixelDepth pixelDepth);
100
101 NvBool nvEvoSetUsageBoundsC5(NVDevEvoPtr pDevEvo, NvU32 sd, NvU32 head,
102 const struct NvKmsUsageBounds *pUsage,
103 NVEvoUpdateState *updateState);
104
105 void nvEvoUpdateC3(NVDevEvoPtr pDevEvo,
106 const NVEvoUpdateState *updateState,
107 NvBool releaseElv);
108
109 void
110 nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
111 const NVEvoIsModePossibleDispInput *pInput,
112 NVEvoIsModePossibleDispOutput *pOutput);
113
114 void nvEvoPrePostIMPC3(NVDispEvoPtr pDispEvo, NvBool isPre);
115
116 void nvEvoSetNotifierC3(NVDevEvoRec *pDevEvo,
117 const NvBool notify,
118 const NvBool awaken,
119 const NvU32 notifier,
120 NVEvoUpdateState *updateState);
121
122 NvBool nvEvoGetCapabilitiesC6(NVDevEvoPtr pDevEvo);
123
124 void
125 nvEvoFlipC6(NVDevEvoPtr pDevEvo,
126 NVEvoChannelPtr pChannel,
127 const NVFlipChannelEvoHwState *pHwState,
128 NVEvoUpdateState *updateState,
129 NvBool bypassComposition);
130
131 void nvEvoFlipTransitionWARC6(NVDevEvoPtr pDevEvo, NvU32 sd, NvU32 head,
132 const NVEvoSubDevHeadStateRec *pSdHeadState,
133 const NVFlipEvoHwState *pFlipState,
134 NVEvoUpdateState *updateState);
135
136 void
137 nvEvoFillLUTSurfaceC5(NVEvoLutEntryRec *pLUTBuffer,
138 const NvU16 *red,
139 const NvU16 *green,
140 const NvU16 *blue,
141 int nColorMapEntries, int depth);
142
143 void nvSetupOutputLUT5(NVDevEvoPtr pDevEvo,
144 const NVDispHeadStateEvoRec *pHeadState,
145 const int head,
146 NVLutSurfaceEvoPtr pLutSurfEvo,
147 NvBool enableBaseLut,
148 NvBool enableOutputLut,
149 NVEvoUpdateState *updateState,
150 NvBool bypassComposition,
151 NVSurfaceDescriptor **pSurfaceDesc,
152 NvU32 *lutSize,
153 NvBool *disableOcsc0,
154 NvU32 *fpNormScale,
155 NvBool *isLutModeVss);
156
157 NvBool nvEvoGetHeadSetControlCursorValueC3(const NVDevEvoRec *pDevEvo,
158 const NVSurfaceEvoRec *pSurfaceEvo,
159 NvU32 *pValue);
160
161 NvBool nvEvoValidateCursorSurfaceC3(const NVDevEvoRec *pDevEvo,
162 const NVSurfaceEvoRec *pSurfaceEvo);
163
164 NvBool nvEvoValidateWindowFormatC6(
165 const enum NvKmsSurfaceMemoryFormat format,
166 const struct NvKmsRect *sourceFetchRect,
167 NvU32 *hwFormatOut);
168
169 void nvEvoInitCompNotifierC3(const NVDispEvoRec *pDispEvo, int idx);
170
171 NvBool nvEvoIsCompNotifierCompleteC3(NVDispEvoPtr pDispEvo, int idx);
172
173 void nvEvoWaitForCompNotifierC3(const NVDispEvoRec *pDispEvo, int idx);
174
175 void nvEvoInitChannel3(NVDevEvoPtr pDevEvo, NVEvoChannelPtr pChannel);
176
177 void nvInitScalerCoefficientsPrecomp5(NVEvoChannelPtr pChannel,
178 NvU32 coeff, NvU32 index);
179
180 void nvEvoInitDefaultLutC5(NVDevEvoPtr pDevEvo);
181
182 void nvEvoInitWindowMappingC5(const NVDispEvoRec *pDispEvo,
183 NVEvoModesetUpdateState *pModesetUpdateState);
184
185 NvBool nvEvoIsChannelIdleC3(NVDevEvoPtr pDevEvo,
186 NVEvoChannelPtr pChan,
187 NvU32 sd,
188 NvBool *result);
189
190 NvBool nvEvoIsChannelMethodPendingC3(NVDevEvoPtr pDevEvo,
191 NVEvoChannelPtr pChan,
192 NvU32 sd,
193 NvBool *result);
194
195 NvBool nvEvoForceIdleSatelliteChannelC3(
196 NVDevEvoPtr pDevEvo,
197 const NVEvoIdleChannelState *idleChannelState);
198
199 NvBool nvEvoForceIdleSatelliteChannelIgnoreLockC3(
200 NVDevEvoPtr pDevEvo,
201 const NVEvoIdleChannelState *idleChannelState);
202
203 void nvEvoAccelerateChannelC3(NVDevEvoPtr pDevEvo,
204 NVEvoChannelPtr pChannel,
205 const NvU32 sd,
206 const NvBool trashPendingMethods,
207 const NvBool unblockMethodsInExecutation,
208 NvU32 *pOldAccelerators);
209
210 void nvEvoResetChannelAcceleratorsC3(NVDevEvoPtr pDevEvo,
211 NVEvoChannelPtr pChannel,
212 const NvU32 sd,
213 const NvBool trashPendingMethods,
214 const NvBool unblockMethodsInExecutation,
215 NvU32 oldAccelerators);
216
217 NvBool nvEvoAllocRmCtrlObjectC3(NVDevEvoPtr pDevEvo);
218
219 void nvEvoFreeRmCtrlObjectC3(NVDevEvoPtr pDevEvo);
220
221 void nvEvoSetImmPointOutC3(NVDevEvoPtr pDevEvo,
222 NVEvoChannelPtr pChannel,
223 NvU32 sd,
224 NVEvoUpdateState *updateState,
225 NvU16 x, NvU16 y);
226
227 NvBool nvEvoQueryHeadCRC32_C3(NVDevEvoPtr pDevEvo,
228 NVEvoDmaPtr pDma,
229 NvU32 sd,
230 NvU32 entry_count,
231 CRC32NotifierCrcOut *crc32,
232 NvU32 *numCRC32);
233
234 void nvEvoGetScanLineC3(const NVDispEvoRec *pDispEvo,
235 const NvU32 head,
236 NvU16 *pScanLine,
237 NvBool *pInBlankingPeriod);
238
239 NvU32 nvEvoGetActiveViewportOffsetC3(NVDispEvoRec *pDispEvo, NvU32 head);
240
241 NvBool nvEvoComputeWindowScalingTapsC5(const NVDevEvoRec *pDevEvo,
242 const NVEvoChannel *pChannel,
243 NVFlipChannelEvoHwState *pHwState);
244
245 const struct NvKmsCscMatrix* nvEvoGetOCsc1MatrixC5(const NVDispHeadStateEvoRec *pHeadState);
246
247 struct EvoClampRangeC5 nvEvoGetOCsc1ClampRange(const NVDispHeadStateEvoRec *pHeadState);
248
249 void nvEvo3PickOCsc0(NVDispEvoPtr pDispEvo, const NvU32 head, struct NvKms3x4MatrixF32 *ocsc0Matrix);
250
251 static inline const NVEvoScalerCaps*
nvEvoGetWindowScalingCapsC3(const NVDevEvoRec * pDevEvo)252 nvEvoGetWindowScalingCapsC3(const NVDevEvoRec *pDevEvo)
253 {
254 /*
255 * Use window 0 by default. This should be fine for now since precomp
256 * scaling will only be enabled on Orin, and all windows have the same
257 * capabilities on Orin.
258 *
259 * The mapping in this function can be updated if/when precomp scaling
260 * support is extended to other display architectures.
261 */
262 return &pDevEvo->gpus[0].capabilities.window[0].scalerCaps;
263 }
264
nvGetMaxPixelsFetchedPerLine(NvU16 inWidth,NvU16 maxHDownscaleFactor)265 static inline NvU32 nvGetMaxPixelsFetchedPerLine(NvU16 inWidth,
266 NvU16 maxHDownscaleFactor)
267 {
268 /*
269 * Volta should be:
270 * (((SetViewportSizeIn.Width + 6) * SetMaxInputScaleFactor.Horizontal + 1023 ) >> 10 ) + 6
271 *
272 * Turing should be:
273 * (((SetViewportSizeIn.Width + 6) * SetMaxInputScaleFactor.Horizontal + 1023 ) >> 10 ) + 8
274 *
275 * Ampere, which adds "overfetch" to have tiled displays / 2-head-1-OR use cases without
276 * visual artefacts at head boundaries:
277 * (((SetViewportSizeIn.Width + 14) * SetMaxInputScaleFactor.Horizontal + 1023) >> 10) + 8
278 *
279 * We don't have to be super-precise when programming maxPixelsFetchedPerLine,
280 * so return realistic worst-case value.
281 */
282 return (((inWidth + 14) * maxHDownscaleFactor + 1023) >> 10) + 8;
283 }
284
285 #endif /* __NVKMS_EVO_3_H__ */
286