mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-01-30 13:09:47 +00:00
580.65.06
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -154,7 +154,8 @@ NvU32 nvRmAllocAndBindSurfaceDescriptor(
|
||||
NvU32 hMemory,
|
||||
const enum NvKmsSurfaceMemoryLayout layout,
|
||||
NvU64 limit,
|
||||
NVSurfaceDescriptor *pSurfaceDesc);
|
||||
NVSurfaceDescriptor *pSurfaceDesc,
|
||||
NvBool mapToDisplayRm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
/*!
|
||||
|
||||
@@ -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,
|
||||
¶msHead->mode,
|
||||
¶msHead->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 =
|
||||
¶ms->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;
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
¶ms, 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,
|
||||
¶ms, 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.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
¶ms, 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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user