580.65.06

This commit is contained in:
Maneet Singh
2025-08-04 11:15:02 -07:00
parent d890313300
commit 307159f262
1315 changed files with 477791 additions and 279973 deletions

View File

@@ -91,6 +91,9 @@ enum NVDpLinkMode nvDPGetActiveLinkMode(NVDPLibConnectorPtr pDpLibConnector);
void nvDPSetLinkHandoff(NVDPLibConnectorPtr pDpLibConnector, NvBool enable);
NvBool nvDPIsFECForceEnabled(NVConnectorEvoPtr pConnectorEvo);
NvBool nvDPForceEnableFEC(NVConnectorEvoPtr pConnectorEvo, NvBool enable);
#ifdef __cplusplus
};
#endif

View File

@@ -31,9 +31,6 @@ extern "C" {
#endif
void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo);
NVEvoPassiveDpDongleType nvDpyGetPassiveDpDongleType(
const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz);
void nvDpySetValidSyncsEvo(const NVDpyEvoRec *pDpyEvo,
struct NvKmsModeValidationValidSyncs *pValidSyncs);
NVDpyEvoPtr nvAllocDpyEvo(NVDispEvoPtr pDispEvo,

View File

@@ -172,6 +172,7 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
const NvBool dscPassThrough,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct NvKmsModeValidationParams

View File

@@ -76,9 +76,9 @@ void nvHdmiDpConstructHeadAudioState(const NvU32 displayId,
const NVDpyEvoRec *pDpyEvo,
NVDispHeadAudioStateEvoRec *pAudioState);
NvU32 nvHdmiGetEffectivePixelClockKHz(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor);
NvBool nvHdmiIsTmdsPossible(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor);
static inline NvBool nvHdmiDpySupportsDsc(const NVDpyEvoRec *pDpyEvo)
{

View File

@@ -154,7 +154,8 @@ NvU32 nvRmAllocAndBindSurfaceDescriptor(
NvU32 hMemory,
const enum NvKmsSurfaceMemoryLayout layout,
NvU64 limit,
NVSurfaceDescriptor *pSurfaceDesc);
NVSurfaceDescriptor *pSurfaceDesc,
NvBool mapToDisplayRm);
#ifdef __cplusplus
};

View File

