Forgot a few things.
[nouveau] / src / nv50_cursor.c
1 /*
2  * Copyright (c) 2007 NVIDIA, Corporation
3  * Copyright (c) 2008 Maarten Maathuis
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include <string.h>
26
27 #include <cursorstr.h>
28
29 #include "nv_include.h"
30
31 void NV50CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update)
32 {
33         ScrnInfoPtr pScrn = crtc->scrn;
34         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcShowHideCursor is called (%s, %s).\n", show ? "show" : "hide", update ? "update" : "no update");
35
36         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
37
38         NV50CrtcCommand(crtc, NV50_CRTC0_CURSOR, 
39                 show ? NV50_CRTC0_CURSOR_SHOW : NV50_CRTC0_CURSOR_HIDE);
40         if (update) {
41                 nv_crtc->cursorVisible = show;
42                 NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
43         }
44 }
45
46 void nv50_crtc_show_cursor(xf86CrtcPtr crtc)
47 {
48         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
49
50         /* Calling NV50_UPDATE_DISPLAY during modeset will lock up everything. */
51         if (nv_crtc->modeset_lock)
52                 return;
53
54         NV50CrtcShowHideCursor(crtc, TRUE, TRUE);
55 }
56
57 void nv50_crtc_hide_cursor(xf86CrtcPtr crtc)
58 {
59         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
60
61         /* Calling NV50_UPDATE_DISPLAY during modeset will lock up everything. */
62         if (nv_crtc->modeset_lock)
63                 return;
64
65         NV50CrtcShowHideCursor(crtc, FALSE, TRUE);
66 }
67
68 void nv50_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
69 {
70         NVPtr pNv = NVPTR(crtc->scrn);
71         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
72
73         if (nv_crtc->head == 1)
74                 NVWrite(pNv, NV50_CRTC1_CURSOR_POS, (y & 0xFFFF) << 16 | (x & 0xFFFF));
75         else
76                 NVWrite(pNv, NV50_CRTC0_CURSOR_POS, (y & 0xFFFF) << 16 | (x & 0xFFFF));
77
78         /* This is needed to allow the cursor to move. */
79         NVWrite(pNv, 0x00647080 + nv_crtc->head * 0x1000, 0);
80 }
81
82 void nv50_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *src)
83 {
84         NVPtr pNv = NVPTR(crtc->scrn);
85         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
86         uint32_t *dst = NULL;
87
88         if (nv_crtc->head == 1)
89                 dst = (uint32_t *) pNv->Cursor2->map;
90         else
91                 dst = (uint32_t *) pNv->Cursor->map;
92
93         /* Assume cursor is 64x64 */
94         memcpy(dst, (uint32_t *)src, 64 * 64 * 4);
95 }
96
97 Bool NV50CursorAcquire(ScrnInfoPtr pScrn)
98 {
99         NVPtr pNv = NVPTR(pScrn);
100         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
101         int i;
102
103         if (!pNv->HWCursor) return TRUE;
104
105         /* Initialize the cursor on each head */
106         for(i = 0; i < xf86_config->num_crtc; i++) {
107                 NVCrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
108                 const int headOff = 0x10 * nv_crtc->head;
109
110                 NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL+headOff, 0x2000);
111                 while (NVRead(pNv, NV50_CRTC0_CURSOR_CTRL+headOff) & 0x30000);
112
113                 NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL+headOff, NV50_CRTC_CURSOR_CTRL_ON);
114                 while ((NVRead(pNv, NV50_CRTC0_CURSOR_CTRL+headOff) & 0x30000) != 0x10000);
115         }
116
117         return TRUE;
118 }
119
120 void NV50CursorRelease(ScrnInfoPtr pScrn)
121 {
122         NVPtr pNv = NVPTR(pScrn);
123         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
124         int i;
125
126         if (!pNv->HWCursor) return;
127
128         /* Release the cursor on each head */
129         for(i = 0; i < xf86_config->num_crtc; i++) {
130                 NVCrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
131                 const int headOff = 0x10 * nv_crtc->head;
132
133                 NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL+headOff, NV50_CRTC_CURSOR_CTRL_OFF);
134                 while (NVRead(pNv, NV50_CRTC0_CURSOR_CTRL+headOff) & 0x30000);
135         }
136 }
137
138 Bool NV50CursorInit(ScreenPtr pScreen)
139 {
140         return xf86_cursors_init(pScreen, 64, 64,
141                 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
142                 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
143                 HARDWARE_CURSOR_ARGB);
144 }
145