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