@@ -180,10 +180,12 @@ typedef struct _NVEvoApiHandlesRec {
typedef struct _NVSurfaceDescriptor
{
NvU32 memoryHandle;
NvU32 ctxDmaHandle;
NvU32 memAperture;
NvU64 memOffset;
NvBool bValid;
NvBool isMemoryMappedForDisplayAccess;
} NVSurfaceDescriptor;
typedef struct _NVEvoDma
@@ -950,6 +952,7 @@ typedef struct {
NvU8 legacyNotifierFormatSizeBytes[NVKMS_MAX_LAYERS_PER_HEAD];
NvU8 dpYCbCr422MaxBpc;
NvU8 hdmiYCbCr422MaxBpc;
NvU16 hdmiTmds10BpcMaxPClkMHz;
} NVEvoCapsRec;
typedef struct {
@@ -1065,10 +1068,10 @@ typedef struct _NVEvoDevRec {
const struct NvKmsPerOpenDev *modesetOwner;
/*!
* Indicates whether modeset ownership is changed since
* Indicates whether modeset ownership or sub-ownership has changed since
* last modeset.
*/
NvBool modesetOwnerChanged;
NvBool modesetOwnerOrSubOwnerChanged;
/*!
* modesetSubOwner points to the pOpenDev of the client that called
@@ -1509,7 +1512,7 @@ typedef struct _NVHwModeTimingsEvo {
* If true, then pixelClock is doubled.
*/
NvBool hdmi3D : 1;
NvBool dscPassThrough : 1;
struct {
/* The vrr type for which this mode is adjusted. */
enum NvKmsDpyVRRType type;
@@ -2184,13 +2187,6 @@ static inline NvU32 nvGetPrimaryHwHead(const NVDispEvoRec *pDispEvo,
NV_INVALID_HEAD;
}
typedef enum {
NV_EVO_PASSIVE_DP_DONGLE_UNUSED,
NV_EVO_PASSIVE_DP_DONGLE_DP2DVI,
NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_1,
NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_2,
} NVEvoPassiveDpDongleType;
typedef struct NVEdidRec {
NvU8 *buffer;
size_t length;
@@ -2837,6 +2833,9 @@ struct _NVSurfaceEvoRec {
/* Keep track of prefetched surfaces. */
NvU32 difrLastPrefetchPass;
/* Map memory allocation into display GPU's IOMMU space */
NvBool mapToDisplayRm;
};
typedef struct _NVDeferredRequestFifoRec {
@@ -3206,7 +3205,8 @@ typedef const struct _nv_evo_hal {
NVSurfaceDescriptor *pSurfaceDesc,
NvU32 memoryHandle,
NvU32 localCtxDmaFlags,
NvU64 limit);
NvU64 limit,
NvBool mapToDisplayRm);
void (*FreeSurfaceDescriptor) (NVDevEvoPtr pDevEvo,
NvU32 deviceHandle,

View File

@@ -2720,6 +2720,7 @@ enum NvKmsDpyAttribute {
NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE,
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE,
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE_10MHZ,
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_FORCE_ENABLE_FEC,
NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG,
/*
* XXX NVKMS TODO: Delete UPDATE_GLS_FRAMELOCK; this event-only
@@ -4395,6 +4396,7 @@ struct NvKmsAccelVblankSemControlsParams {
* It should be invoked after flip if needed. If device does not supports
* VRR semaphores, then this is a no-op action for compatibility.
*/
struct NvKmsVrrSignalSemaphoreRequest {
NvKmsDeviceHandle deviceHandle;
NvS32 vrrSemaphoreIndex;

View File

@@ -132,6 +132,7 @@ struct NvKmsKapiDevice {
NvBool supportsInputColorSpace;
NvBool supportsInputColorRange;
NvBool supportsWindowMode;
} caps;
NvU64 supportedSurfaceMemoryFormats[NVKMS_KAPI_LAYER_MAX];
@@ -147,6 +148,10 @@ struct NvKmsKapiDevice {
NvU32 numDisplaySemaphores;
struct {
struct NvKmsMode mode;
} headState[NVKMS_KAPI_MAX_HEADS];
struct {
NvU32 currFlipNotifierIndex;
} layerState[NVKMS_KAPI_MAX_HEADS][NVKMS_MAX_LAYERS_PER_HEAD];
@@ -166,10 +171,13 @@ struct NvKmsKapiMemory {
struct NvKmsKapiPrivSurfaceParams surfaceParams;
NvBool isVidmem;
/* Whether memory can be updated directly on the screen */
NvBool noDisplayCaching;
};
struct NvKmsKapiSurface {
NvKmsSurfaceHandle hKmsHandle;
struct NvKmsSize size;
};
static inline void *nvKmsKapiCalloc(size_t nmem, size_t size)

View File

@@ -562,9 +562,6 @@ struct NvKmsKapiCreateSurfaceParams {
* explicit_layout is NV_TRUE and layout is
* NvKmsSurfaceMemoryLayoutBlockLinear */
NvU8 log2GobsPerBlockY;
/* [IN] Whether a surface can be updated directly on the screen */
NvBool noDisplayCaching;
};
enum NvKmsKapiAllocationType {
@@ -573,6 +570,28 @@ enum NvKmsKapiAllocationType {
NVKMS_KAPI_ALLOCATION_TYPE_OFFSCREEN = 2,
};
struct NvKmsKapiAllocateMemoryParams {
/* [IN] BlockLinear or Pitch */
enum NvKmsSurfaceMemoryLayout layout;
/* [IN] Allocation type */
enum NvKmsKapiAllocationType type;
/* [IN] Size, in bytes, of the memory to allocate */
NvU64 size;
/* [IN] Whether memory can be updated directly on the screen */
NvBool noDisplayCaching;
/* [IN] Whether to allocate memory from video memory or system memory */
NvBool useVideoMemory;
/* [IN/OUT] For input, non-zero if compression backing store should be
* allocated for the memory, for output, non-zero if compression backing
* store was allocated for the memory */
NvU8 *compressible;
};
typedef enum NvKmsKapiRegisterWaiterResultRec {
NVKMS_KAPI_REG_WAITER_FAILED,
NVKMS_KAPI_REG_WAITER_SUCCESS,
@@ -602,14 +621,19 @@ struct NvKmsKapiFunctionsTable {
} systemInfo;
/*!
* Enumerate the available physical GPUs that can be used with NVKMS.
* Enumerate the available GPUs that can be used with NVKMS.
*
* \param [out] gpuInfo The information of the enumerated GPUs.
* It is an array of NVIDIA_MAX_GPUS elements.
* The gpuCallback will be called with a NvKmsKapiGpuInfo for each
* physical and MIG GPU currently available in the system.
*
* \param [in] gpuCallback Client function to handle each GPU.
*
* \return Count of enumerated gpus.
*/
NvU32 (*enumerateGpus)(struct NvKmsKapiGpuInfo *kapiGpuInfo);
NvU32 (*enumerateGpus)
(
void (*gpuCallback)(const struct NvKmsKapiGpuInfo *info)
);
/*!
* Allocate an NVK device using which you can query/allocate resources on
@@ -839,66 +863,22 @@ struct NvKmsKapiFunctionsTable {
);
/*!
* Allocate some unformatted video memory of the specified size.
* Allocate some unformatted video or system memory of the specified size.
*
* This function allocates video memory on the specified GPU.
* It should be suitable for mapping on the CPU as a pitch
* linear or block-linear surface.
* This function allocates video or system memory on the specified GPU. It
* should be suitable for mapping on the CPU as a pitch linear or
* block-linear surface.
*
* \param [in] device A device allocated using allocateDevice().
* \param [in] device A device allocated using allocateDevice().
*
* \param [in] layout BlockLinear or Pitch.
*
* \param [in] type Allocation type.
*
* \param [in] size Size, in bytes, of the memory to allocate.
*
* \param [in/out] compressible For input, non-zero if compression
* backing store should be allocated for
* the memory, for output, non-zero if
* compression backing store was
* allocated for the memory.
* \param [in/out] params Parameters required for memory allocation.
*
* \return An valid memory handle on success, NULL on failure.
*/
struct NvKmsKapiMemory* (*allocateVideoMemory)
struct NvKmsKapiMemory* (*allocateMemory)
(
struct NvKmsKapiDevice *device,
enum NvKmsSurfaceMemoryLayout layout,
enum NvKmsKapiAllocationType type,
NvU64 size,
NvU8 *compressible
);
/*!
* Allocate some unformatted system memory of the specified size.
*
* This function allocates system memory . It should be suitable
* for mapping on the CPU as a pitch linear or block-linear surface.
*
* \param [in] device A device allocated using allocateDevice().
*
* \param [in] layout BlockLinear or Pitch.
*
* \param [in] type Allocation type.
*
* \param [in] size Size, in bytes, of the memory to allocate.
*
* \param [in/out] compressible For input, non-zero if compression
* backing store should be allocated for
* the memory, for output, non-zero if
* compression backing store was
* allocated for the memory.
*
* \return An valid memory handle on success, NULL on failure.
*/
struct NvKmsKapiMemory* (*allocateSystemMemory)
(
struct NvKmsKapiDevice *device,
enum NvKmsSurfaceMemoryLayout layout,
enum NvKmsKapiAllocationType type,
NvU64 size,
NvU8 *compressible
struct NvKmsKapiAllocateMemoryParams *params
);
/*!

View File

@@ -71,9 +71,10 @@ ct_assert(NVKMS_KAPI_LAYER_MAX == NVKMS_MAX_LAYERS_PER_HEAD);
(1 << NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED) | \
(1 << NVKMS_EVENT_TYPE_FLIP_OCCURRED))
static NvU32 EnumerateGpus(struct NvKmsKapiGpuInfo *kapiGpuInfo)
static NvU32 EnumerateGpus(void (*gpuCallback)(const struct NvKmsKapiGpuInfo *info))
{
nv_gpu_info_t *gpu_info = NULL;
struct NvKmsKapiGpuInfo kapiGpuInfo;
nvMIGDeviceDescription *activeDevices = NULL;
NvU32 activeDeviceCount = 0;
NvU32 gpuCount;
@@ -82,11 +83,13 @@ static NvU32 EnumerateGpus(struct NvKmsKapiGpuInfo *kapiGpuInfo)
if (NV_OK != nvSMGGetDeviceList(&nvEvoGlobal.rmSmgContext,
&activeDevices,
&activeDeviceCount)) {
nvKmsKapiLogDebug("Failed to query SMG device list");
return 0;
}
gpu_info = nvkms_alloc(NV_MAX_GPUS * sizeof(*gpu_info), NV_TRUE);
if (!gpu_info) {
nvKmsKapiLogDebug("Out of memory");
return 0;
}
@@ -101,36 +104,27 @@ static NvU32 EnumerateGpus(struct NvKmsKapiGpuInfo *kapiGpuInfo)
NvBool foundMig = NV_FALSE;
for (NvU32 j = 0; j < activeDeviceCount; j++) {
/* Fail completely if we run out of array space. */
if (kapiGpuCount == NV_MAX_GPUS) {
nvKmsKapiLogDebug("Failed to enumerate devices: out of memory");
kapiGpuCount = 0;
break;
}
/*
* Return an NvKmsKapiGpuInfo for each active device found for
* the current gpu_id. For regular GPUs this will only be one
* but in MIG mode the same gpu_id can host multiple MIG
* Pass back an NvKmsKapiGpuInfo for each active device found
* for the current gpu_id. For regular GPUs this will only be
* one but in MIG mode the same gpu_id can host multiple MIG
* devices.
*/
if (activeDevices[j].gpuId == gpu_info[i].gpu_id) {
kapiGpuInfo[kapiGpuCount].gpuInfo = gpu_info[i];
kapiGpuInfo[kapiGpuCount].migDevice = activeDevices[j].migDeviceId;
kapiGpuInfo.gpuInfo = gpu_info[i];
kapiGpuInfo.migDevice = activeDevices[j].migDeviceId;
gpuCallback(&kapiGpuInfo);
kapiGpuCount++;
foundMig = NV_TRUE;
}
}
if (!foundMig) {
if (kapiGpuCount == NV_MAX_GPUS) {
nvKmsKapiLogDebug("Failed to enumerate devices: out of memory");
kapiGpuCount = 0;
break;
}
kapiGpuInfo.gpuInfo = gpu_info[i];
kapiGpuInfo.migDevice = NO_MIG_DEVICE;
gpuCallback(&kapiGpuInfo);
kapiGpuInfo[kapiGpuCount].gpuInfo = gpu_info[i];
kapiGpuInfo[kapiGpuCount].migDevice = NO_MIG_DEVICE;
kapiGpuCount++;
}
}
@@ -510,6 +504,8 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
device->caps.supportsInputColorRange =
paramsAlloc->reply.supportsInputColorRange;
device->caps.supportsWindowMode =
paramsAlloc->reply.layerCaps[NVKMS_MAIN_LAYER].supportsWindowMode;
/* XXX Add LUT support */
@@ -693,6 +689,9 @@ NvBool nvKmsKapiAllocateSystemMemory(struct NvKmsKapiDevice *device,
pIOCoherencyModes = &device->isoIOCoherencyModes;
memAllocParams.attr2 = FLD_SET_DRF(OS32, _ATTR2, _ISO,
_YES, memAllocParams.attr2);
break;
case NVKMS_KAPI_ALLOCATION_TYPE_NOTIFIER:
if (layout == NvKmsSurfaceMemoryLayoutBlockLinear) {
@@ -830,6 +829,9 @@ NvBool nvKmsKapiAllocateVideoMemory(struct NvKmsKapiDevice *device,
FLD_SET_DRF(OS32, _ATTR, _PHYSICALITY, _CONTIGUOUS,
memAllocParams.attr);
memAllocParams.attr2 = FLD_SET_DRF(OS32, _ATTR2, _ISO,
_YES, memAllocParams.attr2);
/* XXX [JRJ] Note compression and scanout do not work together on
* any current GPUs. However, some use cases do involve scanning
* out a compression-capable surface:
@@ -1605,17 +1607,15 @@ static struct NvKmsKapiMemory *AllocMemoryObjectAndHandle(
return memory;
}
static struct NvKmsKapiMemory* AllocateVideoMemory
static struct NvKmsKapiMemory* AllocateMemory
(
struct NvKmsKapiDevice *device,
enum NvKmsSurfaceMemoryLayout layout,
enum NvKmsKapiAllocationType type,
NvU64 size,
NvU8 *compressible
struct NvKmsKapiAllocateMemoryParams *params
)
{
struct NvKmsKapiMemory *memory = NULL;
NvU32 hRmHandle;
NvBool allocSucceeded;
memory = AllocMemoryObjectAndHandle(device, &hRmHandle);
@@ -1623,64 +1623,27 @@ static struct NvKmsKapiMemory* AllocateVideoMemory
return NULL;
}
if (!nvKmsKapiAllocateVideoMemory(device,
hRmHandle,
layout,
size,
type,
compressible)) {
allocSucceeded =
params->useVideoMemory
? nvKmsKapiAllocateVideoMemory(device, hRmHandle, params->layout,
params->size, params->type,
params->compressible)
: nvKmsKapiAllocateSystemMemory(device, hRmHandle, params->layout,
params->size, params->type,
params->compressible);
if (!allocSucceeded) {
nvKmsKapiFreeRmHandle(device, hRmHandle);
FreeMemory(device, memory);
return NULL;
}
memory->hRmHandle = hRmHandle;
memory->size = size;
memory->surfaceParams.layout = layout;
memory->isVidmem = NV_TRUE;
memory->size = params->size;
memory->surfaceParams.layout = params->layout;
memory->noDisplayCaching = params->noDisplayCaching;
memory->isVidmem = params->useVideoMemory;
if (layout == NvKmsSurfaceMemoryLayoutBlockLinear) {
memory->surfaceParams.blockLinear.genericMemory = NV_TRUE;
}
return memory;
}
static struct NvKmsKapiMemory* AllocateSystemMemory
(
struct NvKmsKapiDevice *device,
enum NvKmsSurfaceMemoryLayout layout,
enum NvKmsKapiAllocationType type,
NvU64 size,
NvU8 *compressible
)
{
struct NvKmsKapiMemory *memory = NULL;
NvU32 hRmHandle;
memory = AllocMemoryObjectAndHandle(device, &hRmHandle);
if (!memory) {
return NULL;
}
if (!nvKmsKapiAllocateSystemMemory(device,
hRmHandle,
layout,
size,
type,
compressible)) {
nvKmsKapiFreeRmHandle(device, hRmHandle);
FreeMemory(device, memory);
return NULL;
}
memory->hRmHandle = hRmHandle;
memory->size = size;
memory->surfaceParams.layout = layout;
memory->isVidmem = NV_FALSE;
if (layout == NvKmsSurfaceMemoryLayoutBlockLinear) {
if (params->layout == NvKmsSurfaceMemoryLayoutBlockLinear) {
memory->surfaceParams.blockLinear.genericMemory = NV_TRUE;
}
@@ -2260,7 +2223,6 @@ static NvBool GetSurfaceParams(
NvU32 *pNumPlanes,
enum NvKmsSurfaceMemoryLayout *pLayout,
NvU32 *pLog2GobsPerBlockY,
NvBool *pNoDisplayCaching,
NvU32 pitch[])
{
const NvKmsSurfaceMemoryFormatInfo *pFormatInfo =
@@ -2354,7 +2316,6 @@ static NvBool GetSurfaceParams(
*pNumPlanes = pFormatInfo->numPlanes;
*pLayout = layout;
*pLog2GobsPerBlockY = log2GobsPerBlockY;
*pNoDisplayCaching = params->noDisplayCaching;
return NV_TRUE;
}
@@ -2373,14 +2334,12 @@ static struct NvKmsKapiSurface* CreateSurface
NvU32 log2GobsPerBlockY = 0;
NvU32 numPlanes = 0;
NvU32 pitch[NVKMS_MAX_PLANES_PER_SURFACE] = { 0 };
NvBool noDisplayCaching = NV_FALSE;
NvU32 i;
if (!GetSurfaceParams(params,
&numPlanes,
&layout,
&log2GobsPerBlockY,
&noDisplayCaching,
pitch))
{
goto failed;
@@ -2423,9 +2382,9 @@ static struct NvKmsKapiSurface* CreateSurface
paramsReg.request.planes[i].rmObjectSizeInBytes = memory->size;
paramsReg.request.planes[i].offset = params->planes[i].offset;
paramsReg.request.planes[i].pitch = pitch[i];
}
paramsReg.request.noDisplayCaching = noDisplayCaching;
paramsReg.request.noDisplayCaching |= memory->noDisplayCaching;
}
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_REGISTER_SURFACE,
@@ -2443,6 +2402,8 @@ static struct NvKmsKapiSurface* CreateSurface
}
surface->hKmsHandle = paramsReg.reply.surfaceHandle;
surface->size.width = params->width;
surface->size.height = params->height;
done:
return surface;
@@ -3027,6 +2988,7 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
struct NvKmsKapiDevice *device,
const struct NvKmsKapiLayerRequestedConfig *layerRequestedConfig,
const NvU32 head,
const struct NvKmsMode *mode,
struct NvKmsFlipCommonParams *params,
NvBool commit,
NvBool bFromKmsSetMode)
@@ -3053,12 +3015,42 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
layerConfig->surface->hKmsHandle;
if (params->layer[NVKMS_MAIN_LAYER].surface.handle[0] != 0) {
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.width = layerConfig->srcWidth;
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.height = layerConfig->srcHeight;
params->layer[NVKMS_MAIN_LAYER].sizeIn.specified = TRUE;
const NvU32 surfaceWidth = layerConfig->surface->size.width;
const NvU32 surfaceHeight = layerConfig->surface->size.height;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.width = layerConfig->dstWidth;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.height = layerConfig->dstHeight;
// If there's no scaling and the sizeOut is going to be clamped
// to size of the mode, then set the sizes to the size of the
// surface rather than the size requested in the layerConfig.
//
// GPUs prior to nvdisplay require the sizeIn to match the size
// of the surface.
if (!device->caps.supportsWindowMode &&
layerConfig->srcWidth == layerConfig->dstWidth &&
layerConfig->dstWidth >= mode->timings.hVisible &&
layerConfig->dstX == 0 &&
surfaceWidth > layerConfig->dstWidth) {
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.width = surfaceWidth;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.width = surfaceWidth;
} else {
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.width = layerConfig->srcWidth;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.width = layerConfig->dstWidth;
}
if (!device->caps.supportsWindowMode &&
layerConfig->srcHeight == layerConfig->dstHeight &&
layerConfig->dstHeight >= mode->timings.vVisible &&
layerConfig->dstY == 0 &&
surfaceHeight > layerConfig->dstHeight) {
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.height = surfaceHeight;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.height = surfaceHeight;
} else {
params->layer[NVKMS_MAIN_LAYER].sizeIn.val.height = layerConfig->srcHeight;
params->layer[NVKMS_MAIN_LAYER].sizeOut.val.height = layerConfig->dstHeight;
}
params->layer[NVKMS_MAIN_LAYER].sizeIn.specified = TRUE;
params->layer[NVKMS_MAIN_LAYER].sizeOut.specified = TRUE;
}
}
@@ -3216,6 +3208,7 @@ static NvBool NvKmsKapiLayerConfigToKms(
const struct NvKmsKapiLayerRequestedConfig *layerRequestedConfig,
const NvU32 layer,
const NvU32 head,
const struct NvKmsMode *mode,
struct NvKmsFlipCommonParams *params,
NvBool commit,
NvBool bFromKmsSetMode)
@@ -3224,6 +3217,7 @@ static NvBool NvKmsKapiLayerConfigToKms(
return NvKmsKapiPrimaryLayerConfigToKms(device,
layerRequestedConfig,
head,
mode,
params,
commit,
bFromKmsSetMode);
@@ -3416,6 +3410,7 @@ static NvBool NvKmsKapiRequestedModeSetConfigToKms(
layerRequestedConfig,
layer,
head,
&paramsHead->mode,
&paramsHead->flip,
commit,
NV_TRUE /* bFromKmsSetMode */)) {
@@ -3519,6 +3514,19 @@ static NvBool KmsSetMode(
}
status = NV_FALSE;
} else {
const NvU32 dispIdx = device->dispIdx;
int head;
// Cache the mode timings to be used later by
// NvKmsKapiPrimaryLayerConfigToKms.
for (head = 0; head < ARRAY_LEN(device->headState); head++) {
const struct NvKmsSetModeOneDispRequest *dispRequest =
&params->request.disp[dispIdx];
if (dispRequest->requestedHeadsBitMask & (1 << head)) {
device->headState[head].mode = dispRequest->head[head].mode;
}
}
}
done:
@@ -3614,6 +3622,7 @@ static NvBool KmsFlip(
layerRequestedConfig,
layer,
head,
&device->headState[head].mode,
flipParams,
commit,
NV_FALSE /* bFromKmsSetMode */);
@@ -4059,8 +4068,7 @@ NvBool nvKmsKapiGetFunctionsTableInternal
funcsTable->getStaticDisplayInfo = GetStaticDisplayInfo;
funcsTable->getDynamicDisplayInfo = GetDynamicDisplayInfo;
funcsTable->allocateVideoMemory = AllocateVideoMemory;
funcsTable->allocateSystemMemory = AllocateSystemMemory;
funcsTable->allocateMemory = AllocateMemory;
funcsTable->importMemory = ImportMemory;
funcsTable->dupMemory = DupMemory;
funcsTable->exportMemory = ExportMemory;

View File

@@ -489,12 +489,18 @@ static NvBool ConstructDpLibIsModesetPossibleParamsOneHead(
DisplayPort::DSC_FORCE_ENABLE;
break;
case NVKMS_DSC_MODE_FORCE_DISABLE:
nvAssert(!pTimings->dscPassThrough);
pParams->head[head].pDscParams->forceDsc =
DisplayPort::DSC_FORCE_DISABLE;
break;
default:
pParams->head[head].pDscParams->forceDsc =
DisplayPort::DSC_DEFAULT;
if (pTimings->dscPassThrough) {
pParams->head[head].pDscParams->forceDsc =
DisplayPort::DSC_FORCE_ENABLE;
} else {
pParams->head[head].pDscParams->forceDsc =
DisplayPort::DSC_DEFAULT;
}
break;
}
@@ -525,8 +531,35 @@ static NvBool ConstructDpLibIsModesetPossibleParamsOneHead(
break;
}
pParams->head[head].pDscParams->bitsPerPixelX16 =
pModeValidationParams->dscOverrideBitsPerPixelX16;
if (pTimings->dscPassThrough) {
const NVDpyEvoRec *pDpyEvo =
nvGetOneArbitraryDpyEvo(dpyIdList, pDispEvo);
const NVT_DISPLAYID_2_0_INFO *pDisplyIdInfo =
&pDpyEvo->parsedEdid.info.ext_displayid20;
const NVT_DISPLAYID_VENDOR_SPECIFIC *pDisplayIdVS =
&pDisplyIdInfo->vendor_specific;
const VESA_VSDB_PARSED_INFO *pVesaVSDB = &pDisplayIdVS->vesaVsdb;
if (pVesaVSDB->pass_through_integer.pass_through_integer_dsc == 0) {
goto failed;
}
const NvU32 dscPassThroughBitsPerPixel16 =
(pVesaVSDB->pass_through_integer.pass_through_integer_dsc * 16) +
pVesaVSDB->pass_through_fractional.pass_through_fraction_dsc;
if ((pModeValidationParams->dscOverrideBitsPerPixelX16 != 0) &&
(pModeValidationParams->dscOverrideBitsPerPixelX16 !=
dscPassThroughBitsPerPixel16)) {
goto failed;
}
pParams->head[head].pDscParams->bitsPerPixelX16 =
dscPassThroughBitsPerPixel16;
} else {
pParams->head[head].pDscParams->bitsPerPixelX16 =
pModeValidationParams->dscOverrideBitsPerPixelX16;
}
pParams->head[head].pErrorStatus = pErrorCode;
return TRUE;
@@ -1215,3 +1248,25 @@ void nvDPSetLinkHandoff(NVDPLibConnectorPtr pDpLibConnector, NvBool enable)
pDpLibConnector->connector->releaseLinkHandsOff();
}
}
NvBool nvDPIsFECForceEnabled(NVConnectorEvoPtr pConnectorEvo)
{
NVDPLibConnectorPtr pDpLibConnector = pConnectorEvo->pDpLibConnector;
DisplayPort::LinkConfiguration linkConfig =
pDpLibConnector->connector->getActiveLinkConfig();
return linkConfig.bEnableFEC;
}
NvBool nvDPForceEnableFEC(NVConnectorEvoPtr pConnectorEvo, NvBool enable)
{
NVDPLibConnectorPtr pDpLibConnector = pConnectorEvo->pDpLibConnector;
DisplayPort::LinkConfiguration linkConfig =
pDpLibConnector->connector->getActiveLinkConfig();
linkConfig.bEnableFEC = enable;
return pDpLibConnector->connector->setPreferredLinkConfig(linkConfig,
TRUE /* commit */,
TRUE /* force */);
}

View File

@@ -32,6 +32,7 @@
#include "nvos.h"
#include "nvkms-stereo.h"
#include "nvkms-hdmi.h"
#include "dp/nvdp-connector.h"
#include <ctrl/ctrl0073/ctrl0073dp.h> // NV0073_CTRL_CMD_DP_GET_LINK_CONFIG_*
@@ -677,11 +678,9 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
nvDpyGetOutputColorFormatInfo(pDpyEvo);
while (nvHdmiGetEffectivePixelClockKHz(pDpyEvo,
&pApiHeadState->timings,
&tmpDpyColor) >
pDpyEvo->maxSingleLinkPixelClockKHz) {
while (!nvHdmiIsTmdsPossible(pDpyEvo,
&pApiHeadState->timings,
&tmpDpyColor)) {
if(!nvDowngradeColorSpaceAndBpc(pDpyEvo,
&colorFormatsInfo,
&tmpDpyColor)) {
@@ -1125,6 +1124,42 @@ static NvBool GetDisplayportSinkIsAudioCapableValidValues(
return TRUE;
}
static NvBool SetDisplayportForceEnableFEC(NVDpyEvoRec *pDpyEvo, NvS64 value)
{
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
if (!nvConnectorUsesDPLib(pConnectorEvo)) {
return FALSE;
}
return nvDPForceEnableFEC(pConnectorEvo, !!value);
}
static NvBool GetDisplayportForceEnableFEC(const NVDpyEvoRec *pDpyEvo,
NvS64 *pValue)
{
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
if (!nvConnectorUsesDPLib(pConnectorEvo)) {
return FALSE;
}
*pValue = nvDPIsFECForceEnabled(pConnectorEvo);
return TRUE;
}
static NvBool GetDisplayportForceEnableFECValidValues(
const NVDpyEvoRec *pDpyEvo,
struct NvKmsAttributeValidValuesCommonReply *pValidValues)
{
if (!nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo)) {
return FALSE;
}
return TRUE;
}
NvS64 nvRMLaneCountToNvKms(NvU32 rmLaneCount)
{
switch (rmLaneCount) {
@@ -1415,6 +1450,12 @@ static const struct {
.getValidValues = GetDisplayportSinkIsAudioCapableValidValues,
.type = NV_KMS_ATTRIBUTE_TYPE_BOOLEAN,
},
[NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_FORCE_ENABLE_FEC] = {
.set = SetDisplayportForceEnableFEC,
.get = GetDisplayportForceEnableFEC,
.getValidValues = GetDisplayportForceEnableFECValidValues,
.type = NV_KMS_ATTRIBUTE_TYPE_BOOLEAN,
},
[NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG] = {
.set = nvSetFrameLockDisplayConfigEvo,
.get = nvGetFrameLockDisplayConfigEvo,

View File

@@ -429,8 +429,10 @@ extern NVEvoCursorHAL nvEvoCursor91;
extern NVEvoCursorHAL nvEvoCursorC3;
extern NVEvoCursorHAL nvEvoCursorC5;
extern NVEvoCursorHAL nvEvoCursorC6;
extern NVEvoCursorHAL nvEvoCursorC9;
extern NVEvoCursorHAL nvEvoCursorCA;
extern NVEvoCursorHAL nvEvoCursorCB;
extern NVEvoCursorHAL nvEvoCursorCC;
enum NvKmsAllocDeviceStatus nvInitDispHalCursorEvo(NVDevEvoPtr pDevEvo)
@@ -440,8 +442,10 @@ enum NvKmsAllocDeviceStatus nvInitDispHalCursorEvo(NVDevEvoPtr pDevEvo)
&nvEvoCursorC3,
&nvEvoCursorC5,
&nvEvoCursorC6,
&nvEvoCursorC9,
&nvEvoCursorCA,
&nvEvoCursorCB,
&nvEvoCursorCC,
};
int i;

View File

@@ -27,8 +27,10 @@
#include <class/clc37a.h>
#include <class/clc57a.h>
#include <class/clc67a.h>
#include <class/clc97a.h>
#include <class/clca7a.h>
#include <class/clcb7a.h>
#include <class/clcc7a.h>
static void WaitForFreeSpace(NVDevEvoPtr pDevEvo,
NVC37ADispCursorImmControlPio *pEvoCursorControl)
@@ -115,6 +117,15 @@ NVEvoCursorHAL nvEvoCursorC6 = {
},
};
NVEvoCursorHAL nvEvoCursorC9 = {
NVC97A_CURSOR_IMM_CHANNEL_PIO, /* klass */
MoveCursorC3, /* MoveCursor */
ReleaseElvC3, /* ReleaseElv */
{ /* caps */
256, /* maxSize */
},
};
NVEvoCursorHAL nvEvoCursorCA = {
NVCA7A_CURSOR_IMM_CHANNEL_PIO, /* klass */
MoveCursorC3, /* MoveCursor */
@@ -132,3 +143,12 @@ NVEvoCursorHAL nvEvoCursorCB = {
256, /* maxSize */
},
};
NVEvoCursorHAL nvEvoCursorCC = {
NVCC7A_CURSOR_IMM_CHANNEL_PIO, /* klass */
MoveCursorC3, /* MoveCursor */
ReleaseElvC3, /* ReleaseElv */
{ /* caps */
256, /* maxSize */
},
};

View File

@@ -100,6 +100,23 @@ static void DpyDisconnectEvo(NVDpyEvoPtr pDpyEvo, const NvBool bSendHdmiCapsToRm
ClearEdid(pDpyEvo, bSendHdmiCapsToRm);
}
static void HdmiFrlSetConfig(NVDpyEvoRec *pDpyEvo)
{
NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
NvU32 head;
if ((pDpyEvo->apiHead == NV_INVALID_HEAD) || !nvDpyIsHdmiEvo(pDpyEvo) ||
!nvHdmiDpySupportsFrl(pDpyEvo)) {
return;
}
head = nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
nvAssert(head != NV_INVALID_HEAD);
nvHdmiFrlSetConfig(pDispEvo, head);
}
static NvBool DpyConnectEvo(
NVDpyEvoPtr pDpyEvo,
struct NvKmsQueryDpyDynamicDataParams *pParams)
@@ -123,6 +140,8 @@ static NvBool DpyConnectEvo(
nvUpdateInfoFrames(pDpyEvo);
HdmiFrlSetConfig(pDpyEvo);
return TRUE;
}
@@ -667,6 +686,95 @@ static void ReadAndApplyEdidEvo(
nvFree(pParsedEdid);
}
typedef enum {
NV_EVO_PASSIVE_DP_DONGLE_UNUSED,
NV_EVO_PASSIVE_DP_DONGLE_DP2DVI,
NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_1,
NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_2,
} NVEvoPassiveDpDongleType;
/*!
* Query RM for the passive Displayport dongle type; this can influence
* the maximum pixel clock allowed on that display.
*/
static NVEvoPassiveDpDongleType
DpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
{
NV0073_CTRL_DFP_GET_DISPLAYPORT_DONGLE_INFO_PARAMS params = { 0 };
NvU32 ret;
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
NVDispEvoPtr pDispEvo = pDpyEvo->pDispEvo;
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVEvoPassiveDpDongleType passiveDpDongleType =
NV_EVO_PASSIVE_DP_DONGLE_UNUSED;
// The rmcontrol below fails if we try querying the dongle info on
// non-TMDS connectors.
if (!IsConnectorTMDS(pConnectorEvo)) {
return passiveDpDongleType;
}
params.displayId = nvDpyIdToNvU32(pConnectorEvo->displayId);
params.subDeviceInstance = pDispEvo->displayOwner;
params.flags = 0;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_GET_DISPLAYPORT_DONGLE_INFO,
&params, sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDisp(pDispEvo, EVO_LOG_ERROR,
"Failure reading DP dongle info "
"for display device %s.", pDpyEvo->name);
return passiveDpDongleType;
}
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS,
_ATTACHED, _TRUE, params.flags))
{
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS, _TYPE, _DP2DVI,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2DVI;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = TMDS_SINGLE_LINK_PCLK_MAX;
}
} else if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS, _TYPE, _DP2HDMI,
params.flags)) {
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS_DP2TMDS_DONGLE, _TYPE, _1,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_1;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = params.maxTmdsClkRateHz / 1000;
}
} else if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS_DP2TMDS_DONGLE, _TYPE, _2,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_2;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = params.maxTmdsClkRateHz / 1000;
}
}
// For other dongle types: LFH_DVI (DMS59-DVI) and LFH_VGA (DMS59-VGA) breakout dongles,
// We consider them as native connection, hence we don't track passiveDpDongleType here
}
}
return passiveDpDongleType;
}
/*!
* Get the maximum allowed pixel clock for pDpyEvo.
*
@@ -825,7 +933,7 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
* these dongles is in use, and override the limit accordingly.
*/
passiveDpDongleType =
nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz);
DpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz);
if (passiveDpDongleType != NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
pDpyEvo->maxPixelClockKHz = NV_MIN(passiveDpDongleMaxPclkKHz,
@@ -898,89 +1006,6 @@ static NvBool IsConnectorTMDS(NVConnectorEvoPtr pConnectorEvo)
(protocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS)));
}
/*!
* Query RM for the passive Displayport dongle type; this can influence
* the maximum pixel clock allowed on that display.
*/
NVEvoPassiveDpDongleType
nvDpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
{
NV0073_CTRL_DFP_GET_DISPLAYPORT_DONGLE_INFO_PARAMS params = { 0 };
NvU32 ret;
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
NVDispEvoPtr pDispEvo = pDpyEvo->pDispEvo;
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVEvoPassiveDpDongleType passiveDpDongleType =
NV_EVO_PASSIVE_DP_DONGLE_UNUSED;
// The rmcontrol below fails if we try querying the dongle info on
// non-TMDS connectors.
if (!IsConnectorTMDS(pConnectorEvo)) {
return passiveDpDongleType;
}
params.displayId = nvDpyIdToNvU32(pConnectorEvo->displayId);
params.subDeviceInstance = pDispEvo->displayOwner;
params.flags = 0;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_GET_DISPLAYPORT_DONGLE_INFO,
&params, sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDisp(pDispEvo, EVO_LOG_ERROR,
"Failure reading DP dongle info "
"for display device %s.", pDpyEvo->name);
return passiveDpDongleType;
}
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS,
_ATTACHED, _TRUE, params.flags))
{
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS, _TYPE, _DP2DVI,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2DVI;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = TMDS_SINGLE_LINK_PCLK_MAX;
}
} else if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS, _TYPE, _DP2HDMI,
params.flags)) {
if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS_DP2TMDS_DONGLE, _TYPE, _1,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_1;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = params.maxTmdsClkRateHz / 1000;
}
} else if (FLD_TEST_DRF(0073_CTRL_DFP,
_GET_DISPLAYPORT_DONGLE_INFO_FLAGS_DP2TMDS_DONGLE, _TYPE, _2,
params.flags)) {
passiveDpDongleType = NV_EVO_PASSIVE_DP_DONGLE_DP2HDMI_TYPE_2;
if (passiveDpDongleMaxPclkKHz) {
*passiveDpDongleMaxPclkKHz = params.maxTmdsClkRateHz / 1000;
}
}
// For other dongle types: LFH_DVI (DMS59-DVI) and LFH_VGA (DMS59-VGA) breakout dongles,
// We consider them as native connection, hence we don't track passiveDpDongleType here
}
}
return passiveDpDongleType;
}
/*!
* Validate an NVKMS client-specified NvKmsModeValidationFrequencyRanges.
*/

