2 * Copyright (C) 2008 Maarten Maathuis.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a 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:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
31 #include "nouveau_reg.h"
32 #include "nouveau_drv.h"
33 #include "nouveau_crtc.h"
34 #include "nv50_display.h"
37 nv50_cursor_show(struct nouveau_crtc
*nv_crtc
, bool update
)
39 struct drm_device
*dev
= nv_crtc
->base
.dev
;
40 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
41 struct nouveau_channel
*evo
= nv50_display(dev
)->master
;
44 NV_DEBUG_KMS(dev
, "\n");
46 if (update
&& nv_crtc
->cursor
.visible
)
49 ret
= RING_SPACE(evo
, (dev_priv
->chipset
!= 0x50 ? 5 : 3) + update
* 2);
51 NV_ERROR(dev
, "no space while unhiding cursor\n");
55 if (dev_priv
->chipset
!= 0x50) {
56 BEGIN_RING(evo
, 0, NV84_EVO_CRTC(nv_crtc
->index
, CURSOR_DMA
), 1);
57 OUT_RING(evo
, NvEvoVRAM
);
59 BEGIN_RING(evo
, 0, NV50_EVO_CRTC(nv_crtc
->index
, CURSOR_CTRL
), 2);
60 OUT_RING(evo
, NV50_EVO_CRTC_CURSOR_CTRL_SHOW
);
61 OUT_RING(evo
, nv_crtc
->cursor
.offset
>> 8);
64 BEGIN_RING(evo
, 0, NV50_EVO_UPDATE
, 1);
67 nv_crtc
->cursor
.visible
= true;
72 nv50_cursor_hide(struct nouveau_crtc
*nv_crtc
, bool update
)
74 struct drm_device
*dev
= nv_crtc
->base
.dev
;
75 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
76 struct nouveau_channel
*evo
= nv50_display(dev
)->master
;
79 NV_DEBUG_KMS(dev
, "\n");
81 if (update
&& !nv_crtc
->cursor
.visible
)
84 ret
= RING_SPACE(evo
, (dev_priv
->chipset
!= 0x50 ? 5 : 3) + update
* 2);
86 NV_ERROR(dev
, "no space while hiding cursor\n");
89 BEGIN_RING(evo
, 0, NV50_EVO_CRTC(nv_crtc
->index
, CURSOR_CTRL
), 2);
90 OUT_RING(evo
, NV50_EVO_CRTC_CURSOR_CTRL_HIDE
);
92 if (dev_priv
->chipset
!= 0x50) {
93 BEGIN_RING(evo
, 0, NV84_EVO_CRTC(nv_crtc
->index
, CURSOR_DMA
), 1);
94 OUT_RING(evo
, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE
);
98 BEGIN_RING(evo
, 0, NV50_EVO_UPDATE
, 1);
101 nv_crtc
->cursor
.visible
= false;
106 nv50_cursor_set_pos(struct nouveau_crtc
*nv_crtc
, int x
, int y
)
108 struct drm_device
*dev
= nv_crtc
->base
.dev
;
110 nv_crtc
->cursor_saved_x
= x
; nv_crtc
->cursor_saved_y
= y
;
111 nv_wr32(dev
, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc
->index
),
112 ((y
& 0xFFFF) << 16) | (x
& 0xFFFF));
113 /* Needed to make the cursor move. */
114 nv_wr32(dev
, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc
->index
), 0);
118 nv50_cursor_set_offset(struct nouveau_crtc
*nv_crtc
, uint32_t offset
)
120 NV_DEBUG_KMS(nv_crtc
->base
.dev
, "\n");
121 if (offset
== nv_crtc
->cursor
.offset
)
124 nv_crtc
->cursor
.offset
= offset
;
125 if (nv_crtc
->cursor
.visible
) {
126 nv_crtc
->cursor
.visible
= false;
127 nv_crtc
->cursor
.show(nv_crtc
, true);
132 nv50_cursor_init(struct nouveau_crtc
*nv_crtc
)
134 nv_crtc
->cursor
.set_offset
= nv50_cursor_set_offset
;
135 nv_crtc
->cursor
.set_pos
= nv50_cursor_set_pos
;
136 nv_crtc
->cursor
.hide
= nv50_cursor_hide
;
137 nv_crtc
->cursor
.show
= nv50_cursor_show
;
142 nv50_cursor_fini(struct nouveau_crtc
*nv_crtc
)
144 struct drm_device
*dev
= nv_crtc
->base
.dev
;
145 int idx
= nv_crtc
->index
;
147 NV_DEBUG_KMS(dev
, "\n");
149 nv_wr32(dev
, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx
), 0);
150 if (!nv_wait(dev
, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx
),
151 NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS
, 0)) {
152 NV_ERROR(dev
, "timeout: CURSOR_CTRL2_STATUS == 0\n");
153 NV_ERROR(dev
, "CURSOR_CTRL2 = 0x%08x\n",
154 nv_rd32(dev
, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx
)));