mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-26 09:53:59 +00:00
committed by
Gaurav Juvekar
parent
caa2dd11a0
commit
3084c04453
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
61
src/nvidia-modeset/interface/nvkms-modetimings.h
Normal file
61
src/nvidia-modeset/interface/nvkms-modetimings.h
Normal 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 */
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#define __NVKMS_KAPI_INTERNAL_H__
|
||||
|
||||
|
||||
|
||||
#include "unix_rm_handle.h"
|
||||
|
||||
#include "nvkms-utils.h"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -430,6 +430,7 @@ extern NVEvoCursorHAL nvEvoCursorC3;
|
||||
extern NVEvoCursorHAL nvEvoCursorC5;
|
||||
extern NVEvoCursorHAL nvEvoCursorC6;
|
||||
|
||||
|
||||
enum NvKmsAllocDeviceStatus nvInitDispHalCursorEvo(NVDevEvoPtr pDevEvo)
|
||||
{
|
||||
static const NVEvoCursorHALPtr cursorTable[] = {
|
||||
|
||||
@@ -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 !=
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
¶ms, 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, ¶ms)) {
|
||||
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,
|
||||
¶ms, 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,
|
||||
¶ms, sizeof(params)) == NVOS_STATUS_SUCCESS) {
|
||||
|
||||
nvEvoDecrementSurfaceRefCnts(pDevEvo, pVblankSemControl->pSurfaceEvo);
|
||||
nvFree(pVblankSemControl);
|
||||
return TRUE;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user