515.43.04

This commit is contained in:
Andy Ritger
2022-05-09 13:18:59 -07:00
commit 1739a20efc
2519 changed files with 1060036 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "nvkms-format.h"
#include "nv_common_utils.h"
#include "nvctassert.h"
#include <stddef.h>
#define RGB_ENTRY(_format, _depth, _bytesPerPixel) \
[NvKmsSurfaceMemoryFormat##_format] = { \
.format = NvKmsSurfaceMemoryFormat##_format, \
.name = #_format, \
.depth = _depth, \
.isYUV = NV_FALSE, \
.numPlanes = 1, \
{ \
.rgb = { \
.bytesPerPixel = _bytesPerPixel, \
.bitsPerPixel = _bytesPerPixel * 8, \
}, \
}, \
}
#define YUV_ENTRY(_format, \
_depth, \
_numPlanes, \
_depthPerComponent, \
_storageBitsPerComponent, \
_horizChromaDecimationFactor, \
_vertChromaDecimationFactor) \
[NvKmsSurfaceMemoryFormat##_format] = { \
.format = NvKmsSurfaceMemoryFormat##_format, \
.name = #_format, \
.depth = _depth, \
.isYUV = NV_TRUE, \
.numPlanes = _numPlanes, \
{ \
.yuv = { \
.depthPerComponent = _depthPerComponent, \
.storageBitsPerComponent = _storageBitsPerComponent, \
.horizChromaDecimationFactor = _horizChromaDecimationFactor, \
.vertChromaDecimationFactor = _vertChromaDecimationFactor, \
}, \
}, \
}
static const NvKmsSurfaceMemoryFormatInfo nvKmsEmptyFormatInfo;
/*
* For 10/12-bit YUV formats, each component is packed in a 16-bit container in
* memory, and fetched by display HW as such.
*/
static const NvKmsSurfaceMemoryFormatInfo nvKmsSurfaceMemoryFormatInfo[] = {
RGB_ENTRY(I8, 8, 1),
RGB_ENTRY(A1R5G5B5, 16, 2),
RGB_ENTRY(X1R5G5B5, 15, 2),
RGB_ENTRY(R5G6B5, 16, 2),
RGB_ENTRY(A8R8G8B8, 32, 4),
RGB_ENTRY(X8R8G8B8, 24, 4),
RGB_ENTRY(A2B10G10R10, 32, 4),
RGB_ENTRY(X2B10G10R10, 30, 4),
RGB_ENTRY(A8B8G8R8, 32, 4),
RGB_ENTRY(X8B8G8R8, 24, 4),
RGB_ENTRY(RF16GF16BF16AF16, 64, 8),
RGB_ENTRY(R16G16B16A16, 64, 8),
RGB_ENTRY(RF32GF32BF32AF32, 128, 16),
YUV_ENTRY(Y8_U8__Y8_V8_N422, 16, 1, 8, 8, 2, 1),
YUV_ENTRY(U8_Y8__V8_Y8_N422, 16, 1, 8, 8, 2, 1),
YUV_ENTRY(Y8___U8V8_N444, 24, 2, 8, 8, 1, 1),
YUV_ENTRY(Y8___V8U8_N444, 24, 2, 8, 8, 1, 1),
YUV_ENTRY(Y8___U8V8_N422, 16, 2, 8, 8, 2, 1),
YUV_ENTRY(Y8___V8U8_N422, 16, 2, 8, 8, 2, 1),
YUV_ENTRY(Y8___U8V8_N420, 12, 2, 8, 8, 2, 2),
YUV_ENTRY(Y8___V8U8_N420, 12, 2, 8, 8, 2, 2),
YUV_ENTRY(Y10___U10V10_N444, 30, 2, 10, 16, 1, 1),
YUV_ENTRY(Y10___V10U10_N444, 30, 2, 10, 16, 1, 1),
YUV_ENTRY(Y10___U10V10_N422, 20, 2, 10, 16, 2, 1),
YUV_ENTRY(Y10___V10U10_N422, 20, 2, 10, 16, 2, 1),
YUV_ENTRY(Y10___U10V10_N420, 15, 2, 10, 16, 2, 2),
YUV_ENTRY(Y10___V10U10_N420, 15, 2, 10, 16, 2, 2),
YUV_ENTRY(Y12___U12V12_N444, 36, 2, 12, 16, 1, 1),
YUV_ENTRY(Y12___V12U12_N444, 36, 2, 12, 16, 1, 1),
YUV_ENTRY(Y12___U12V12_N422, 24, 2, 12, 16, 2, 1),
YUV_ENTRY(Y12___V12U12_N422, 24, 2, 12, 16, 2, 1),
YUV_ENTRY(Y12___U12V12_N420, 18, 2, 12, 16, 2, 2),
YUV_ENTRY(Y12___V12U12_N420, 18, 2, 12, 16, 2, 2),
YUV_ENTRY(Y8___U8___V8_N444, 24, 3, 8, 8, 1, 1),
YUV_ENTRY(Y8___U8___V8_N420, 12, 3, 8, 8, 2, 2),
};
ct_assert(ARRAY_LEN(nvKmsSurfaceMemoryFormatInfo) ==
(NvKmsSurfaceMemoryFormatMax + 1));
const NvKmsSurfaceMemoryFormatInfo *nvKmsGetSurfaceMemoryFormatInfo(
const enum NvKmsSurfaceMemoryFormat format)
{
if (format >= ARRAY_LEN(nvKmsSurfaceMemoryFormatInfo)) {
return &nvKmsEmptyFormatInfo;
}
return &nvKmsSurfaceMemoryFormatInfo[format];
}
const char *nvKmsSurfaceMemoryFormatToString(
const enum NvKmsSurfaceMemoryFormat format)
{
const NvKmsSurfaceMemoryFormatInfo *pFormatInfo =
nvKmsGetSurfaceMemoryFormatInfo(format);
return (pFormatInfo != NULL) ? pFormatInfo->name : NULL;
}