View File

@@ -6903,7 +6903,7 @@ static NvBool GetDfpHdmiProtocol(const NVDpyEvoRec *pDpyEvo,
const NvU32 rmProtocol = pConnectorEvo->or.protocol;
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
nvDpyGetOutputColorFormatInfo(pDpyEvo);
const NvBool forceHdmiFrlIsSupported = FALSE;
const NvBool forceHdmiFrlIfSupported = FALSE;
nvAssert(rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS ||
rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A ||
@@ -6912,11 +6912,10 @@ static NvBool GetDfpHdmiProtocol(const NVDpyEvoRec *pDpyEvo,
/* 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)) {
(!nvHdmiIsTmdsPossible(pDpyEvo, pTimings, pDpyColor) ||
forceHdmiFrlIfSupported) &&
/* If FRL is supported... */
nvHdmiDpySupportsFrl(pDpyEvo)) {
/* Hardware does not support HDMI FRL with YUV422 */
if ((pDpyColor->format ==
@@ -6930,9 +6929,7 @@ static NvBool GetDfpHdmiProtocol(const NVDpyEvoRec *pDpyEvo,
}
do {
if (nvHdmiGetEffectivePixelClockKHz(pDpyEvo, pTimings, pDpyColor) <=
pDpyEvo->maxSingleLinkPixelClockKHz) {
if (nvHdmiIsTmdsPossible(pDpyEvo, pTimings, pDpyColor)) {
switch (rmProtocol) {
case NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS:
/*
@@ -7093,6 +7090,7 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
const NvBool dscPassThrough,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct
@@ -7103,6 +7101,26 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
ConstructHwModeTimingsFromNvModeTimings(pModeTimings, pTimings);
pTimings->dscPassThrough = dscPassThrough;
if (pTimings->dscPassThrough &&
(pDpyColor->format !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB)) {
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
nvDpyGetOutputColorFormatInfo(pDpyEvo);
if (colorFormatsInfo.rgb444.maxBpc ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
return FALSE;
}
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
pDpyColor->colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
pDpyColor->format = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB;
pDpyColor->bpc = colorFormatsInfo.rgb444.maxBpc;
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
}
ret = GetDfpProtocol(pDpyEvo, pParams, pDpyColor, pTimings);
if (!ret) {
@@ -7275,6 +7293,7 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
const struct NvKmsMode *pKmsMode,
const struct NvKmsSize *pViewPortSizeIn,
const struct NvKmsRect *pViewPortOut,
const NvBool dscPassThrough,
NVDpyAttributeColor *pDpyColor,
NVHwModeTimingsEvoPtr pTimings,
const struct NvKmsModeValidationParams
@@ -7291,10 +7310,12 @@ NvBool nvConstructHwModeTimingsEvo(const NVDpyEvoRec *pDpyEvo,
ret = ConstructHwModeTimingsEvoDfp(pDpyEvo,
&pKmsMode->timings,
pViewPortSizeIn, pViewPortOut,
dscPassThrough,
pDpyColor, pTimings, pParams,
pInfoString);
} else if (pConnectorEvo->legacyType ==
NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_CRT) {
nvAssert(dscPassThrough == FALSE);
ret = ConstructHwModeTimingsEvoCrt(pConnectorEvo,
&pKmsMode->timings,
pViewPortSizeIn, pViewPortOut,
@@ -9997,11 +10018,11 @@ NvBool nvEvoIsConsoleActive(const NVDevEvoRec *pDevEvo)
* console or the NVKMS console might be active.
*
* If (pDevEvo->modesetOwner != NULL) but
* pDevEvo->modesetOwnerChanged is TRUE, that means the modeset
* pDevEvo->modesetOwnerOrSubOwnerChanged is TRUE, that means the modeset
* ownership is grabbed by the external client but it hasn't
* performed any modeset and the console is still active.
* performed any modeset and the console might still be active.
*/
if ((pDevEvo->modesetOwner == NULL) || pDevEvo->modesetOwnerChanged) {
if ((pDevEvo->modesetOwner == NULL) || pDevEvo->modesetOwnerOrSubOwnerChanged) {
NvU32 sd;
const NVDispEvoRec *pDispEvo;
FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) {

View File

@@ -3985,7 +3985,8 @@ static void EvoResetChannelAccelerators91(NVDevEvoPtr pDevEvo,
static NvU32 EvoAllocSurfaceDescriptor90(
NVDevEvoPtr pDevEvo, NVSurfaceDescriptor *pSurfaceDesc,
NvU32 memoryHandle, NvU32 localCtxDmaFlags,
NvU64 limit)
NvU64 limit,
NvBool mapToDisplayRm)
{
return nvCtxDmaAlloc(pDevEvo, &pSurfaceDesc->ctxDmaHandle,
memoryHandle,

View File

@@ -1588,11 +1588,11 @@ static void EvoSetRasterParamsC5(NVDevEvoPtr pDevEvo, int head,
static NvU32 GetHdmiDscHBlankPixelTarget(const NVHwModeTimingsEvo *pTimings,
const NVDscInfoEvoRec *pDscInfo)
{
nvAssert((pDscInfo->dp.dscMode == NV_DSC_EVO_MODE_DUAL) ||
(pDscInfo->dp.dscMode == NV_DSC_EVO_MODE_SINGLE));
nvAssert((pDscInfo->hdmi.dscMode == NV_DSC_EVO_MODE_DUAL) ||
(pDscInfo->hdmi.dscMode == NV_DSC_EVO_MODE_SINGLE));
const NvU32 hblankMin =
(pDscInfo->dp.dscMode == NV_DSC_EVO_MODE_DUAL) ?
(pDscInfo->hdmi.dscMode == NV_DSC_EVO_MODE_DUAL) ?
((pDscInfo->hdmi.hblankMin + 1) / 2) :
pDscInfo->hdmi.hblankMin;
@@ -1603,7 +1603,7 @@ static NvU32 GetHdmiDscHBlankPixelTarget(const NVHwModeTimingsEvo *pTimings,
hBlankPixelTarget = NV_MAX(hblankMin, hBlankPixelTarget);
if (pDscInfo->dp.dscMode == NV_DSC_EVO_MODE_DUAL) {
if (pDscInfo->hdmi.dscMode == NV_DSC_EVO_MODE_DUAL) {
hBlankPixelTarget += (hBlankPixelTarget % 2);
}
@@ -8031,7 +8031,8 @@ static void EvoSetMergeModeC5(const NVDispEvoRec *pDispEvo,
static NvU32 EvoAllocSurfaceDescriptorC3(
NVDevEvoPtr pDevEvo, NVSurfaceDescriptor *pSurfaceDesc,
NvU32 memoryHandle, NvU32 localCtxDmaFlags,
NvU64 limit)
NvU64 limit,
NvBool mapToDisplayRm)
{
return nvCtxDmaAlloc(pDevEvo, &pSurfaceDesc->ctxDmaHandle,
memoryHandle,

View File

@@ -309,6 +309,17 @@ static void EvoSetRasterParams9(NVDevEvoPtr pDevEvo, int head,
nvDmaSetEvoMethodData(pChannel, hdmiStereoCtrl);
}
static void EvoSetRasterParamsC9(NVDevEvoPtr pDevEvo, int head,
const NVHwModeTimingsEvo *pTimings,
const NvU8 tilePosition,
const NVDscInfoEvoRec *pDscInfo,
const NVEvoColorRec *pOverscanColor,
NVEvoUpdateState *updateState)
{
nvAssert(tilePosition == 0);
EvoSetRasterParams9(pDevEvo, head, pTimings, pOverscanColor, updateState);
}
static void EvoSetOCsc1C9(NVDispEvoPtr pDispEvo, const NvU32 head)
{
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
@@ -1476,7 +1487,8 @@ static void EvoSetDscParamsC9(const NVDispEvoRec *pDispEvo,
static NvU32 EvoAllocSurfaceDescriptorC9(
NVDevEvoPtr pDevEvo, NVSurfaceDescriptor *pSurfaceDesc,
NvU32 memoryHandle, NvU32 localCtxDmaFlags,
NvU64 limit)
NvU64 limit,
NvBool mapToDisplayRm)
{
NV0041_CTRL_GET_SURFACE_PHYS_ATTR_PARAMS params = { };
NvU32 ret;
@@ -1494,9 +1506,7 @@ static NvU32 EvoAllocSurfaceDescriptorC9(
if (ret != NVOS_STATUS_SUCCESS) {
return ret;
}
pSurfaceDesc->bValid = TRUE;
pSurfaceDesc->memOffset = params.memOffset;
pSurfaceDesc->memAperture = params.memAperture;
#if defined(NV_EVO4_PB_ALLOC_WAR)
@@ -1505,6 +1515,38 @@ static NvU32 EvoAllocSurfaceDescriptorC9(
localCtxDmaFlags, limit);
#endif
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLog(EVO_LOG_ERROR, "nvCtxDmaAlloc failed\n");
return ret;
}
if (mapToDisplayRm) {
NV0041_CTRL_MAP_MEMORY_FOR_GPU_ACCESS_PARAMS mapParams = { };
mapParams.hSubdevice = pDevEvo->pSubDevices[0]->handle;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
memoryHandle,
NV0041_CTRL_CMD_MAP_MEMORY_FOR_GPU_ACCESS,
&mapParams, sizeof(mapParams));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLog(EVO_LOG_ERROR, "NV0041_CTRL_CMD_MAP_MEMORY_FOR_GPU_ACCESS failed\n");
#if defined(NV_EVO4_PB_ALLOC_WAR)
nvCtxDmaFree(pDevEvo, pDevEvo->deviceHandle, &pSurfaceDesc->ctxDmaHandle);
#endif
return ret;
}
pSurfaceDesc->memOffset = mapParams.address;
pSurfaceDesc->memoryHandle = memoryHandle;
pSurfaceDesc->isMemoryMappedForDisplayAccess = TRUE;
} else {
pSurfaceDesc->memOffset = params.memOffset;
pSurfaceDesc->isMemoryMappedForDisplayAccess = FALSE;
}
pSurfaceDesc->bValid = TRUE;
return ret;
}
@@ -1513,9 +1555,27 @@ static void EvoFreeSurfaceDescriptorC9(
NvU32 deviceHandle,
NVSurfaceDescriptor *pSurfaceDesc)
{
NvU32 ret;
if (!pSurfaceDesc->bValid) {
return;
}
if (pSurfaceDesc->isMemoryMappedForDisplayAccess) {
NV0041_CTRL_UNMAP_MEMORY_FOR_GPU_ACCESS_PARAMS params = { };
params.hSubdevice = pDevEvo->pSubDevices[0]->handle;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pSurfaceDesc->memoryHandle,
NV0041_CTRL_CMD_UNMAP_MEMORY_FOR_GPU_ACCESS,
&params, sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLog(EVO_LOG_ERROR, "NV0041_CTRL_CMD_UNMAP_MEMORY_FOR_GPU_ACCESS failed\n");
}
pSurfaceDesc->isMemoryMappedForDisplayAccess = FALSE;
}
#if defined(NV_EVO4_PB_ALLOC_WAR)
nvCtxDmaFree(pDevEvo, deviceHandle, &pSurfaceDesc->ctxDmaHandle);
#endif
@@ -2424,18 +2484,34 @@ static void EvoInitWindowMappingCA(const NVDispEvoRec *pDispEvo,
pModesetUpdateState);
/*
* clear the default tile/phywin assigments of all inactive heads.
* Clear the default tile assignments of all inactive heads.
*
* By default, the hardware assigns tile-n to head-n and phywin-n to win-n.
* These assignments should be cleared during the first modeset after the
* core channel allocation.
* By default, the hardware assigns tile-n to head-n, but NVKMS may change
* the tile assignment at modeset time.
*
* If the default tile/phywin assignments are left as-is, subsequent
* modesets may end up assigning the same tile/phywin to more than one
* head/win, which is not allowed and causes XID 56 or display engine hang.
* If the default tile assignments are left as-is, subsequent modesets may
* end up assigning the same tile to more than one head, which is not
* allowed and causes XID 56 or display engine hang.
*
* If required, the default tile/phywin assigments of active heads gets
* clear as part of modeset.
* If required, the default tile assigments of active heads gets cleared as
* part of modeset.
*
* Note that some chips have more than pDevEvo->numHeads, and the tile
* assignment needs to be cleared on all of them. Infer the number of
* possible heads from the class.
*/
for (NvU32 head = 0; head < NVCA73_SYS_CAP_HEAD_EXISTS__SIZE_1; head++) {
if (!nvHeadIsActive(pDispEvo, head)) {
nvDmaSetStartEvoMethod(pChannel, NVCA7D_HEAD_SET_TILE_MASK(head), 1);
nvDmaSetEvoMethodData(pChannel, 0x0);
}
}
/*
* Clear the default phywin assigments of all inactive heads.
*
* Similar to the loop above, make sure the same phywin isn't assigned to
* two window channels simultaneously.
*/
for (NvU32 head = 0; head < pDevEvo->numHeads; head++) {
const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
@@ -2444,8 +2520,6 @@ static void EvoInitWindowMappingCA(const NVDispEvoRec *pDispEvo,
continue;
}
nvDmaSetStartEvoMethod(pChannel, NVCA7D_HEAD_SET_TILE_MASK(head), 1);
nvDmaSetEvoMethodData(pChannel, 0x0);
for (NvU32 layer = 0;
layer < pDevEvo->head[head].numLayers; layer++) {
const NVEvoChannel *pWinChannel = pDevEvo->head[head].layer[layer];
@@ -2975,6 +3049,104 @@ static void EvoSetMultiTileConfigCA(const NVDispEvoRec *pDispEvo,
nvPopEvoSubDevMask(pDevEvo);
}
NVEvoHAL nvEvoC9 = {
EvoSetRasterParamsC9, /* SetRasterParams */
EvoSetProcAmpC9, /* SetProcAmp */
EvoSetHeadControlC9, /* SetHeadControl */
NULL, /* SetHeadRefClk */
EvoHeadSetControlORC9, /* HeadSetControlOR */
nvEvoORSetControlC3, /* ORSetControl */
EvoHeadSetDisplayIdC9, /* HeadSetDisplayId */
nvEvoSetUsageBoundsC5, /* SetUsageBounds */
nvEvoUpdateC3, /* Update */
nvEvoIsModePossibleC3, /* IsModePossible */
nvEvoPrePostIMPC3, /* PrePostIMP */
nvEvoSetNotifierC3, /* SetNotifier */
nvEvoGetCapabilitiesC6, /* GetCapabilities */
nvEvoFlipC6, /* Flip */
nvEvoFlipTransitionWARC6, /* FlipTransitionWAR */
nvEvoFillLUTSurfaceC5, /* FillLUTSurface */
EvoSetOutputLutC9, /* SetOutputLut */
EvoSetOutputScalerC9, /* SetOutputScaler */
EvoSetViewportPointInC9, /* SetViewportPointIn */
EvoSetViewportInOutC9, /* SetViewportInOut */
EvoSetCursorImageC9, /* SetCursorImage */
nvEvoValidateCursorSurfaceC3, /* ValidateCursorSurface */
nvEvoValidateWindowFormatC6, /* ValidateWindowFormat */
nvEvoInitCompNotifierC3, /* InitCompNotifier */
nvEvoIsCompNotifierCompleteC3, /* IsCompNotifierComplete */
nvEvoWaitForCompNotifierC3, /* WaitForCompNotifier */
EvoSetDitherC9, /* SetDither */
EvoSetStallLockC9, /* SetStallLock */
EvoSetDisplayRateC9, /* SetDisplayRate */
EvoInitChannelC9, /* InitChannel */
nvEvoInitDefaultLutC5, /* InitDefaultLut */
nvEvoInitWindowMappingC5, /* InitWindowMapping */
nvEvoIsChannelIdleC3, /* IsChannelIdle */
nvEvoIsChannelMethodPendingC3, /* IsChannelMethodPending */
nvEvoForceIdleSatelliteChannelC3, /* ForceIdleSatelliteChannel */
nvEvoForceIdleSatelliteChannelIgnoreLockC3, /* ForceIdleSatelliteChannelIgnoreLock */
nvEvoAccelerateChannelC3, /* AccelerateChannel */
nvEvoResetChannelAcceleratorsC3, /* ResetChannelAccelerators */
nvEvoAllocRmCtrlObjectC3, /* AllocRmCtrlObject */
nvEvoFreeRmCtrlObjectC3, /* FreeRmCtrlObject */
nvEvoSetImmPointOutC3, /* SetImmPointOut */
EvoStartHeadCRC32CaptureC9, /* StartCRC32Capture */
EvoStopHeadCRC32CaptureC9, /* StopCRC32Capture */
nvEvoQueryHeadCRC32_C3, /* QueryCRC32 */
nvEvoGetScanLineC3, /* GetScanLine */
EvoConfigureVblankSyncObjectC9, /* ConfigureVblankSyncObject */
EvoSetDscParamsC9, /* SetDscParams */
NULL, /* EnableMidFrameAndDWCFWatermark */
nvEvoGetActiveViewportOffsetC3, /* GetActiveViewportOffset */
NULL, /* ClearSurfaceUsage */
nvEvoComputeWindowScalingTapsC5, /* ComputeWindowScalingTaps */
nvEvoGetWindowScalingCapsC3, /* GetWindowScalingCaps */
NULL, /* SetMergeMode */
nvEvo1SendHdmiInfoFrame, /* SendHdmiInfoFrame */
nvEvo1DisableHdmiInfoFrame, /* DisableHdmiInfoFrame */
nvEvo1SendDpInfoFrameSdp, /* SendDpInfoFrameSdp */
NULL, /* SetDpVscSdp */
NULL, /* InitHwHeadMultiTileConfig */
NULL, /* SetMultiTileConfig */
EvoAllocSurfaceDescriptorC9, /* AllocSurfaceDescriptor */
EvoFreeSurfaceDescriptorC9, /* FreeSurfaceDescriptor */
EvoBindSurfaceDescriptorC9, /* BindSurfaceDescriptor */
EvoSetTmoLutSurfaceAddressC9, /* SetTmoLutSurfaceAddress */
EvoSetILUTSurfaceAddressC9, /* SetILUTSurfaceAddress */
EvoSetISOSurfaceAddressC9, /* SetISOSurfaceAddress */
EvoSetCoreNotifierSurfaceAddressAndControlC9, /* SetCoreNotifierSurfaceAddressAndControl */
EvoSetWinNotifierSurfaceAddressAndControlC9, /* SetWinNotifierSurfaceAddressAndControl */
EvoSetSemaphoreSurfaceAddressAndControlC9, /* SetSemaphoreSurfaceAddressAndControl */
EvoSetAcqSemaphoreSurfaceAddressAndControlC9, /* SetAcqSemaphoreSurfaceAddressAndControl */
{ /* caps */
TRUE, /* supportsNonInterlockedUsageBoundsUpdate */
TRUE, /* supportsDisplayRate */
FALSE, /* supportsFlipLockRGStatus */
TRUE, /* needDefaultLutSurface */
TRUE, /* hasUnorm10OLUT */
FALSE, /* supportsImageSharpening */
TRUE, /* supportsHDMIVRR */
FALSE, /* supportsCoreChannelSurface */
TRUE, /* supportsHDMIFRL */
FALSE, /* supportsSetStorageMemoryLayout */
TRUE, /* supportsIndependentAcqRelSemaphore */
FALSE, /* supportsCoreLut */
TRUE, /* supportsSynchronizedOverlayPositionUpdate */
TRUE, /* supportsVblankSyncObjects */
FALSE, /* requiresScalingTapsInBothDimensions */
FALSE, /* supportsMergeMode */
TRUE, /* supportsHDMI10BPC */
TRUE, /* supportsDPAudio192KHz */
TRUE, /* supportsInputColorSpace */
TRUE, /* supportsInputColorRange */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
NV_EVO3_X_EMULATED_SURFACE_MEMORY_FORMATS_C6, /* xEmulatedSurfaceMemoryFormats */
},
};
NVEvoHAL nvEvoCA = {
EvoSetRasterParamsCA, /* SetRasterParams */
EvoSetProcAmpC9, /* SetProcAmp */

View File

@@ -36,8 +36,10 @@
#include "class/clc570.h" // NVC570_DISPLAY
#include "class/clc670.h" // NVC670_DISPLAY
#include "class/clc770.h" // NVC770_DISPLAY
#include "class/clc970.h" // NVC970_DISPLAY
#include "class/clca70.h" // NVCA70_DISPLAY
#include "class/clcb70.h" // NVCB70_DISPLAY
#include "class/clcc70.h" // NVCC70_DISPLAY
#include "class/cl947d.h" // NV947D_CORE_CHANNEL_DMA
#include "class/cl957d.h" // NV957D_CORE_CHANNEL_DMA
@@ -50,16 +52,21 @@
#include "class/clc67d.h" // NVC67D_CORE_CHANNEL_DMA
#include "class/clc67e.h" // NVC67E_WINDOW_CHANNEL_DMA
#include "class/clc77d.h" // NVC67D_CORE_CHANNEL_DMA
#include "class/clc97d.h" // NVC97D_CORE_CHANNEL_DMA
#include "class/clc97e.h" // NVC97E_WINDOW_CHANNEL_DMA
#include "class/clca7d.h" // NVCA7D_CORE_CHANNEL_DMA
#include "class/clca7e.h" // NVCA7E_WINDOW_CHANNEL_DMA
#include "class/clcb7d.h" // NVCB7D_CORE_CHANNEL_DMA
#include "class/clcb7e.h" // NVCB7E_WINDOW_CHANNEL_DMA
#include "class/clcc7d.h" // NVCC7D_CORE_CHANNEL_DMA
#include "class/clcc7e.h" // NVCC7E_WINDOW_CHANNEL_DMA
extern NVEvoHAL nvEvo94;
extern NVEvoHAL nvEvo97;
extern NVEvoHAL nvEvoC3;
extern NVEvoHAL nvEvoC5;
extern NVEvoHAL nvEvoC6;
extern NVEvoHAL nvEvoC9;
extern NVEvoHAL nvEvoCA;
enum NvKmsAllocDeviceStatus nvAssignEvoCaps(NVDevEvoPtr pDevEvo)
@@ -72,6 +79,7 @@ enum NvKmsAllocDeviceStatus nvAssignEvoCaps(NVDevEvoPtr pDevEvo)
_inputLutAppliesToBase, \
_dpYCbCr422MaxBpc, \
_hdmiYCbCr422MaxBpc, \
_hdmiTmds10BpcMaxPClkMHz, \
_validNIsoFormatMask, \
_maxPitch, \
_maxWidthInBytes, \
@@ -103,6 +111,7 @@ enum NvKmsAllocDeviceStatus nvAssignEvoCaps(NVDevEvoPtr pDevEvo)
.maxRasterHeight = DRF_MASK(NV ## _classPrefix ## 7D_HEAD_SET_RASTER_SIZE_HEIGHT),\
.dpYCbCr422MaxBpc = _dpYCbCr422MaxBpc, \
.hdmiYCbCr422MaxBpc = _hdmiYCbCr422MaxBpc, \
.hdmiTmds10BpcMaxPClkMHz = _hdmiTmds10BpcMaxPClkMHz, \
} \
}
@@ -163,36 +172,40 @@ enum NvKmsAllocDeviceStatus nvAssignEvoCaps(NVDevEvoPtr pDevEvo)
const NVEvoCapsRec evoCaps;
} dispTable[] = {
/*
* hdmiYCbCr422MaxBpc-----------------------+
* dpYCbCr422MaxBpc---------------------+ |
* inputLutAppliesToBase ------------+ | |
* supportsYUV2020 ---------------+ | | |
* supportsHDMI20 -------------+ | | | |
* supportsDP13 ------------+ | | | | |
* pEvoHal --------------+ | | | | | |
* windowClassPrefix | | | | | | |
* classPrefix | | | | | | | |
* | | | | | | | | |
* hdmiTmds10BpcMaxPClkMHz----------------------+
* hdmiYCbCr422MaxBpc-----------------------+ |
* dpYCbCr422MaxBpc---------------------+ | |
* inputLutAppliesToBase ------------+ | | |
* supportsYUV2020 ---------------+ | | | |
* supportsHDMI20 -------------+ | | | | |
* supportsDP13 ------------+ | | | | | |
* pEvoHal --------------+ | | | | | | |
* windowClassPrefix | | | | | | | |
* classPrefix | | | | | | | | |
* | | | | | | | | | |
*/
ENTRY_NVD(CB, CB, &nvEvoCA, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(CC, CC, &nvEvoCA, 1, 1, 1, 0, 12, 12, 324),
ENTRY_NVD(CB, CB, &nvEvoCA, 1, 1, 1, 0, 12, 12, 324),
/* Blackwell GB20X */
ENTRY_NVD(CA, CA, &nvEvoCA, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(CA, CA, &nvEvoCA, 1, 1, 1, 0, 12, 12, 324),
/* Blackwell */
ENTRY_NVD(C9, C9, &nvEvoC9, 1, 1, 1, 0, 12, 12, 324),
/* Ada */
ENTRY_NVD(C7, C6, &nvEvoC6, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(C7, C6, &nvEvoC6, 1, 1, 1, 0, 12, 12, 324),
/* Ampere */
ENTRY_NVD(C6, C6, &nvEvoC6, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(C6, C6, &nvEvoC6, 1, 1, 1, 0, 12, 12, 324),
/* Turing */
ENTRY_NVD(C5, C5, &nvEvoC5, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(C5, C5, &nvEvoC5, 1, 1, 1, 0, 12, 12, 0),
/* Volta */
ENTRY_NVD(C3, C3, &nvEvoC3, 1, 1, 1, 0, 12, 12),
ENTRY_NVD(C3, C3, &nvEvoC3, 1, 1, 1, 0, 12, 12, 0),
/* gp10x */
ENTRY_EVO(98, &nvEvo97, 1, 1, 1, 1, 12, 12),
ENTRY_EVO(98, &nvEvo97, 1, 1, 1, 1, 12, 12, 0),
/* gp100 */
ENTRY_EVO(97, &nvEvo97, 1, 1, 1, 1, 12, 12),
ENTRY_EVO(97, &nvEvo97, 1, 1, 1, 1, 12, 12, 0),
/* gm20x */
ENTRY_EVO(95, &nvEvo94, 0, 1, 0, 1, 8, 0),
ENTRY_EVO(95, &nvEvo94, 0, 1, 0, 1, 8, 0, 0),
/* gm10x */
ENTRY_EVO(94, &nvEvo94, 0, 0, 0, 1, 8, 0),
ENTRY_EVO(94, &nvEvo94, 0, 0, 0, 1, 8, 0, 0),
};
int i;

View File

@@ -1999,7 +1999,6 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
*/
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo)
{
NvU32 passiveDpDongleMaxPclkKHz;
const NVDevEvoRec *pDevEvo = pDpyEvo->pDispEvo->pDevEvo;
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
@@ -2014,45 +2013,78 @@ NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo)
return FALSE;
}
/*
* Can't use FRL if the connector is not natively HDMI (e.g., if
* using a passive DP-to-HDMI dongle, or if overrideEdid/forceConnected
* attempted to force HDMI FRL on a DP connector).
*/
if (pDpyEvo->pConnectorEvo->type != NVKMS_CONNECTOR_TYPE_HDMI) {
return FALSE;
}
/* Can't use FRL if the HDMI sink doesn't support it. */
if (!pDpyEvo->parsedEdid.valid ||
!pDpyEvo->parsedEdid.info.hdmiForumInfo.max_FRL_Rate) {
return FALSE;
}
/* Can't use FRL if we are using a passive DP to HDMI dongle. */
if (nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz) !=
NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
return FALSE;
}
return TRUE;
}
NvU32 nvHdmiGetEffectivePixelClockKHz(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor)
NvBool nvHdmiIsTmdsPossible(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor)
{
/* For YUV420 HW mode, divide pixel clock by 2. */
const NvU32 pixelClock = (pHwTimings->yuv420Mode == NV_YUV420_MODE_HW) ?
(pHwTimings->pixelClock / 2) : pHwTimings->pixelClock;
ct_assert(NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10 ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_MAX);
nvAssert((pHwTimings->yuv420Mode == NV_YUV420_MODE_NONE) ||
(pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420));
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/*
* HDMI requires 8+ BPC, enforced via nvDpyGetOutputColorFormatInfo() and
* IsColorBpcSupported(), so just assert instead of handling < 8 BPC.
*/
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 YCbCr422, compare without adjusting maximum pixel clock despite BPC. */
if (pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) {
return (pixelClock <= pDpyEvo->maxSingleLinkPixelClockKHz);
}
/*
* For > 8 BPC, the effective pixel clock is adjusted upwards according to
* the ratio of the given BPC and 8 BPC.
* For 10 BPC, compare with hardware reduced limit if applicable, otherwise
* adjust maximum pixel clock by a ratio of 8/10 BPC.
*/
return ((pixelClock * pDpyColor->bpc) / 8ULL);
if (pDpyColor->bpc == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10) {
NvU32 hdmiTmds10BpcMaxPClkKHz =
pDpyEvo->pDispEvo->pDevEvo->caps.hdmiTmds10BpcMaxPClkMHz * 1000UL;
NvU32 adjustedMaxPixelClock =
(pDpyEvo->maxSingleLinkPixelClockKHz * 4ULL) / 5ULL;
/* Pixel clock must satisfy hdmiTmds10BpcMaxPClkKHz, if applicable. */
if ((hdmiTmds10BpcMaxPClkKHz > 0) &&
(pixelClock > hdmiTmds10BpcMaxPClkKHz)) {
return FALSE;
}
/* Pixel clock must also satisfy adjustedMaxPixelClock. */
if (pixelClock > adjustedMaxPixelClock) {
return FALSE;
}
return TRUE;
}
/* For 8 BPC, compare without adjusting maximum pixel clock. */
nvAssert(pDpyColor->bpc == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8);
return (pixelClock <= pDpyEvo->maxSingleLinkPixelClockKHz);
}
static NvU64 GetHdmiFrlLinkRate(HDMI_FRL_DATA_RATE frlRate)
@@ -2114,8 +2146,7 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(nvHdmiDpySupportsFrl(pDpyEvo));
nvAssert(nvHdmiGetEffectivePixelClockKHz(pDpyEvo, pHwTimings, pDpyColor) >
pDpyEvo->maxSingleLinkPixelClockKHz);
nvAssert(!nvHdmiIsTmdsPossible(pDpyEvo, pHwTimings, pDpyColor));
/* See if we can find an NVT_TIMING for this mode from the EDID. */
pNvtTiming = nvFindEdidNVT_TIMING(pDpyEvo, pModeTimings, pValidationParams);

View File

@@ -1717,14 +1717,16 @@ ValidateColorspace(const NVDevEvoRec *pDevEvo,
const NVFlipEvoHwState *pFlipState,
NvU32 layer)
{
NVSurfaceEvoPtr pSurfaceEvo =
pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT];
if (pSurfaceEvo == NULL) {
return TRUE;
}
if ((pFlipState->layer[layer].colorSpace !=
NVKMS_INPUT_COLOR_SPACE_NONE)) {
NVSurfaceEvoPtr pSurfaceEvo =
pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT];
const NvKmsSurfaceMemoryFormatInfo *pFormatInfo =
(pSurfaceEvo != NULL) ?
nvKmsGetSurfaceMemoryFormatInfo(pSurfaceEvo->format) : NULL;
nvKmsGetSurfaceMemoryFormatInfo(pSurfaceEvo->format);
if (pFormatInfo == NULL) {
return FALSE;

View File

@@ -43,6 +43,7 @@
typedef struct {
enum NvKmsModeSource source;
NvBool patchedStereoTimings;
NvBool dscPassThrough;
} EvoValidateModeFlags;
static NvBool
@@ -405,6 +406,10 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo,
&pReply->hdmi3DAvailable);
nvKmsUpdateNvModeTimingsForHdmi3D(&kmsMode.timings, hdmi3D);
if (!!(timing.etc.flag & NVT_FLAG_DISPLAYID_T7_DSC_PASSTHRU)) {
flags.dscPassThrough = TRUE;
}
kmsMode.timings.yuv420Mode = GetYUV420Value(pDpyEvo, pParams, &timing);
/* validate the mode */
@@ -890,8 +895,7 @@ static NvBool IsVesaMode(const NvModeTimings *pModeTimings,
*/
static void LogModeValidationBegin(NVEvoInfoStringPtr pInfoString,
const NvModeTimings *pModeTimings,
const char *modeName)
const NvModeTimings *pModeTimings)
{
nvEvoLogInfoString(pInfoString, "%d x %d @ %d Hz%s",
pModeTimings->hVisible,
@@ -922,7 +926,6 @@ static void LogModeValidationEnd(const NVDispEvoRec *pDispEvo,
}
}
/*!
* Print mode timings to the NVEvoInfoStringPtr.
*/
@@ -964,6 +967,7 @@ void nvEvoLogModeValidationModeTimings(NVEvoInfoStringPtr
pModeTimings->vSyncPos ? "+V " : "",
pModeTimings->vSyncNeg ? "-V " : "");
if (pModeTimings->interlaced && pModeTimings->doubleScan) {
extra = "Interlace DoubleScan";
} else if (pModeTimings->interlaced) {
@@ -1529,6 +1533,13 @@ static NvBool ValidateModeTimings(
return FALSE;
}
if (flags->dscPassThrough &&
(pParams->dscMode == NVKMS_DSC_MODE_FORCE_DISABLE)) {
LogModeValidationEnd(pDispEvo, pInfoString,
"Mode is only supported with DSC pass-through, but DSC is force disabled");
return FALSE;
}
return TRUE;
}
@@ -1644,13 +1655,16 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
/* begin logging of ModeValidation for this mode */
LogModeValidationBegin(pInfoString, pModeTimings, modeName);
LogModeValidationBegin(pInfoString, pModeTimings);
if (!ValidateModeTimings(pDpyEvo, pKmsMode, flags, pParams,
pInfoString, pValidSyncs)) {
goto done;
}
nvEvoLogInfoString(pInfoString,
"DSCPassThrough: %s", flags->dscPassThrough ? "Yes" : "No");
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;
@@ -1685,6 +1699,7 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
pKmsMode,
NULL, /* pViewPortSizeIn */
NULL, /* pViewPortOut */
flags->dscPassThrough,
&dpyColor,
pTimingsEvo,
pParams,
@@ -1939,6 +1954,10 @@ static NvBool ConstructModeTimingsMetaData(
return FALSE;
}
if (!!(timing.etc.flag & NVT_FLAG_DISPLAYID_T7_DSC_PASSTHRU)) {
flags.dscPassThrough = TRUE;
}
if (pParams->stereoMode == NVKMS_STEREO_HDMI_3D) {
if (!nvDpyEvoSupportsHdmi3D(pDpyEvo)) {
nvEvoLogDisp(pDispEvo, EVO_LOG_WARN,
@@ -2035,6 +2054,7 @@ NvBool nvValidateModeForModeset(NVDpyEvoRec *pDpyEvo,
&kmsMode,
pViewPortSizeIn,
pViewPortOut,
flags.dscPassThrough,
pDpyColor,
pTimingsEvo,
pParams,

View File

@@ -148,14 +148,14 @@ ClearProposedModeSetHwState(const NVDevEvoRec *pDevEvo,
* Inherit the previous modeset state as part of this modeset if:
* - The requesting client is not the internal NVKMS client (i.e., this is not
* a console restore modeset).
* - There is no modeset ownership change since the last modeset.
* - There is no modeset ownership or sub-ownership change since the last modeset.
*/
static NvBool
InheritPreviousModesetState(const NVDevEvoRec *pDevEvo,
const struct NvKmsPerOpenDev *pCurrentModesetOpenDev)
{
return (pCurrentModesetOpenDev != pDevEvo->pNvKmsOpenDev) &&
!pDevEvo->modesetOwnerChanged;
!pDevEvo->modesetOwnerOrSubOwnerChanged;
}
/*!
@@ -4121,7 +4121,7 @@ NvBool nvSetDispModeEvo(NVDevEvoPtr pDevEvo,
pDevEvo->skipConsoleRestore = FALSE;
pDevEvo->modesetOwnerChanged = FALSE;
pDevEvo->modesetOwnerOrSubOwnerChanged = FALSE;
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
/*

View File

@@ -45,6 +45,7 @@
#include "nv_smg.h"
#include "class/cl00c3.h" /* NV01_MEMORY_SYNCPOINT */
#include "class/cl0005.h" /* NV01_EVENT */
#include <class/cl0070.h> // NV01_MEMORY_VIRTUAL
@@ -61,10 +62,14 @@
#include "class/clc57e.h" /* NVC57E_WINDOW_CHANNEL_DMA */
#include "class/clc67b.h" /* NVC67B_WINDOW_IMM_CHANNEL_DMA */
#include "class/clc67e.h" /* NVC67E_WINDOW_CHANNEL_DMA */
#include "class/clc97b.h" /* NVC97B_WINDOW_IMM_CHANNEL_DMA */
#include "class/clc97e.h" /* NVC97E_WINDOW_CHANNEL_DMA */
#include "class/clca7b.h" /* NVCA7B_WINDOW_IMM_CHANNEL_DMA */
#include "class/clca7e.h" /* NVCA7E_WINDOW_CHANNEL_DMA */
#include "class/clcb7b.h" /* NVCB7B_WINDOW_IMM_CHANNEL_DMA */
#include "class/clcb7e.h" /* NVCB7E_WINDOW_CHANNEL_DMA */
#include "class/clcc7b.h" /* NVCC7B_WINDOW_IMM_CHANNEL_DMA */
#include "class/clcc7e.h" /* NVCC7E_WINDOW_CHANNEL_DMA */
#include "class/cl917b.h" /* NV917B_OVERLAY_IMM_CHANNEL_PIO */
@@ -269,7 +274,8 @@ static NvBool QueryGpuCapabilities(NVDevEvoPtr pDevEvo)
}
pDevEvo->supportsSyncpts =
FALSE;
nvkms_kernel_supports_syncpts() &&
nvRmEvoClassListCheck(pDevEvo, NV01_MEMORY_SYNCPOINT);
return TRUE;
}
@@ -2533,7 +2539,8 @@ NvBool nvRmAllocEvoDma(NVDevEvoPtr pDevEvo, NVEvoDmaPtr pDma,
// Create surface descriptor for this allocation.
ret = pDevEvo->hal->AllocSurfaceDescriptor(pDevEvo, &surfaceDesc, memoryHandle,
localCtxDmaFlags, limit);
localCtxDmaFlags, limit,
FALSE /* mapToDisplayRm */);
if (ret != NVOS_STATUS_SUCCESS) {
if (pBase != NULL) {
@@ -3212,10 +3219,14 @@ NvBool nvRMAllocateWindowChannels(NVDevEvoPtr pDevEvo)
NvU32 windowClass;
NvU32 immClass;
} windowChannelClasses[] = {
{ NVCC7E_WINDOW_CHANNEL_DMA,
NVCC7B_WINDOW_IMM_CHANNEL_DMA },
{ NVCB7E_WINDOW_CHANNEL_DMA,
NVCB7B_WINDOW_IMM_CHANNEL_DMA },
{ NVCA7E_WINDOW_CHANNEL_DMA,
NVCA7B_WINDOW_IMM_CHANNEL_DMA },
{ NVC97E_WINDOW_CHANNEL_DMA,
NVC97B_WINDOW_IMM_CHANNEL_DMA },
{ NVC67E_WINDOW_CHANNEL_DMA,
NVC67B_WINDOW_IMM_CHANNEL_DMA },
{ NVC57E_WINDOW_CHANNEL_DMA,
@@ -3649,6 +3660,67 @@ NvBool nvRmEvoAllocAndBindSyncpt(
NVSurfaceDescriptor *pSurfaceDesc,
NVEvoSyncpt *pEvoSyncpt)
{
NvU32 ret = FALSE;
NvU32 hSyncpt;
NV_MEMORY_SYNCPOINT_ALLOCATION_PARAMS syncptAllocParams = {0};
/*! Alloc SYNC Object */
syncptAllocParams.syncpointId = id;
hSyncpt = nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
if (hSyncpt == 0) {
goto skipEverythingAndFail;
}
ret = nvRmApiAlloc(nvEvoGlobal.clientHandle,
pDevEvo->deviceHandle,
hSyncpt,
NV01_MEMORY_SYNCPOINT,
&syncptAllocParams);
if (ret != NVOS_STATUS_SUCCESS) {
nvAssert(!"Failed to allocate syncpt object");
goto cleanHandleAndFail;
}
/*! Alloc surface descriptor for syncpt object */
ret = pDevEvo->hal->AllocSurfaceDescriptor(
pDevEvo, pSurfaceDesc, hSyncpt,
(DRF_DEF(OS03, _FLAGS, _HASH_TABLE, _DISABLE)),
65535 /* 64K-1 */,
FALSE /* mapToDisplayRm */);
if (ret != NVOS_STATUS_SUCCESS) {
nvAssert(!"Failed to allocate surface descriptor");
goto cleanSyncptHandleAndFail;
}
/*! Bind surface descriptor to syncpt Object */
ret = pDevEvo->hal->BindSurfaceDescriptor(pDevEvo, pChannel, pSurfaceDesc);
if (ret != NVOS_STATUS_SUCCESS) {
nvAssert(!"Failed to bind surface descriptor");
goto cleanEverythingAndFail;
}
pEvoSyncpt->id = id;
pEvoSyncpt->surfaceDesc = *pSurfaceDesc;
pEvoSyncpt->hSyncpt = hSyncpt;
pEvoSyncpt->allocated = TRUE;
return TRUE;
cleanEverythingAndFail:
pDevEvo->hal->FreeSurfaceDescriptor(pDevEvo,
pDevEvo->deviceHandle,
pSurfaceDesc);
cleanSyncptHandleAndFail:
nvRmApiFree(nvEvoGlobal.clientHandle, pDevEvo->deviceHandle, hSyncpt);
cleanHandleAndFail:
nvFreeUnixRmHandle(&pDevEvo->handleAllocator, hSyncpt);
skipEverythingAndFail:
return FALSE;
}
@@ -5688,7 +5760,8 @@ NvU32 nvRmAllocAndBindSurfaceDescriptor(
NvU32 hMemory,
const enum NvKmsSurfaceMemoryLayout layout,
NvU64 limit,
NVSurfaceDescriptor *pSurfaceDesc)
NVSurfaceDescriptor *pSurfaceDesc,
NvBool mapToDisplayRm)
{
NVSurfaceDescriptor surfaceDesc;
NvU32 flags = DRF_DEF(OS03, _FLAGS, _HASH_TABLE, _DISABLE);
@@ -5713,7 +5786,8 @@ NvU32 nvRmAllocAndBindSurfaceDescriptor(
ret =
pDevEvo->hal->AllocSurfaceDescriptor(pDevEvo, &surfaceDesc,
hMemory, flags, limit);
hMemory, flags, limit,
mapToDisplayRm);
if (ret != NVOS_STATUS_SUCCESS) {
return ret;

View File

@@ -374,39 +374,41 @@ static NvBool ValidateRegisterSurfaceRequest(
return TRUE;
}
static NvBool ValidateSurfaceAddressSpace(
static NvBool ValidateSurfaceAllocation(
NVDevEvoPtr pDevEvo,
NvU64 rmObjectSizeInBytes,
const struct NvKmsRegisterSurfaceRequest *pRequest,
NvU32 rmHandle)
{
NV0041_CTRL_GET_SURFACE_INFO_PARAMS surfaceInfoParams = {};
NV0041_CTRL_SURFACE_INFO surfaceInfo = {};
NV0041_CTRL_SURFACE_INFO surfaceInfo[3];
enum {
PHYS_SIZE_LO = 0,
PHYS_SIZE_HI,
ADDR_SPACE_TYPE,
};
NV_STATUS status;
NvU64 memSize;
/*
* Don't do these checks on tegra. Tegra has different capabilities.
* Here we always say display is possible so we never fail framebuffer
* creation.
*/
if (pDevEvo->isSOCDisplay) {
return TRUE;
}
/*
* Don't do these checks for surfaces that do not need access to display
* Do not require vidmem on tegra. Tegra has different capabilities. Here we
* always say display is possible so we never fail framebuffer creation.
*
* Do not require vidmem for surfaces that do not need access to display
* hardware.
*/
if (pRequest->noDisplayHardwareAccess) {
return TRUE;
}
/*
*
* If the memory is not isochronous, the memory will not be scanned out to a
* display. The checks are not needed for such memory types.
*/
if (pRequest->isoType != NVKMS_MEMORY_ISO) {
return TRUE;
}
NvBool requireVidmem = (pRequest->isoType == NVKMS_MEMORY_ISO) &&
!pDevEvo->isSOCDisplay &&
!pRequest->noDisplayHardwareAccess;
/*
* Check if the surface's actual size matches the request's sizeInBytes
* specification after duplicating the RM object under the NVKMS RM client.
*/
surfaceInfo[PHYS_SIZE_LO].index = NV0041_CTRL_SURFACE_INFO_INDEX_PHYS_SIZE_LO;
surfaceInfo[PHYS_SIZE_HI].index = NV0041_CTRL_SURFACE_INFO_INDEX_PHYS_SIZE_HI;
/*
* Check if the memory we are registering this surface with is valid. We
@@ -415,9 +417,9 @@ static NvBool ValidateSurfaceAddressSpace(
* If we cannot use this memory for display it may be resident in sysmem
* or may belong to another GPU.
*/
surfaceInfo.index = NV0041_CTRL_SURFACE_INFO_INDEX_ADDR_SPACE_TYPE;
surfaceInfo[ADDR_SPACE_TYPE].index = NV0041_CTRL_SURFACE_INFO_INDEX_ADDR_SPACE_TYPE;
surfaceInfoParams.surfaceInfoListSize = 1;
surfaceInfoParams.surfaceInfoListSize = requireVidmem ? 3 : 2;
surfaceInfoParams.surfaceInfoList = (NvP64)&surfaceInfo;
status = nvRmApiControl(nvEvoGlobal.clientHandle,
@@ -427,12 +429,21 @@ static NvBool ValidateSurfaceAddressSpace(
sizeof(surfaceInfoParams));
if (status != NV_OK) {
nvEvoLogDevDebug(pDevEvo, EVO_LOG_ERROR,
"Failed to get memory location of RM memory object 0x%x",
rmHandle);
"Failed to get surface information of RM memory object 0x%x",
rmHandle);
return FALSE;
}
if (surfaceInfo.data != NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE_VIDMEM) {
memSize = NvU64_BUILD(surfaceInfo[PHYS_SIZE_HI].data,
surfaceInfo[PHYS_SIZE_LO].data);
if (memSize < rmObjectSizeInBytes) {
nvEvoLogDevDebug(pDevEvo, EVO_LOG_ERROR,
"Memory allocated is not large enough for the surface");
return FALSE;
}
if (requireVidmem &&
surfaceInfo[ADDR_SPACE_TYPE].data != NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE_VIDMEM) {
nvEvoLogDevDebug(pDevEvo, EVO_LOG_ERROR,
"Memory used for surface not appropriate for scanout");
return FALSE;
@@ -601,20 +612,37 @@ void nvEvoRegisterSurface(NVDevEvoPtr pDevEvo,
goto fail;
}
if (!ValidateSurfaceAddressSpace(pDevEvo, pRequest, planeRmHandle)) {
if (!ValidateSurfaceAllocation(pDevEvo,
pRequest->planes[planeIndex].rmObjectSizeInBytes,
pRequest,
planeRmHandle)) {
goto fail;
}
/* XXX Validate sizeInBytes: can we query the surface size from RM? */
if (!pRequest->noDisplayHardwareAccess) {
NvU32 ret =
NvU32 ret;
/*
* For the surfaces that need display HW access, if the the 'fd' or the
* (rmClient, rmObject) tuple from the request is allocated from sysmem,
* irrespective of whether it is allocated by the same or a different GPU
* than the one nvkms is using for display or is allocated by an external
* allocator (like nvmap), map it for access by the GPU device that nvkms
* is using for display, using NV0041_CTRL_CMD_MAP_MEMORY_FOR_GPU_ACCESS.
* If the mapping is already created, the ctrl call will just refcount it.
*/
if (pDevEvo->isSOCDisplay) {
pSurfaceEvo->mapToDisplayRm = TRUE;
}
ret =
nvRmAllocAndBindSurfaceDescriptor(
pDevEvo,
planeRmHandle,
pRequest->layout,
pRequest->planes[planeIndex].rmObjectSizeInBytes - 1,
&pSurfaceEvo->planes[planeIndex].surfaceDesc);
&pSurfaceEvo->planes[planeIndex].surfaceDesc,
pSurfaceEvo->mapToDisplayRm);
if (ret != NVOS_STATUS_SUCCESS) {
goto fail;
}

View File

@@ -974,7 +974,7 @@ static NvBool GrabModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
}
pDevEvo->modesetOwner = pOpenDev;
pDevEvo->modesetOwnerChanged = TRUE;
pDevEvo->modesetOwnerOrSubOwnerChanged = TRUE;
AssignFullNvKmsPermissions(pOpenDev);
return TRUE;
@@ -1080,6 +1080,7 @@ static void RevokePermissionsInternal(
(typeBitmask & NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER))) {
FreeSwapGroups(pOpenDev);
pDevEvo->modesetSubOwner = NULL;
pDevEvo->modesetOwnerOrSubOwnerChanged = TRUE;
}
/*
@@ -1148,7 +1149,7 @@ static NvBool ReleaseModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
FreeSwapGroups(pOpenDev);
pDevEvo->modesetOwner = NULL;
pDevEvo->modesetOwnerChanged = TRUE;
pDevEvo->modesetOwnerOrSubOwnerChanged = TRUE;
pDevEvo->handleConsoleHotplugs = TRUE;
RestoreConsole(pDevEvo);
@@ -1642,6 +1643,7 @@ static void FreeDeviceReference(struct NvKmsPerOpen *pOpen,
// If this pOpenDev is the modeset sub-owner, implicitly release it.
if (pOpenDev->pDevEvo->modesetSubOwner == pOpenDev) {
pOpenDev->pDevEvo->modesetSubOwner = NULL;
pOpenDev->pDevEvo->modesetOwnerOrSubOwnerChanged = TRUE;
}
}
@@ -3524,6 +3526,7 @@ static NvBool AcquirePermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
}
pOpenDev->pDevEvo->modesetSubOwner = pOpenDev;
pOpenDev->pDevEvo->modesetOwnerOrSubOwnerChanged = TRUE;
AssignFullNvKmsPermissions(pOpenDev);
} else {
@@ -6566,7 +6569,8 @@ static void AllocSurfaceCtxDmasForAllOpens(NVDevEvoRec *pDevEvo)
pSurfaceEvo->planes[planeIndex].rmHandle,
pSurfaceEvo->layout,
pSurfaceEvo->planes[planeIndex].rmObjectSizeInBytes - 1,
&pSurfaceEvo->planes[planeIndex].surfaceDesc);
&pSurfaceEvo->planes[planeIndex].surfaceDesc,
pSurfaceEvo->mapToDisplayRm);
if (ret != NVOS_STATUS_SUCCESS) {
FreeSurfaceCtxDmasForAllOpens(pDevEvo);
nvAssert(!"Failed to re-allocate surface descriptor");

View File

@@ -136,6 +136,8 @@ SRCS += ../common/modeset/hdmipacket/nvhdmipkt_C771.c
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_C871.c
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_C971.c
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_CA71.c
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_CB71.c
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_CC71.c
SRCS += ../common/modeset/timing/nvt_cvt.c
SRCS += ../common/modeset/timing/nvt_displayid20.c
SRCS += ../common/modeset/timing/nvt_dmt.c