1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2016 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 <nvkms-types.h>
25 #include <nvkms-utils.h>
26 
27 #include <class/clc37a.h>
28 #include <class/clc57a.h>
29 #include <class/clc67a.h>
30 
WaitForFreeSpace(NVDevEvoPtr pDevEvo,NVC37ADispCursorImmControlPio * pEvoCursorControl)31 static void WaitForFreeSpace(NVDevEvoPtr pDevEvo,
32                              NVC37ADispCursorImmControlPio *pEvoCursorControl)
33 {
34     /*
35      * Wait for Free to be non-zero, indicating there is space to push a method.
36      * The only case where Free is expected to be zero is when display
37      * frontend (FE) hardware is processing a previous method.
38      * .1s should be more than enough time to wait for that.
39      */
40     NvU64 startTime = 0;
41     const NvU64 timeout = 100000; /* 0.1 seconds */
42 
43     do {
44         if (pEvoCursorControl->Free != 0) {
45             return;
46         }
47 
48         if (nvExceedsTimeoutUSec(pDevEvo, &startTime, timeout)) {
49             break;
50         }
51 
52         nvkms_yield();
53 
54     } while (TRUE);
55 
56     nvEvoLogDevDebug(pDevEvo, EVO_LOG_ERROR,
57                      "Timed out waiting for cursor PIO space");
58 }
59 
MoveCursorC3(NVDevEvoPtr pDevEvo,NvU32 sd,NvU32 head,NvS16 x,NvS16 y)60 static void MoveCursorC3(NVDevEvoPtr pDevEvo, NvU32 sd, NvU32 head,
61                          NvS16 x, NvS16 y)
62 {
63     NVEvoSubDevPtr pEvoSubDev = &pDevEvo->gpus[sd];
64     NVC37ADispCursorImmControlPio *pEvoCursorControl =
65         pEvoSubDev->cursorPio[head];
66 
67     WaitForFreeSpace(pDevEvo, pEvoCursorControl);
68     pEvoCursorControl->SetCursorHotSpotPointOut[0] =
69             DRF_NUM(C37A, _SET_CURSOR_HOT_SPOT_POINT_OUT, _X, x) |
70             DRF_NUM(C37A, _SET_CURSOR_HOT_SPOT_POINT_OUT, _Y, y);
71 
72     WaitForFreeSpace(pDevEvo, pEvoCursorControl);
73     pEvoCursorControl->Update =
74             DRF_DEF(C37A, _UPDATE, _FLIP_LOCK_PIN, _LOCK_PIN_NONE);
75 }
76 
ReleaseElvC3(NVDevEvoPtr pDevEvo,NvU32 sd,NvU32 head)77 static void ReleaseElvC3(NVDevEvoPtr pDevEvo, NvU32 sd, NvU32 head)
78 {
79     NVEvoSubDevPtr pEvoSubDev = &pDevEvo->gpus[sd];
80     NVC37ADispCursorImmControlPio *pEvoCursorControl =
81         pEvoSubDev->cursorPio[head];
82 
83     WaitForFreeSpace(pDevEvo, pEvoCursorControl);
84     pEvoCursorControl->Update =
85             DRF_DEF(C37A, _UPDATE, _FLIP_LOCK_PIN, _LOCK_PIN_NONE) |
86             DRF_DEF(C37A, _UPDATE, _RELEASE_ELV, _TRUE);
87 }
88 
89 NVEvoCursorHAL nvEvoCursorC3 = {
90     NVC37A_CURSOR_IMM_CHANNEL_PIO,              /* klass */
91     MoveCursorC3,                               /* MoveCursor */
92     ReleaseElvC3,                               /* ReleaseElv */
93     {                                           /* caps */
94         256,                                    /* maxSize */
95     },
96 };
97 
98 NVEvoCursorHAL nvEvoCursorC5 = {
99     NVC57A_CURSOR_IMM_CHANNEL_PIO,              /* klass */
100     MoveCursorC3,                               /* MoveCursor */
101     ReleaseElvC3,                               /* ReleaseElv */
102     {                                           /* caps */
103         256,                                    /* maxSize */
104     },
105 };
106 
107 NVEvoCursorHAL nvEvoCursorC6 = {
108     NVC67A_CURSOR_IMM_CHANNEL_PIO,              /* klass */
109     MoveCursorC3,                               /* MoveCursor */
110     ReleaseElvC3,                               /* ReleaseElv */
111     {                                           /* caps */
112         256,                                    /* maxSize */
113     },
114 };
115 
116