575.51.02

This commit is contained in:
Bernhard Stoeckner
2025-04-17 19:35:38 +02:00
parent e8113f665d
commit 4159579888
1142 changed files with 309085 additions and 272273 deletions

View File

@@ -32,6 +32,8 @@
#include "nvkms-utils.h"
#include "nvkms-kapi-private.h"
#include "nv_smg.h"
//XXX Decouple functions like nvEvoLog used for logging from NVKMS
#define nvKmsKapiLogDebug(__format...) \
@@ -107,9 +109,12 @@ struct NvKmsKapiDevice {
/* SMG state */
MIGDeviceId migDevice;
NvU32 smgGpuInstSubscriptionHdl;
NvU32 smgComputeInstSubscriptionHdl;
nvRMContext rmSmgContext;
/* Device capabilities */
struct {
@@ -124,6 +129,9 @@ struct NvKmsKapiDevice {
NvU8 genericPageKind;
NvBool requiresVrrSemaphores;
NvBool supportsInputColorSpace;
NvBool supportsInputColorRange;
} caps;
NvU64 supportedSurfaceMemoryFormats[NVKMS_KAPI_LAYER_MAX];
@@ -146,6 +154,9 @@ struct NvKmsKapiDevice {
void *privateData;
void (*eventCallback)(const struct NvKmsKapiEvent *event);
NvU64 vtFbBaseAddress;
NvU64 vtFbSize;
};
struct NvKmsKapiMemory {

View File

@@ -24,8 +24,10 @@
#if !defined(__NVKMS_KAPI_H__)
#include "nvtypes.h"
#include "nv_mig_types.h"
#include "nv-gpu-info.h"
#include "nv_dpy_id.h"
#include "nvkms-api-types.h"
#include "nvkms-format.h"
@@ -173,12 +175,18 @@ struct NvKmsKapiDeviceResourcesInfo {
NvBool supportsSyncpts;
NvBool requiresVrrSemaphores;
NvBool supportsInputColorRange;
NvBool supportsInputColorSpace;
} caps;
NvU64 supportedSurfaceMemoryFormats[NVKMS_KAPI_LAYER_MAX];
NvBool supportsICtCp[NVKMS_KAPI_LAYER_MAX];
struct NvKmsKapiLutCaps lutCaps;
NvU64 vtFbBaseAddress;
NvU64 vtFbSize;
};
#define NVKMS_KAPI_LAYER_MASK(layerType) (1 << (layerType))
@@ -204,6 +212,7 @@ struct NvKmsKapiConnectorInfo {
NvU32 numIncompatibleConnectors;
NvKmsKapiConnector incompatibleConnectorHandles[NVKMS_KAPI_MAX_CONNECTORS];
NVDpyIdList dynamicDpyIdList;
};
struct NvKmsKapiStaticDisplayInfo {
@@ -222,6 +231,8 @@ struct NvKmsKapiStaticDisplayInfo {
NvKmsKapiDisplay possibleCloneHandles[NVKMS_KAPI_MAX_CLONE_DISPLAYS];
NvU32 headMask;
NvBool isDpMST;
};
struct NvKmsKapiSyncParams {
@@ -260,7 +271,8 @@ struct NvKmsKapiLayerConfig {
NvBool enabled;
} hdrMetadata;
enum NvKmsOutputTf tf;
enum NvKmsInputTf inputTf;
enum NvKmsOutputTf outputTf;
NvU8 minPresentInterval;
NvBool tearing;
@@ -272,6 +284,7 @@ struct NvKmsKapiLayerConfig {
NvU16 dstWidth, dstHeight;
enum NvKmsInputColorSpace inputColorSpace;
enum NvKmsInputColorRange inputColorRange;
struct {
NvBool enabled;
@@ -315,7 +328,10 @@ struct NvKmsKapiLayerRequestedConfig {
NvBool dstXYChanged : 1;
NvBool dstWHChanged : 1;
NvBool cscChanged : 1;
NvBool tfChanged : 1;
NvBool inputTfChanged : 1;
NvBool outputTfChanged : 1;
NvBool inputColorSpaceChanged : 1;
NvBool inputColorRangeChanged : 1;
NvBool hdrMetadataChanged : 1;
NvBool matrixOverridesChanged : 1;
NvBool ilutChanged : 1;
@@ -481,6 +497,8 @@ struct NvKmsKapiEvent {
struct NvKmsKapiAllocateDeviceParams {
/* [IN] GPU ID obtained from enumerateGpus() */
NvU32 gpuId;
/* [IN] MIG device if requested */
MIGDeviceId migDevice;
/* [IN] Private data of device allocator */
void *privateData;
@@ -563,6 +581,11 @@ typedef enum NvKmsKapiRegisterWaiterResultRec {
typedef void NvKmsKapiSuspendResumeCallbackFunc(NvBool suspend);
struct NvKmsKapiGpuInfo {
nv_gpu_info_t gpuInfo;
MIGDeviceId migDevice;
};
struct NvKmsKapiFunctionsTable {
/*!
@@ -586,7 +609,7 @@ struct NvKmsKapiFunctionsTable {
*
* \return Count of enumerated gpus.
*/
NvU32 (*enumerateGpus)(nv_gpu_info_t *gpuInfo);
NvU32 (*enumerateGpus)(struct NvKmsKapiGpuInfo *kapiGpuInfo);
/*!
* Allocate an NVK device using which you can query/allocate resources on
@@ -1559,6 +1582,26 @@ struct NvKmsKapiFunctionsTable {
NvS32 index
);
/*!
* Check or wait on a head's LUT notifier.
*
* \param [in] device A device allocated using allocateDevice().
*
* \param [in] head The head to check for LUT completion.
*
* \param [in] waitForCompletion If true, wait for the notifier in NvKms
* before returning.
*
* \param [out] complete Returns whether the notifier has completed.
*/
NvBool
(*checkLutNotifier)
(
struct NvKmsKapiDevice *device,
NvU32 head,
NvBool waitForCompletion
);
/*
* Notify NVKMS that the system's framebuffer console has been disabled and
* the reserved allocation for the old framebuffer console can be unmapped.

View File

@@ -58,6 +58,8 @@
#include "ctrl/ctrl003e.h" /* NV003E_CTRL_CMD_GET_SURFACE_PHYS_PAGES */
#include "ctrl/ctrl0041.h" /* NV0041_CTRL_SURFACE_INFO */
#include "nv_smg.h"
ct_assert(NVKMS_KAPI_LAYER_PRIMARY_IDX == NVKMS_MAIN_LAYER);
ct_assert(NVKMS_KAPI_LAYER_MAX == NVKMS_MAX_LAYERS_PER_HEAD);
@@ -69,9 +71,73 @@ ct_assert(NVKMS_KAPI_LAYER_MAX == NVKMS_MAX_LAYERS_PER_HEAD);
(1 << NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED) | \
(1 << NVKMS_EVENT_TYPE_FLIP_OCCURRED))
static NvU32 EnumerateGpus(nv_gpu_info_t *gpuInfo)
static NvU32 EnumerateGpus(struct NvKmsKapiGpuInfo *kapiGpuInfo)
{
return nvkms_enumerate_gpus(gpuInfo);
nv_gpu_info_t *gpu_info = NULL;
nvMIGDeviceDescription *activeDevices = NULL;
NvU32 activeDeviceCount = 0;
NvU32 gpuCount;
NvU32 kapiGpuCount;
if (NV_OK != nvSMGGetDeviceList(&nvEvoGlobal.rmSmgContext,
&activeDevices,
&activeDeviceCount)) {
return 0;
}
gpu_info = nvkms_alloc(NV_MAX_GPUS * sizeof(*gpu_info), NV_TRUE);
if (!gpu_info) {
return 0;
}
/*
* Enumerate physical GPUs and generate an expanded list where entries
* for GPUs in MIG mode are replaced by a list of MIG GPUs on that GPU.
*/
gpuCount = nvkms_enumerate_gpus(gpu_info);
kapiGpuCount = 0;
for (NvU32 i = 0; i < gpuCount; i++) {
NvBool foundMig = NV_FALSE;
for (NvU32 j = 0; j < activeDeviceCount; j++) {
/* Fail completely if we run out of array space. */
if (kapiGpuCount == NV_MAX_GPUS) {
nvKmsKapiLogDebug("Failed to enumerate devices: out of memory");
kapiGpuCount = 0;
break;
}
/*
* Return an NvKmsKapiGpuInfo for each active device found for
* the current gpu_id. For regular GPUs this will only be one
* but in MIG mode the same gpu_id can host multiple MIG
* devices.
*/
if (activeDevices[j].gpuId == gpu_info[i].gpu_id) {
kapiGpuInfo[kapiGpuCount].gpuInfo = gpu_info[i];
kapiGpuInfo[kapiGpuCount].migDevice = activeDevices[j].migDeviceId;
kapiGpuCount++;
foundMig = NV_TRUE;
}
}
if (!foundMig) {
if (kapiGpuCount == NV_MAX_GPUS) {
nvKmsKapiLogDebug("Failed to enumerate devices: out of memory");
kapiGpuCount = 0;
break;
}
kapiGpuInfo[kapiGpuCount].gpuInfo = gpu_info[i];
kapiGpuInfo[kapiGpuCount].migDevice = NO_MIG_DEVICE;
kapiGpuCount++;
}
}
nvkms_free(gpu_info, NV_MAX_GPUS * sizeof(*gpu_info));
return kapiGpuCount;
}
/*
@@ -79,8 +145,14 @@ static NvU32 EnumerateGpus(nv_gpu_info_t *gpuInfo)
*/
static void RmFreeDevice(struct NvKmsKapiDevice *device)
{
nvKmsKapiFreeRmHandle(device, device->smgGpuInstSubscriptionHdl);
nvKmsKapiFreeRmHandle(device, device->smgComputeInstSubscriptionHdl);
if (device->smgGpuInstSubscriptionHdl != 0x0) {
nvKmsKapiFreeRmHandle(device, device->smgGpuInstSubscriptionHdl);
device->smgGpuInstSubscriptionHdl = 0x0;
}
if (device->smgComputeInstSubscriptionHdl != 0x0) {
nvKmsKapiFreeRmHandle(device, device->smgComputeInstSubscriptionHdl);
device->smgComputeInstSubscriptionHdl = 0x0;
}
if (device->hRmSubDevice != 0x0) {
nvRmApiFree(device->hRmClient,
@@ -117,27 +189,21 @@ static void RmFreeDevice(struct NvKmsKapiDevice *device)
}
/*
* Wrappers to help NVSubdevSMG access NvKmsKapiDevice's RM abstraction.
* Wrappers to help SMG access NvKmsKAPI's RM context.
*/
static NvU32 NvKmsSmgRMControl(void *ctx, NvU32 object, NvU32 cmd, void *params, NvU32 paramsSize)
static NvU32 NvKmsKapiRMControl(nvRMContextPtr rmctx, NvU32 client, NvU32 object, NvU32 cmd, void *params, NvU32 paramsSize)
{
struct NvKmsKapiDevice *pDev = (struct NvKmsKapiDevice *)ctx;
return nvRmApiControl(pDev->hRmClient, object, cmd, params, paramsSize);
return nvRmApiControl(client, object, cmd, params, paramsSize);
}
static NvU32 NvKmsSmgRMAlloc(void *ctx, NvHandle parent, NvHandle object, NvU32 class, void *allocParams)
static NvU32 NvKmsKapiRMAlloc(nvRMContextPtr rmctx, NvU32 client, NvHandle parent, NvHandle object, NvU32 cls, void *allocParams)
{
struct NvKmsKapiDevice *pDev = (struct NvKmsKapiDevice *)ctx;
return nvRmApiAlloc(pDev->hRmClient, parent, object, class, allocParams);
return nvRmApiAlloc(client, parent, object, cls, allocParams);
}
static NvU32 NvKmsSmgRMFree(void *ctx, NvHandle parent, NvHandle object)
static NvU32 NvKmsKapiRMFree(nvRMContextPtr rmctx, NvU32 client, NvHandle parent, NvHandle object)
{
struct NvKmsKapiDevice *pDev = (struct NvKmsKapiDevice *)ctx;
return nvRmApiFree(pDev->hRmClient, parent, object);
return nvRmApiFree(client, parent, object);
}
/*
@@ -168,6 +234,13 @@ static NvBool RmAllocateDevice(struct NvKmsKapiDevice *device)
goto failed;
}
/* Initialize RM context */
device->rmSmgContext.clientHandle = device->hRmClient;
device->rmSmgContext.control = NvKmsKapiRMControl;
device->rmSmgContext.alloc = NvKmsKapiRMAlloc;
device->rmSmgContext.free = NvKmsKapiRMFree;
/* Query device instance */
idInfoParams.gpuId = device->gpuId;
@@ -266,23 +339,22 @@ static NvBool RmAllocateDevice(struct NvKmsKapiDevice *device)
device->hRmSubDevice = hRmSubDevice;
device->smgGpuInstSubscriptionHdl = nvKmsKapiGenerateRmHandle(device);
device->smgComputeInstSubscriptionHdl = nvKmsKapiGenerateRmHandle(device);
if (device->migDevice != NO_MIG_DEVICE) {
device->smgGpuInstSubscriptionHdl = nvKmsKapiGenerateRmHandle(device);
device->smgComputeInstSubscriptionHdl = nvKmsKapiGenerateRmHandle(device);
if (!device->smgGpuInstSubscriptionHdl || !device->smgComputeInstSubscriptionHdl) {
goto failed;
}
if (!device->smgGpuInstSubscriptionHdl || !device->smgComputeInstSubscriptionHdl) {
goto failed;
}
if (!NVSubdevSMGSetPartition(device,
device->hRmSubDevice,
NULL,
device->smgGpuInstSubscriptionHdl,
device->smgComputeInstSubscriptionHdl,
NvKmsSmgRMControl,
NvKmsSmgRMAlloc,
NvKmsSmgRMFree)) {
nvKmsKapiLogDeviceDebug(device, "Unable to configure SMG partition in SMC mode");
goto failed;
if (!nvSMGSubscribeSubDevToPartition(&device->rmSmgContext,
device->hRmSubDevice,
device->migDevice,
device->smgGpuInstSubscriptionHdl,
device->smgComputeInstSubscriptionHdl)) {
nvKmsKapiLogDeviceDebug(device, "Unable to configure MIG (Multi-Instance GPU) partition");
goto failed;
}
}
if (device->isSOC) {
@@ -304,7 +376,7 @@ static NvBool RmAllocateDevice(struct NvKmsKapiDevice *device)
NV0080_CTRL_FB_CAPS_GENERIC_PAGE_KIND);
}
device->caps.genericPageKind =
device->caps.genericPageKind =
supportsGenericPageKind ?
0x06 /* NV_MMU_PTE_KIND_GENERIC_MEMORY */ :
0xfe /* NV_MMU_PTE_KIND_GENERIC_16BX2 */;
@@ -383,11 +455,8 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
NV_VERSION_STRING,
sizeof(paramsAlloc->request.versionString));
if (device->isSOC) {
paramsAlloc->request.deviceId = NVKMS_DEVICE_ID_TEGRA;
} else {
paramsAlloc->request.deviceId = device->deviceInstance;
}
paramsAlloc->request.deviceId.rmDeviceId = device->deviceInstance;
paramsAlloc->request.deviceId.migDevice = device->migDevice;
paramsAlloc->request.sliMosaic = NV_FALSE;
paramsAlloc->request.enableConsoleHotplugHandling = NV_TRUE;
@@ -413,7 +482,7 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
device,
"Failed to NVKM device %u(%u): %d %d\n",
device->gpuId,
paramsAlloc->request.deviceId,
paramsAlloc->request.deviceId.rmDeviceId,
status,
paramsAlloc->reply.status);
@@ -436,10 +505,19 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
device->caps.maxCursorSizeInPixels = paramsAlloc->reply.maxCursorSize;
device->caps.requiresVrrSemaphores = paramsAlloc->reply.requiresVrrSemaphores;
device->caps.supportsInputColorSpace =
paramsAlloc->reply.supportsInputColorSpace;
device->caps.supportsInputColorRange =
paramsAlloc->reply.supportsInputColorRange;
/* XXX Add LUT support */
device->numHeads = paramsAlloc->reply.numHeads;
device->vtFbBaseAddress = paramsAlloc->reply.vtFbBaseAddress;
device->vtFbSize = paramsAlloc->reply.vtFbSize;
for (head = 0; head < device->numHeads; head++) {
if (paramsAlloc->reply.numLayers[head] < 1) {
goto done;
@@ -855,6 +933,7 @@ static struct NvKmsKapiDevice* AllocateDevice
}
device->gpuId = params->gpuId;
device->migDevice = params->migDevice;
nvKmsKapiLogDebug(
"Allocating NvKmsKapiDevice 0x%p for GPU ID 0x%08x",
@@ -924,7 +1003,7 @@ static void ReleaseOwnership(struct NvKmsKapiDevice *device)
static NvBool GrantPermissions
(
NvS32 fd,
NvS32 fd,
struct NvKmsKapiDevice *device,
NvU32 head,
NvKmsKapiDisplay display
@@ -1087,6 +1166,9 @@ static NvBool GetDeviceResourcesInfo
info->caps.genericPageKind = device->caps.genericPageKind;
info->caps.requiresVrrSemaphores = device->caps.requiresVrrSemaphores;
info->vtFbBaseAddress = device->vtFbBaseAddress;
info->vtFbSize = device->vtFbSize;
if (device->hKmsDevice == 0x0) {
info->caps.pitchAlignment = 0x1;
return NV_TRUE;
@@ -1157,6 +1239,8 @@ static NvBool GetDeviceResourcesInfo
info->caps.pitchAlignment = NV_EVO_PITCH_ALIGNMENT;
info->caps.supportsSyncpts = device->supportsSyncpts;
info->caps.supportsInputColorRange = device->caps.supportsInputColorRange;
info->caps.supportsInputColorSpace = device->caps.supportsInputColorSpace;
info->caps.supportedCursorSurfaceMemoryFormats =
NVBIT(NvKmsSurfaceMemoryFormatA8R8G8B8);
@@ -1248,7 +1332,10 @@ static NvBool GetConnectorInfo
)
{
struct NvKmsQueryConnectorStaticDataParams paramsConnector = { };
struct NvKmsQueryConnectorDynamicDataParams paramsDynamicConnector = { };
NvBool status = NV_FALSE;
NvU64 startTime = 0;
NvBool timeout;
if (device == NULL || info == NULL) {
goto done;
@@ -1279,6 +1366,44 @@ static NvBool GetConnectorInfo
info->type = paramsConnector.reply.type;
startTime = nvkms_get_usec();
do {
nvkms_memset(&paramsDynamicConnector, 0, sizeof(paramsDynamicConnector));
paramsDynamicConnector.request.deviceHandle = device->hKmsDevice;
paramsDynamicConnector.request.dispHandle = device->hKmsDisp;
paramsDynamicConnector.request.connectorHandle = connector;
if (!nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_QUERY_CONNECTOR_DYNAMIC_DATA,
&paramsDynamicConnector,
sizeof(paramsDynamicConnector))) {
nvKmsKapiLogDeviceDebug(
device,
"Failed to query dynamic data of connector 0x%08x",
connector);
status = NV_FALSE;
goto done;
}
timeout = nvkms_get_usec() - startTime >
NVKMS_DP_DETECT_COMPLETE_TIMEOUT_USEC;
if (!paramsDynamicConnector.reply.detectComplete && !timeout) {
nvkms_usleep(NVKMS_DP_DETECT_COMPLETE_POLL_INTERVAL_USEC);
}
} while (!paramsDynamicConnector.reply.detectComplete && !timeout);
if (!paramsDynamicConnector.reply.detectComplete) {
nvKmsKapiLogDeviceDebug(device, "Timed out waiting for DisplayPort"
" device detection to complete.");
status = NV_FALSE;
}
info->dynamicDpyIdList = paramsDynamicConnector.reply.dynamicDpyIdList;
done:
return status;
@@ -1331,6 +1456,7 @@ static NvBool GetStaticDisplayInfo
info->internal = paramsDpyStatic.reply.mobileInternal;
info->headMask = paramsDpyStatic.reply.headMask;
info->isDpMST = paramsDpyStatic.reply.isDpMST;
done:
return status;
@@ -1391,8 +1517,6 @@ static NvBool GetDynamicDisplayInfo(
params->connected = pParamsDpyDynamic->reply.connected;
if (pParamsDpyDynamic->reply.connected && !params->overrideEdid) {
NvBool vrrSupported =
(pParamsDpyDynamic->reply.vrrType != NVKMS_DPY_VRR_TYPE_NONE) ? NV_TRUE : NV_FALSE;
nvkms_memcpy(
params->edid.buffer,
@@ -1400,6 +1524,11 @@ static NvBool GetDynamicDisplayInfo(
sizeof(params->edid.buffer));
params->edid.bufferSize = pParamsDpyDynamic->reply.edid.bufferSize;
}
if (pParamsDpyDynamic->reply.connected) {
NvBool vrrSupported =
(pParamsDpyDynamic->reply.vrrType != NVKMS_DPY_VRR_TYPE_NONE) ? NV_TRUE : NV_FALSE;
params->vrrSupported = vrrSupported;
}
@@ -2154,8 +2283,6 @@ static NvBool GetSurfaceParams(
return FALSE;
}
pitch[i] = params->planes[i].pitch;
if (i == 0) {
if (params->explicit_layout) {
layout = params->layout;
@@ -2201,6 +2328,7 @@ static NvBool GetSurfaceParams(
if (layout == NvKmsSurfaceMemoryLayoutBlockLinear) {
if (params->explicit_layout) {
pitch[i] = params->planes[i].pitch;
if (pitch[i] & 63) {
nvKmsKapiLogDebug(
"Invalid block-linear pitch alignment: %u", pitch[i]);
@@ -2612,7 +2740,7 @@ static NvBool AssignSyncObjectConfig(
return NV_TRUE;
}
static void AssignHDRMetadataConfig(
static NvBool AssignHDRMetadataConfig(
const struct NvKmsKapiLayerConfig *layerConfig,
const struct NvKmsKapiLayerRequestedConfig *layerRequestedConfig,
const NvU32 layer,
@@ -2627,9 +2755,11 @@ static void AssignHDRMetadataConfig(
params->layer[layer].hdr.staticMetadata =
layerConfig->hdrMetadata.val;
}
return params->layer[layer].hdr.specified;
}
static void AssignLayerLutConfig(
static NvBool AssignLayerLutConfig(
const struct NvKmsKapiDevice *device,
const struct NvKmsKapiLayerConfig *layerConfig,
const struct NvKmsKapiLayerRequestedConfig *layerRequestedConfig,
@@ -2637,6 +2767,8 @@ static void AssignLayerLutConfig(
struct NvKmsFlipCommonParams *params,
NvBool bFromKmsSetMode)
{
NvBool changed = FALSE;
if ((device->lutCaps.layer[layer].ilut.supported) &&
(layerRequestedConfig->flags.ilutChanged || bFromKmsSetMode)) {
@@ -2654,6 +2786,8 @@ static void AssignLayerLutConfig(
layerConfig->ilut.vssSegments;
params->layer[layer].ilut.lut.lutEntries =
layerConfig->ilut.lutEntries;
changed = TRUE;
}
if ((device->lutCaps.layer[layer].tmo.supported) &&
@@ -2673,7 +2807,11 @@ static void AssignLayerLutConfig(
layerConfig->tmo.vssSegments;
params->layer[layer].tmo.lut.lutEntries =
layerConfig->tmo.lutEntries;
changed = TRUE;
}
return changed;
}
static void NvKmsKapiCursorConfigToKms(
@@ -2740,9 +2878,6 @@ static NvBool NvKmsKapiOverlayLayerConfigToKms(
params->layer[layer].compositionParams.specified = TRUE;
params->layer[layer].minPresentInterval =
layerConfig->minPresentInterval;
params->layer[layer].colorSpace.val = layerConfig->inputColorSpace;
params->layer[layer].colorSpace.specified = TRUE;
}
if (layerRequestedConfig->flags.cscChanged ||
@@ -2781,6 +2916,21 @@ static NvBool NvKmsKapiOverlayLayerConfigToKms(
params->layer[layer].outputPosition.specified = NV_TRUE;
}
if (layerRequestedConfig->flags.inputColorSpaceChanged || bFromKmsSetMode) {
params->layer[layer].colorSpace.val = layerConfig->inputColorSpace;
params->layer[layer].colorSpace.specified = TRUE;
}
if (layerRequestedConfig->flags.inputTfChanged || bFromKmsSetMode) {
params->layer[layer].tf.val = layerConfig->inputTf;
params->layer[layer].tf.specified = TRUE;
}
if (layerRequestedConfig->flags.inputColorRangeChanged || bFromKmsSetMode) {
params->layer[layer].colorRange.val = layerConfig->inputColorRange;
params->layer[layer].colorSpace.specified = TRUE;
}
AssignHDRMetadataConfig(layerConfig, layerRequestedConfig, layer,
params, bFromKmsSetMode);
@@ -2913,9 +3063,6 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
}
}
params->layer[NVKMS_MAIN_LAYER].colorSpace.val = layerConfig->inputColorSpace;
params->layer[NVKMS_MAIN_LAYER].colorSpace.specified = TRUE;
changed = TRUE;
}
@@ -2945,8 +3092,31 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
changed = TRUE;
}
AssignHDRMetadataConfig(layerConfig, layerRequestedConfig, NVKMS_MAIN_LAYER,
params, bFromKmsSetMode);
if (layerRequestedConfig->flags.inputColorSpaceChanged || bFromKmsSetMode) {
params->layer[NVKMS_MAIN_LAYER].colorSpace.val = layerConfig->inputColorSpace;
params->layer[NVKMS_MAIN_LAYER].colorSpace.specified = TRUE;
changed = TRUE;
}
if (layerRequestedConfig->flags.inputTfChanged || bFromKmsSetMode) {
params->layer[NVKMS_MAIN_LAYER].tf.val = layerConfig->inputTf;
params->layer[NVKMS_MAIN_LAYER].tf.specified = TRUE;
changed = TRUE;
}
if (layerRequestedConfig->flags.inputColorRangeChanged || bFromKmsSetMode) {
params->layer[NVKMS_MAIN_LAYER].colorRange.val = layerConfig->inputColorRange;
params->layer[NVKMS_MAIN_LAYER].colorRange.specified = TRUE;
changed = TRUE;
}
if (AssignHDRMetadataConfig(layerConfig, layerRequestedConfig,
NVKMS_MAIN_LAYER, params, bFromKmsSetMode)) {
changed = TRUE;
}
if (layerRequestedConfig->flags.matrixOverridesChanged || bFromKmsSetMode) {
// 'lmsCtm' explicitly provides a matrix to program CSC00.
@@ -2992,8 +3162,10 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
changed = TRUE;
}
AssignLayerLutConfig(device, layerConfig, layerRequestedConfig, NVKMS_MAIN_LAYER,
params, bFromKmsSetMode);
if (AssignLayerLutConfig(device, layerConfig, layerRequestedConfig,
NVKMS_MAIN_LAYER, params, bFromKmsSetMode)) {
changed = TRUE;
}
if (commit && changed) {
NvU32 nextIndex = NVKMS_KAPI_INC_NOTIFIER_INDEX(
@@ -3096,7 +3268,7 @@ static void NvKmsKapiHeadLutConfigToKms(
}
}
static NvBool AnyLayerTransferFunctionChanged(
static NvBool AnyLayerOutputTransferFunctionChanged(
const struct NvKmsKapiHeadRequestedConfig *headRequestedConfig)
{
NvU32 layer;
@@ -3107,7 +3279,7 @@ static NvBool AnyLayerTransferFunctionChanged(
const struct NvKmsKapiLayerRequestedConfig *layerRequestedConfig =
&headRequestedConfig->layerRequestedConfig[layer];
if (layerRequestedConfig->flags.tfChanged) {
if (layerRequestedConfig->flags.outputTfChanged) {
return NV_TRUE;
}
}
@@ -3134,9 +3306,9 @@ static NvBool GetOutputTransferFunction(
if (layerConfig->hdrMetadata.enabled) {
if (!found) {
*tf = layerConfig->tf;
*tf = layerConfig->outputTf;
found = NV_TRUE;
} else if (*tf != layerConfig->tf) {
} else if (*tf != layerConfig->outputTf) {
nvKmsKapiLogDebug(
"Output transfer function should be the same for all layers on a head");
return NV_FALSE;
@@ -3452,7 +3624,7 @@ static NvBool KmsFlip(
}
flipParams->tf.specified =
AnyLayerTransferFunctionChanged(headRequestedConfig);
AnyLayerOutputTransferFunctionChanged(headRequestedConfig);
if (flipParams->tf.specified) {
enum NvKmsOutputTf tf;
status = GetOutputTransferFunction(headRequestedConfig, &tf);
@@ -3801,6 +3973,31 @@ static NvBool SignalVrrSemaphore
return status;
}
static NvBool CheckLutNotifier
(
struct NvKmsKapiDevice *device,
NvU32 head,
NvBool waitForCompletion
)
{
NvBool status = NV_TRUE;
struct NvKmsCheckLutNotifierParams params = { };
params.request.deviceHandle = device->hKmsDevice;
params.request.dispHandle = device->hKmsDisp;
params.request.head = head;
params.request.waitForCompletion = waitForCompletion;
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_CHECK_LUT_NOTIFIER,
&params, sizeof(params));
/*
* In cases where we're first enabling a head, we would expect status to be
* false, but in that case, there's no LUT notifier to wait for, so treat
* that case as complete.
*/
return !status || params.reply.complete;
}
static void FramebufferConsoleDisabled
(
struct NvKmsKapiDevice *device
@@ -3907,6 +4104,7 @@ NvBool nvKmsKapiGetFunctionsTableInternal
funcsTable->signalDisplaySemaphore = nvKmsKapiSignalDisplaySemaphore;
funcsTable->cancelDisplaySemaphore = nvKmsKapiCancelDisplaySemaphore;
funcsTable->signalVrrSemaphore = SignalVrrSemaphore;
funcsTable->checkLutNotifier = CheckLutNotifier;
return NV_TRUE;
}