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