555.42.02

(cherry picked from commit 5a1c474040)
This commit is contained in:
Bernhard Stoeckner
2024-05-21 15:11:46 +02:00
committed by Gaurav Juvekar
parent caa2dd11a0
commit 3084c04453
1004 changed files with 172522 additions and 150960 deletions

View File

@@ -59,8 +59,7 @@ NvBool nvDPLibIsModePossible(const NVDPLibConnectorRec *pDpLibConnector,
NvBool nvDPValidateModeForDpyEvo(
const NVDpyEvoRec *pDpyEvo,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc,
const NVDpyAttributeColor *pDpyColor,
const struct NvKmsModeValidationParams *pModeValidationParams,
const NVHwModeTimingsEvo *pTimings,
const NvBool b2Heads1Or,
@@ -90,6 +89,8 @@ enum NVDpLinkMode {
enum NVDpLinkMode nvDPGetActiveLinkMode(NVDPLibConnectorPtr pDpLibConnector);
void nvDPSetLinkHandoff(NVDPLibConnectorPtr pDpLibConnector, NvBool enable);
#ifdef __cplusplus
};
#endif

View File

@@ -163,6 +163,7 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct NvKmsModeValidationParams
*pParams,
@@ -173,23 +174,21 @@ NvBool nvConstructHwModeTimingsImpCheckEvo(
const NVHwModeTimingsEvo *pTimings,
const NvBool enableDsc,
const NvBool b2Heads1Or,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc,
const NVDpyAttributeColor *pDpyColor,
const struct NvKmsModeValidationParams *pParams,
NVHwModeTimingsEvo timings[NVKMS_MAX_HEADS_PER_DISP],
NvU32 *pNumHeads,
NVEvoInfoStringPtr pInfoString);
NvBool nvDowngradeColorBpc(NVDpyAttributeColor *pDpyColor);
NvBool nvDowngradeColorSpaceAndBpc(
const NVColorFormatInfoRec *pSupportedColorFormats,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
enum NvKmsDpyAttributeColorRangeValue *pColorRange);
NVDpyAttributeColor *pDpyColor);
NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
NVHwModeTimingsEvoPtr pTimings,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
NVDscInfoEvoRec *pDscInfo,
const struct NvKmsModeValidationParams *pParams);
@@ -257,8 +256,7 @@ NvBool nvChooseColorRangeEvo(
NvBool nvChooseCurrentColorSpaceAndRangeEvo(
const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
NvU8 hdmiFrlBpc,
const enum NvYuv420Mode yuv420Mode,
enum NvKmsOutputColorimetry colorimetry,
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
@@ -269,13 +267,13 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
NVDispEvoPtr pDispEvo,
const NvU32 head,
const enum NvKmsOutputColorimetry colorimetry,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorRangeValue colorRange,
const NVDpyAttributeColor *pDpyColor,
NVEvoUpdateState *pUpdateState);
NvBool nvAssignSOREvo(const NVDispEvoRec *pDispEvo, const NvU32 displayId,
const NvBool b2Heads1Or, const NvU32 sorExcludeMask);
NvBool nvAssignSOREvo(const NVConnectorEvoRec *pConnectorEvo,
const NvU32 targetDisplayId,
const NvBool b2Heads1Or,
const NvU32 sorExcludeMask);
void nvSetSwapBarrierNotifyEvo(NVDispEvoPtr pDispEvo,
NvBool enable, NvBool isPre);
@@ -343,17 +341,14 @@ NvBool nvNeedsTmoLut(NVDevEvoPtr pDevEvo,
NvBool nvIsCscMatrixIdentity(const struct NvKmsCscMatrix *matrix);
enum nvKmsPixelDepth nvEvoColorSpaceBpcToPixelDepth(
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc);
enum nvKmsPixelDepth nvEvoDpyColorToPixelDepth(
const NVDpyAttributeColor *pDpyColor);
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo);
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo);
NvBool nvGetDefaultColorSpace(
const NVColorFormatInfoRec *pColorFormatsInfo,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc);
NvBool nvGetDefaultDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
NVDpyAttributeColor *pDpyColor);
static inline void nvEvoSetFlipOccurredEvent(const NVDispEvoRec *pDispEvo,
const NvU32 head,

View File

@@ -29,6 +29,8 @@
#include "nvkms-softfloat.h"
#include <class/clc57d.h> // NVC57D_CORE_CHANNEL_DMA
#include <ctrl/ctrlc372/ctrlc372chnc.h>
#define NV_EVO3_X_EMULATED_SURFACE_MEMORY_FORMATS_C6 \
(NVBIT64(NvKmsSurfaceMemoryFormatRF16GF16BF16XF16) | \
NVBIT64(NvKmsSurfaceMemoryFormatX2B10G10R10))
@@ -106,6 +108,15 @@ void nvEvoUpdateC3(NVDevEvoPtr pDevEvo,
const NVEvoUpdateState *updateState,
NvBool releaseElv);
NvBool
nvEvoSetCtrlIsModePossibleParams3(NVDispEvoPtr pDispEvo,
const NVEvoIsModePossibleDispInput *pInput,
NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp);
void
nvEvoSetIsModePossibleDispOutput3(const NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp,
const NvBool result,
NVEvoIsModePossibleDispOutput *pOutput);
void
nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
const NVEvoIsModePossibleDispInput *pInput,

View File

@@ -29,12 +29,9 @@
typedef struct {
struct {
enum NvKmsOutputTf tf;
enum NvKmsOutputColorimetry colorimetry;
NVDpyAttributeColor dpyColor;
NvBool infoFrameOverride;
NvU32 staticMetadataLayerMask;
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace;
enum NvKmsDpyAttributeColorBpcValue colorBpc;
enum NvKmsDpyAttributeColorRangeValue colorRange;
} hdr;
struct NvKmsPoint viewPortPointIn;

View File

@@ -32,7 +32,7 @@ extern "C" {
void nvUpdateHdmiInfoFrames(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NVAttributesSetEvoRec *pAttributesSet,
const NVDpyAttributeColor *pDpyColor,
const NVDispHeadInfoFrameStateEvoRec *pInfoFrameState,
NVDpyEvoRec *pDpyEvo);
@@ -64,10 +64,10 @@ NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo);
NvBool nvHdmiFrlQueryConfig(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
HDMI_FRL_CONFIG *pConfig,
NvU8 *pHdmiFrlBpc,
NVDscInfoEvoRec *pDscInfo);
void nvHdmiFrlClearConfig(NVDispEvoRec *pDispEvo, NvU32 activeRmId);
void nvHdmiFrlSetConfig(NVDispEvoRec *pDispEvo, NvU32 head);
@@ -76,9 +76,9 @@ void nvHdmiDpConstructHeadAudioState(const NvU32 displayId,
const NVDpyEvoRec *pDpyEvo,
NVDispHeadAudioStateEvoRec *pAudioState);
NvBool nvHdmiTimingsNeedFrl(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
NvU8 bpc);
NvU32 nvHdmiGetEffectivePixelClockKHz(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor);
static inline NvBool nvHdmiDpySupportsDsc(const NVDpyEvoRec *pDpyEvo)
{

View File

@@ -49,6 +49,7 @@ NvBool nvValidateModeForModeset(NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvo *pTimingsEvo,
NVT_VIDEO_INFOFRAME_CTRL *pInfoFrameCtrl);

View File

@@ -41,7 +41,6 @@ typedef struct {
NVDscInfoEvoRec dscInfo;
NVDispHeadInfoFrameStateEvoRec infoFrame;
enum NvKmsOutputTf tf;
enum NvKmsOutputColorimetry colorimetry;
NvBool hdrInfoFrameOverride;
NvU32 hdrStaticMetadataLayerMask;
NvBool colorSpaceSpecified : 1;
@@ -55,7 +54,6 @@ typedef struct {
NVHwModeTimingsEvo timings;
NVConnectorEvoRec *pConnectorEvo;
HDMI_FRL_CONFIG hdmiFrlConfig;
NvU8 hdmiFrlBpc;
NVDPLibModesetStatePtr pDpLibModesetState;
NVDispHeadAudioStateEvoRec audio;
} NVProposedModeSetHwStateOneHead;

View File

@@ -33,8 +33,10 @@ extern "C" {
NvBool
nvGetHwModeTimings(const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
NVHwModeTimingsEvo *pTimings,
NVDpyAttributeColor *pDpyColor,
NVT_VIDEO_INFOFRAME_CTRL *pInfoFrameCtrl);
NvBool nvGetAllowHeadSurfaceInNvKms(const NVDevEvoRec *pDevEvo,

View File

@@ -64,6 +64,11 @@ NVSurfaceEvoPtr nvEvoGetSurfaceFromHandleNoDispHWAccessOk(
const NVEvoApiHandlesRec *pOpenDevSurfaceHandles,
NvKmsSurfaceHandle surfaceHandle);
NVSurfaceEvoPtr nvEvoGetSurfaceFromHandleNoHWAccess(
const NVDevEvoRec *pDevEvo,
const NVEvoApiHandlesRec *pOpenDevSurfaceHandles,
NvKmsSurfaceHandle surfaceHandle);
NVDeferredRequestFifoRec *nvEvoRegisterDeferredRequestFifo(
NVDevEvoPtr pDevEvo,
NVSurfaceEvoPtr pSurfaceEvo);
@@ -75,7 +80,7 @@ void nvEvoUnregisterDeferredRequestFifo(
NVVblankSemControl *nvEvoEnableVblankSemControl(
NVDevEvoRec *pDevEvo,
NVDispEvoRec *pDispEvo,
NvU32 hwHead,
NvU32 apiHeadMask,
NVSurfaceEvoRec *pSurfaceEvo,
NvU64 surfaceOffset);

View File

@@ -178,7 +178,9 @@ typedef struct _NVEvoApiHandlesRec {
typedef struct _NVSurfaceDescriptor
{
NvU32 ctxDmaHandle;
NvU64 iovaAddress;
NvU32 memAperture;
NvU64 memOffset;
NvBool bValid;
} NVSurfaceDescriptor;
typedef struct _NVEvoDma
@@ -705,8 +707,6 @@ typedef struct {
struct NvKmsHDRStaticMetadata staticMetadata;
} hdrInfoFrame;
enum NvKmsOutputColorimetry colorimetry;
NvBool skipLayerPendingFlips[NVKMS_MAX_LAYERS_PER_HEAD];
struct {
@@ -715,7 +715,6 @@ typedef struct {
NvBool cursorPosition : 1;
NvBool tf : 1;
NvBool hdrStaticMetadata : 1;
NvBool colorimetry : 1;
NvBool layerPosition[NVKMS_MAX_LAYERS_PER_HEAD];
NvBool layerSyncObjects[NVKMS_MAX_LAYERS_PER_HEAD];
@@ -1661,14 +1660,7 @@ typedef struct _NVDpyAttributeCurrentDitheringConfigRec {
enum NvKmsDpyAttributeCurrentDitheringModeValue mode;
} NVDpyAttributeCurrentDitheringConfig;
typedef struct __NVAttributesSetEvoRec {
#define NV_EVO_DVC_MIN (-1024)
#define NV_EVO_DVC_MAX 1023
#define NV_EVO_DVC_DEFAULT 0
NvS32 dvc;
typedef struct __NVDpyAttributeColorRec {
/*
* For both colorSpace and colorRange, the value for
* NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_{SPACE,RANGE} sent by the client is
@@ -1685,10 +1677,26 @@ typedef struct __NVAttributesSetEvoRec {
*
* For SW YUV420 mode, these values are ignored in
* HEAD_SET_PROCAMP and applied in the headSurface composite shader.
*
* XXX Rename NvKmsDpyAttributeCurrentColorSpaceValue to
* NvKmsDpyAttributeCurrentFormatValue.
*/
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace;
enum NvKmsDpyAttributeColorBpcValue colorBpc;
enum NvKmsDpyAttributeColorRangeValue colorRange;
enum NvKmsDpyAttributeCurrentColorSpaceValue format;
enum NvKmsDpyAttributeColorBpcValue bpc;
enum NvKmsDpyAttributeColorRangeValue range;
enum NvKmsOutputColorimetry colorimetry;
} NVDpyAttributeColor;
typedef struct __NVAttributesSetEvoRec {
#define NV_EVO_DVC_MIN (-1024)
#define NV_EVO_DVC_MAX 1023
#define NV_EVO_DVC_DEFAULT 0
NvS32 dvc;
NVDpyAttributeColor color;
NVDpyAttributeCurrentDitheringConfig dithering;
@@ -1709,8 +1717,10 @@ typedef struct __NVAttributesSetEvoRec {
#define NV_EVO_DEFAULT_ATTRIBUTES_SET \
(NVAttributesSetEvoRec) { \
.dvc = NV_EVO_DVC_DEFAULT, \
.colorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB, \
.colorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL, \
.color = { \
.format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB, \
.range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL, \
}, \
.dithering = { \
.enabled = FALSE, \
.mode = NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE_NONE, \
@@ -1801,7 +1811,6 @@ typedef struct _NVDispHeadStateEvoRec {
NVConnectorEvoRec *pConnectorEvo; /* NULL if the head is not active */
HDMI_FRL_CONFIG hdmiFrlConfig;
NvU8 hdmiFrlBpc;
NVDscInfoEvoRec dscInfo;
@@ -1811,8 +1820,6 @@ typedef struct _NVDispHeadStateEvoRec {
enum NvKmsOutputTf tf;
enum NvKmsOutputColorimetry colorimetry;
struct {
NvBool enabled;
enum NvKmsInfoFrameEOTF eotf;
@@ -1869,8 +1876,6 @@ typedef struct _NVDispApiHeadStateEvoRec {
enum NvKmsOutputTf tf;
enum NvKmsOutputColorimetry colorimetry;
NvBool hdrInfoFrameOverride;
NvU32 hdrStaticMetadataLayerMask;
@@ -3059,36 +3064,43 @@ typedef const struct _nv_evo_hal {
NVEvoChannelPtr pChannel,
NVSurfaceDescriptor *pSurfaceDesc);
void (*SetTmoLutSurfaceAddress) (NVEvoChannelPtr pChannel,
void (*SetTmoLutSurfaceAddress) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset);
void (*SetILUTSurfaceAddress) (NVEvoChannelPtr pChannel,
void (*SetILUTSurfaceAddress) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset);
void (*SetISOSurfaceAddress) (NVEvoChannelPtr pChannel,
void (*SetISOSurfaceAddress) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset,
NvU32 ctxDmaIdx,
NvBool isBlocklinear);
void (*SetCoreNotifierSurfaceAddressAndControl) (NVEvoChannelPtr pChannel,
void (*SetCoreNotifierSurfaceAddressAndControl) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 notifierOffset,
NvU32 ctrlVal);
void (*SetWinNotifierSurfaceAddressAndControl) (NVEvoChannelPtr pChannel,
void (*SetWinNotifierSurfaceAddressAndControl) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 notifierOffset,
NvU32 ctrlVal);
void (*SetSemaphoreSurfaceAddressAndControl) (NVEvoChannelPtr pChannel,
void (*SetSemaphoreSurfaceAddressAndControl) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 semaphoreOffset,
NvU32 ctrlVal);
void (*SetAcqSemaphoreSurfaceAddressAndControl) (NVEvoChannelPtr pChannel,
void (*SetAcqSemaphoreSurfaceAddressAndControl) (const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 semaphoreOffset,
NvU32 ctrlVal);
@@ -3111,6 +3123,7 @@ typedef const struct _nv_evo_hal {
NvU32 requiresScalingTapsInBothDimensions :1;
NvU32 supportsMergeMode :1;
NvU32 supportsHDMI10BPC :1;
NvU32 supportsDPAudio192KHz :1;
NvU32 supportedDitheringModes;
size_t impStructSize;
@@ -3172,7 +3185,7 @@ static inline void nvAssignHwHeadsMaskApiHeadState(
typedef struct _NVVblankSemControl {
NvU32 dispIndex;
NvU32 hwHead;
NvU32 hwHeadMask;
NvU64 surfaceOffset;
NVSurfaceEvoRec *pSurfaceEvo;
} NVVblankSemControl;

View File

@@ -1599,6 +1599,12 @@ struct NvKmsValidateModeIndexReply {
* NvKmsSetModeOneHeadReply.
*/
struct NvKmsUsageBounds modeUsage;
/*
* Whether this mode supports stereo mode hdmi3D, but wasn't
* requested.
*/
NvBool hdmi3DAvailable;
};
struct NvKmsValidateModeIndexParams {
@@ -4092,7 +4098,7 @@ struct NvKmsSetFlipLockGroupParams {
* NVKMS_IOCTL_DISABLE_VBLANK_SEM_CONTROL
* NVKMS_IOCTL_ACCEL_VBLANK_SEM_CONTROLS
*
* Enable or disable vblank semaphore control for the given head using the
* Enable or disable vblank semaphore control for the given heads using the
* specified surface and surface offset. The memory at that location is
* interpreted as an NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_DATA. See the
* RMAPI documentation for NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_DATA for
@@ -4118,7 +4124,7 @@ struct NvKmsSetFlipLockGroupParams {
struct NvKmsEnableVblankSemControlRequest {
NvKmsDeviceHandle deviceHandle;
NvKmsDispHandle dispHandle;
NvU32 head;
NvU32 headMask;
NvKmsSurfaceHandle surfaceHandle;
NvU64 surfaceOffset NV_ALIGN_BYTES(8);
};

View File

@@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 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.
*/
#if !defined(NVKMS_MODETIMINGS_H)
#define NVKMS_MODETIMINGS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "nvtypes.h"
#include "nv_mode_timings.h"
/*
* For Kepler HW HDMI 1.4 frame packed stereo, HW combines two flips
* into a single top-down double-height frame, and it needs a
* doubled refresh rate to accommodate this.
*/
static inline void nvKmsUpdateNvModeTimingsForHdmi3D(NvModeTimings *pModeTimings,
NvBool hdmi3D)
{
if (pModeTimings->hdmi3D == hdmi3D) {
return;
}
if (hdmi3D) {
pModeTimings->pixelClockHz *= 2;
pModeTimings->RRx1k *= 2;
} else {
pModeTimings->pixelClockHz /= 2;
pModeTimings->RRx1k /= 2;
}
pModeTimings->hdmi3D = hdmi3D;
}
#ifdef __cplusplus
};
#endif
#endif /* NVKMS_MODETIMINGS_H */

View File

@@ -25,6 +25,8 @@
#define __NVKMS_KAPI_INTERNAL_H__
#include "unix_rm_handle.h"
#include "nvkms-utils.h"

View File

@@ -52,7 +52,6 @@
#include "ctrl/ctrl003e.h" /* NV003E_CTRL_CMD_GET_SURFACE_PHYS_PAGES */
#include "ctrl/ctrl0041.h" /* NV0041_CTRL_SURFACE_INFO */
ct_assert(NVKMS_KAPI_LAYER_PRIMARY_IDX == NVKMS_MAIN_LAYER);
ct_assert(NVKMS_KAPI_LAYER_MAX == NVKMS_MAX_LAYERS_PER_HEAD);
@@ -74,6 +73,7 @@ static NvU32 EnumerateGpus(nv_gpu_info_t *gpuInfo)
*/
static void RmFreeDevice(struct NvKmsKapiDevice *device)
{
if (device->hRmSubDevice != 0x0) {
nvRmApiFree(device->hRmClient,
device->hRmDevice,
@@ -3010,9 +3010,9 @@ static NvBool KmsSetMode(
goto done;
}
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_SET_MODE,
params, sizeof(*params));
status = nvkms_ioctl_from_kapi_try_pmlock(device->pKmsOpen,
NVKMS_IOCTL_SET_MODE,
params, sizeof(*params));
replyConfig->flipResult =
(params->reply.status == NVKMS_SET_MODE_STATUS_SUCCESS) ?
@@ -3198,9 +3198,9 @@ static NvBool KmsFlip(
goto done;
}
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_FLIP,
params, sizeof(*params));
status = nvkms_ioctl_from_kapi_try_pmlock(device->pKmsOpen,
NVKMS_IOCTL_FLIP,
params, sizeof(*params));
replyConfig->flipResult = params->reply.flipResult;

View File

@@ -304,6 +304,11 @@ NvU32 nvkms_enumerate_gpus(nv_gpu_info_t *gpu_info);
NvBool nvkms_allow_write_combining(void);
/*!
* Check if OS supports syncpoints.
*/
NvBool nvkms_kernel_supports_syncpts(void);
/*!
* Checks whether the fd is associated with an nvidia character device.
*/
@@ -328,6 +333,16 @@ NvBool nvkms_ioctl_from_kapi
NvU32 cmd, void *params_address, const size_t params_size
);
/*!
* Like nvkms_ioctl_from_kapi, but return NV_FALSE instead of waiting if the
* power management read lock cannot be acquired.
*/
NvBool nvkms_ioctl_from_kapi_try_pmlock
(
struct nvkms_per_open *popen,
NvU32 cmd, void *params_address, const size_t params_size
);
/*!
* APIs for locking.
*/

View File

@@ -83,6 +83,11 @@ struct _nv_dplibconnector {
// Connector::resume() and gets updated by
// Connector::notifyLongPulse().
NvBool plugged;
// Indicates whether the HDMI/DVI half of the connector is active
// If so link is being driven by HDMI/DVI and avoid LT etc on DP
// link of the connector
NvBool linkHandoffEnabled;
};
struct _nv_dplibdevice {

View File

@@ -109,10 +109,11 @@ void nvDPNotifyLongPulse(NVConnectorEvoPtr pConnectorEvo,
pNVDpLibConnector->plugged = connected;
if (connected && !nvAssignSOREvo(pConnectorEvo->pDispEvo,
nvDpyIdToNvU32(pConnectorEvo->displayId),
FALSE /* b2Heads1Or */,
0 /* sorExcludeMask */)) {
if (!pNVDpLibConnector->linkHandoffEnabled &&
connected && !nvAssignSOREvo(pConnectorEvo,
nvDpyIdToNvU32(pConnectorEvo->displayId),
FALSE /* b2Heads1Or */,
0 /* sorExcludeMask */)) {
// DPLib takes care of skipping LT on unassigned SOR Display.
}
@@ -592,8 +593,7 @@ done:
NvBool nvDPValidateModeForDpyEvo(
const NVDpyEvoRec *pDpyEvo,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc,
const NVDpyAttributeColor *pDpyColor,
const struct NvKmsModeValidationParams *pModeValidationParams,
const NVHwModeTimingsEvo *pTimings,
const NvBool b2Heads1Or,
@@ -617,8 +617,8 @@ NvBool nvDPValidateModeForDpyEvo(
pParams->head[head].displayId = 0;
pParams->head[head].dpyIdList = nvAddDpyIdToEmptyDpyIdList(pDpyEvo->id);
pParams->head[head].colorSpace = colorSpace;
pParams->head[head].colorBpc = colorBpc;
pParams->head[head].colorSpace = pDpyColor->format;
pParams->head[head].colorBpc = pDpyColor->bpc;
pParams->head[head].pModeValidationParams = pModeValidationParams;
pParams->head[head].pTimings = pTimings;
pParams->head[head].b2Heads1Or = b2Heads1Or;
@@ -863,16 +863,18 @@ static NvU32 GetFirmwareHead(NVConnectorEvoPtr pConnectorEvo)
/*!
* Determine whether an active connector shares an OR with this connector.
*/
static bool ConnectorIsSharedWithActiveOR(NVConnectorEvoPtr pConnectorEvo)
static bool IsDDCPartnerActive(NVDPLibConnectorPtr pNVDpLibConnector)
{
NVConnectorEvoRec *pConnectorEvo =
pNVDpLibConnector->pConnectorEvo;
NVDispEvoPtr pDispEvo = pConnectorEvo->pDispEvo;
NVConnectorEvoPtr pOtherConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pOtherConnectorEvo, pDispEvo) {
if (pOtherConnectorEvo != pConnectorEvo &&
nvIsConnectorActiveEvo(pOtherConnectorEvo) &&
(pOtherConnectorEvo->or.primary == pConnectorEvo->or.primary)) {
nvAssert(pOtherConnectorEvo->or.primary != NV_INVALID_OR);
nvDpyIdIsInDpyIdList(pOtherConnectorEvo->displayId,
pConnectorEvo->ddcPartnerDpyIdsList)) {
return true;
}
}
@@ -887,11 +889,13 @@ NvBool nvDPResume(NVDPLibConnectorPtr pNVDpLibConnector, NvBool plugged)
NVDispEvoPtr pDispEvo = pConnectorEvo->pDispEvo;
DisplayPort::Connector *c = pNVDpLibConnector->connector;
const unsigned int firmwareHead = GetFirmwareHead(pConnectorEvo);
const bool firmwareLinkHandsOff = ConnectorIsSharedWithActiveOR(pConnectorEvo);
bool dpyIdIsDynamic = false;
/* By default allow MST */
bool allowMST = true;
pNVDpLibConnector->linkHandoffEnabled =
IsDDCPartnerActive(pNVDpLibConnector);
if (firmwareHead != NV_INVALID_HEAD) {
NVDpyId firmwareDpyId = nvInvalidDpyId();
@@ -920,7 +924,7 @@ NvBool nvDPResume(NVDPLibConnectorPtr pNVDpLibConnector, NvBool plugged)
pNVDpLibConnector->plugged = plugged;
if (plugged && !pNVDpLibConnector->headInFirmware) {
NvBool ret = nvAssignSOREvo(pDispEvo,
NvBool ret = nvAssignSOREvo(pConnectorEvo,
nvDpyIdToNvU32(pConnectorEvo->displayId),
FALSE /* b2Heads1Or */,
0 /* sorExcludeMask */);
@@ -931,7 +935,7 @@ NvBool nvDPResume(NVDPLibConnectorPtr pNVDpLibConnector, NvBool plugged)
}
}
c->resume(firmwareLinkHandsOff,
c->resume(pNVDpLibConnector->linkHandoffEnabled,
pNVDpLibConnector->headInFirmware,
plugged,
false /* isUefiSystem */,
@@ -1093,3 +1097,14 @@ enum NVDpLinkMode nvDPGetActiveLinkMode(NVDPLibConnectorPtr pDpLibConnector)
return linkConfig.multistream ? NV_DP_LINK_MODE_MST :
NV_DP_LINK_MODE_SST;
}
void nvDPSetLinkHandoff(NVDPLibConnectorPtr pDpLibConnector, NvBool enable)
{
if (enable) {
pDpLibConnector->connector->enableLinkHandsOff();
pDpLibConnector->linkHandoffEnabled = TRUE;
} else {
pDpLibConnector->linkHandoffEnabled = FALSE;
pDpLibConnector->connector->releaseLinkHandsOff();
}
}

View File

@@ -29,6 +29,8 @@
#include "nvkms-rmapi.h"
#include "nvdp-connector-event-sink.hpp"
namespace nvkmsDisplayPort {
EvoInterface::EvoInterface(NVConnectorEvoPtr pConnectorEvo)
@@ -110,7 +112,15 @@ NvU32 EvoInterface::getDisplayId()
NvU32 EvoInterface::getSorIndex()
{
return pConnectorEvo->or.primary;
if (pConnectorEvo->pDpLibConnector) {
if (pConnectorEvo->pDpLibConnector->linkHandoffEnabled) {
return DP_INVALID_SOR_INDEX;
} else {
return pConnectorEvo->or.primary;
}
} else {
return pConnectorEvo->or.primary;
}
}
NvU32 EvoInterface::getLinkIndex()

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2008-2018 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2008-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,6 +28,7 @@
#include "nvkms-utils.h"
#include "dp_hostimp.h"
#include "dp_printf.h"
void *dpMalloc(NvLength sz)
{
@@ -39,6 +40,12 @@ void dpFree(void *p)
nvFree(p);
}
static NVEvoLogType dpSeverityToNvkmsMap(DP_LOG_LEVEL severity)
{
NVEvoLogType level = EVO_LOG_INFO;
return level;
}
void dpPrint(const char *format, ...)
{
va_list ap;
@@ -47,6 +54,16 @@ void dpPrint(const char *format, ...)
va_end(ap);
}
void dpPrintf(DP_LOG_LEVEL severity, const char *format, ...)
{
if (severity == DP_SILENT) return;
va_list ap;
va_start(ap, format);
nvVEvoLog(dpSeverityToNvkmsMap(severity), NV_INVALID_GPU_LOG_INDEX, format, ap);
va_end(ap);
}
void dpDebugBreakpoint(void)
{
nvAssert(!"DisplayPort library debug breakpoint");

View File

@@ -232,7 +232,7 @@ static void SetDitheringCommon(NVDpyEvoPtr pDpyEvo)
(nvDpyIdIsInDpyIdList(pDpyEvo->id, pApiHeadState->activeDpys)));
nvChooseDitheringEvo(pConnectorEvo,
pApiHeadState->attributes.colorBpc,
pApiHeadState->attributes.color.bpc,
&pDpyEvo->requestedDithering,
&pApiHeadState->attributes.dithering);
@@ -610,11 +610,7 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
NVEvoUpdateState updateState = { };
NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
NVDispApiHeadStateEvoRec *pApiHeadState;
NvU8 hdmiFrlBpc;
NvU32 head;
#if defined(DEBUG)
NvU32 hwHead;
#endif
if (pDpyEvo->apiHead == NV_INVALID_HEAD) {
return;
@@ -624,23 +620,13 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
nvAssert((pApiHeadState->hwHeadsMask) != 0x0 &&
(nvDpyIdIsInDpyIdList(pDpyEvo->id, pApiHeadState->activeDpys)));
head = nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
hdmiFrlBpc = pDispEvo->headState[head].hdmiFrlBpc;
#if defined(DEBUG)
FOR_EACH_EVO_HW_HEAD_IN_MASK(pApiHeadState->hwHeadsMask, hwHead) {
nvAssert(pDispEvo->headState[head].timings.yuv420Mode ==
pDispEvo->headState[hwHead].timings.yuv420Mode);
}
#endif
/*
* Choose current colorSpace and colorRange based on the current mode
* timings and the requested color space and range.
*/
if (!nvChooseCurrentColorSpaceAndRangeEvo(pDpyEvo,
&pDispEvo->headState[head].timings,
hdmiFrlBpc,
pApiHeadState->colorimetry,
pApiHeadState->timings.yuv420Mode,
pApiHeadState->attributes.color.colorimetry,
pDpyEvo->requestedColorSpace,
pDpyEvo->requestedColorRange,
&colorSpace,
@@ -652,26 +638,68 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
/* For DP, neither color space nor bpc can be changed without a modeset */
if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo) &&
((pApiHeadState->attributes.colorSpace != colorSpace) ||
(pApiHeadState->attributes.colorBpc != colorBpc))) {
((pApiHeadState->attributes.color.format != colorSpace) ||
(pApiHeadState->attributes.color.bpc != colorBpc))) {
return;
}
pApiHeadState->attributes.colorSpace = colorSpace;
pApiHeadState->attributes.colorRange = colorRange;
pApiHeadState->attributes.colorBpc = colorBpc;
/*
* Hardware does not support HDMI FRL with YUV422, and it is not possible
* to downgrade current color bpc on HDMI FRL at this point.
*/
if ((pApiHeadState->timings.protocol == NVKMS_PROTOCOL_SOR_HDMI_FRL) &&
((colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) ||
(pApiHeadState->attributes.color.bpc > colorBpc))) {
return;
}
if (nvDpyIsHdmiEvo(pDpyEvo) &&
(colorBpc > pApiHeadState->attributes.color.bpc)) {
NVDpyAttributeColor tmpDpyColor = pApiHeadState->attributes.color;
tmpDpyColor.format = colorSpace;
tmpDpyColor.range = colorRange;
tmpDpyColor.bpc = colorBpc;
/*
* For HDMI FRL, downgrade the selected color bpc to the current color
* bpc so that the current color bpc remains unchanged.
*/
if (pApiHeadState->timings.protocol == NVKMS_PROTOCOL_SOR_HDMI_FRL) {
tmpDpyColor.bpc = pApiHeadState->attributes.color.bpc;
} else {
const NVColorFormatInfoRec colorFormatsInfo =
nvGetColorFormatInfo(pDpyEvo);
while (nvHdmiGetEffectivePixelClockKHz(pDpyEvo,
&pApiHeadState->timings,
&tmpDpyColor) >
pDpyEvo->maxSingleLinkPixelClockKHz) {
if(!nvDowngradeColorSpaceAndBpc(&colorFormatsInfo,
&tmpDpyColor)) {
return;
}
}
}
pApiHeadState->attributes.color.format = tmpDpyColor.format;
pApiHeadState->attributes.color.range = tmpDpyColor.range;
pApiHeadState->attributes.color.bpc = tmpDpyColor.bpc;
} else {
pApiHeadState->attributes.color.format = colorSpace;
pApiHeadState->attributes.color.range = colorRange;
pApiHeadState->attributes.color.bpc = colorBpc;
}
/* Update hardware's current colorSpace and colorRange */
FOR_EACH_EVO_HW_HEAD_IN_MASK(pApiHeadState->hwHeadsMask, head) {
enum nvKmsPixelDepth newPixelDepth =
nvEvoColorSpaceBpcToPixelDepth(pApiHeadState->attributes.colorSpace,
pApiHeadState->attributes.colorBpc);
nvEvoDpyColorToPixelDepth(&pApiHeadState->attributes.color);
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(pDispEvo,
head,
pApiHeadState->colorimetry,
pApiHeadState->attributes.colorSpace,
pApiHeadState->attributes.colorRange,
&pApiHeadState->attributes.color,
&updateState);
if (newPixelDepth != pDispEvo->headState[head].pixelDepth) {
@@ -739,7 +767,7 @@ static NvBool GetCurrentColorSpace(const NVDpyEvoRec *pDpyEvo, NvS64 *pValue)
return FALSE;
}
*pValue = pDpyEvo->currentAttributes.colorSpace;
*pValue = pDpyEvo->currentAttributes.color.format;
return TRUE;
}
@@ -812,7 +840,7 @@ static NvBool GetCurrentColorRange(const NVDpyEvoRec *pDpyEvo, NvS64 *pValue)
return FALSE;
}
*pValue = pDpyEvo->currentAttributes.colorRange;
*pValue = pDpyEvo->currentAttributes.color.range;
return TRUE;
}

View File

@@ -430,6 +430,7 @@ extern NVEvoCursorHAL nvEvoCursorC3;
extern NVEvoCursorHAL nvEvoCursorC5;
extern NVEvoCursorHAL nvEvoCursorC6;
enum NvKmsAllocDeviceStatus nvInitDispHalCursorEvo(NVDevEvoPtr pDevEvo)
{
static const NVEvoCursorHALPtr cursorTable[] = {

View File

@@ -667,7 +667,6 @@ static void ReadAndApplyEdidEvo(
nvFree(pParsedEdid);
}
/*!
* Get the maximum allowed pixel clock for pDpyEvo.
*
@@ -768,7 +767,7 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
* those driving heads, we don't need to exclude RM from
* selecting any SOR, so an sorExcludeMask of 0 is appropriate.
*/
if (nvAssignSOREvo(pDispEvo,
if (nvAssignSOREvo(pConnectorEvo,
nvDpyIdToNvU32(pConnectorEvo->displayId),
FALSE /* b2Heads1Or */,
0 /* sorExcludeMask */) &&
@@ -2509,7 +2508,7 @@ static void UpdateDpHDRInfoFrame(const NVDispEvoRec *pDispEvo, const NvU32 head)
*/
static void UpdateDpYUV420InfoFrame(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NVAttributesSetEvoRec *pAttributesSet)
const NVDpyAttributeColor *pDpyColor)
{
const NVDispHeadStateEvoRec *pHeadState =
&pDispEvo->headState[head];
@@ -2520,8 +2519,7 @@ static void UpdateDpYUV420InfoFrame(const NVDispEvoRec *pDispEvo,
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = pHeadState->activeRmId;
if (pAttributesSet->colorSpace ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420) {
if (pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420) {
// DPSDP_DP_VSC_SDP_DESCRIPTOR has a (dataSize, hb, db) layout, while
// NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS.aPacket needs to contain
@@ -2545,7 +2543,7 @@ static void UpdateDpYUV420InfoFrame(const NVDispEvoRec *pDispEvo,
sdp->db.pixEncoding = SDP_VSC_PIX_ENC_YCBCR420;
sdp->db.colorimetryFormat = SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT709;
switch (pAttributesSet->colorBpc) {
switch (pDpyColor->bpc) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
sdp->db.bitDepth = SDP_VSC_BIT_DEPTH_YCBCR_10BPC;
break;
@@ -2557,7 +2555,7 @@ static void UpdateDpYUV420InfoFrame(const NVDispEvoRec *pDispEvo,
break;
}
switch (pAttributesSet->colorRange) {
switch (pDpyColor->range) {
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL:
sdp->db.dynamicRange = SDP_VSC_DYNAMIC_RANGE_VESA;
break;
@@ -2594,11 +2592,11 @@ static void UpdateDpYUV420InfoFrame(const NVDispEvoRec *pDispEvo,
static void UpdateDpInfoFrames(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NVAttributesSetEvoRec *pAttributesSet)
const NVDpyAttributeColor *pDpyColor)
{
UpdateDpHDRInfoFrame(pDispEvo, head);
UpdateDpYUV420InfoFrame(pDispEvo, head, pAttributesSet);
UpdateDpYUV420InfoFrame(pDispEvo, head, pDpyColor);
}
void nvCancelSDRTransitionTimer(NVDpyEvoRec *pDpyEvo)
@@ -2666,11 +2664,11 @@ void nvUpdateInfoFrames(NVDpyEvoRec *pDpyEvo)
pHeadState = &pDispEvo->headState[head];
if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo)) {
UpdateDpInfoFrames(pDispEvo, head, &pApiHeadState->attributes);
UpdateDpInfoFrames(pDispEvo, head, &pApiHeadState->attributes.color);
} else {
nvUpdateHdmiInfoFrames(pDispEvo,
head,
&pApiHeadState->attributes,
&pApiHeadState->attributes.color,
&pApiHeadState->infoFrame,
pDpyEvo);
}
@@ -3035,20 +3033,20 @@ void nvDpyUpdateCurrentAttributes(NVDpyEvoRec *pDpyEvo)
newAttributes.numberOfHardwareHeadsUsed = 0;
}
if (newAttributes.colorSpace !=
pDpyEvo->currentAttributes.colorSpace) {
if (newAttributes.color.format !=
pDpyEvo->currentAttributes.color.format) {
nvSendDpyAttributeChangedEventEvo(
pDpyEvo,
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE,
newAttributes.colorSpace);
newAttributes.color.format);
}
if (newAttributes.colorRange !=
pDpyEvo->currentAttributes.colorRange) {
if (newAttributes.color.range !=
pDpyEvo->currentAttributes.color.range) {
nvSendDpyAttributeChangedEventEvo(
pDpyEvo,
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE,
newAttributes.colorRange);
newAttributes.color.range);
}
if (newAttributes.dithering.enabled !=

View File

@@ -139,11 +139,6 @@ static void ScheduleLutUpdate(NVDispEvoRec *pDispEvo,
const NvU32 apiHead, const NvU32 data,
const NvU64 usec);
static NvBool DowngradeColorBpc(
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
enum NvKmsDpyAttributeColorRangeValue *pColorRange);
NVEvoGlobal nvEvoGlobal = {
.clientHandle = 0,
.frameLockList = NV_LIST_INIT(&nvEvoGlobal.frameLockList),
@@ -2729,7 +2724,7 @@ void nvEnableMidFrameAndDWCFWatermark(NVDevEvoPtr pDevEvo,
pUpdateState);
}
NvBool nvGetDefaultColorSpace(
static NvBool GetDefaultColorSpace(
const NVColorFormatInfoRec *pColorFormatsInfo,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc)
@@ -2758,6 +2753,27 @@ NvBool nvGetDefaultColorSpace(
return FALSE;
}
NvBool nvGetDefaultDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
NVDpyAttributeColor *pDpyColor)
{
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
if (!GetDefaultColorSpace(pColorFormatsInfo, &pDpyColor->format,
&pDpyColor->bpc)) {
return FALSE;
}
if (pDpyColor->format != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
} else {
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
}
pDpyColor->colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
return TRUE;
}
NvBool nvChooseColorRangeEvo(
enum NvKmsOutputColorimetry colorimetry,
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
@@ -2804,8 +2820,7 @@ NvBool nvChooseColorRangeEvo(
*/
NvBool nvChooseCurrentColorSpaceAndRangeEvo(
const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
NvU8 hdmiFrlBpc,
const enum NvYuv420Mode yuv420Mode,
enum NvKmsOutputColorimetry colorimetry,
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
@@ -2830,13 +2845,13 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
* requested color space with RGB. We cannot support yuv420Mode in
* that configuration, so fail in that case.
*/
if (pHwTimings->yuv420Mode != NV_YUV420_MODE_NONE) {
if (yuv420Mode != NV_YUV420_MODE_NONE) {
return FALSE;
}
newColorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB;
newColorBpc = colorFormatsInfo.rgb444.maxBpc;
} else if (pHwTimings->yuv420Mode != NV_YUV420_MODE_NONE) {
} else if (yuv420Mode != NV_YUV420_MODE_NONE) {
/*
* If the current mode timing requires YUV420 compression, we override the
* requested color space with YUV420.
@@ -2871,25 +2886,12 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
if ((newColorBpc ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) &&
!nvGetDefaultColorSpace(&colorFormatsInfo, &newColorSpace,
&newColorBpc)) {
!GetDefaultColorSpace(&colorFormatsInfo, &newColorSpace,
&newColorBpc)) {
return FALSE;
}
}
/*
* Downgrade BPC if HDMI configuration does not support current selection
* with TMDS or FRL.
*/
if (nvDpyIsHdmiEvo(pDpyEvo) &&
nvHdmiTimingsNeedFrl(pDpyEvo, pHwTimings, newColorBpc) &&
(newColorBpc > hdmiFrlBpc)) {
newColorBpc =
hdmiFrlBpc ? hdmiFrlBpc : NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
nvAssert(newColorBpc >= NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8);
}
// 10 BPC required for HDR
// XXX HDR TODO: Handle other colorimetries
// XXX HDR TODO: Handle YUV
@@ -2912,9 +2914,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
NVDispEvoPtr pDispEvo,
const NvU32 head,
enum NvKmsOutputColorimetry colorimetry,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorRangeValue colorRange,
const NVDpyAttributeColor *pDpyColor,
NVEvoUpdateState *pUpdateState)
{
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
@@ -2924,16 +2924,17 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
nvAssert(pConnectorEvo != NULL);
// XXX HDR TODO: Support more output colorimetries
if (colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
nvAssert(pHeadState->timings.yuv420Mode == NV_YUV420_MODE_NONE);
nvAssert(colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB);
nvAssert(colorRange == NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED);
nvAssert(pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB);
nvAssert(pDpyColor->range == NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED);
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_BT2020RGB;
pHeadState->procAmp.colorRange = NVT_COLOR_RANGE_LIMITED;
pHeadState->procAmp.colorFormat = NVT_COLOR_FORMAT_RGB;
} else if ((pHeadState->timings.yuv420Mode == NV_YUV420_MODE_SW) &&
(colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420)) {
(pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420)) {
/*
* In SW YUV420 mode, HW is programmed with RGB color space and full
* color range. The color space conversion and color range compression
@@ -2949,7 +2950,7 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
pHeadState->procAmp.colorRange = NVT_COLOR_RANGE_FULL;
// Set color format
switch (colorSpace) {
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
pHeadState->procAmp.colorFormat = NVT_COLOR_FORMAT_RGB;
break;
@@ -2969,7 +2970,7 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
switch (pConnectorEvo->legacyType) {
case NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_DFP:
// program HW with RGB/YCbCr
switch (colorSpace) {
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_RGB;
break;
@@ -2990,7 +2991,8 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
// colorSpace isn't used for DEVICE_TYPE_CRT and
// hence should be set to the "unchanged" value
// (i.e. the default - RGB)
nvAssert(colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB);
nvAssert(pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB);
// program HW with RGB only
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_RGB;
@@ -3000,18 +3002,20 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
}
/* YCbCr444 should be advertise only for DisplayPort and HDMI */
nvAssert((colorSpace != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444) ||
nvAssert((pDpyColor->format !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444) ||
nvConnectorUsesDPLib(pConnectorEvo) ||
pConnectorEvo->isHdmiEnabled);
/* YcbCr422 should be advertised only for HDMI and DP on supported GPUs */
nvAssert((colorSpace != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) ||
nvAssert((pDpyColor->format !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) ||
(((pDevEvo->caps.hdmiYCbCr422MaxBpc != 0) &&
pConnectorEvo->isHdmiEnabled)) ||
((pDevEvo->caps.dpYCbCr422MaxBpc != 0) &&
nvConnectorUsesDPLib(pConnectorEvo)));
switch (colorRange) {
switch (pDpyColor->range) {
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL:
pHeadState->procAmp.colorRange = NVT_COLOR_RANGE_FULL;
break;
@@ -5387,9 +5391,12 @@ static void RefreshSORAssignments(const NVDispEvoRec *pDispEvo,
* pConnectorEvo->or.secondaryMask on *every* connector after calling
* NV0073_CTRL_CMD_DFP_ASSIGN_SOR for *any* connector.
*/
NvBool nvAssignSOREvo(const NVDispEvoRec *pDispEvo, const NvU32 displayId,
const NvBool b2Heads1Or, const NvU32 sorExcludeMask)
NvBool nvAssignSOREvo(const NVConnectorEvoRec *pConnectorEvo,
const NvU32 targetDisplayId,
const NvBool b2Heads1Or,
const NvU32 sorExcludeMask)
{
const NVDispEvoRec *pDispEvo = pConnectorEvo->pDispEvo;
const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS params = { 0 };
NvU32 ret;
@@ -5400,7 +5407,7 @@ NvBool nvAssignSOREvo(const NVDispEvoRec *pDispEvo, const NvU32 displayId,
}
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = displayId;
params.displayId = targetDisplayId;
params.bIs2Head1Or = b2Heads1Or;
params.sorExcludeMask = sorExcludeMask;
@@ -5920,8 +5927,7 @@ NvBool nvConstructHwModeTimingsImpCheckEvo(
const NVHwModeTimingsEvo *pTimings,
const NvBool enableDsc,
const NvBool b2Heads1Or,
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc,
const NVDpyAttributeColor *pColor,
const struct NvKmsModeValidationParams *pParams,
NVHwModeTimingsEvo timings[NVKMS_MAX_HEADS_PER_DISP],
NvU32 *pNumHeads,
@@ -5946,8 +5952,7 @@ NvBool nvConstructHwModeTimingsImpCheckEvo(
for (head = 0; head < numHeads; head++) {
timingsParams[head].pConnectorEvo = pConnectorEvo;
timingsParams[head].activeRmId = activeRmId;
timingsParams[head].pixelDepth =
nvEvoColorSpaceBpcToPixelDepth(colorSpace, colorBpc);
timingsParams[head].pixelDepth = nvEvoDpyColorToPixelDepth(pColor);
if (!nvEvoGetSingleTileHwModeTimings(pTimings, numHeads,
&timings[head])) {
ret = FALSE;
@@ -6648,6 +6653,80 @@ ConstructHwModeTimingsViewPort(const NVDispEvoRec *pDispEvo,
}
static NvBool GetDefaultFrlDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
NVDpyAttributeColor *pDpyColor)
{
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
pDpyColor->colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
if (pColorFormatsInfo->rgb444.maxBpc >=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8) {
pDpyColor->format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB;
pDpyColor->bpc = pColorFormatsInfo->rgb444.maxBpc;
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
return TRUE;
}
if (pColorFormatsInfo->yuv444.maxBpc >=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8) {
pDpyColor->format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444;
pDpyColor->bpc = pColorFormatsInfo->yuv444.maxBpc;
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
return TRUE;
}
return FALSE;
}
static NvBool GetDfpHdmiProtocol(const NVDpyEvoRec *pDpyEvo,
const NvU32 overrides,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
enum nvKmsTimingsProtocol *pTimingsProtocol)
{
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
const NvU32 rmProtocol = pConnectorEvo->or.protocol;
const NVColorFormatInfoRec colorFormatsInfo =
nvGetColorFormatInfo(pDpyEvo);
const NvBool forceHdmiFrlIsSupported = FALSE;
nvAssert(rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A ||
rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B);
/* Override protocol if this mode requires HDMI FRL. */
/* If we don't require boot clocks... */
if (((overrides & NVKMS_MODE_VALIDATION_REQUIRE_BOOT_CLOCKS) == 0) &&
((nvHdmiGetEffectivePixelClockKHz(pDpyEvo, pTimings, pDpyColor) >
pDpyEvo->maxSingleLinkPixelClockKHz) ||
forceHdmiFrlIsSupported) &&
/* If FRL is supported... */
nvHdmiDpySupportsFrl(pDpyEvo)) {
/* Hardware does not support HDMI FRL with YUV422 */
if ((pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) &&
!GetDefaultFrlDpyColor(&colorFormatsInfo, pDpyColor)) {
return FALSE;
}
*pTimingsProtocol = NVKMS_PROTOCOL_SOR_HDMI_FRL;
return TRUE;
}
do {
if (nvHdmiGetEffectivePixelClockKHz(pDpyEvo, pTimings, pDpyColor) <=
pDpyEvo->maxSingleLinkPixelClockKHz) {
*pTimingsProtocol = (rmProtocol ==
NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A) ?
NVKMS_PROTOCOL_SOR_SINGLE_TMDS_A :
NVKMS_PROTOCOL_SOR_SINGLE_TMDS_B;
return TRUE;
}
} while (nvDowngradeColorSpaceAndBpc(&colorFormatsInfo,
pDpyColor));
return FALSE;
}
/*
* GetDfpProtocol()- determine the protocol to use on the given pDpy
@@ -6656,6 +6735,7 @@ ConstructHwModeTimingsViewPort(const NVDispEvoRec *pDispEvo,
static NvBool GetDfpProtocol(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsModeValidationParams *pParams,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings)
{
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
@@ -6667,31 +6747,13 @@ static NvBool GetDfpProtocol(const NVDpyEvoRec *pDpyEvo,
NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_DFP);
if (pConnectorEvo->or.type == NV0073_CTRL_SPECIFIC_OR_TYPE_SOR) {
/* Override protocol if this mode requires HDMI FRL. */
if (nvDpyIsHdmiEvo(pDpyEvo) &&
/* If we don't require boot clocks... */
((overrides & NVKMS_MODE_VALIDATION_REQUIRE_BOOT_CLOCKS) == 0) &&
/* If FRL is supported... */
nvHdmiDpySupportsFrl(pDpyEvo) &&
/* Use FRL for 10 BPC if needed. */
((nvDpyIsHdmiDepth30Evo(pDpyEvo) &&
nvHdmiTimingsNeedFrl(pDpyEvo, pTimings, HDMI_BPC10)) ||
/* Use FRL for 8 BPC if needed. */
nvHdmiTimingsNeedFrl(pDpyEvo, pTimings, HDMI_BPC8))) {
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A ||
rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B);
timingsProtocol = NVKMS_PROTOCOL_SOR_HDMI_FRL;
} else {
/* If HDMI FRL is needed for 8 BPC, but not supported, fail. */
if (nvDpyIsHdmiEvo(pDpyEvo) &&
nvHdmiTimingsNeedFrl(pDpyEvo, pTimings, HDMI_BPC8) &&
((overrides & NVKMS_MODE_VALIDATION_NO_MAX_PCLK_CHECK) == 0)) {
nvAssert(!nvHdmiDpySupportsFrl(pDpyEvo));
if (nvDpyIsHdmiEvo(pDpyEvo)) {
if (!GetDfpHdmiProtocol(pDpyEvo, overrides, pDpyColor, pTimings,
&timingsProtocol)) {
return FALSE;
}
} else {
switch (rmProtocol) {
default:
nvAssert(!"unrecognized SOR RM protocol");
@@ -6799,6 +6861,7 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct
NvKmsModeValidationParams *pParams,
@@ -6808,7 +6871,7 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
ConstructHwModeTimingsFromNvModeTimings(pModeTimings, pTimings);
ret = GetDfpProtocol(pDpyEvo, pParams, pTimings);
ret = GetDfpProtocol(pDpyEvo, pParams, pDpyColor, pTimings);
if (!ret) {
return ret;
@@ -6825,20 +6888,20 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
pViewPortOut);
}
static NvBool DowngradeColorBpc(
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
enum NvKmsDpyAttributeColorRangeValue *pColorRange)
NvBool nvDowngradeColorBpc(NVDpyAttributeColor *pDpyColor)
{
switch (*pColorBpc) {
switch (pDpyColor->bpc) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
*pColorBpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
return FALSE;
}
pDpyColor->bpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
break;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8:
/* At depth 18 only RGB and full range are allowed */
if (colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
*pColorBpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
*pColorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
if (pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
pDpyColor->bpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
} else {
return FALSE;
}
@@ -6853,22 +6916,25 @@ static NvBool DowngradeColorBpc(
NvBool nvDowngradeColorSpaceAndBpc(
const NVColorFormatInfoRec *pSupportedColorFormats,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
enum NvKmsDpyAttributeColorRangeValue *pColorRange)
NVDpyAttributeColor *pDpyColor)
{
if (DowngradeColorBpc(*pColorSpace, pColorBpc, pColorRange)) {
if (nvDowngradeColorBpc(pDpyColor)) {
return TRUE;
}
switch (*pColorSpace) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB: /* fallthrough */
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
/* XXX Add support for downgrading to YUV with BT2100 */
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
return FALSE;
}
/* fallthrough */
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444:
if (pSupportedColorFormats->yuv422.maxBpc !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
*pColorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422;
*pColorBpc = pSupportedColorFormats->yuv422.maxBpc;
*pColorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
pDpyColor->format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422;
pDpyColor->bpc = pSupportedColorFormats->yuv422.maxBpc;
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
return TRUE;
}
break;
@@ -6888,16 +6954,13 @@ NvBool nvDowngradeColorSpaceAndBpc(
NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
NVHwModeTimingsEvoPtr pTimings,
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
enum NvKmsDpyAttributeColorBpcValue *pColorBpc,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
NVDscInfoEvoRec *pDscInfo,
const struct NvKmsModeValidationParams *pParams)
{
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace = *pColorSpace;
enum NvKmsDpyAttributeColorBpcValue colorBpc = *pColorBpc;
enum NvKmsDpyAttributeColorRangeValue colorRange;
NVDpyAttributeColor dpyColor = *pDpyColor;
const NVColorFormatInfoRec supportedColorFormats =
nvGetColorFormatInfo(pDpyEvo);
@@ -6911,21 +6974,14 @@ NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
return TRUE;
}
if (colorSpace != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
colorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
} else {
colorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
}
nvAssert(nvDpyUsesDPLib(pDpyEvo));
nvAssert(pConnectorEvo->or.type == NV0073_CTRL_SPECIFIC_OR_TYPE_SOR);
tryAgain:
if (!nvDPValidateModeForDpyEvo(pDpyEvo, colorSpace, colorBpc, pParams,
pTimings, b2Heads1Or, pDscInfo)) {
if (nvDowngradeColorSpaceAndBpc(&supportedColorFormats, &colorSpace,
&colorBpc, &colorRange)) {
if (!nvDPValidateModeForDpyEvo(pDpyEvo, &dpyColor, pParams, pTimings,
b2Heads1Or, pDscInfo)) {
if (nvDowngradeColorSpaceAndBpc(&supportedColorFormats, &dpyColor)) {
goto tryAgain;
}
/*
@@ -6936,8 +6992,7 @@ NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
return FALSE;
}
*pColorSpace = colorSpace;
*pColorBpc = colorBpc;
*pDpyColor = dpyColor;
return TRUE;
}
@@ -6950,6 +7005,7 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct NvKmsModeValidationParams
*pParams,
@@ -6965,7 +7021,8 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
ret = ConstructHwModeTimingsEvoDfp(pDpyEvo,
&pKmsMode->timings,
pViewPortSizeIn, pViewPortOut,
pTimings, pParams, pInfoString);
pDpyColor, pTimings, pParams,
pInfoString);
} else if (pConnectorEvo->legacyType ==
NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_CRT) {
ret = ConstructHwModeTimingsEvoCrt(pConnectorEvo,
@@ -9338,15 +9395,14 @@ NvBool nvIsCscMatrixIdentity(const struct NvKmsCscMatrix *matrix)
return TRUE;
}
enum nvKmsPixelDepth nvEvoColorSpaceBpcToPixelDepth(
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
const enum NvKmsDpyAttributeColorBpcValue colorBpc)
enum nvKmsPixelDepth nvEvoDpyColorToPixelDepth(
const NVDpyAttributeColor *pDpyColor)
{
switch (colorSpace) {
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444:
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420:
switch (colorBpc) {
switch (pDpyColor->bpc) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
return NVKMS_PIXEL_DEPTH_30_444;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8:
@@ -9357,8 +9413,8 @@ enum nvKmsPixelDepth nvEvoColorSpaceBpcToPixelDepth(
}
break;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422:
nvAssert(colorBpc != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6);
switch (colorBpc) {
nvAssert(pDpyColor->bpc != NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6);
switch (pDpyColor->bpc) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
return NVKMS_PIXEL_DEPTH_20_422;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6: /* fallthrough */

View File

@@ -3914,6 +3914,7 @@ NVEvoHAL nvEvo94 = {
TRUE, /* requiresScalingTapsInBothDimensions */
FALSE, /* supportsMergeMode */
FALSE, /* supportsHDMI10BPC */
FALSE, /* supportsDPAudio192KHz */
NV_EVO2_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NV5070_CTRL_CMD_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_1TAP, /* minScalerTaps */

View File

@@ -765,6 +765,7 @@ static NvBool UpdateTmoParams(NVEvoChannelPtr pChannel,
}
static void EvoSetTmoLutSurfaceAddressC5(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset)
@@ -812,7 +813,7 @@ static void ConfigureTmoLut(NVDevEvoPtr pDevEvo,
}
if (!pChannel->tmoParams.enabled) {
pDevEvo->hal->SetTmoLutSurfaceAddress(pChannel,
pDevEvo->hal->SetTmoLutSurfaceAddress(pDevEvo, pChannel,
NULL /* pSurfaceDesc */, 0 /* offset */);
return;
}
@@ -835,7 +836,7 @@ static void ConfigureTmoLut(NVDevEvoPtr pDevEvo,
DRF_DEF(C57E, _SET_TMO_CONTROL, _INTERPOLATE, _ENABLE) |
DRF_NUM(C57E, _SET_TMO_CONTROL, _SAT_MODE, tmoLutSettings->satMode));
pDevEvo->hal->SetTmoLutSurfaceAddress(pChannel,
pDevEvo->hal->SetTmoLutSurfaceAddress(pDevEvo, pChannel,
&pHwState->tmoLut.pLutSurfaceEvo->surfaceDesc, offset);
// Low Intensity
@@ -2602,6 +2603,7 @@ NvBool nvEvoSetUsageBoundsC5(NVDevEvoPtr pDevEvo, NvU32 sd, NvU32 head,
}
static void EvoSetCoreNotifierSurfaceAddressAndControlC3(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 notifierOffset,
@@ -2652,14 +2654,14 @@ void nvEvoSetNotifierC3(NVDevEvoRec *pDevEvo,
for (sd = 0; sd < pDevEvo->numSubDevices; sd++) {
if (nvPeekEvoSubDevMask(pDevEvo) & (1 << sd)) {
nvPushEvoSubDevMask(pDevEvo, NVBIT(sd));
pDevEvo->hal->SetCoreNotifierSurfaceAddressAndControl(pChannel,
&pDevEvo->core->notifiersDma[sd].surfaceDesc,
pDevEvo->hal->SetCoreNotifierSurfaceAddressAndControl(pDevEvo,
pChannel, &pDevEvo->core->notifiersDma[sd].surfaceDesc,
notifier, ctrlVal);
nvPopEvoSubDevMask(pDevEvo);
}
}
} else {
pDevEvo->hal->SetCoreNotifierSurfaceAddressAndControl(pChannel,
pDevEvo->hal->SetCoreNotifierSurfaceAddressAndControl(pDevEvo, pChannel,
NULL /* pSurfaceDesc */, 0 /* offset */ , 0 /* ctrlVal */);
}
}
@@ -3202,18 +3204,14 @@ static void AssignPerWindowImpParams(NVC372_CTRL_IMP_WINDOW *pImpWindow,
pImpWindow->tmoLut = NVC372_CTRL_IMP_LUT_USAGE_1025;
}
void
nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
const NVEvoIsModePossibleDispInput *pInput,
NVEvoIsModePossibleDispOutput *pOutput)
NvBool
nvEvoSetCtrlIsModePossibleParams3(NVDispEvoPtr pDispEvo,
const NVEvoIsModePossibleDispInput *pInput,
NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp)
{
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
const NVEvoCapabilitiesPtr pEvoCaps = &pDevEvo->gpus[0].capabilities;
NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp =
nvPreallocGet(pDevEvo, PREALLOC_TYPE_IMP_PARAMS, sizeof(*pImp));
NvBool result = FALSE;
NvU32 head;
NvU32 ret;
nvkms_memset(pImp, 0, sizeof(*pImp));
@@ -3242,7 +3240,7 @@ nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
b2Heads1Or,
head,
&pEvoCaps->head[head].scalerCaps)) {
goto done;
return FALSE;
}
/* XXXnvdisplay: This assumes a fixed window<->head mapping */
@@ -3282,6 +3280,36 @@ nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
pImp->options = NVC372_CTRL_IS_MODE_POSSIBLE_OPTIONS_NEED_MIN_VPSTATE;
}
return TRUE;
}
void
nvEvoSetIsModePossibleDispOutput3(const NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp,
const NvBool result,
NVEvoIsModePossibleDispOutput *pOutput)
{
pOutput->possible = result;
if (pOutput->possible) {
pOutput->minRequiredBandwidthKBPS = pImp->minRequiredBandwidthKBPS;
pOutput->floorBandwidthKBPS = pImp->floorBandwidthKBPS;
}
}
void
nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
const NVEvoIsModePossibleDispInput *pInput,
NVEvoIsModePossibleDispOutput *pOutput)
{
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS *pImp =
nvPreallocGet(pDevEvo, PREALLOC_TYPE_IMP_PARAMS, sizeof(*pImp));
NvBool result = FALSE;
NvU32 ret;
if (!nvEvoSetCtrlIsModePossibleParams3(pDispEvo, pInput, pImp)) {
goto done;
}
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->rmCtrlHandle,
NVC372_CTRL_CMD_IS_MODE_POSSIBLE,
@@ -3296,11 +3324,7 @@ nvEvoIsModePossibleC3(NVDispEvoPtr pDispEvo,
result = TRUE;
done:
pOutput->possible = result;
if (pOutput->possible) {
pOutput->minRequiredBandwidthKBPS = pImp->minRequiredBandwidthKBPS;
pOutput->floorBandwidthKBPS = pImp->floorBandwidthKBPS;
}
nvEvoSetIsModePossibleDispOutput3(pImp, result, pOutput);
nvPreallocRelease(pDevEvo, PREALLOC_TYPE_IMP_PARAMS);
}
@@ -3530,6 +3554,7 @@ EvoProgramSemaphore3(NVDevEvoPtr pDevEvo,
}
static void EvoSetSemaphoreSurfaceAddressAndControlC6(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 semaphoreOffset,
@@ -3548,6 +3573,7 @@ static void EvoSetSemaphoreSurfaceAddressAndControlC6(
}
static void EvoSetAcqSemaphoreSurfaceAddressAndControlC6(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 semaphoreOffset,
@@ -3603,7 +3629,7 @@ EvoProgramSemaphore6(NVDevEvoPtr pDevEvo,
}
}
pDevEvo->hal->SetAcqSemaphoreSurfaceAddressAndControl(pChannel,
pDevEvo->hal->SetAcqSemaphoreSurfaceAddressAndControl(pDevEvo, pChannel,
pSurfaceDesc, offset, acqMode);
/*! set semaphore value */
@@ -3633,7 +3659,7 @@ EvoProgramSemaphore6(NVDevEvoPtr pDevEvo,
}
}
pDevEvo->hal->SetSemaphoreSurfaceAddressAndControl(pChannel,
pDevEvo->hal->SetSemaphoreSurfaceAddressAndControl(pDevEvo, pChannel,
pSurfaceDesc, offset, (acqMode | relMode));
/*! set semaphore value */
@@ -3643,6 +3669,7 @@ EvoProgramSemaphore6(NVDevEvoPtr pDevEvo,
}
static void EvoSetWinNotifierSurfaceAddressAndControlC3(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 notifierOffset,
@@ -3660,6 +3687,7 @@ static void EvoSetWinNotifierSurfaceAddressAndControlC3(
}
static void EvoSetISOSurfaceAddressC3(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset,
@@ -3708,12 +3736,12 @@ EvoFlipC3Common(NVDevEvoPtr pDevEvo,
pSurfaceDesc = &pChannel->notifiersDma[sd].surfaceDesc;
offset = nvPrepareNextVrrNotifier(pChannel, sd, head);
ctrlVal = DRF_DEF(C37E, _SET_NOTIFIER_CONTROL, _MODE, _WRITE_AWAKEN);
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pChannel,
pSurfaceDesc, offset, ctrlVal);
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pDevEvo,
pChannel, pSurfaceDesc, offset, ctrlVal);
} else {
offset = ctrlVal = 0;
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pChannel,
NULL, offset, ctrlVal);
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pDevEvo,
pChannel, NULL, offset, ctrlVal);
}
} else {
const NVFlipNIsoSurfaceEvoHwState *pNIso =
@@ -3734,8 +3762,8 @@ EvoFlipC3Common(NVDevEvoPtr pDevEvo,
_WRITE, ctrlVal);
}
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pChannel,
pSurfaceDesc, offset, ctrlVal);
pDevEvo->hal->SetWinNotifierSurfaceAddressAndControl(pDevEvo,
pChannel, pSurfaceDesc, offset, ctrlVal);
}
if (!pHwState->pSurfaceEvo[NVKMS_LEFT]) {
@@ -3745,7 +3773,7 @@ EvoFlipC3Common(NVDevEvoPtr pDevEvo,
planeIndex < NVKMS_MAX_PLANES_PER_SURFACE;
planeIndex++) {
const NvU8 ctxDmaIdx = EyeAndPlaneToCtxDmaIdx(eye, planeIndex);
pDevEvo->hal->SetISOSurfaceAddress(pChannel,
pDevEvo->hal->SetISOSurfaceAddress(pDevEvo, pChannel,
NULL /* pSurfaceDec */, 0 /* offset */, ctxDmaIdx,
NV_FALSE /* isBlocklinear */);
}
@@ -3823,7 +3851,7 @@ EvoFlipC3Common(NVDevEvoPtr pDevEvo,
offset = pSurfaceEvoPerEye->planes[planeIndex].offset;
}
pDevEvo->hal->SetISOSurfaceAddress(pChannel,
pDevEvo->hal->SetISOSurfaceAddress(pDevEvo, pChannel,
pSurfaceDesc, offset, ctxDmaIdx, isBlockLinear);
}
}
@@ -4367,6 +4395,7 @@ skipInit:
}
static void EvoSetILUTSurfaceAddressC5(
const NVDevEvoRec *pDevEvo,
NVEvoChannelPtr pChannel,
const NVSurfaceDescriptor *pSurfaceDesc,
NvU32 offset)
@@ -4515,10 +4544,10 @@ EvoFlipC5Common(NVDevEvoPtr pDevEvo,
DRF_DEF(C57E, _SET_ILUT_CONTROL, _MODE, _DIRECT10)) |
DRF_NUM(C57E, _SET_ILUT_CONTROL, _SIZE, lutSize));
pDevEvo->hal->SetILUTSurfaceAddress(pChannel,
pDevEvo->hal->SetILUTSurfaceAddress(pDevEvo, pChannel,
&pLutSurfaceEvo->surfaceDesc, origin);
} else {
pDevEvo->hal->SetILUTSurfaceAddress(pChannel,
pDevEvo->hal->SetILUTSurfaceAddress(pDevEvo, pChannel,
NULL /* pSurfaceDesc */, 0 /* offset */);
}
@@ -7945,6 +7974,7 @@ NVEvoHAL nvEvoC3 = {
FALSE, /* requiresScalingTapsInBothDimensions */
FALSE, /* supportsMergeMode */
FALSE, /* supportsHDMI10BPC */
FALSE, /* supportsDPAudio192KHz */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
@@ -8034,6 +8064,7 @@ NVEvoHAL nvEvoC5 = {
FALSE, /* requiresScalingTapsInBothDimensions */
TRUE, /* supportsMergeMode */
FALSE, /* supportsHDMI10BPC */
FALSE, /* supportsDPAudio192KHz */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
@@ -8123,6 +8154,7 @@ NVEvoHAL nvEvoC6 = {
FALSE, /* requiresScalingTapsInBothDimensions */
TRUE, /* supportsMergeMode */
TRUE, /* supportsHDMI10BPC */
FALSE, /* supportsDPAudio192KHz */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */

View File

@@ -140,7 +140,7 @@ static NvBool UpdateProposedFlipStateOneApiHead(
if (pParams->colorimetry.specified) {
pProposedApiHead->dirty.hdr = TRUE;
pProposedApiHead->hdr.colorimetry = pParams->colorimetry.val;
pProposedApiHead->hdr.dpyColor.colorimetry = pParams->colorimetry.val;
}
if (pParams->hdrInfoFrame.specified) {
@@ -172,7 +172,7 @@ static NvBool UpdateProposedFlipStateOneApiHead(
}
/* NVKMS_OUTPUT_TF_PQ requires the RGB color space */
if (pProposedApiHead->hdr.colorSpace !=
if (pProposedApiHead->hdr.dpyColor.format !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
return FALSE;
}
@@ -182,7 +182,8 @@ static NvBool UpdateProposedFlipStateOneApiHead(
// XXX HDR TODO: Handle other colorimetries
if (pProposedApiHead->hdr.infoFrameOverride ||
(pProposedApiHead->hdr.staticMetadataLayerMask != 0) ||
(pProposedApiHead->hdr.colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
(pProposedApiHead->hdr.dpyColor.colorimetry ==
NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
const NVDpyEvoRec *pDpyEvoIter;
// All dpys on apiHead must support HDR.
@@ -195,11 +196,11 @@ static NvBool UpdateProposedFlipStateOneApiHead(
}
}
if (!nvChooseColorRangeEvo(pProposedApiHead->hdr.colorimetry,
if (!nvChooseColorRangeEvo(pProposedApiHead->hdr.dpyColor.colorimetry,
pDpyEvo->requestedColorRange,
pProposedApiHead->hdr.colorSpace,
pProposedApiHead->hdr.colorBpc,
&pProposedApiHead->hdr.colorRange)) {
pProposedApiHead->hdr.dpyColor.format,
pProposedApiHead->hdr.dpyColor.bpc,
&pProposedApiHead->hdr.dpyColor.range)) {
return FALSE;
}
}
@@ -336,17 +337,11 @@ static void InitNvKmsFlipWorkArea(const NVDevEvoRec *pDevEvo,
&pDispEvo->apiHeadState[apiHead];
pProposedApiHead->hdr.tf = pApiHeadState->tf;
pProposedApiHead->hdr.colorimetry = pApiHeadState->colorimetry;
pProposedApiHead->hdr.dpyColor = pApiHeadState->attributes.color;
pProposedApiHead->hdr.infoFrameOverride =
pApiHeadState->hdrInfoFrameOverride;
pProposedApiHead->hdr.staticMetadataLayerMask =
pApiHeadState->hdrStaticMetadataLayerMask;
pProposedApiHead->hdr.colorSpace =
pApiHeadState->attributes.colorSpace;
pProposedApiHead->hdr.colorBpc =
pApiHeadState->attributes.colorBpc;
pProposedApiHead->hdr.colorRange =
pApiHeadState->attributes.colorRange;
pProposedApiHead->viewPortPointIn =
pApiHeadState->viewPortPointIn;
@@ -399,9 +394,7 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo,
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
pDispEvo,
head,
pProposedApiHead->hdr.colorimetry,
pProposedApiHead->hdr.colorSpace,
pProposedApiHead->hdr.colorRange,
&pProposedApiHead->hdr.dpyColor,
pUpdateState);
}
@@ -413,17 +406,9 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo,
}
if (pProposedApiHead->dirty.hdr) {
pApiHeadState->attributes.colorSpace =
pProposedApiHead->hdr.colorSpace;
pApiHeadState->attributes.colorBpc =
pProposedApiHead->hdr.colorBpc;
pApiHeadState->attributes.colorRange =
pProposedApiHead->hdr.colorRange;
pApiHeadState->attributes.color = pProposedApiHead->hdr.dpyColor;
pApiHeadState->tf = pProposedApiHead->hdr.tf;
pApiHeadState->colorimetry = pProposedApiHead->hdr.colorimetry;
pApiHeadState->hdrInfoFrameOverride =
pProposedApiHead->hdr.infoFrameOverride;
pApiHeadState->hdrStaticMetadataLayerMask =

View File

@@ -67,8 +67,7 @@ static inline const NVT_EDID_CEA861_INFO *GetExt861(const NVParsedEdidEvoRec *pP
* colorimetry and colorrange for video infoframe.
*/
static void CalculateVideoInfoFrameColorFormat(
const NVAttributesSetEvoRec *pAttributesSet,
enum NvKmsOutputColorimetry colorimetry,
const NVDpyAttributeColor *pDpyColor,
const NvU32 hdTimings,
NVT_VIDEO_INFOFRAME_CTRL *pCtrl)
{
@@ -77,12 +76,12 @@ static void CalculateVideoInfoFrameColorFormat(
* is RGB. This is enforced when the colorSpace is selected.
* XXX HDR TODO: Support YUV
*/
nvAssert((colorimetry != NVKMS_OUTPUT_COLORIMETRY_BT2100) ||
(pAttributesSet->colorSpace ==
nvAssert((pDpyColor->colorimetry != NVKMS_OUTPUT_COLORIMETRY_BT2100) ||
(pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB));
// sets video infoframe colorspace (RGB/YUV).
switch (pAttributesSet->colorSpace) {
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
pCtrl->color_space = NVT_VIDEO_INFOFRAME_BYTE1_Y1Y0_RGB;
break;
@@ -101,9 +100,9 @@ static void CalculateVideoInfoFrameColorFormat(
}
// sets video infoframe colorimetry.
switch (pAttributesSet->colorSpace) {
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
if (colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
pCtrl->colorimetry = NVT_COLORIMETRY_BT2020RGB;
} else {
pCtrl->colorimetry = NVT_COLORIMETRY_RGB;
@@ -126,7 +125,7 @@ static void CalculateVideoInfoFrameColorFormat(
}
// sets video infoframe colorrange.
switch (pAttributesSet->colorRange) {
switch (pDpyColor->range) {
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL:
pCtrl->rgb_quantization_range =
NVT_VIDEO_INFOFRAME_BYTE3_Q1Q0_FULL_RANGE;
@@ -524,7 +523,7 @@ static void SendInfoFrame(const NVDispEvoRec *pDispEvo,
*/
static void SendVideoInfoFrame(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NVAttributesSetEvoRec *pAttributesSet,
const NVDpyAttributeColor *pDpyColor,
const NVDispHeadInfoFrameStateEvoRec *pInfoFrameState,
NVT_EDID_INFO *pEdidInfo)
{
@@ -534,11 +533,7 @@ static void SendVideoInfoFrame(const NVDispEvoRec *pDispEvo,
NVT_STATUS status;
CalculateVideoInfoFrameColorFormat(
pAttributesSet,
pDispEvo->headState[head].colorimetry,
hdTimings,
&videoCtrl);
CalculateVideoInfoFrameColorFormat(pDpyColor, hdTimings, &videoCtrl);
status = NvTiming_ConstructVideoInfoframe(pEdidInfo,
&videoCtrl,
@@ -675,7 +670,7 @@ SendHDRInfoFrame(const NVDispEvoRec *pDispEvo, const NvU32 head,
*/
void nvUpdateHdmiInfoFrames(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NVAttributesSetEvoRec *pAttributesSet,
const NVDpyAttributeColor *pDpyColor,
const NVDispHeadInfoFrameStateEvoRec *pInfoFrameState,
NVDpyEvoRec *pDpyEvo)
{
@@ -692,7 +687,7 @@ void nvUpdateHdmiInfoFrames(const NVDispEvoRec *pDispEvo,
SendVideoInfoFrame(pDispEvo,
head,
pAttributesSet,
pDpyColor,
pInfoFrameState,
&pDpyEvo->parsedEdid.info);
@@ -844,9 +839,11 @@ static void EnableHdmiAudio(const NVDispEvoRec *pDispEvo,
}
static const NVT_EDID_CEA861_INFO *GetMaxSampleRateExtBlock(
const NVDpyEvoRec *pDpyEvo,
const NVParsedEdidEvoRec *pParsedEdid,
NvU32 *pMaxFreqSupported)
{
const NVDevEvoRec *pDevEvo = pDpyEvo->pDispEvo->pDevEvo;
const NVT_EDID_CEA861_INFO *pExt861 = NULL;
int extIndex;
int i;
@@ -903,6 +900,15 @@ static const NVT_EDID_CEA861_INFO *GetMaxSampleRateExtBlock(
NV0073_CTRL_DFP_ELD_AUDIO_CAPS_MAX_FREQ_SUPPORTED_0480KHZ;
}
/* Cap DP audio to 48 KHz unless device supports 192 KHz */
if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo) &&
!pDevEvo->hal->caps.supportsDPAudio192KHz &&
(maxFreqSupported >
NV0073_CTRL_DFP_ELD_AUDIO_CAPS_MAX_FREQ_SUPPORTED_0480KHZ)) {
maxFreqSupported =
NV0073_CTRL_DFP_ELD_AUDIO_CAPS_MAX_FREQ_SUPPORTED_0480KHZ;
}
if (maxFreqSupported > *pMaxFreqSupported) {
*pMaxFreqSupported = maxFreqSupported;
pExt861 = pTmpExt861;
@@ -932,8 +938,8 @@ static const VSDB_DATA *GetVsdb(const NVT_EDID_CEA861_INFO *pExt861)
return pVsdb;
}
static NvBool FillELDBuffer(const NvU32 displayId,
const NvBool isDisplayPort,
static NvBool FillELDBuffer(const NVDpyEvoRec *pDpyEvo,
const NvU32 displayId,
const NVParsedEdidEvoRec *pParsedEdid,
NVEldEvoRec *pEld,
NvU32 *pMaxFreqSupported)
@@ -946,8 +952,9 @@ static NvBool FillELDBuffer(const NvU32 displayId,
NvU8 EldSAI = 0;
NvU8 EldAudSynchDelay = 0;
const VSDB_DATA *pVsdb;
NvBool isDisplayPort = nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo);
pExt861 = GetMaxSampleRateExtBlock(pParsedEdid, pMaxFreqSupported);
pExt861 = GetMaxSampleRateExtBlock(pDpyEvo, pParsedEdid, pMaxFreqSupported);
if (pExt861 == NULL) {
return FALSE;
@@ -1110,8 +1117,8 @@ void nvHdmiDpConstructHeadAudioState(const NvU32 displayId,
pAudioState->isAudioOverHdmi = nvDpyIsHdmiEvo(pDpyEvo);
if (FillELDBuffer(displayId,
nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo),
if (FillELDBuffer(pDpyEvo,
displayId,
&pDpyEvo->parsedEdid,
&pAudioState->eld,
&pAudioState->maxFreqSupported)) {
@@ -2142,30 +2149,30 @@ NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo)
return TRUE;
}
/*
* Determine if HDMI FRL is needed to drive timings with the given pixel clock
* on the given dpy.
*
* Returns TRUE if FRL is needed, or FALSE otherwise.
* */
NvBool nvHdmiTimingsNeedFrl(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
NvU8 bpc)
NvU32 nvHdmiGetEffectivePixelClockKHz(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor)
{
const NvU32 pixelClock = (pHwTimings->yuv420Mode == NV_YUV420_MODE_HW) ?
(pHwTimings->pixelClock / 2) : pHwTimings->pixelClock;
nvAssert((pHwTimings->yuv420Mode == NV_YUV420_MODE_NONE) ||
(pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420));
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(bpc >= 8);
nvAssert(pDpyColor->bpc >= NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8);
/* YCbCr422 does not change the effective pixel clock. */
if (pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) {
return pixelClock;
}
/*
* For HDMI, maxSingleLinkPixelClockKHz is the maximum non-FRL rate.
* If the rate is higher than that, try to use FRL for the mode.
*
* For > 8 BPC, the effective pixel clock is adjusted upwards according to
* the ratio of the given BPC and 8 BPC.
*/
return ((pixelClock * bpc) / 8) > pDpyEvo->maxSingleLinkPixelClockKHz;
return ((pixelClock * pDpyColor->bpc) / 8ULL);
}
static NvU64 GetHdmiFrlLinkRate(HDMI_FRL_DATA_RATE frlRate)
@@ -2205,11 +2212,10 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
NvU8 bpc,
HDMI_FRL_CONFIG *pConfig,
NvU8 *pHdmiFrlBpc,
NVDscInfoEvoRec *pDscInfo)
{
const NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
@@ -2220,17 +2226,16 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
NVT_TIMING nvtTiming = { };
NVHDMIPKT_RESULT ret;
*pHdmiFrlBpc = 0;
if (pHwTimings->protocol != NVKMS_PROTOCOL_SOR_HDMI_FRL) {
nvkms_memset(pDscInfo, 0, sizeof(*pDscInfo));
nvkms_memset(pConfig, 0, sizeof(*pConfig));
return TRUE;
}
nvAssert(nvDpyIsHdmiEvo(pDpyEvo) &&
nvHdmiDpySupportsFrl(pDpyEvo) &&
nvHdmiTimingsNeedFrl(pDpyEvo, pHwTimings, bpc));
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(nvHdmiDpySupportsFrl(pDpyEvo));
nvAssert(nvHdmiGetEffectivePixelClockKHz(pDpyEvo, pHwTimings, pDpyColor) >
pDpyEvo->maxSingleLinkPixelClockKHz);
/* See if we can find an NVT_TIMING for this mode from the EDID. */
pNvtTiming = nvFindEdidNVT_TIMING(pDpyEvo, pModeTimings, pValidationParams);
@@ -2273,7 +2278,17 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
* This matches the non-DP default assigned later in
* nvConstructHwModeTimingsEvo().
*/
videoTransportInfo.bpc = bpc;
switch(pDpyColor->bpc) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
videoTransportInfo.bpc = HDMI_BPC10;
break;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8:
videoTransportInfo.bpc = HDMI_BPC8;
break;
default:
return FALSE;
}
/* TODO: support YUV/YCbCr 444 and 422 packing modes. */
switch (pModeTimings->yuv420Mode) {
case NV_YUV420_MODE_NONE:
@@ -2331,8 +2346,6 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
}
if (ret == NVHDMIPKT_SUCCESS) {
*pHdmiFrlBpc = bpc;
if (pDscInfo != NULL) {
const NvU64 hdmiLinkRate = GetHdmiFrlLinkRate(pConfig->frlRate);
@@ -2391,37 +2404,28 @@ NvBool nvHdmiFrlQueryConfig(
const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
HDMI_FRL_CONFIG *pConfig,
NvU8 *pHdmiFrlBpc,
NVDscInfoEvoRec *pDscInfo)
{
if (nvDpyIsHdmiDepth30Evo(pDpyEvo)) {
// Try first with 10 BPC
NVDpyAttributeColor dpyColor = *pDpyColor;
do {
if (nvHdmiFrlQueryConfigOneBpc(pDpyEvo,
pModeTimings,
pHwTimings,
&dpyColor,
b2Heads1Or,
pValidationParams,
HDMI_BPC10,
pConfig,
pHdmiFrlBpc,
pDscInfo)) {
*pDpyColor = dpyColor;
return TRUE;
}
}
// Try again with 8 BPC
return nvHdmiFrlQueryConfigOneBpc(pDpyEvo,
pModeTimings,
pHwTimings,
b2Heads1Or,
pValidationParams,
HDMI_BPC8,
pConfig,
pHdmiFrlBpc,
pDscInfo);
} while(nvDowngradeColorBpc(&dpyColor) &&
(dpyColor.bpc >= NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8));
return FALSE;
}
void nvHdmiFrlSetConfig(NVDispEvoRec *pDispEvo, NvU32 head)

View File

@@ -831,7 +831,8 @@ NvBool nvHsConfigInitModeset(
sizeof(*pTimings));
nvkms_memset(pTimings, 0, sizeof(*pTimings));
if (!nvGetHwModeTimings(pDispEvo, pRequestHead, pTimings,
if (!nvGetHwModeTimings(pDispEvo, apiHead, pRequestHead,
pTimings, NULL /* pDpyColor */,
NULL /* pInfoFrameCtrl */)) {
nvPreallocRelease(pDevEvo, PREALLOC_TYPE_HS_INIT_CONFIG_HW_TIMINGS);
return FALSE;
@@ -1247,7 +1248,8 @@ NvBool nvHsConfigDowngrade(
sizeof(*pTimings));
nvkms_memset(pTimings, 0, sizeof(*pTimings));
if (!nvGetHwModeTimings(pDispEvo, pRequestHead, pTimings,
if (!nvGetHwModeTimings(pDispEvo, apiHead, pRequestHead,
pTimings, NULL /* pDpyColor */,
NULL /* pInfoFrameCtrl */)) {
nvPreallocRelease(pDevEvo, PREALLOC_TYPE_HS_INIT_CONFIG_HW_TIMINGS);
return FALSE;

View File

@@ -227,8 +227,6 @@ void nvInitFlipEvoHwState(
pFlipState->hdrInfoFrame.eotf = pHeadState->hdrInfoFrameOverride.eotf;
pFlipState->hdrInfoFrame.staticMetadata =
pHeadState->hdrInfoFrameOverride.staticMetadata;
pFlipState->colorimetry = pHeadState->colorimetry;
}
@@ -1008,11 +1006,6 @@ NvBool nvUpdateFlipEvoHwState(
pFlipState->tf = pParams->tf.val;
}
if (pParams->colorimetry.specified) {
pFlipState->dirty.colorimetry = TRUE;
pFlipState->colorimetry = pParams->colorimetry.val;
}
if (pParams->hdrInfoFrame.specified) {
pFlipState->dirty.hdrStaticMetadata = TRUE;
@@ -1670,11 +1663,6 @@ static void UpdateHDR(NVDevEvoPtr pDevEvo,
dirty = TRUE;
}
if (pFlipState->dirty.colorimetry) {
pHeadState->colorimetry = pFlipState->colorimetry;
dirty = TRUE;
}
if (dirty) {
// Update OCSC / OLUT
nvEvoSetLUTContextDma(pDispEvo, head, updateState);

View File

@@ -29,6 +29,7 @@
#include "nvkms-3dvision.h"
#include "nvkms-evo.h"
#include "nvkms-ioctl.h"
#include "nvkms-modetimings.h"
#include "nv_mode_timings_utils.h"
#include "nv_vasprintf.h"
@@ -177,17 +178,21 @@ nvValidateModeEvo(NVDpyEvoPtr pDpyEvo,
*
* Currently only frame packed 3D modes are supported, as we rely on
* Kepler's HW support for this mode.
*
* If hdmi 3D is supported, then only one of hdmi3D or hdmi3DAvailable
* will be returned true, based on if it was requested.
*/
static NvBool GetHdmi3DValue(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsModeValidationParams *pParams,
const NVT_TIMING *pTiming)
static void GetHdmi3DValue(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsModeValidationParams *pParams,
const NVT_TIMING *pTiming,
NvBool *hdmi3D,
NvBool *hdmi3DAvailable)
{
/* This should only be used in paths where we have a valid parsed EDID. */
nvAssert(pDpyEvo->parsedEdid.valid);
if ((pParams->stereoMode == NVKMS_STEREO_HDMI_3D) &&
(NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status) ==
if ((NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status) ==
NVT_TYPE_EDID_861ST) &&
nvDpyEvoSupportsHdmi3D(pDpyEvo)) {
@@ -200,32 +205,15 @@ static NvBool GetHdmi3DValue(const NVDpyEvoRec *pDpyEvo,
if ((vic == hdmi3DMap.Vic) &&
(hdmi3DMap.StereoStructureMask &
NVT_HDMI_3D_SUPPORTED_FRAMEPACK_MASK)) {
return TRUE;
*hdmi3D = pParams->stereoMode == NVKMS_STEREO_HDMI_3D;
*hdmi3DAvailable = pParams->stereoMode != NVKMS_STEREO_HDMI_3D;
return;
}
}
}
return FALSE;
}
/*
* For Kepler HW HDMI 1.4 frame packed stereo, HW combines two flips
* into a single top-down double-height frame, and it needs a
* doubled refresh rate to accommodate this.
*/
static void UpdateNvModeTimingsForHdmi3D(NvModeTimings *pModeTimings,
NvBool enableHdmi3D)
{
if (enableHdmi3D) {
pModeTimings->pixelClockHz *= 2;
pModeTimings->RRx1k *= 2;
} else {
nvAssert((pModeTimings->pixelClockHz % 2) == 0);
pModeTimings->pixelClockHz /= 2;
nvAssert((pModeTimings->RRx1k % 2) == 0);
pModeTimings->RRx1k /= 2;
}
*hdmi3D = FALSE;
*hdmi3DAvailable = FALSE;
}
/*
@@ -359,6 +347,7 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo,
NVT_TIMING timing = pDpyEvo->parsedEdid.info.timing[i];
EvoValidateModeFlags flags;
struct NvKmsMode kmsMode = { };
NvBool hdmi3D = FALSE;
/* Skip this mode if it was marked invalid by nvtiming. */
@@ -405,11 +394,9 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo,
* Currently only frame packed 3D modes are supported, as we rely on
* Kepler's HW support for this mode.
*/
kmsMode.timings.hdmi3D = GetHdmi3DValue(pDpyEvo, pParams, &timing);
if (kmsMode.timings.hdmi3D) {
UpdateNvModeTimingsForHdmi3D(&kmsMode.timings, TRUE);
}
GetHdmi3DValue(pDpyEvo, pParams, &timing, &hdmi3D,
&pReply->hdmi3DAvailable);
nvKmsUpdateNvModeTimingsForHdmi3D(&kmsMode.timings, hdmi3D);
kmsMode.timings.yuv420Mode = GetYUV420Value(pDpyEvo, pParams, &timing);
@@ -422,6 +409,49 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo,
pInfoString,
&pReply->validSyncs,
&pReply->modeUsage);
/*
* The client did not request hdmi3D, but this mode supports hdmi3D.
* Re-validate the mode with hdmi3D enabled. If that passes, report
* to the client that the mode could be used with hdmi3D if they choose
* later.
*/
if (pReply->valid && pReply->hdmi3DAvailable) {
/*
* Use dummy validSyncs and modeUsage so the original result isn't
* affected.
*
* Create a temporary KMS mode so that we can enable hdmi3D in it
* without perturbing the currently validated mode.
*
* Put all of this in a temporary heap allocation, to conserve
* stack.
*/
struct workArea {
struct NvKmsModeValidationValidSyncs stereoValidSyncs;
struct NvKmsUsageBounds stereoModeUsage;
struct NvKmsMode stereoKmsMode;
} *pWorkArea = nvCalloc(1, sizeof(*pWorkArea));
if (pWorkArea == NULL) {
pReply->hdmi3DAvailable = FALSE;
} else {
pWorkArea->stereoKmsMode = kmsMode;
nvKmsUpdateNvModeTimingsForHdmi3D(
&pWorkArea->stereoKmsMode.timings, TRUE);
pReply->hdmi3DAvailable =
ValidateMode(pDpyEvo,
&pWorkArea->stereoKmsMode,
&flags,
pParams,
pInfoString,
&pWorkArea->stereoValidSyncs,
&pWorkArea->stereoModeUsage);
nvFree(pWorkArea);
}
}
/*
* if this is a detailed timing, then flag it as such; this
* will be used later when searching for the AutoSelect mode
@@ -458,16 +488,13 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo,
*/
if (flags.patchedStereoTimings) {
enum NvYuv420Mode yuv420Mode = kmsMode.timings.yuv420Mode;
NvBool hdmi3D = kmsMode.timings.hdmi3D;
hdmi3D = kmsMode.timings.hdmi3D;
NVT_TIMINGtoNvModeTimings(&pDpyEvo->parsedEdid.info.timing[i],
&kmsMode.timings);
kmsMode.timings.yuv420Mode = yuv420Mode;
kmsMode.timings.hdmi3D = hdmi3D;
if (hdmi3D) {
UpdateNvModeTimingsForHdmi3D(&kmsMode.timings, TRUE);
}
nvKmsUpdateNvModeTimingsForHdmi3D(&kmsMode.timings, hdmi3D);
}
pReply->mode.timings = kmsMode.timings;
@@ -1643,12 +1670,10 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
NVKMS_MAX_HEADS_PER_DISP);
NvU32 impOutNumHeads = 0x0;
NvU32 head;
NvU8 hdmiFrlBpc;
NvBool ret = FALSE;
const NVColorFormatInfoRec supportedColorFormats = nvGetColorFormatInfo(pDpyEvo);
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace;
enum NvKmsDpyAttributeColorBpcValue colorBpc;
NVDpyAttributeColor dpyColor;
if (modeName[0] == '\0') {
nvBuildModeName(pModeTimings->hVisible, pModeTimings->vVisible,
@@ -1672,6 +1697,17 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
goto done;
}
if (pTimingsEvo->yuv420Mode != NV_YUV420_MODE_NONE) {
dpyColor.format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420;
dpyColor.bpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
dpyColor.range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
dpyColor.colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
} else if (!nvGetDefaultDpyColor(&supportedColorFormats, &dpyColor)) {
LogModeValidationEnd(pDispEvo, pInfoString,
"Failed to get default color space and Bpc");
goto done;
}
/*
* we made it past the rest of mode validation; now construct the
* hw modetimings to use for this mode; we do this here so that we
@@ -1695,6 +1731,7 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
pKmsMode,
NULL, /* pViewPortSizeIn */
NULL, /* pViewPortOut */
&dpyColor,
pTimingsEvo,
pParams,
pInfoString)) {
@@ -1706,32 +1743,22 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
b2Heads1Or = nvEvoUse2Heads1OR(pDpyEvo, pTimingsEvo, pParams);
if (pTimingsEvo->yuv420Mode != NV_YUV420_MODE_NONE) {
colorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420;
colorBpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
} else if (!nvGetDefaultColorSpace(&supportedColorFormats, &colorSpace,
&colorBpc)) {
LogModeValidationEnd(pDispEvo, pInfoString,
"Failed to get default color space and Bpc");
goto done;
}
if (nvDpyIsHdmiEvo(pDpyEvo)) {
if (!nvHdmiFrlQueryConfig(pDpyEvo,
&pKmsMode->timings,
pTimingsEvo,
&dpyColor,
b2Heads1Or,
pParams,
pHdmiFrlConfig,
&hdmiFrlBpc,
pDscInfo)) {
LogModeValidationEnd(pDispEvo, pInfoString,
"Unable to determine HDMI 2.1 Fixed Rate Link configuration.");
goto done;
}
} else {
if (!nvDPValidateModeEvo(pDpyEvo, pTimingsEvo, &colorSpace, &colorBpc,
b2Heads1Or, pDscInfo, pParams)) {
if (!nvDPValidateModeEvo(pDpyEvo, pTimingsEvo, &dpyColor, b2Heads1Or,
pDscInfo, pParams)) {
LogModeValidationEnd(pDispEvo,
pInfoString, "DP Bandwidth check failed");
goto done;
@@ -1755,8 +1782,7 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
(pDscInfo->type !=
NV_DSC_INFO_EVO_TYPE_DISABLED),
b2Heads1Or,
colorSpace,
colorBpc,
&dpyColor,
pParams,
impOutTimings,
&impOutNumHeads,
@@ -1857,16 +1883,13 @@ const NVT_TIMING *nvFindEdidNVT_TIMING
* in ValidateModeIndexEdid(), so that the modeTimings can be
* compared with the NVT_TIMINGs in the parsed EDID.
*/
if (tmpModeTimings.hdmi3D) {
UpdateNvModeTimingsForHdmi3D(&tmpModeTimings, FALSE);
}
nvKmsUpdateNvModeTimingsForHdmi3D(&tmpModeTimings, FALSE);
/*
* The NVT_TIMINGs we compare against below won't have hdmi3D or
* yuv420 set; clear those flags in tmpModeTimings so that we can
* do a more meaningful comparison.
*/
tmpModeTimings.hdmi3D = FALSE;
tmpModeTimings.yuv420Mode = NV_YUV420_MODE_NONE;
for (i = 0; i < pDpyEvo->parsedEdid.info.total_timings; i++) {
@@ -1943,12 +1966,9 @@ static NvBool ConstructModeTimingsMetaData(
/* Restore the yuv420 and hdmi3D flags from the client's mode. */
modeTimings.yuv420Mode = pKmsMode->timings.yuv420Mode;
modeTimings.hdmi3D = pKmsMode->timings.hdmi3D;
/* Re-apply adjustments for hdmi3D. */
if (modeTimings.hdmi3D) {
UpdateNvModeTimingsForHdmi3D(&modeTimings, TRUE);
}
nvKmsUpdateNvModeTimingsForHdmi3D(&modeTimings, pKmsMode->timings.hdmi3D);
}
@@ -1959,7 +1979,10 @@ static NvBool ConstructModeTimingsMetaData(
}
/* Validate hdmi3D. */
if (modeTimings.hdmi3D != GetHdmi3DValue(pDpyEvo, pParams, &timing)) {
NvBool hdmi3D = FALSE;
NvBool hdmi3DAvailable = FALSE;
GetHdmi3DValue(pDpyEvo, pParams, &timing, &hdmi3D, &hdmi3DAvailable);
if ((modeTimings.hdmi3D != hdmi3D) && !hdmi3DAvailable) {
return FALSE;
}
@@ -2027,6 +2050,7 @@ NvBool nvValidateModeForModeset(NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvo *pTimingsEvo,
NVT_VIDEO_INFOFRAME_CTRL *pInfoFrameCtrl)
{
@@ -2058,6 +2082,7 @@ NvBool nvValidateModeForModeset(NVDpyEvoRec *pDpyEvo,
&kmsMode,
pViewPortSizeIn,
pViewPortOut,
pDpyColor,
pTimingsEvo,
pParams,
&dummyInfoString)) {

View File

@@ -92,6 +92,7 @@
#include "nvkms-dma.h"
#include "dp/nvdp-connector.h"
#include "dp/nvdp-device.h"
#include "nvkms-api.h"
@@ -101,6 +102,13 @@
#include "nvkms-attributes.h"
#include "nvkms-headsurface-config.h"
static NvBool
GetColorSpaceAndColorRange(
const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
NVDpyAttributeColor *pDpyColor);
static void
ClearProposedModeSetHwState(const NVDevEvoRec *pDevEvo,
NVProposedModeSetHwState *pProposed,
@@ -168,11 +176,14 @@ InheritPreviousModesetState(const NVDevEvoRec *pDevEvo,
*/
NvBool
nvGetHwModeTimings(const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
NVHwModeTimingsEvo *pTimings,
NVDpyAttributeColor *pDpyColor,
NVT_VIDEO_INFOFRAME_CTRL *pInfoFrameCtrl)
{
NVDpyEvoPtr pDpyEvo;
NVDpyAttributeColor dpyColor = { };
if (nvDpyIdListIsEmpty(pRequestHead->dpyIdList)) {
return TRUE;
@@ -184,14 +195,28 @@ nvGetHwModeTimings(const NVDispEvoRec *pDispEvo,
return FALSE;
}
return nvValidateModeForModeset(pDpyEvo,
&pRequestHead->modeValidationParams,
&pRequestHead->mode,
&pRequestHead->viewPortSizeIn,
pRequestHead->viewPortOutSpecified ?
&pRequestHead->viewPortOut : NULL,
pTimings,
pInfoFrameCtrl);
if (!GetColorSpaceAndColorRange(pDispEvo, apiHead, pRequestHead,
&dpyColor)) {
return FALSE;
}
if (!nvValidateModeForModeset(pDpyEvo,
&pRequestHead->modeValidationParams,
&pRequestHead->mode,
&pRequestHead->viewPortSizeIn,
pRequestHead->viewPortOutSpecified ?
&pRequestHead->viewPortOut : NULL,
&dpyColor,
pTimings,
pInfoFrameCtrl)) {
return FALSE;
}
if (pDpyColor != NULL) {
*pDpyColor = dpyColor;
}
return TRUE;
}
static NvBool IsPreSyncptSpecified(
@@ -215,11 +240,12 @@ static NvBool IsPreSyncptSpecified(
static NvBool
GetColorSpaceAndColorRange(
const NVDispEvoPtr pDispEvo,
const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
const NVProposedModeSetHwStateOneHead *pProposedPrimaryHead,
NVProposedModeSetStateOneApiHead *pProposedApiHead)
NVDpyAttributeColor *pDpyColor)
{
enum NvKmsOutputColorimetry colorimetry;
enum NvKmsDpyAttributeColorRangeValue requestedColorRange;
enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace;
NVDpyEvoRec *pOneArbitraryDpyEvo =
@@ -249,29 +275,43 @@ GetColorSpaceAndColorRange(
requestedColorRange = pOneArbitraryDpyEvo->requestedColorRange;
}
if (pRequestHead->flip.colorimetry.specified) {
colorimetry = pRequestHead->flip.colorimetry.val;
} else {
colorimetry =
pDispEvo->apiHeadState[apiHead].attributes.color.colorimetry;
}
/*
* Choose current colorSpace and colorRange based on the current mode
* timings and the requested color space and range.
*/
if (!nvChooseCurrentColorSpaceAndRangeEvo(pOneArbitraryDpyEvo,
&pProposedApiHead->timings,
pProposedPrimaryHead->hdmiFrlBpc,
pProposedApiHead->colorimetry,
pRequestHead->mode.timings.yuv420Mode,
colorimetry,
requestedColorSpace,
requestedColorRange,
&pProposedApiHead->attributes.colorSpace,
&pProposedApiHead->attributes.colorBpc,
&pProposedApiHead->attributes.colorRange)) {
&pDpyColor->format,
&pDpyColor->bpc,
&pDpyColor->range)) {
return FALSE;
}
pDpyColor->colorimetry = colorimetry;
return TRUE;
}
static NvBool AssignProposedModeSetColorSpaceAndColorRangeSpecified(
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
NVProposedModeSetStateOneApiHead *pProposedApiHead)
{
/*
* When colorspace is specified in modeset request, it should
* match the proposed colorspace.
*/
if (pRequestHead->colorSpaceSpecified) {
NvBool ret = FALSE;
switch (pProposedApiHead->attributes.colorSpace) {
switch (pProposedApiHead->attributes.color.format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
ret = (pRequestHead->colorSpace ==
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB);
@@ -297,13 +337,12 @@ GetColorSpaceAndColorRange(
* match the proposed color range.
*/
if (pRequestHead->colorRangeSpecified &&
(pProposedApiHead->attributes.colorRange != pRequestHead->colorRange)) {
(pProposedApiHead->attributes.color.range != pRequestHead->colorRange)) {
return FALSE;
}
pProposedApiHead->colorSpaceSpecified = pRequestHead->colorSpaceSpecified;
pProposedApiHead->colorRangeSpecified = pRequestHead->colorRangeSpecified;
return TRUE;
}
@@ -434,7 +473,6 @@ InitNVProposedModeSetStateOneApiHead(
pProposedApiHead->infoFrame =
pDispEvo->apiHeadState[apiHead].infoFrame;
pProposedApiHead->tf = pDispEvo->apiHeadState[apiHead].tf;
pProposedApiHead->colorimetry = pDispEvo->apiHeadState[apiHead].colorimetry;
pProposedApiHead->hdrInfoFrameOverride =
pDispEvo->apiHeadState[apiHead].hdrInfoFrameOverride;
pProposedApiHead->hdrStaticMetadataLayerMask =
@@ -491,7 +529,6 @@ InitProposedModeSetHwState(const NVDevEvoRec *pDevEvo,
NVFlipEvoHwState *pFlip = &pProposed->sd[sd].head[head].flip;
pFlip->dirty.tf = TRUE;
pFlip->dirty.hdrStaticMetadata = TRUE;
pFlip->dirty.colorimetry = TRUE;
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
pFlip->dirty.layer[layer] = TRUE;
}
@@ -525,7 +562,6 @@ InitProposedModeSetHwState(const NVDevEvoRec *pDevEvo,
pProposedHead->timings = pHeadState->timings;
pProposedHead->pConnectorEvo = pHeadState->pConnectorEvo;
pProposedHead->hdmiFrlConfig = pHeadState->hdmiFrlConfig;
pProposedHead->hdmiFrlBpc = pHeadState->hdmiFrlBpc;
pProposedHead->audio = pHeadState->audio;
}
}
@@ -567,7 +603,6 @@ AssignProposedModeSetNVFlipEvoHwState(
pFlip->dirty.tf = TRUE;
pFlip->dirty.hdrStaticMetadata = TRUE;
pFlip->dirty.colorimetry = TRUE;
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
pFlip->dirty.layer[layer] = TRUE;
@@ -748,6 +783,7 @@ static NvU32 GetFree2Heads1ORHeadsMask(const NVDevEvoRec *pDevEvo,
static NvU32 GetFreeHeads(const NVDevEvoRec *pDevEvo,
const NvU32 apiHead,
const NVDpyEvoRec *pDpyEvo,
const NvU32 freeHwHeadsMask)
{
NvU32 foundHead = NV_INVALID_HEAD;
@@ -812,7 +848,8 @@ static NvBool AssignProposedHwHeadsGeneric(
&pProposedApiHead->timings,
&pProposedApiHead->modeValidationParams));
NvU32 foundHead = GetFreeHeads(pDevEvo, apiHead, freeHwHeadsMask);
NvU32 foundHead = GetFreeHeads(pDevEvo, apiHead, pDpyEvo,
freeHwHeadsMask);
if (foundHead != NV_INVALID_HEAD) {
foundHeadsMask = NVBIT(foundHead);
}
@@ -1057,8 +1094,10 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
* more complete failure information to the client.
*/
if (!nvGetHwModeTimings(pDispEvo,
apiHead,
pRequestHead,
&pProposedApiHead->timings,
&pProposedApiHead->attributes.color,
&pProposedApiHead->infoFrame.ctrl)) {
pReply->disp[sd].head[apiHead].status =
NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE;
@@ -1066,6 +1105,14 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
continue;
}
if (!AssignProposedModeSetColorSpaceAndColorRangeSpecified(
pRequestHead, pProposedApiHead)) {
pReply->disp[sd].head[apiHead].status =
NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE;
ret = FALSE;
continue;
}
AdjustHwModeTimingsForVrr(pDispEvo,
pRequestHead,
prohibitAdaptiveSync,
@@ -1139,7 +1186,7 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
}
/* NVKMS_OUTPUT_TF_PQ requires the RGB color space */
if (pProposedApiHead->attributes.colorSpace !=
if (pProposedApiHead->attributes.color.format !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
ret = FALSE;
pReply->disp[sd].head[apiHead].status =
@@ -1149,10 +1196,6 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
}
}
if (pRequestHead->flip.colorimetry.specified) {
pProposedApiHead->colorimetry = pRequestHead->flip.colorimetry.val;
}
if (pRequestHead->flip.hdrInfoFrame.specified) {
pProposedApiHead->hdrInfoFrameOverride =
pRequestHead->flip.hdrInfoFrame.enabled;
@@ -1174,7 +1217,8 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
// XXX HDR TODO: Handle other colorimetries
if (pProposedApiHead->hdrInfoFrameOverride ||
(pProposedApiHead->hdrStaticMetadataLayerMask != 0) ||
(pProposedApiHead->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
(pProposedApiHead->attributes.color.colorimetry ==
NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
const NVDpyEvoRec *pDpyEvo;
// All dpys on apiHead must support HDR.
@@ -1291,11 +1335,11 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
if (!nvHdmiFrlQueryConfig(pDpyEvo,
&pRequestHead->mode.timings,
&pProposedApiHead->timings,
&pProposedApiHead->attributes.color,
(nvPopCount32(pProposedApiHead->hwHeadsMask) > 1)
/* b2Heads1Or */,
&pProposedApiHead->modeValidationParams,
&pProposedPrimaryHead->hdmiFrlConfig,
&pProposedPrimaryHead->hdmiFrlBpc,
&pProposedApiHead->dscInfo)) {
pReply->disp[sd].head[apiHead].status =
NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE;
@@ -1303,15 +1347,6 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
continue;
}
if (!GetColorSpaceAndColorRange(pDispEvo, pRequestHead,
pProposedPrimaryHead,
pProposedApiHead)) {
pReply->disp[sd].head[apiHead].status =
NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE;
ret = FALSE;
continue;
}
/*
* Construct the api head audio state, and pass it
* to the primary hardware head.
@@ -1412,8 +1447,7 @@ ValidateProposedModeSetHwStateOneDispImp(NVDispEvoPtr pDispEvo,
timingsParams[head].pConnectorEvo = pProposedHead->pConnectorEvo;
timingsParams[head].activeRmId = pProposedApiHead->activeRmId;
timingsParams[head].pixelDepth =
nvEvoColorSpaceBpcToPixelDepth(pProposedApiHead->attributes.colorSpace,
pProposedApiHead->attributes.colorBpc);
nvEvoDpyColorToPixelDepth(&pProposedApiHead->attributes.color);
timingsParams[head].pTimings = &pProposedHead->timings;
timingsParams[head].enableDsc = (pProposedApiHead->dscInfo.type !=
NV_DSC_INFO_EVO_TYPE_DISABLED);
@@ -1501,37 +1535,28 @@ static NvBool DowngradeColorSpaceAndBpcOneHead(
const NVDispEvoRec *pDispEvo,
NVProposedModeSetStateOneApiHead *pProposedApiHead)
{
enum NvKmsDpyAttributeColorRangeValue colorRange =
pProposedApiHead->attributes.colorRange;
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace =
pProposedApiHead->attributes.colorSpace;
enum NvKmsDpyAttributeColorBpcValue colorBpc =
pProposedApiHead->attributes.colorBpc;
NVDpyAttributeColor dpyColor = pProposedApiHead->attributes.color;
NVDpyEvoRec *pDpyEvo =
nvGetOneArbitraryDpyEvo(pProposedApiHead->dpyIdList,
pDispEvo);
const NVColorFormatInfoRec supportedColorFormats =
nvGetColorFormatInfo(pDpyEvo);
if (!nvDowngradeColorSpaceAndBpc(&supportedColorFormats,
&colorSpace, &colorBpc, &colorRange)) {
if (!nvDowngradeColorSpaceAndBpc(&supportedColorFormats, &dpyColor)) {
return FALSE;
}
if (pProposedApiHead->colorRangeSpecified &&
(colorRange != pProposedApiHead->attributes.colorRange)) {
(dpyColor.range != pProposedApiHead->attributes.color.range)) {
return FALSE;
}
if (pProposedApiHead->colorSpaceSpecified &&
(colorSpace != pProposedApiHead->attributes.colorSpace)) {
(dpyColor.format != pProposedApiHead->attributes.color.format)) {
return FALSE;
}
pProposedApiHead->attributes.colorRange = colorRange;
pProposedApiHead->attributes.colorSpace = colorSpace;
pProposedApiHead->attributes.colorBpc = colorBpc;
pProposedApiHead->attributes.color = dpyColor;
return TRUE;
}
@@ -1599,8 +1624,8 @@ static NvU32 SetDpLibImpParamsOneConnectorEvo(
pParams->head[head].displayId = pProposedApiHead->activeRmId;
pParams->head[head].dpyIdList = pProposedApiHead->dpyIdList;
pParams->head[head].colorSpace = pProposedApiHead->attributes.colorSpace;
pParams->head[head].colorBpc = pProposedApiHead->attributes.colorBpc;
pParams->head[head].colorSpace = pProposedApiHead->attributes.color.format;
pParams->head[head].colorBpc = pProposedApiHead->attributes.color.bpc;
pParams->head[head].pModeValidationParams =
&pProposedApiHead->modeValidationParams;
pParams->head[head].pTimings = &pProposedApiHead->timings;
@@ -1766,8 +1791,8 @@ static NvBool ValidateProposedModeSetHwStateOneDispDPlib(
primaryHead,
pProposedApiHead->activeRmId,
pProposedApiHead->dpyIdList,
pProposedApiHead->attributes.colorSpace,
pProposedApiHead->attributes.colorBpc,
pProposedApiHead->attributes.color.format,
pProposedApiHead->attributes.color.bpc,
&pProposedApiHead->timings,
&pProposedApiHead->dscInfo);
if (pProposedPrimaryHead->pDpLibModesetState == NULL) {
@@ -1925,7 +1950,7 @@ ValidateProposedModeSetHwStateOneDisp(
}
nvChooseDitheringEvo(pDpyEvo->pConnectorEvo,
pProposedApiHead->attributes.colorBpc,
pProposedApiHead->attributes.color.bpc,
&pDpyEvo->requestedDithering,
&pProposedApiHead->attributes.dithering);
}
@@ -2111,7 +2136,7 @@ static void AssignSor(const NVDispEvoRec *pDispEvo,
return;
}
if (nvAssignSOREvo(pDispEvo, displayId, b2Heads1Or, sorExcludeMask)) {
if (nvAssignSOREvo(pDpyEvo->pConnectorEvo, displayId, b2Heads1Or, sorExcludeMask)) {
nvAssert(pConnectorEvo->or.primary != NV_INVALID_OR);
pWorkArea->sd[sd].assignedSorMask |= nvConnectorGetORMaskEvo(pConnectorEvo);
} else {
@@ -2119,6 +2144,20 @@ static void AssignSor(const NVDispEvoRec *pDispEvo,
}
}
static void
SetLinkHandOffOnDpDdcPartners(NVConnectorEvoRec *pConnectorEvo, NVDispEvoPtr pDispEvo, NvBool enable)
{
NVConnectorEvoRec *pTmpConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pTmpConnectorEvo, pDispEvo) {
if (nvDpyIdIsInDpyIdList(pTmpConnectorEvo->displayId,
pConnectorEvo->ddcPartnerDpyIdsList)) {
if (nvConnectorUsesDPLib(pTmpConnectorEvo)) {
nvDPSetLinkHandoff(pTmpConnectorEvo->pDpLibConnector, enable);
}
}
}
}
static void
KickoffModesetUpdateState(
NVDispEvoPtr pDispEvo,
@@ -2145,6 +2184,10 @@ KickoffModesetUpdateState(
modesetUpdateState);
} else if (nvConnectorIsDPSerializer(pConnectorEvo)) {
nvDPSerializerPreSetMode(pDispEvo, pConnectorEvo);
} else {
if (nvIsConnectorActiveEvo(pConnectorEvo)) {
SetLinkHandOffOnDpDdcPartners(pConnectorEvo, pDispEvo, TRUE);
}
}
}
}
@@ -2166,6 +2209,10 @@ KickoffModesetUpdateState(
modesetUpdateState);
} else if (nvConnectorIsDPSerializer(pConnectorEvo)) {
nvDPSerializerPostSetMode(pDispEvo, pConnectorEvo);
} else {
if (!nvIsConnectorActiveEvo(pConnectorEvo)) {
SetLinkHandOffOnDpDdcPartners(pConnectorEvo, pDispEvo, FALSE);
}
}
}
}
@@ -2233,6 +2280,7 @@ IsProposedModeSetStateOneApiHeadIncompatible(
&pProposedDisp->apiHead[tmpApiHead];
const NVDpyEvoRec *pDpyEvoTmp =
nvGetOneArbitraryDpyEvo(pTmpProposedApiHead->dpyIdList, pDispEvo);
NVDpyIdList dpyIdList;
if (!pTmpProposedApiHead->changed) {
continue;
@@ -2248,13 +2296,30 @@ IsProposedModeSetStateOneApiHeadIncompatible(
return TRUE;
}
/*
* For the remaining tests, we compare apiHead against all other heads
* in the tmpApiHead loop.
*/
if (tmpApiHead == apiHead) {
continue;
}
/*
* Consider this api-head incompatible if its current hardware heads
* are proposed to map onto the different api-head.
*/
if ((tmpApiHead != apiHead) &&
((pTmpProposedApiHead->hwHeadsMask &
pApiHeadState->hwHeadsMask) != 0x0)) {
if ((pTmpProposedApiHead->hwHeadsMask &
pApiHeadState->hwHeadsMask) != 0x0) {
return TRUE;
}
/*
* Consider this api-head incompatible if its current
* dpy(s) are proposed to attach to a different api-head.
*/
dpyIdList = nvIntersectDpyIdListAndDpyIdList(pTmpProposedApiHead->dpyIdList,
pApiHeadState->activeDpys);
if (!nvDpyIdListIsEmpty(dpyIdList)) {
return TRUE;
}
}
@@ -2491,9 +2556,6 @@ ApplyProposedModeSetStateOneDispFlip(
pDispEvo->apiHeadState[apiHead].tf =
pProposedApiHead->tf;
pDispEvo->apiHeadState[apiHead].colorimetry =
pProposedApiHead->colorimetry;
pDispEvo->apiHeadState[apiHead].hdrInfoFrameOverride =
pProposedApiHead->hdrInfoFrameOverride;
@@ -2551,10 +2613,8 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate(
pHeadState->timings = pProposedHead->timings;
pHeadState->dscInfo = pProposedApiHead->dscInfo;
pHeadState->hdmiFrlConfig = pProposedHead->hdmiFrlConfig;
pHeadState->hdmiFrlBpc = pProposedHead->hdmiFrlBpc;
pHeadState->pixelDepth =
nvEvoColorSpaceBpcToPixelDepth(pProposedApiHead->attributes.colorSpace,
pProposedApiHead->attributes.colorBpc);
nvEvoDpyColorToPixelDepth(&pProposedApiHead->attributes.color);
pHeadState->audio = pProposedHead->audio;
/* Update current LUT to hardware */
@@ -2572,9 +2632,7 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate(
/* Update hardware's current colorSpace and colorRange */
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(pDispEvo,
head,
pProposedApiHead->colorimetry,
pProposedApiHead->attributes.colorSpace,
pProposedApiHead->attributes.colorRange,
&pProposedApiHead->attributes.color,
updateState);
nvEvoAttachConnector(pProposedHead->pConnectorEvo,
@@ -2744,7 +2802,6 @@ ApplyProposedModeSetStateOneApiHeadPreUpdate(
pApiHeadState->attributes = pProposedApiHead->attributes;
pApiHeadState->tf = pProposedApiHead->tf;
pApiHeadState->colorimetry = pProposedApiHead->colorimetry;
pApiHeadState->hdrInfoFrameOverride =
pProposedApiHead->hdrInfoFrameOverride;
pApiHeadState->hdrStaticMetadataLayerMask =

View File

@@ -199,8 +199,17 @@ static NvBool QueryGpuCapabilities(NVDevEvoPtr pDevEvo)
/* TODO: This cap bit should be queried from RM */
pDevEvo->requiresAllAllocationsInSysmem = pDevEvo->isSOCDisplay;
/*
* Prohibit vblank_sem_control if:
* - on tegra, or
* - the kernel interface layer says so, or
* - (RM-based) SLI mosaic is enabled (WAR for bug 4552673, until RM-based
* SLI is dropped)
*/
pDevEvo->supportsVblankSemControl =
!pDevEvo->isSOCDisplay && nvkms_vblank_sem_control();
!pDevEvo->isSOCDisplay &&
nvkms_vblank_sem_control() &&
!pDevEvo->sli.mosaic;
/* ctxDma{,Non}CoherentAllowed */
@@ -906,6 +915,15 @@ static NvBool ProbeHeadCountAndWindowAssignment(NVDevEvoPtr pDevEvo)
return FALSE;
}
if (numHeadsParams.numHeads > NV_MAX_HEADS)
{
nvEvoLog(EVO_LOG_WARN,
"HW supports %d heads. Limiting to %d heads",
numHeadsParams.numHeads, NV_MAX_HEADS);
numHeadsParams.numHeads = NV_MAX_HEADS;
}
if (numHeads == 0) {
numHeads = numHeadsParams.numHeads;
} else {

View File

@@ -1076,7 +1076,8 @@ static NVSurfaceEvoPtr GetSurfaceFromHandle(
const NvKmsSurfaceHandle surfaceHandle,
const NvBool isUsedByCursorChannel,
const NvBool isUsedByLayerChannel,
const NvBool requireDisplayHardwareAccess)
const NvBool requireDisplayHardwareAccess,
const NvBool maybeUsedBy3d)
{
NVSurfaceEvoPtr pSurfaceEvo =
nvEvoGetPointerFromApiHandle(pOpenDevSurfaceHandles, surfaceHandle);
@@ -1102,15 +1103,13 @@ static NVSurfaceEvoPtr GetSurfaceFromHandle(
}
/*
* XXX If !requireDisplayHardwareAccess, fetched surfaces aren't going to be
* accessed by the display hardware, so they shouldn't need to be checked by
* nvEvoGetHeadSetStoragePitchValue(). These surfaces will be used as a
* texture by the 3d engine. But previously all surfaces were checked by
* XXX If maybeUsedBy3d, the fetched surface may be used as a texture by the
* 3d engine. Previously, all surfaces were checked by
* nvEvoGetHeadSetStoragePitchValue() at registration time, and we don't
* know if nvEvoGetHeadSetStoragePitchValue() was protecting us from any
* surface dimensions that could cause trouble for the 3d engine.
*/
if (isUsedByLayerChannel || !requireDisplayHardwareAccess) {
if (isUsedByLayerChannel || maybeUsedBy3d) {
NvU8 planeIndex;
FOR_ALL_VALID_PLANES(planeIndex, pSurfaceEvo) {
@@ -1138,7 +1137,8 @@ NVSurfaceEvoPtr nvEvoGetSurfaceFromHandle(
surfaceHandle,
isUsedByCursorChannel,
isUsedByLayerChannel,
TRUE /* requireDisplayHardwareAccess */);
TRUE /* requireDisplayHardwareAccess */,
TRUE /* maybeUsedBy3d */);
}
NVSurfaceEvoPtr nvEvoGetSurfaceFromHandleNoDispHWAccessOk(
@@ -1151,7 +1151,22 @@ NVSurfaceEvoPtr nvEvoGetSurfaceFromHandleNoDispHWAccessOk(
surfaceHandle,
FALSE /* isUsedByCursorChannel */,
FALSE /* isUsedByLayerChannel */,
FALSE /* requireDisplayHardwareAccess */);
FALSE /* requireDisplayHardwareAccess */,
TRUE /* maybeUsedBy3d */);
}
NVSurfaceEvoPtr nvEvoGetSurfaceFromHandleNoHWAccess(
const NVDevEvoRec *pDevEvo,
const NVEvoApiHandlesRec *pOpenDevSurfaceHandles,
NvKmsSurfaceHandle surfaceHandle)
{
return GetSurfaceFromHandle(pDevEvo,
pOpenDevSurfaceHandles,
surfaceHandle,
FALSE /* isUsedByCursorChannel */,
FALSE /* isUsedByLayerChannel */,
FALSE /* requireDisplayHardwareAccess */,
FALSE /* maybeUsedBy3d */);
}
/*!
@@ -1226,38 +1241,47 @@ void nvEvoUnregisterDeferredRequestFifo(
nvFree(pDeferredRequestFifo);
}
static NvBool UpdateVblankSemControl(
NVDevEvoRec *pDevEvo,
NVVblankSemControl *pVblankSemControl,
NvBool enable)
static NvBool AssignVblankSemControlHwHeadMask(
NVDispEvoRec *pDispEvo,
NvU32 apiHeadMask,
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_ENABLE_PARAMS *pParams)
{
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_PARAMS params = { };
NvU32 apiHead;
params.subDeviceInstance = pVblankSemControl->dispIndex;
params.head = pVblankSemControl->hwHead;
params.hMemory = pVblankSemControl->pSurfaceEvo->planes[0].rmHandle;
params.memoryOffset = pVblankSemControl->surfaceOffset;
params.bEnable = enable;
FOR_ALL_HEADS(apiHead, apiHeadMask) {
return nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL,
&params, sizeof(params)) == NVOS_STATUS_SUCCESS;
NvU32 hwHead = nvGetPrimaryHwHead(pDispEvo, apiHead);
if (hwHead == NV_INVALID_HEAD) {
return FALSE;
}
pParams->headMask |= NVBIT(hwHead);
pParams->headIndexMap[hwHead] = apiHead;
}
pParams->bUseHeadIndexMap = TRUE;
return TRUE;
}
NVVblankSemControl *nvEvoEnableVblankSemControl(
NVDevEvoRec *pDevEvo,
NVDispEvoRec *pDispEvo,
NvU32 hwHead,
NvU32 apiHeadMask,
NVSurfaceEvoRec *pSurfaceEvo,
NvU64 surfaceOffset)
{
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_ENABLE_PARAMS params = { };
NVVblankSemControl *pVblankSemControl;
if (!pDevEvo->supportsVblankSemControl) {
return NULL;
}
if (!AssignVblankSemControlHwHeadMask(pDispEvo, apiHeadMask, &params)) {
return NULL;
}
/*
* We cannot enable VblankSemControl if the requested offset within the
* surface is too large.
@@ -1279,14 +1303,19 @@ NVVblankSemControl *nvEvoEnableVblankSemControl(
return NULL;
}
pVblankSemControl->hwHead = hwHead;
pVblankSemControl->dispIndex = pDispEvo->displayOwner;
pVblankSemControl->surfaceOffset = surfaceOffset;
pVblankSemControl->pSurfaceEvo = pSurfaceEvo;
if (UpdateVblankSemControl(pDevEvo,
pVblankSemControl,
TRUE /* enable */)) {
params.subDeviceInstance = pVblankSemControl->dispIndex;
params.hMemory = pVblankSemControl->pSurfaceEvo->planes[0].rmHandle;
params.memoryOffset = pVblankSemControl->surfaceOffset;
if (nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_ENABLE,
&params, sizeof(params)) == NVOS_STATUS_SUCCESS) {
nvEvoIncrementSurfaceRefCnts(pSurfaceEvo);
return pVblankSemControl;
} else {
@@ -1299,13 +1328,21 @@ NvBool nvEvoDisableVblankSemControl(
NVDevEvoRec *pDevEvo,
NVVblankSemControl *pVblankSemControl)
{
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_DISABLE_PARAMS params = { };
if (!pDevEvo->supportsVblankSemControl) {
return FALSE;
}
if (UpdateVblankSemControl(pDevEvo,
pVblankSemControl,
FALSE /* enable */)) {
params.subDeviceInstance = pVblankSemControl->dispIndex;
params.hMemory = pVblankSemControl->pSurfaceEvo->planes[0].rmHandle;
params.memoryOffset = pVblankSemControl->surfaceOffset;
if (nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_SYSTEM_VBLANK_SEM_CONTROL_DISABLE,
&params, sizeof(params)) == NVOS_STATUS_SUCCESS) {
nvEvoDecrementSurfaceRefCnts(pDevEvo, pVblankSemControl->pSurfaceEvo);
nvFree(pVblankSemControl);
return TRUE;

View File

@@ -38,6 +38,7 @@
#include "nvkms-attributes.h"
#include "nvkms-dpy-override.h"
#include "nvkms-framelock.h"
#include "nvkms-stereo.h"
#include "nvkms-surface.h"
#include "nvkms-3dvision.h"
#include "nvkms-ioctl.h"
@@ -2737,9 +2738,9 @@ static NvBool GrantSurface(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
}
pSurfaceEvo =
nvEvoGetSurfaceFromHandleNoDispHWAccessOk(pOpenDev->pDevEvo,
&pOpenDev->surfaceHandles,
pParams->request.surfaceHandle);
nvEvoGetSurfaceFromHandleNoHWAccess(pOpenDev->pDevEvo,
&pOpenDev->surfaceHandles,
pParams->request.surfaceHandle);
if (pSurfaceEvo == NULL) {
return FALSE;
}
@@ -3567,6 +3568,28 @@ static NvBool IsHeadRevoked(const NVDispEvoRec *pDispEvo,
pPermissions->modeset.disp[pDispEvo->displayOwner].head[apiHead].dpyIdList);
}
static void DisableStereoPin(struct NvKmsPerOpenDev *pOpenDev,
const struct NvKmsModesetPermissions *pModeset)
{
NVDispEvoPtr pDispEvo;
NvU32 dispIndex, apiHead;
NvBool stereoEnabled;
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pOpenDev->pDevEvo) {
for (apiHead = 0; apiHead < pOpenDev->pDevEvo->numApiHeads; apiHead++) {
const NVDpyIdList dpyIdList =
pModeset->disp[dispIndex].head[apiHead].dpyIdList;
if (!nvDpyIdListIsEmpty(dpyIdList)) {
stereoEnabled = nvGetStereo(pDispEvo, apiHead);
if (stereoEnabled) {
nvSetStereo(pDispEvo, apiHead, FALSE);
}
}
}
}
}
static NvBool RevokePermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
{
struct NvKmsRevokePermissionsParams *pParams = pParamsVoid;
@@ -3637,6 +3660,9 @@ static NvBool RevokePermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
* being able to be leased again.
*/
if (pParams->request.permissions.type == NV_KMS_PERMISSIONS_TYPE_MODESET) {
// Also disable stereo pins if enabled.
DisableStereoPin(pOpenDev, &pParams->request.permissions.modeset);
nvShutDownApiHeads(pOpenDev->pDevEvo, pOpenDev, IsHeadRevoked,
&pParams->request.permissions,
TRUE /* doRasterLock */);
@@ -3661,7 +3687,7 @@ static NvBool RegisterDeferredRequestFifo(struct NvKmsPerOpen *pOpen,
return FALSE;
}
pSurfaceEvo = nvEvoGetSurfaceFromHandleNoDispHWAccessOk(
pSurfaceEvo = nvEvoGetSurfaceFromHandleNoHWAccess(
pOpenDev->pDevEvo,
&pOpenDev->surfaceHandles,
pParams->request.surfaceHandle);
@@ -4726,7 +4752,6 @@ static NvBool EnableVblankSemControl(
NVSurfaceEvoPtr pSurfaceEvo;
NVVblankSemControl *pVblankSemControl;
NvKmsVblankSemControlHandle vblankSemControlHandle;
NvU32 hwHead;
if (!GetPerOpenDevAndDisp(pOpen,
pParams->request.deviceHandle,
@@ -4740,7 +4765,7 @@ static NvBool EnableVblankSemControl(
pDispEvo = pOpenDisp->pDispEvo;
pSurfaceEvo =
nvEvoGetSurfaceFromHandleNoDispHWAccessOk(
nvEvoGetSurfaceFromHandleNoHWAccess(
pDevEvo,
&pOpenDev->surfaceHandles,
pParams->request.surfaceHandle);
@@ -4749,16 +4774,10 @@ static NvBool EnableVblankSemControl(
return FALSE;
}
hwHead = nvGetPrimaryHwHead(pDispEvo, pParams->request.head);
if (hwHead == NV_INVALID_HEAD) {
return FALSE;
}
pVblankSemControl = nvEvoEnableVblankSemControl(
pDevEvo,
pDispEvo,
hwHead,
pParams->request.headMask,
pSurfaceEvo,
pParams->request.surfaceOffset);