1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "core/core.h"
25 #include "kernel/gpu/intr/intr.h"
26 #include "gpu/gpu.h"
27 #include "core/locks.h"
28 #include "kernel/gpu/gr/kernel_graphics.h"
29 #include "kernel/gpu/intr/engine_idx.h"
30 #include "gpu/gsp/kernel_gsp.h"
31 #include "resserv/rs_server.h"
32 #include "vgpu/vgpu_events.h"
33 #include "gpu/disp/kern_disp.h"
34 
35 #include "published/maxwell/gm107/dev_boot.h"
36 
37 /**
38  * @brief Returns a bitfield with the MC_ENGINES that have pending interrupts
39  */
40 NV_STATUS
intrGetPendingStall_GM107(OBJGPU * pGpu,Intr * pIntr,MC_ENGINE_BITVECTOR * pEngines,THREAD_STATE_NODE * pThreadState)41 intrGetPendingStall_GM107
42 (
43     OBJGPU              *pGpu,
44     Intr                *pIntr,
45     MC_ENGINE_BITVECTOR *pEngines,
46     THREAD_STATE_NODE   *pThreadState
47 )
48 {
49     KernelDisplay *pKernelDisplay = GPU_GET_KERNEL_DISPLAY(pGpu);
50     KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
51     NvU8 i;
52 
53     NV_ASSERT_OR_RETURN(pEngines != NULL, NV_ERR_INVALID_ARGUMENT);
54 
55     bitVectorClrAll(pEngines);
56 
57     //
58     // If the GPU is in GC6 (aka powered down or rail-gated state), return
59     // early from this routine. We don't want to touch any GPU registers while
60     // its powered off as it will hang the system.
61     //
62     // If the GPU has fallen off the bus, there are obviously no interrupts
63     // pending that we can do anything about, but attempting to read a status
64     // register might indicate otherwise (returning 0xffffffff). Its better to do a GPU
65     // sanity check after we read the status register and bail out if necessary.
66     //
67     if (IS_GPU_GC6_STATE_ENTERED(pGpu))
68     {
69         return NV_ERR_GPU_NOT_FULL_POWER;
70     }
71 
72     NV_ASSERT_OK_OR_RETURN(intrGetPendingStallEngines_HAL(pGpu, pIntr, pEngines, pThreadState));
73 
74     if (!API_GPU_ATTACHED_SANITY_CHECK(pGpu))
75     {
76         return NV_ERR_GPU_IS_LOST;
77     }
78 
79     if (IS_VIRTUAL(pGpu) && vgpuGetPendingEvent(pGpu, pThreadState))
80         bitVectorSet(pEngines, MC_ENGINE_IDX_VGPU);
81 
82     if (pKernelDisplay != NULL && kdispGetDeferredVblankHeadMask(pKernelDisplay))
83     {
84         // Deferred vblank is pending which we need to handle
85         bitVectorSet(pEngines, MC_ENGINE_IDX_DISP);
86     }
87 
88     if ((pKernelGraphicsManager != NULL) && (fecsGetCtxswLogConsumerCount(pGpu, pKernelGraphicsManager) > 0))
89     {
90         //
91         // WARNING: This loop must not call any GR HALs or
92         //          access any PGRAPH registers
93         //
94         for (i = 0; i < GPU_MAX_GRS; i++)
95         {
96             KernelGraphics *pKernelGraphics = pGpu->pKernelGraphics[i];
97             if ((pKernelGraphics != NULL) &&
98                 kgraphicsIsIntrDrivenCtxswLoggingEnabled(pGpu, pKernelGraphics) &&
99                 fecsIsIntrPending(pGpu, pKernelGraphics))
100             {
101                 bitVectorSet(pEngines, MC_ENGINE_IDX_GRn_FECS_LOG(i));
102             }
103         }
104     }
105 
106     return NV_OK;
107 }
108