View File

@@ -0,0 +1,377 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <nvkms-sync.h>
#include <nvmisc.h>
#include <class/cl917c.h> /* NV_DISP_BASE_NOTIFIER_1, NV_DISP_NOTIFICATION_2 */
#include <class/clc37d.h> /* NV_DISP_NOTIFIER */
/*
* HW will never write 1 to lower 32bits of timestamp
*/
#define NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID 1
/*
* Higher 32bits of timestamp will be 0 only during first ~4sec of
* boot. So for practical purposes, we can consider 0 as invalid.
*/
#define NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_HI_INVALID 0
static void GetNotifierTimeStamp(volatile const NvU32 *notif,
NvU32 timeStampLoIdx,
NvU32 timeStampHiIdx,
struct nvKmsParsedNotifier *out)
{
NvU32 lo, hi;
NvU32 pollCount = 0;
/*
* Caller of ParseNotifier() is expected to poll for notifier
* status to become BEGUN/FINISHED for valid timestamp.
*/
if (out->status == NVKMS_NOTIFIER_STATUS_NOT_BEGUN) {
return;
}
/*
* HW does 4B writes to notifier, so poll till both timestampLo
* and timestampHi bytes become valid.
*/
do {
lo = notif[timeStampLoIdx];
hi = notif[timeStampHiIdx];
if ((lo != NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID) &&
(hi != NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_HI_INVALID)) {
out->timeStamp = (NvU64)lo | ((NvU64)hi << 32);
out->timeStampValid = NV_TRUE;
break;
}
if (++pollCount >= 100) {
break;
}
} while (1);
}
static void ResetNotifierLegacy(NvBool overlay, volatile void *in)
{
volatile NvU32 *notif = in;
if (overlay) {
notif[NV_DISP_NOTIFICATION_2_INFO16_3] =
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _NOT_BEGUN);
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] =
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
} else {
notif[NV_DISP_BASE_NOTIFIER_1__0] =
DRF_DEF(_DISP, _BASE_NOTIFIER_1__0, _STATUS, _NOT_BEGUN);
}
}
static void ResetNotifierFourWord(volatile void *in)
{
volatile NvU32 *notif = in;
notif[NV_DISP_NOTIFICATION_2_INFO16_3] =
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _NOT_BEGUN);
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] =
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
}
static void ResetNotifierFourWordNVDisplay(volatile void *in)
{
volatile NvU32 *notif = in;
notif[NV_DISP_NOTIFIER__0] =
DRF_DEF(_DISP, _NOTIFIER__0, _STATUS, _NOT_BEGUN);
notif[NV_DISP_NOTIFIER__2] =
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
}
void nvKmsResetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
NvU32 index, void *base)
{
const NvU32 sizeInBytes = nvKmsSizeOfNotifier(format, overlay);
void *notif =
(void *)((char *)base + (sizeInBytes * index));
switch (format) {
case NVKMS_NISO_FORMAT_LEGACY:
ResetNotifierLegacy(overlay, notif);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD:
ResetNotifierFourWord(notif);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
ResetNotifierFourWordNVDisplay(notif);
break;
}
}
static void ParseNotifierLegacy(NvBool overlay, volatile const void *in,
struct nvKmsParsedNotifier *out)
{
volatile const NvU32 *notif = in;
if (overlay) {
NvU32 notif3;
/* Read this once since it may be in video memory and we need multiple
* fields */
notif3 = notif[NV_DISP_NOTIFICATION_2_INFO16_3];
switch(DRF_VAL(_DISP, _NOTIFICATION_2__3, _STATUS, notif3)) {
case NV_DISP_NOTIFICATION_2__3_STATUS_NOT_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_NOT_BEGUN;
break;
case NV_DISP_NOTIFICATION_2__3_STATUS_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_BEGUN;
break;
case NV_DISP_NOTIFICATION_2__3_STATUS_FINISHED:
out->status = NVKMS_NOTIFIER_STATUS_FINISHED;
break;
}
out->presentCount =
DRF_VAL(_DISP, _NOTIFICATION_2_INFO16_3, _PRESENT_COUNT, notif3);
GetNotifierTimeStamp(notif,
NV_DISP_NOTIFICATION_2_TIME_STAMP_0,
NV_DISP_NOTIFICATION_2_TIME_STAMP_1,
out);
} else {
NvU32 notif0;
/* There's a timestamp available in this notifier, but it's a weird
* 14-bit "audit timestamp" that's not useful for us. */
out->timeStampValid = NV_FALSE;
/* Read this once since it may be in video memory and we need multiple
* fields */
notif0 = notif[NV_DISP_BASE_NOTIFIER_1__0];
switch(DRF_VAL(_DISP, _BASE_NOTIFIER_1__0, _STATUS, notif0)) {
case NV_DISP_BASE_NOTIFIER_1__0_STATUS_NOT_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_NOT_BEGUN;
break;
case NV_DISP_BASE_NOTIFIER_1__0_STATUS_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_BEGUN;
break;
case NV_DISP_BASE_NOTIFIER_1__0_STATUS_FINISHED:
out->status = NVKMS_NOTIFIER_STATUS_FINISHED;
break;
}
out->presentCount =
DRF_VAL(_DISP, _BASE_NOTIFIER_1__0, _PRESENTATION_COUNT, notif0);
}
}
static void ParseNotifierFourWord(const void *in,
struct nvKmsParsedNotifier *out)
{
volatile const NvU32 *notif = in;
NvU32 notif3;
/* Read this once since it may be in video memory and we need multiple
* fields */
notif3 = notif[NV_DISP_NOTIFICATION_2_INFO16_3];
switch(DRF_VAL(_DISP, _NOTIFICATION_2__3, _STATUS, notif3)) {
case NV_DISP_NOTIFICATION_2__3_STATUS_NOT_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_NOT_BEGUN;
break;
case NV_DISP_NOTIFICATION_2__3_STATUS_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_BEGUN;
break;
case NV_DISP_NOTIFICATION_2__3_STATUS_FINISHED:
out->status = NVKMS_NOTIFIER_STATUS_FINISHED;
break;
}
out->presentCount =
DRF_VAL(_DISP, _NOTIFICATION_2_INFO16_3, _PRESENT_COUNT, notif3);
GetNotifierTimeStamp(notif,
NV_DISP_NOTIFICATION_2_TIME_STAMP_0,
NV_DISP_NOTIFICATION_2_TIME_STAMP_1,
out);
}
static void ParseNotifierFourWordNVDisplay(const void *in,
struct nvKmsParsedNotifier *out)
{
volatile const NvU32 *notif = in;
NvU32 notif0;
/* Read this once since it may be in video memory and we need multiple
* fields */
notif0 = notif[NV_DISP_NOTIFIER__0];
switch(DRF_VAL(_DISP, _NOTIFIER__0, _STATUS, notif0)) {
case NV_DISP_NOTIFIER__0_STATUS_NOT_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_NOT_BEGUN;
break;
case NV_DISP_NOTIFIER__0_STATUS_BEGUN:
out->status = NVKMS_NOTIFIER_STATUS_BEGUN;
break;
case NV_DISP_NOTIFIER__0_STATUS_FINISHED:
out->status = NVKMS_NOTIFIER_STATUS_FINISHED;
break;
}
out->presentCount =
DRF_VAL(_DISP, _NOTIFIER__0, _PRESENT_COUNT, notif0);
GetNotifierTimeStamp(notif,
NV_DISP_NOTIFIER__2,
NV_DISP_NOTIFIER__3,
out);
}
void nvKmsParseNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
NvU32 index, const void *base,
struct nvKmsParsedNotifier *out)
{
const NvU32 sizeInBytes = nvKmsSizeOfNotifier(format, overlay);
const void *notif =
(const void *)((const char *)base + (sizeInBytes * index));
switch (format) {
case NVKMS_NISO_FORMAT_LEGACY:
ParseNotifierLegacy(overlay, notif, out);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD:
ParseNotifierFourWord(notif, out);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
ParseNotifierFourWordNVDisplay(notif, out);
break;
}
}
NvU32 nvKmsSemaphorePayloadOffset(enum NvKmsNIsoFormat format)
{
switch (format) {
case NVKMS_NISO_FORMAT_LEGACY:
return 0;
case NVKMS_NISO_FORMAT_FOUR_WORD:
return NV_DISP_NOTIFICATION_2_INFO32_2;
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
return NV_DISP_NOTIFIER__0;
}
return 0;
}
static void ResetSemaphoreLegacy(volatile void *in, NvU32 payload)
{
volatile NvU32 *sema = in;
*sema = payload;
}
static void ResetSemaphoreFourWord(volatile void *in, NvU32 payload)
{
volatile NvU32 *sema = in;
sema[NV_DISP_NOTIFICATION_2_INFO32_2] = payload;
}
static void ResetSemaphoreFourWordNVDisplay(volatile void *in, NvU32 payload)
{
volatile NvU32 *sema = in;
sema[NV_DISP_NOTIFIER__0] = payload;
}
void nvKmsResetSemaphore(enum NvKmsNIsoFormat format,
NvU32 index, void *base,
NvU32 payload)
{
const NvU32 sizeInBytes = nvKmsSizeOfSemaphore(format);
void *sema =
(void *)((char *)base + (sizeInBytes * index));
switch (format) {
case NVKMS_NISO_FORMAT_LEGACY:
ResetSemaphoreLegacy(sema, payload);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD:
ResetSemaphoreFourWord(sema, payload);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
ResetSemaphoreFourWordNVDisplay(sema, payload);
break;
}
}
static NvU32 ParseSemaphoreLegacy(const volatile void *in)
{
const volatile NvU32 *sema = in;
return *sema;
}
static NvU32 ParseSemaphoreFourWord(const volatile void *in)
{
const volatile NvU32 *sema = in;
return sema[NV_DISP_NOTIFICATION_2_INFO32_2];
}
static NvU32 ParseSemaphoreFourWordNVDisplay(const volatile void *in)
{
const volatile NvU32 *sema = in;
return sema[NV_DISP_NOTIFIER__0];
}
void nvKmsParseSemaphore(enum NvKmsNIsoFormat format,
NvU32 index, const void *base,
struct nvKmsParsedSemaphore *out)
{
const NvU32 sizeInBytes = nvKmsSizeOfSemaphore(format);
const void *sema =
(const void *)((const char *)base + (sizeInBytes * index));
NvU32 payload = 0;
switch (format) {
case NVKMS_NISO_FORMAT_LEGACY:
payload = ParseSemaphoreLegacy(sema);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD:
payload = ParseSemaphoreFourWord(sema);
break;
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
payload = ParseSemaphoreFourWordNVDisplay(sema);
break;
}
out->payload = payload;
}