11739a20eSAndy Ritger /*
2eb5c7665SAndy Ritger  * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
31739a20eSAndy Ritger  * SPDX-License-Identifier: MIT
41739a20eSAndy Ritger  *
51739a20eSAndy Ritger  * Permission is hereby granted, free of charge, to any person obtaining a
61739a20eSAndy Ritger  * copy of this software and associated documentation files (the "Software"),
71739a20eSAndy Ritger  * to deal in the Software without restriction, including without limitation
81739a20eSAndy Ritger  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91739a20eSAndy Ritger  * and/or sell copies of the Software, and to permit persons to whom the
101739a20eSAndy Ritger  * Software is furnished to do so, subject to the following conditions:
111739a20eSAndy Ritger  *
121739a20eSAndy Ritger  * The above copyright notice and this permission notice shall be included in
131739a20eSAndy Ritger  * all copies or substantial portions of the Software.
141739a20eSAndy Ritger  *
151739a20eSAndy Ritger  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161739a20eSAndy Ritger  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171739a20eSAndy Ritger  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
181739a20eSAndy Ritger  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191739a20eSAndy Ritger  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201739a20eSAndy Ritger  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211739a20eSAndy Ritger  * DEALINGS IN THE SOFTWARE.
221739a20eSAndy Ritger  */
231739a20eSAndy Ritger 
241739a20eSAndy Ritger /******************************************************************************
251739a20eSAndy Ritger *
261739a20eSAndy Ritger *   Description:
271739a20eSAndy Ritger *       This file contains functions managing the display - both Disp and DispCommon
281739a20eSAndy Ritger *       entries with their insides (DispChannelList and DispDmaControlList)
291739a20eSAndy Ritger *
301739a20eSAndy Ritger ******************************************************************************/
311739a20eSAndy Ritger 
321739a20eSAndy Ritger #define RM_STRICT_CONFIG_EMIT_DISP_ENGINE_DEFINITIONS     0
331739a20eSAndy Ritger 
341739a20eSAndy Ritger #include "core/locks.h"
351739a20eSAndy Ritger #include "resserv/rs_client.h"
361739a20eSAndy Ritger 
371739a20eSAndy Ritger #include "gpu/gpu.h"
381739a20eSAndy Ritger #include "gpu/device/device.h"
391739a20eSAndy Ritger #include "gpu/disp/disp_objs.h"
401739a20eSAndy Ritger #include "gpu/disp/disp_channel.h"
411739a20eSAndy Ritger #include "gpu/disp/kern_disp.h"
421739a20eSAndy Ritger #include "gpu_mgr/gpu_mgr.h"
43*91676d66SBernhard Stoeckner #include "platform/sli/sli.h"
441739a20eSAndy Ritger 
451739a20eSAndy Ritger #include "kernel/gpu/intr/intr.h"
461739a20eSAndy Ritger 
471739a20eSAndy Ritger #include "class/cl0073.h"                // NV04_DISPLAY_COMMON
481739a20eSAndy Ritger #include "class/cl5070.h"                // NV50_DISPLAY
491739a20eSAndy Ritger #include "class/clc370.h"                // NVC370_DISPLAY
501739a20eSAndy Ritger 
511739a20eSAndy Ritger NV_STATUS
dispapiConstruct_IMPL(DisplayApi * pDisplayApi,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)521739a20eSAndy Ritger dispapiConstruct_IMPL
531739a20eSAndy Ritger (
541739a20eSAndy Ritger     DisplayApi                   *pDisplayApi,
551739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
561739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
571739a20eSAndy Ritger )
581739a20eSAndy Ritger {
591739a20eSAndy Ritger     NV_STATUS        status;
601739a20eSAndy Ritger     CLASSDESCRIPTOR *pClassDescriptor;
611739a20eSAndy Ritger     RsResourceRef   *pResourceRef = pCallContext->pResourceRef;
621739a20eSAndy Ritger     OBJGPU          *pGpu;
631739a20eSAndy Ritger     KernelDisplay   *pKernelDisplay;
641739a20eSAndy Ritger     NvBool           bBcResource;
651739a20eSAndy Ritger     NvU32            i;
661739a20eSAndy Ritger 
67758b4ee8SAndy Ritger     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
681739a20eSAndy Ritger 
691739a20eSAndy Ritger     // Use gpuGetByRef instead of GpuResource because it will work even if resource
701739a20eSAndy Ritger     // isn't a GpuResource.
711739a20eSAndy Ritger     status = gpuGetByRef(pResourceRef, &bBcResource, &pGpu);
721739a20eSAndy Ritger     if (status != NV_OK)
731739a20eSAndy Ritger         return status;
741739a20eSAndy Ritger 
751739a20eSAndy Ritger     // Find class in class db (verifies class is valid for this GPU)
761739a20eSAndy Ritger     status = gpuGetClassByClassId(pGpu, pParams->externalClassId, &pClassDescriptor);
771739a20eSAndy Ritger     if (status != NV_OK)
781739a20eSAndy Ritger     {
791739a20eSAndy Ritger         NV_PRINTF(LEVEL_WARNING, "bad class 0x%x\n", pParams->externalClassId);
801739a20eSAndy Ritger         return NV_ERR_INVALID_CLASS;
811739a20eSAndy Ritger     }
821739a20eSAndy Ritger 
831739a20eSAndy Ritger     // Check display is enabled (i.e. not displayless)
841739a20eSAndy Ritger     pKernelDisplay = GPU_GET_KERNEL_DISPLAY(pGpu);
851739a20eSAndy Ritger     if (pKernelDisplay == NULL)
861739a20eSAndy Ritger     {
871739a20eSAndy Ritger         return NV_ERR_NOT_SUPPORTED;
881739a20eSAndy Ritger     }
891739a20eSAndy Ritger 
901739a20eSAndy Ritger     for (i = 0; i < NV2080_MAX_SUBDEVICES; i++)
911739a20eSAndy Ritger         pDisplayApi->pNotifyActions[i]    = NULL;
921739a20eSAndy Ritger 
931739a20eSAndy Ritger     pDisplayApi->pGpuInRmctrl = NULL;
941739a20eSAndy Ritger     pDisplayApi->pGpuGrp = gpumgrGetGpuGrpFromGpu(pGpu);
951739a20eSAndy Ritger     pDisplayApi->bBcResource = bBcResource;
961739a20eSAndy Ritger     pDisplayApi->hNotifierMemory = NV01_NULL_OBJECT;
971739a20eSAndy Ritger     pDisplayApi->pNotifierMemory = NULL;
981739a20eSAndy Ritger 
991739a20eSAndy Ritger     gpuSetThreadBcState(pGpu, bBcResource);
1001739a20eSAndy Ritger 
1011739a20eSAndy Ritger     return status;
1021739a20eSAndy Ritger }
1031739a20eSAndy Ritger 
1041739a20eSAndy Ritger void
dispapiDestruct_IMPL(DisplayApi * pDisplayApi)1051739a20eSAndy Ritger dispapiDestruct_IMPL
1061739a20eSAndy Ritger (
1071739a20eSAndy Ritger     DisplayApi *pDisplayApi
1081739a20eSAndy Ritger )
1091739a20eSAndy Ritger {
1101739a20eSAndy Ritger     NvU32 i;
1111739a20eSAndy Ritger 
1121739a20eSAndy Ritger     // Free notify actions memory if it's been allocated
1131739a20eSAndy Ritger     for (i = 0; i < NV2080_MAX_SUBDEVICES; i++)
1141739a20eSAndy Ritger     {
1151739a20eSAndy Ritger         portMemFree(pDisplayApi->pNotifyActions[i]);
1161739a20eSAndy Ritger         pDisplayApi->pNotifyActions[i] = NULL;
1171739a20eSAndy Ritger     }
1181739a20eSAndy Ritger }
1191739a20eSAndy Ritger 
1201739a20eSAndy Ritger static NV_STATUS
_dispapiNotifierInit(DisplayApi * pDisplayApi,NvU32 numNotifiers,NvU32 disableCmd)1211739a20eSAndy Ritger _dispapiNotifierInit
1221739a20eSAndy Ritger (
1231739a20eSAndy Ritger     DisplayApi *pDisplayApi,
1241739a20eSAndy Ritger     NvU32       numNotifiers,
1251739a20eSAndy Ritger     NvU32       disableCmd
1261739a20eSAndy Ritger )
1271739a20eSAndy Ritger {
1281739a20eSAndy Ritger     NvU32     i, j;
1291739a20eSAndy Ritger     NV_STATUS status = NV_OK;
1301739a20eSAndy Ritger 
1311739a20eSAndy Ritger     pDisplayApi->numNotifiers = numNotifiers;
1321739a20eSAndy Ritger 
1331739a20eSAndy Ritger     for (i = 0; i < NV2080_MAX_SUBDEVICES; i++)
1341739a20eSAndy Ritger     {
1351739a20eSAndy Ritger         // get memory for pNotifyActions table
1361739a20eSAndy Ritger         pDisplayApi->pNotifyActions[i] = portMemAllocNonPaged(
1371739a20eSAndy Ritger                                    pDisplayApi->numNotifiers * sizeof(NvU32));
1381739a20eSAndy Ritger         if (pDisplayApi->pNotifyActions[i] != NULL)
1391739a20eSAndy Ritger         {
1401739a20eSAndy Ritger             // default actions for each notifier type is disabled
1411739a20eSAndy Ritger             for (j = 0; j < pDisplayApi->numNotifiers; j++)
1421739a20eSAndy Ritger             {
1431739a20eSAndy Ritger                 pDisplayApi->pNotifyActions[i][j] = disableCmd;
1441739a20eSAndy Ritger             }
1451739a20eSAndy Ritger         }
1461739a20eSAndy Ritger         else
1471739a20eSAndy Ritger         {
1481739a20eSAndy Ritger             goto fail;
1491739a20eSAndy Ritger         }
1501739a20eSAndy Ritger     }
1511739a20eSAndy Ritger 
1521739a20eSAndy Ritger     return status;
1531739a20eSAndy Ritger 
1541739a20eSAndy Ritger fail:
1551739a20eSAndy Ritger     // first release any notifyActions memory
1561739a20eSAndy Ritger     for (i = 0; i < NV2080_MAX_SUBDEVICES; i++)
1571739a20eSAndy Ritger     {
1581739a20eSAndy Ritger         portMemFree(pDisplayApi->pNotifyActions[i]);
1591739a20eSAndy Ritger         pDisplayApi->pNotifyActions[i] = NULL;
1601739a20eSAndy Ritger     }
1611739a20eSAndy Ritger 
1621739a20eSAndy Ritger     return NV_ERR_INSUFFICIENT_RESOURCES;
1631739a20eSAndy Ritger }
1641739a20eSAndy Ritger 
1651739a20eSAndy Ritger NV_STATUS
dispobjConstructHal_IMPL(DispObject * pDispObject,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)1661739a20eSAndy Ritger dispobjConstructHal_IMPL
1671739a20eSAndy Ritger (
1681739a20eSAndy Ritger     DispObject                   *pDispObject,
1691739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
1701739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
1711739a20eSAndy Ritger )
1721739a20eSAndy Ritger {
1731739a20eSAndy Ritger     DisplayApi  *pDisplayApi  = staticCast(pDispObject, DisplayApi);
1741739a20eSAndy Ritger     Device      *pDevice      = dynamicCast(pCallContext->pResourceRef->pParentRef->pResource, Device);
1751739a20eSAndy Ritger     GpuResource *pGpuResource = staticCast(pDevice, GpuResource);
1761739a20eSAndy Ritger     OBJGPU      *pGpu         = pGpuResource->pGpu;
1771739a20eSAndy Ritger     NV_STATUS    rmStatus     = NV_ERR_INVALID_STATE;
1781739a20eSAndy Ritger 
1791739a20eSAndy Ritger     SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY);
1801739a20eSAndy Ritger     {
1811739a20eSAndy Ritger         KernelDisplay *pKernelDisplay = GPU_GET_KERNEL_DISPLAY(pGpu);
1821739a20eSAndy Ritger 
1831739a20eSAndy Ritger         rmStatus = kdispSelectClass_HAL(pGpu, pKernelDisplay, pCallContext->pResourceRef->externalClassId);
1841739a20eSAndy Ritger 
1851739a20eSAndy Ritger         if (rmStatus != NV_OK)
1861739a20eSAndy Ritger         {
1871739a20eSAndy Ritger             // If the operation fails, it should fail on the first try
1881739a20eSAndy Ritger             NV_ASSERT(gpumgrIsParentGPU(pGpu));
1891739a20eSAndy Ritger             SLI_LOOP_BREAK;
1901739a20eSAndy Ritger         }
1911739a20eSAndy Ritger     }
1921739a20eSAndy Ritger     SLI_LOOP_END;
1931739a20eSAndy Ritger 
1941739a20eSAndy Ritger     if (rmStatus != NV_OK)
1951739a20eSAndy Ritger         return rmStatus;
1961739a20eSAndy Ritger 
1971739a20eSAndy Ritger     if(dynamicCast(pDisplayApi, NvDispApi))
1981739a20eSAndy Ritger     {
1991739a20eSAndy Ritger         rmStatus = _dispapiNotifierInit(pDisplayApi,
2001739a20eSAndy Ritger                                         NVC370_NOTIFIERS_MAXCOUNT,
2011739a20eSAndy Ritger                                         NVC370_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE);
2021739a20eSAndy Ritger     }
2031739a20eSAndy Ritger     else
2041739a20eSAndy Ritger     {
2051739a20eSAndy Ritger         rmStatus = _dispapiNotifierInit(pDisplayApi,
2061739a20eSAndy Ritger                                         NV5070_NOTIFIERS_MAXCOUNT,
2071739a20eSAndy Ritger                                         NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE);
2081739a20eSAndy Ritger     }
2091739a20eSAndy Ritger 
2101739a20eSAndy Ritger     return rmStatus;
2111739a20eSAndy Ritger }
2121739a20eSAndy Ritger 
2131739a20eSAndy Ritger NV_STATUS
dispobjConstruct_IMPL(DispObject * pDispObject,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)2141739a20eSAndy Ritger dispobjConstruct_IMPL
2151739a20eSAndy Ritger (
2161739a20eSAndy Ritger     DispObject                   *pDispObject,
2171739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
2181739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
2191739a20eSAndy Ritger )
2201739a20eSAndy Ritger {
2211739a20eSAndy Ritger     pDispObject->rmFreeFlags = NV5070_CTRL_SET_RMFREE_FLAGS_NONE;
2221739a20eSAndy Ritger 
2231739a20eSAndy Ritger     if (pParams->pSecInfo->privLevel < RS_PRIV_LEVEL_USER_ROOT)
2241739a20eSAndy Ritger     {
2251739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR,
2261739a20eSAndy Ritger                   "Failure allocating display class 0x%08x: Only root(admin)/kernel clients are allowed\n",
2271739a20eSAndy Ritger                   pParams->externalClassId);
2281739a20eSAndy Ritger 
2294397463eSAndy Ritger         //
2304397463eSAndy Ritger         // GPUSWSEC-1560 introduced a central object privilege check in RS. Please mark derived external classes
2314397463eSAndy Ritger         // of DispObject privileged in their RS_ENTRY. Since DispObject doesn't have an external class of its own
2324397463eSAndy Ritger         // and is used as a base class, leaving this check inline to catch future derivations.
2334397463eSAndy Ritger         //
2344397463eSAndy Ritger         osAssertFailed();
2354397463eSAndy Ritger 
2361739a20eSAndy Ritger         return NV_ERR_INSUFFICIENT_PERMISSIONS;
2371739a20eSAndy Ritger     }
2381739a20eSAndy Ritger 
2391739a20eSAndy Ritger     return dispobjConstructHal_HAL(pDispObject, pCallContext, pParams);
2401739a20eSAndy Ritger }
2411739a20eSAndy Ritger 
2421739a20eSAndy Ritger NV_STATUS
dispobjGetByHandle_IMPL(RsClient * pClient,NvHandle hDispObject,DispObject ** ppDispObject)2431739a20eSAndy Ritger dispobjGetByHandle_IMPL
2441739a20eSAndy Ritger (
2451739a20eSAndy Ritger     RsClient    *pClient,
2461739a20eSAndy Ritger     NvHandle     hDispObject,
2471739a20eSAndy Ritger     DispObject **ppDispObject
2481739a20eSAndy Ritger )
2491739a20eSAndy Ritger {
2501739a20eSAndy Ritger     NV_STATUS      status;
2511739a20eSAndy Ritger     RsResourceRef *pResourceRef;
2521739a20eSAndy Ritger 
2531739a20eSAndy Ritger     status = clientGetResourceRef(pClient, hDispObject, &pResourceRef);
2541739a20eSAndy Ritger     if (status != NV_OK)
2551739a20eSAndy Ritger         return status;
2561739a20eSAndy Ritger 
2571739a20eSAndy Ritger     *ppDispObject = dynamicCast(pResourceRef->pResource, DispObject);
2581739a20eSAndy Ritger 
2591739a20eSAndy Ritger     return (*ppDispObject) ? NV_OK : NV_ERR_INVALID_OBJECT_HANDLE;
2601739a20eSAndy Ritger }
2611739a20eSAndy Ritger 
2621739a20eSAndy Ritger NV_STATUS
dispobjGetByDevice_IMPL(RsClient * pClient,Device * pDevice,DispObject ** ppDispObject)2631739a20eSAndy Ritger dispobjGetByDevice_IMPL
2641739a20eSAndy Ritger (
2651739a20eSAndy Ritger     RsClient    *pClient,
2661739a20eSAndy Ritger     Device      *pDevice,
2671739a20eSAndy Ritger     DispObject **ppDispObject
2681739a20eSAndy Ritger )
2691739a20eSAndy Ritger {
2701739a20eSAndy Ritger     NV_STATUS      status;
2711739a20eSAndy Ritger     RsResourceRef *pResourceRef;
2721739a20eSAndy Ritger 
2731739a20eSAndy Ritger     status = refFindChildOfType(RES_GET_REF(pDevice), classId(DispObject), NV_FALSE /*bExactMatch*/, &pResourceRef);
2741739a20eSAndy Ritger     if (status != NV_OK)
2751739a20eSAndy Ritger         return status;
2761739a20eSAndy Ritger 
2771739a20eSAndy Ritger     *ppDispObject = dynamicCast(pResourceRef->pResource, DispObject);
2781739a20eSAndy Ritger 
2791739a20eSAndy Ritger     return (*ppDispObject) ? NV_OK : NV_ERR_INVALID_OBJECT_HANDLE;
2801739a20eSAndy Ritger }
2811739a20eSAndy Ritger 
2821739a20eSAndy Ritger //
2831739a20eSAndy Ritger // Most display control calls take a subDeviceInstance argument.
2841739a20eSAndy Ritger // We need to verify that this argument is valid and then use it to
2851739a20eSAndy Ritger // locate the correct OBJGPU for the particular subdevice.
2861739a20eSAndy Ritger //
2871739a20eSAndy Ritger NV_STATUS
dispapiSetUnicastAndSynchronize_KERNEL(DisplayApi * pDisplayApi,OBJGPUGRP * pGpuGroup,OBJGPU ** ppGpu,OBJDISP ** ppDisp,NvU32 subDeviceInstance)2881739a20eSAndy Ritger dispapiSetUnicastAndSynchronize_KERNEL
2891739a20eSAndy Ritger (
2901739a20eSAndy Ritger     DisplayApi      *pDisplayApi,
2911739a20eSAndy Ritger     OBJGPUGRP       *pGpuGroup,
2921739a20eSAndy Ritger     OBJGPU         **ppGpu,
293eb5c7665SAndy Ritger     OBJDISP        **ppDisp,
2941739a20eSAndy Ritger     NvU32            subDeviceInstance
2951739a20eSAndy Ritger )
2961739a20eSAndy Ritger {
2971739a20eSAndy Ritger     NV_STATUS   nvStatus    = NV_OK;
2981739a20eSAndy Ritger 
2991739a20eSAndy Ritger     nvStatus = gpugrpGetGpuFromSubDeviceInstance(pGpuGroup, subDeviceInstance, ppGpu);
3001739a20eSAndy Ritger     if (nvStatus != NV_OK)
3011739a20eSAndy Ritger         return nvStatus;
3021739a20eSAndy Ritger 
3031739a20eSAndy Ritger     gpumgrSetBcEnabledStatus(*ppGpu, NV_FALSE);
3041739a20eSAndy Ritger 
305eb5c7665SAndy Ritger     //
306eb5c7665SAndy Ritger     // The _KERNEL version of this function is only called from Kernel RM, but
307eb5c7665SAndy Ritger     // in Kernel RM, OBJDISP is not available, so ppDisp must be NULL. If the
308eb5c7665SAndy Ritger     // caller needs to access OBJDISP, either the caller code must remove the
309eb5c7665SAndy Ritger     // OBJDISP dependency, or the caller code must be changed so that
310eb5c7665SAndy Ritger     // dispapiSetUnicastAndSynchronize is called only from physical or
311eb5c7665SAndy Ritger     // monolithic RM, never Kernel RM.
312eb5c7665SAndy Ritger     //
313eb5c7665SAndy Ritger     if (ppDisp != NULL)
314eb5c7665SAndy Ritger     {
315eb5c7665SAndy Ritger         return NV_ERR_INVALID_STATE;
316eb5c7665SAndy Ritger     }
317eb5c7665SAndy Ritger 
3181739a20eSAndy Ritger     return nvStatus;
3191739a20eSAndy Ritger }
3201739a20eSAndy Ritger 
3211739a20eSAndy Ritger NV_STATUS
dispapiControl_Prologue_IMPL(DisplayApi * pDisplayApi,CALL_CONTEXT * pCallContext,RS_RES_CONTROL_PARAMS_INTERNAL * pRmCtrlParams)3221739a20eSAndy Ritger dispapiControl_Prologue_IMPL
3231739a20eSAndy Ritger (
3241739a20eSAndy Ritger     DisplayApi                     *pDisplayApi,
3251739a20eSAndy Ritger     CALL_CONTEXT                   *pCallContext,
3261739a20eSAndy Ritger     RS_RES_CONTROL_PARAMS_INTERNAL *pRmCtrlParams
3271739a20eSAndy Ritger )
3281739a20eSAndy Ritger {
3291739a20eSAndy Ritger     NvU32       subdeviceIndex;
3301739a20eSAndy Ritger     NV_STATUS   status;
3311739a20eSAndy Ritger     RmResource *pResource = staticCast(pDisplayApi, RmResource);
3321739a20eSAndy Ritger 
3331739a20eSAndy Ritger     if (dynamicCast(pDisplayApi, DispCommon))
3341739a20eSAndy Ritger     {
3351739a20eSAndy Ritger         Device      *pDevice = dynamicCast(pCallContext->pResourceRef->pParentRef->pResource, Device);
3361739a20eSAndy Ritger         GpuResource *pGpuResource = staticCast(pDevice, GpuResource);
3371739a20eSAndy Ritger 
3381739a20eSAndy Ritger         pResource->rpcGpuInstance = gpuGetInstance(pGpuResource->pGpu);
3391739a20eSAndy Ritger         pDisplayApi->pGpuInRmctrl = pGpuResource->pGpu;
3401739a20eSAndy Ritger         return rmresControl_Prologue_IMPL(pResource, pCallContext, pRmCtrlParams);
3411739a20eSAndy Ritger     }
3421739a20eSAndy Ritger 
3431739a20eSAndy Ritger     // Read the subdevice ID out and swap GPU pointer
3441739a20eSAndy Ritger     if (dynamicCast(pDisplayApi, NvDispApi))
3451739a20eSAndy Ritger     {
3461739a20eSAndy Ritger         NVC370_CTRL_CMD_BASE_PARAMS *pBaseParameters = pRmCtrlParams->pParams;
3471739a20eSAndy Ritger 
3481739a20eSAndy Ritger         //
3491739a20eSAndy Ritger         // All non-NULL disp control 5070 methods have
3501739a20eSAndy Ritger         // NVC370_CTRL_CMD_BASE_PARAMS as their first member.
3511739a20eSAndy Ritger         //
3521739a20eSAndy Ritger         if ((pBaseParameters == NULL) || (pRmCtrlParams->paramsSize < sizeof(NVC370_CTRL_CMD_BASE_PARAMS)))
3531739a20eSAndy Ritger         {
3541739a20eSAndy Ritger             status = NV_ERR_INVALID_PARAM_STRUCT;
3551739a20eSAndy Ritger             goto done;
3561739a20eSAndy Ritger         }
3571739a20eSAndy Ritger         subdeviceIndex = pBaseParameters->subdeviceIndex;
3581739a20eSAndy Ritger     }
3591739a20eSAndy Ritger     else if (dynamicCast(pDisplayApi, DispSwObj))
3601739a20eSAndy Ritger     {
3611739a20eSAndy Ritger         NVC372_CTRL_CMD_BASE_PARAMS *pBaseParameters = pRmCtrlParams->pParams;
3621739a20eSAndy Ritger 
3631739a20eSAndy Ritger         //
3641739a20eSAndy Ritger         // All non-NULL disp control C372 methods have
3651739a20eSAndy Ritger         // NVC372_CTRL_CMD_BASE_PARAMS as their first member.
3661739a20eSAndy Ritger         //
3671739a20eSAndy Ritger         if ((pBaseParameters == NULL) || (pRmCtrlParams->paramsSize < sizeof(NVC372_CTRL_CMD_BASE_PARAMS)))
3681739a20eSAndy Ritger         {
3691739a20eSAndy Ritger             status = NV_ERR_INVALID_PARAM_STRUCT;
3701739a20eSAndy Ritger             goto done;
3711739a20eSAndy Ritger         }
3721739a20eSAndy Ritger         subdeviceIndex = pBaseParameters->subdeviceIndex;
3731739a20eSAndy Ritger     }
3741739a20eSAndy Ritger     else
3751739a20eSAndy Ritger     {
3761739a20eSAndy Ritger         NV5070_CTRL_CMD_BASE_PARAMS *pBaseParameters = pRmCtrlParams->pParams;
3771739a20eSAndy Ritger 
3781739a20eSAndy Ritger         //
3791739a20eSAndy Ritger         // All non-NULL disp control 5070 methods have
3801739a20eSAndy Ritger         // NV5070_CTRL_CMD_BASE_PARAMS as their first member.
3811739a20eSAndy Ritger         //
3821739a20eSAndy Ritger         if ((pBaseParameters == NULL) || (pRmCtrlParams->paramsSize < sizeof(NV5070_CTRL_CMD_BASE_PARAMS)))
3831739a20eSAndy Ritger         {
3841739a20eSAndy Ritger             status = NV_ERR_INVALID_PARAM_STRUCT;
3851739a20eSAndy Ritger             goto done;
3861739a20eSAndy Ritger         }
3871739a20eSAndy Ritger         subdeviceIndex = pBaseParameters->subdeviceIndex;
3881739a20eSAndy Ritger     }
3891739a20eSAndy Ritger 
3901739a20eSAndy Ritger     status = dispapiSetUnicastAndSynchronize_HAL(pDisplayApi,
3911739a20eSAndy Ritger                                              pRmCtrlParams->pGpuGrp,
3921739a20eSAndy Ritger                                              &pRmCtrlParams->pGpu,
393eb5c7665SAndy Ritger                                              NULL,
3941739a20eSAndy Ritger                                              subdeviceIndex);
3951739a20eSAndy Ritger 
3961739a20eSAndy Ritger     if (status == NV_OK)
3971739a20eSAndy Ritger     {
3981739a20eSAndy Ritger         pResource->rpcGpuInstance = gpuGetInstance(pRmCtrlParams->pGpu);
3991739a20eSAndy Ritger         pDisplayApi->pGpuInRmctrl = pRmCtrlParams->pGpu;
4001739a20eSAndy Ritger         return rmresControl_Prologue_IMPL(pResource, pCallContext, pRmCtrlParams);
4011739a20eSAndy Ritger     }
4021739a20eSAndy Ritger 
4031739a20eSAndy Ritger done:
4041739a20eSAndy Ritger     return status;
4051739a20eSAndy Ritger }
4061739a20eSAndy Ritger 
4071739a20eSAndy Ritger void
dispapiControl_Epilogue_IMPL(DisplayApi * pDisplayApi,CALL_CONTEXT * pCallContext,RS_RES_CONTROL_PARAMS_INTERNAL * pRmCtrlParams)4081739a20eSAndy Ritger dispapiControl_Epilogue_IMPL
4091739a20eSAndy Ritger (
4101739a20eSAndy Ritger     DisplayApi                     *pDisplayApi,
4111739a20eSAndy Ritger     CALL_CONTEXT                   *pCallContext,
4121739a20eSAndy Ritger     RS_RES_CONTROL_PARAMS_INTERNAL *pRmCtrlParams
4131739a20eSAndy Ritger )
4141739a20eSAndy Ritger {
4151739a20eSAndy Ritger     if (dynamicCast(pDisplayApi, DispCommon) == NULL)
4161739a20eSAndy Ritger     {
4171739a20eSAndy Ritger         RmResource *pResource = staticCast(pDisplayApi, RmResource);
4181739a20eSAndy Ritger         pResource->rpcGpuInstance = ~0;
4191739a20eSAndy Ritger     }
4201739a20eSAndy Ritger 
4211739a20eSAndy Ritger     pDisplayApi->pGpuInRmctrl = NULL;
4221739a20eSAndy Ritger }
4231739a20eSAndy Ritger 
4241739a20eSAndy Ritger NV_STATUS
dispapiControl_IMPL(DisplayApi * pDisplayApi,CALL_CONTEXT * pCallContext,RS_RES_CONTROL_PARAMS_INTERNAL * pParams)4251739a20eSAndy Ritger dispapiControl_IMPL
4261739a20eSAndy Ritger (
4271739a20eSAndy Ritger     DisplayApi                     *pDisplayApi,
4281739a20eSAndy Ritger     CALL_CONTEXT                   *pCallContext,
4291739a20eSAndy Ritger     RS_RES_CONTROL_PARAMS_INTERNAL *pParams
4301739a20eSAndy Ritger )
4311739a20eSAndy Ritger {
4321739a20eSAndy Ritger     Intr             *pIntr;
4331739a20eSAndy Ritger     NV_STATUS         status        = NV_OK;
4341739a20eSAndy Ritger     Device           *pDevice       = dynamicCast(pCallContext->pResourceRef->pParentRef->pResource, Device);
4351739a20eSAndy Ritger     GpuResource      *pGpuResource  = staticCast(pDevice, GpuResource);
4361739a20eSAndy Ritger     RmCtrlParams     *pRmCtrlParams = pParams->pLegacyParams;
4371739a20eSAndy Ritger     OBJGPU           *pGpu          = pGpuResource->pGpu;
4381739a20eSAndy Ritger 
4391739a20eSAndy Ritger     NV_PRINTF(LEVEL_INFO, "class: 0x%x cmd 0x%x\n",
4401739a20eSAndy Ritger               RES_GET_EXT_CLASS_ID(pDisplayApi),
4411739a20eSAndy Ritger               pRmCtrlParams->cmd);
4421739a20eSAndy Ritger 
4431739a20eSAndy Ritger     pRmCtrlParams->pGpu    = pGpu;
4441739a20eSAndy Ritger     pRmCtrlParams->pGpuGrp = pGpuResource->pGpuGrp;
4451739a20eSAndy Ritger 
4461739a20eSAndy Ritger     gpuSetThreadBcState(pGpu, NV_TRUE);
4471739a20eSAndy Ritger 
4481739a20eSAndy Ritger     pIntr = GPU_GET_INTR(pGpu);
4491739a20eSAndy Ritger     if (pIntr != NULL)
4501739a20eSAndy Ritger     {
4511739a20eSAndy Ritger         bitVectorClrAll(&pIntr->helperEngineMask);
4521739a20eSAndy Ritger         bitVectorSet(&pIntr->helperEngineMask, MC_ENGINE_IDX_GR);
4531739a20eSAndy Ritger         bitVectorSet(&pIntr->helperEngineMask, MC_ENGINE_IDX_DISP);
4541739a20eSAndy Ritger         bitVectorSet(&pIntr->helperEngineMask, MC_ENGINE_IDX_FIFO);
4551739a20eSAndy Ritger     }
4561739a20eSAndy Ritger 
4571739a20eSAndy Ritger     status = resControl_IMPL(staticCast(pDisplayApi, RsResource),
4581739a20eSAndy Ritger                                 pCallContext, pParams);
4591739a20eSAndy Ritger 
4601739a20eSAndy Ritger     if (pIntr != NULL)
4611739a20eSAndy Ritger     {
4621739a20eSAndy Ritger         bitVectorClrAll(&pIntr->helperEngineMask);
4631739a20eSAndy Ritger     }
4641739a20eSAndy Ritger 
4651739a20eSAndy Ritger     return status;
4661739a20eSAndy Ritger }
4671739a20eSAndy Ritger 
4681739a20eSAndy Ritger NV_STATUS
dispswobjConstruct_IMPL(DispSwObj * pDispSwObj,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)4691739a20eSAndy Ritger dispswobjConstruct_IMPL
4701739a20eSAndy Ritger (
4711739a20eSAndy Ritger     DispSwObj                    *pDispSwObj,
4721739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
4731739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
4741739a20eSAndy Ritger )
4751739a20eSAndy Ritger {
4761739a20eSAndy Ritger     return NV_OK;
4771739a20eSAndy Ritger }
4781739a20eSAndy Ritger 
4791739a20eSAndy Ritger NV_STATUS
dispcmnConstruct_IMPL(DispCommon * pDispCommon,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)4801739a20eSAndy Ritger dispcmnConstruct_IMPL
4811739a20eSAndy Ritger (
4821739a20eSAndy Ritger     DispCommon                   *pDispCommon,
4831739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
4841739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
4851739a20eSAndy Ritger )
4861739a20eSAndy Ritger {
4871739a20eSAndy Ritger     DisplayApi *pDisplayApi = staticCast(pDispCommon, DisplayApi);
4881739a20eSAndy Ritger 
4891739a20eSAndy Ritger     //
4901739a20eSAndy Ritger     // Not adding the priv-level check for this class
4911739a20eSAndy Ritger     // as it is being used by OpenGL from userspace.Once the Cleanup is done from the OpenGL
4921739a20eSAndy Ritger     // we can add the priv level check here  below
4931739a20eSAndy Ritger     //
4941739a20eSAndy Ritger 
4951739a20eSAndy Ritger     pDispCommon->hotPlugMaskToBeReported = 0;
4961739a20eSAndy Ritger     pDispCommon->hotUnplugMaskToBeReported = 0;
4971739a20eSAndy Ritger 
4981739a20eSAndy Ritger     return _dispapiNotifierInit(pDisplayApi,
4991739a20eSAndy Ritger                                 NV0073_NOTIFIERS_MAXCOUNT,
5001739a20eSAndy Ritger                                 NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE);
5011739a20eSAndy Ritger }
5021739a20eSAndy Ritger 
5031739a20eSAndy Ritger NV_STATUS
dispcmnGetByHandle_IMPL(RsClient * pClient,NvHandle hDispCommon,DispCommon ** ppDispCommon)5041739a20eSAndy Ritger dispcmnGetByHandle_IMPL
5051739a20eSAndy Ritger (
5061739a20eSAndy Ritger     RsClient    *pClient,
5071739a20eSAndy Ritger     NvHandle     hDispCommon,
5081739a20eSAndy Ritger     DispCommon **ppDispCommon
5091739a20eSAndy Ritger )
5101739a20eSAndy Ritger {
5111739a20eSAndy Ritger     NV_STATUS      status;
5121739a20eSAndy Ritger     RsResourceRef *pResourceRef;
5131739a20eSAndy Ritger 
5141739a20eSAndy Ritger     status = clientGetResourceRef(pClient, hDispCommon, &pResourceRef);
5151739a20eSAndy Ritger     if (status != NV_OK)
5161739a20eSAndy Ritger         return status;
5171739a20eSAndy Ritger 
5181739a20eSAndy Ritger     *ppDispCommon = dynamicCast(pResourceRef->pResource, DispCommon);
5191739a20eSAndy Ritger 
5201739a20eSAndy Ritger     return (*ppDispCommon) ? NV_OK : NV_ERR_INVALID_OBJECT_HANDLE;
5211739a20eSAndy Ritger }
5221739a20eSAndy Ritger 
5231739a20eSAndy Ritger void
dispcmnGetByDevice_IMPL(RsClient * pClient,NvHandle hDevice,DispCommon ** ppDispCommon)5241739a20eSAndy Ritger dispcmnGetByDevice_IMPL
5251739a20eSAndy Ritger (
5261739a20eSAndy Ritger     RsClient    *pClient,
5271739a20eSAndy Ritger     NvHandle     hDevice,
5281739a20eSAndy Ritger     DispCommon **ppDispCommon
5291739a20eSAndy Ritger )
5301739a20eSAndy Ritger {
5311739a20eSAndy Ritger     Device        *pDevice;
5321739a20eSAndy Ritger     RsResourceRef *pResourceRef;
5331739a20eSAndy Ritger 
5341739a20eSAndy Ritger     *ppDispCommon = NULL; /* return failure by default */
5351739a20eSAndy Ritger 
5361739a20eSAndy Ritger     if (deviceGetByHandle(pClient, hDevice, &pDevice) != NV_OK)
5371739a20eSAndy Ritger         return;
5381739a20eSAndy Ritger 
5391739a20eSAndy Ritger     if (refFindChildOfType(RES_GET_REF(pDevice),
5401739a20eSAndy Ritger                            classId(DispCommon),
5411739a20eSAndy Ritger                            NV_FALSE,
5421739a20eSAndy Ritger                            &pResourceRef) != NV_OK)
5431739a20eSAndy Ritger         return;
5441739a20eSAndy Ritger 
5451739a20eSAndy Ritger     *ppDispCommon = dynamicCast(pResourceRef->pResource, DispCommon);
5461739a20eSAndy Ritger }
5471739a20eSAndy Ritger 
5481739a20eSAndy Ritger /**
5491739a20eSAndy Ritger  * @brief Return NV_TRUE if RmFree() needs to preserve the HW, otherwise NV_FALSE
5501739a20eSAndy Ritger  *
5511739a20eSAndy Ritger  * @param[in] DispObject Pointer
5521739a20eSAndy Ritger  */
dispobjGetRmFreeFlags_IMPL(DispObject * pDispObject)5531739a20eSAndy Ritger NvBool dispobjGetRmFreeFlags_IMPL(DispObject *pDispObject)
5541739a20eSAndy Ritger {
5551739a20eSAndy Ritger     return !!(pDispObject->rmFreeFlags & NV5070_CTRL_SET_RMFREE_FLAGS_PRESERVE_HW);
5561739a20eSAndy Ritger }
5571739a20eSAndy Ritger 
5581739a20eSAndy Ritger /**
5591739a20eSAndy Ritger  * @brief Clears the RmFree() temporary flags
5601739a20eSAndy Ritger  *
5611739a20eSAndy Ritger  * @param[in] DispObject Pointer
5621739a20eSAndy Ritger  *
5631739a20eSAndy Ritger  * @return void
5641739a20eSAndy Ritger  */
dispobjClearRmFreeFlags_IMPL(DispObject * pDispObject)5651739a20eSAndy Ritger void dispobjClearRmFreeFlags_IMPL(DispObject *pDispObject)
5661739a20eSAndy Ritger {
5671739a20eSAndy Ritger     pDispObject->rmFreeFlags  = NV5070_CTRL_SET_RMFREE_FLAGS_NONE;
5681739a20eSAndy Ritger }
5691739a20eSAndy Ritger 
5701739a20eSAndy Ritger NV_STATUS
nvdispapiConstruct_IMPL(NvDispApi * pNvdispApi,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)5711739a20eSAndy Ritger nvdispapiConstruct_IMPL
5721739a20eSAndy Ritger (
5731739a20eSAndy Ritger     NvDispApi                    *pNvdispApi,
5741739a20eSAndy Ritger     CALL_CONTEXT                 *pCallContext,
5751739a20eSAndy Ritger     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
5761739a20eSAndy Ritger )
5771739a20eSAndy Ritger {
5781739a20eSAndy Ritger     return NV_OK;
5791739a20eSAndy Ritger }
5801739a20eSAndy Ritger 
5811739a20eSAndy Ritger // ****************************************************************************
5821739a20eSAndy Ritger //                            Deprecated Functions
5831739a20eSAndy Ritger // ****************************************************************************
5841739a20eSAndy Ritger 
5851739a20eSAndy Ritger /**
5861739a20eSAndy Ritger  * @warning This function is deprecated! Please use dispchnGetByHandle.
5871739a20eSAndy Ritger  */
5881739a20eSAndy Ritger NV_STATUS
CliFindDispChannelInfo(NvHandle hClient,NvHandle hDispChannel,DispChannel ** ppDispChannel,NvHandle * phParent)5891739a20eSAndy Ritger CliFindDispChannelInfo
5901739a20eSAndy Ritger (
5911739a20eSAndy Ritger     NvHandle       hClient,
5921739a20eSAndy Ritger     NvHandle       hDispChannel,
5931739a20eSAndy Ritger     DispChannel  **ppDispChannel,
5941739a20eSAndy Ritger     NvHandle      *phParent
5951739a20eSAndy Ritger )
5961739a20eSAndy Ritger {
5971739a20eSAndy Ritger     RsClient   *pClient;
5981739a20eSAndy Ritger     NV_STATUS   status;
5991739a20eSAndy Ritger 
6001739a20eSAndy Ritger     *ppDispChannel = NULL;
6011739a20eSAndy Ritger 
6021739a20eSAndy Ritger     status = serverGetClientUnderLock(&g_resServ, hClient, &pClient);
6031739a20eSAndy Ritger     if (status != NV_OK)
6041739a20eSAndy Ritger         return NV_ERR_INVALID_CLIENT;
6051739a20eSAndy Ritger 
6061739a20eSAndy Ritger     status = dispchnGetByHandle(pClient, hDispChannel, ppDispChannel);
6071739a20eSAndy Ritger     if (status != NV_OK)
6081739a20eSAndy Ritger         return status;
6091739a20eSAndy Ritger 
6101739a20eSAndy Ritger     if (phParent)
6111739a20eSAndy Ritger         *phParent = RES_GET_PARENT_HANDLE(*ppDispChannel);
6121739a20eSAndy Ritger 
6131739a20eSAndy Ritger     return NV_OK;
6141739a20eSAndy Ritger }
6151739a20eSAndy Ritger 
6161739a20eSAndy Ritger /**
6171739a20eSAndy Ritger  * @warning This function is deprecated! Please use dispcmnGetByHandle.
6181739a20eSAndy Ritger  */
6191739a20eSAndy Ritger NvBool
CliGetDispCommonInfo(NvHandle hClient,NvHandle hDispCommon,DisplayApi ** ppDisplayApi)6201739a20eSAndy Ritger CliGetDispCommonInfo
6211739a20eSAndy Ritger (
6221739a20eSAndy Ritger     NvHandle     hClient,
6231739a20eSAndy Ritger     NvHandle     hDispCommon,
6241739a20eSAndy Ritger     DisplayApi **ppDisplayApi
6251739a20eSAndy Ritger )
6261739a20eSAndy Ritger {
6271739a20eSAndy Ritger     RsClient   *pClient;
6281739a20eSAndy Ritger     NV_STATUS   status;
6291739a20eSAndy Ritger     DispCommon *pDispCommon;
6301739a20eSAndy Ritger 
6311739a20eSAndy Ritger     *ppDisplayApi = NULL;
6321739a20eSAndy Ritger 
6331739a20eSAndy Ritger     status = serverGetClientUnderLock(&g_resServ, hClient, &pClient);
6341739a20eSAndy Ritger     if (status != NV_OK)
6351739a20eSAndy Ritger         return NV_FALSE;
6361739a20eSAndy Ritger 
6371739a20eSAndy Ritger     status = dispcmnGetByHandle(pClient, hDispCommon, &pDispCommon);
6381739a20eSAndy Ritger     if (status != NV_OK)
6391739a20eSAndy Ritger         return NV_FALSE;
6401739a20eSAndy Ritger 
6411739a20eSAndy Ritger     *ppDisplayApi = staticCast(pDispCommon, DisplayApi);
6421739a20eSAndy Ritger 
6431739a20eSAndy Ritger     return NV_TRUE;
6441739a20eSAndy Ritger }
6451739a20eSAndy Ritger 
6461739a20eSAndy Ritger /**
6471739a20eSAndy Ritger  * @warning This function is deprecated! Please use dispobjGetByHandle.
6481739a20eSAndy Ritger  */
6491739a20eSAndy Ritger NvBool
CliGetDispInfo(NvHandle hClient,NvHandle hObject,DisplayApi ** pDisplayApi)6501739a20eSAndy Ritger CliGetDispInfo
6511739a20eSAndy Ritger (
6521739a20eSAndy Ritger     NvHandle     hClient,
6531739a20eSAndy Ritger     NvHandle     hObject,
6541739a20eSAndy Ritger     DisplayApi **pDisplayApi
6551739a20eSAndy Ritger )
6561739a20eSAndy Ritger {
6571739a20eSAndy Ritger     if (!pDisplayApi)
6581739a20eSAndy Ritger         return NV_FALSE;
6591739a20eSAndy Ritger 
6601739a20eSAndy Ritger     *pDisplayApi = CliGetDispFromDispHandle(hClient, hObject);
6611739a20eSAndy Ritger 
6621739a20eSAndy Ritger     return *pDisplayApi ? NV_TRUE : NV_FALSE;
6631739a20eSAndy Ritger }
6641739a20eSAndy Ritger 
6651739a20eSAndy Ritger /**
6661739a20eSAndy Ritger  * @warning This function is deprecated! Please use dispobjGetByHandle.
6671739a20eSAndy Ritger  */
6681739a20eSAndy Ritger DisplayApi *
CliGetDispFromDispHandle(NvHandle hClient,NvHandle hDisp)6691739a20eSAndy Ritger CliGetDispFromDispHandle
6701739a20eSAndy Ritger (
6711739a20eSAndy Ritger     NvHandle hClient,
6721739a20eSAndy Ritger     NvHandle hDisp
6731739a20eSAndy Ritger )
6741739a20eSAndy Ritger {
6751739a20eSAndy Ritger     RsClient   *pClient;
6761739a20eSAndy Ritger     NV_STATUS   status;
6771739a20eSAndy Ritger     DispObject *pDispObject;
6781739a20eSAndy Ritger 
6791739a20eSAndy Ritger     status = serverGetClientUnderLock(&g_resServ, hClient, &pClient);
6801739a20eSAndy Ritger     if (status != NV_OK)
6811739a20eSAndy Ritger         return NULL;
6821739a20eSAndy Ritger 
6831739a20eSAndy Ritger     status = dispobjGetByHandle(pClient, hDisp, &pDispObject);
6841739a20eSAndy Ritger     if (status != NV_OK)
6851739a20eSAndy Ritger         return NULL;
6861739a20eSAndy Ritger 
6871739a20eSAndy Ritger     return staticCast(pDispObject, DisplayApi);
6881739a20eSAndy Ritger }
6891739a20eSAndy Ritger 
6901739a20eSAndy Ritger //
6911739a20eSAndy Ritger // DISP Event RM Controls
6921739a20eSAndy Ritger //
6931739a20eSAndy Ritger NV_STATUS
dispapiCtrlCmdEventSetNotification_IMPL(DisplayApi * pDisplayApi,NV5070_CTRL_EVENT_SET_NOTIFICATION_PARAMS * pSetEventParams)6941739a20eSAndy Ritger dispapiCtrlCmdEventSetNotification_IMPL
6951739a20eSAndy Ritger (
6961739a20eSAndy Ritger     DisplayApi *pDisplayApi,
6971739a20eSAndy Ritger     NV5070_CTRL_EVENT_SET_NOTIFICATION_PARAMS *pSetEventParams
6981739a20eSAndy Ritger )
6991739a20eSAndy Ritger {
7001739a20eSAndy Ritger     OBJGPU *pGpu = DISPAPI_GET_GPU(pDisplayApi);
7011739a20eSAndy Ritger     NvU32 *pNotifyActions;
7021739a20eSAndy Ritger     NV_STATUS status = NV_OK;
7031739a20eSAndy Ritger     PEVENTNOTIFICATION pEventNotifications = inotifyGetNotificationList(staticCast(pDisplayApi, INotifier));
7041739a20eSAndy Ritger 
7051739a20eSAndy Ritger     // NV01_EVENT must have been plugged into this subdevice
7061739a20eSAndy Ritger     if (pEventNotifications == NULL)
7071739a20eSAndy Ritger     {
7081739a20eSAndy Ritger         NV_PRINTF(LEVEL_INFO, "cmd 0x%x: no event list\n", NV5070_CTRL_CMD_EVENT_SET_NOTIFICATION);
7091739a20eSAndy Ritger         return NV_ERR_INVALID_STATE;
7101739a20eSAndy Ritger     }
7111739a20eSAndy Ritger 
7121739a20eSAndy Ritger     // error check event index
7131739a20eSAndy Ritger     if (pSetEventParams->event >= pDisplayApi->numNotifiers)
7141739a20eSAndy Ritger     {
7151739a20eSAndy Ritger         NV_PRINTF(LEVEL_INFO, "bad event 0x%x\n", pSetEventParams->event);
7161739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
7171739a20eSAndy Ritger     }
7181739a20eSAndy Ritger 
7191739a20eSAndy Ritger     // error check subDeviceInstance
7201739a20eSAndy Ritger     if (pSetEventParams->subDeviceInstance >= gpumgrGetSubDeviceMaxValuePlus1(pGpu))
7211739a20eSAndy Ritger     {
7221739a20eSAndy Ritger         NV_PRINTF(LEVEL_INFO, "bad subDeviceInstance 0x%x\n",
7231739a20eSAndy Ritger                   pSetEventParams->subDeviceInstance);
7241739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
7251739a20eSAndy Ritger     }
7261739a20eSAndy Ritger 
7271739a20eSAndy Ritger     pNotifyActions = pDisplayApi->pNotifyActions[pSetEventParams->subDeviceInstance];
7281739a20eSAndy Ritger 
7291739a20eSAndy Ritger     switch (pSetEventParams->action)
7301739a20eSAndy Ritger     {
7311739a20eSAndy Ritger         case NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_SINGLE:
7321739a20eSAndy Ritger         case NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT:
7331739a20eSAndy Ritger         {
7341739a20eSAndy Ritger             // must be in disabled state to transition to an active state
7351739a20eSAndy Ritger             if (pNotifyActions[pSetEventParams->event] != NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE)
7361739a20eSAndy Ritger             {
7371739a20eSAndy Ritger                 status = NV_ERR_INVALID_STATE;
7381739a20eSAndy Ritger                 break;
7391739a20eSAndy Ritger             }
7401739a20eSAndy Ritger 
7411739a20eSAndy Ritger             // bind hEvent to particular subdeviceInst
7421739a20eSAndy Ritger             status = bindEventNotificationToSubdevice(pEventNotifications,
7431739a20eSAndy Ritger                                                       pSetEventParams->hEvent,
7441739a20eSAndy Ritger                                                       pSetEventParams->subDeviceInstance);
7451739a20eSAndy Ritger             if (status != NV_OK)
7461739a20eSAndy Ritger                 return status;
7471739a20eSAndy Ritger 
7481739a20eSAndy Ritger             pNotifyActions[pSetEventParams->event] = pSetEventParams->action;
7491739a20eSAndy Ritger             break;
7501739a20eSAndy Ritger         }
7511739a20eSAndy Ritger 
7521739a20eSAndy Ritger         case NV5070_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE:
7531739a20eSAndy Ritger         {
7541739a20eSAndy Ritger             pNotifyActions[pSetEventParams->event] = pSetEventParams->action;
7551739a20eSAndy Ritger             break;
7561739a20eSAndy Ritger         }
7571739a20eSAndy Ritger         default:
7581739a20eSAndy Ritger         {
7591739a20eSAndy Ritger             status = NV_ERR_INVALID_ARGUMENT;
7601739a20eSAndy Ritger             break;
7611739a20eSAndy Ritger         }
7621739a20eSAndy Ritger     }
7631739a20eSAndy Ritger 
7641739a20eSAndy Ritger     return status;
7651739a20eSAndy Ritger }
766