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 #include "nouveau_drm.h"
31 #include "nouveau_dma.h"
32 #include "nouveau_crtc.h"
33 #include "nv50_display.h"
36 nv50_cursor_show(struct nouveau_crtc
*nv_crtc
, bool update
)
38 struct drm_device
*dev
= nv_crtc
->base
.dev
;
39 struct nouveau_drm
*drm
= nouveau_drm(dev
);
40 struct nouveau_channel
*evo
= nv50_display(dev
)->master
;
45 if (update
&& nv_crtc
->cursor
.visible
)
48 ret
= RING_SPACE(evo
, (nv_device(drm
->device
)->chipset
!= 0x50 ? 5 : 3) + update
* 2);
50 NV_ERROR(drm
, "no space while unhiding cursor\n");
54 if (nv_device(drm
->device
)->chipset
!= 0x50) {
55 BEGIN_NV04(evo
, 0, NV84_EVO_CRTC(nv_crtc
->index
, CURSOR_DMA
), 1);
56 OUT_RING(evo
, NvEvoVRAM
);
58 BEGIN_NV04(evo
, 0, NV50_EVO_CRTC(nv_crtc
->index
, CURSOR_CTRL
), 2);
59 OUT_RING(evo
, NV50_EVO_CRTC_CURSOR_CTRL_SHOW
);
60 OUT_RING(evo
, nv_crtc
->cursor
.offset
>> 8);
63 BEGIN_NV04(evo
, 0, NV50_EVO_UPDATE
, 1);
66 nv_crtc
->cursor
.visible
= true;
71 nv50_cursor_hide(struct nouveau_crtc
*nv_crtc
, bool update
)
73 struct drm_device
*dev
= nv_crtc
->base
.dev
;
74 struct nouveau_drm
*drm
= nouveau_drm(dev
);
75 struct nouveau_channel
*evo
= nv50_display(dev
)->master
;
80 if (update
&& !nv_crtc
->cursor
.visible
)
83 ret
= RING_SPACE(evo
, (nv_device(drm
->device
)->chipset
!= 0x50 ? 5 : 3) + update
* 2);
85 NV_ERROR(drm
, "no space while hiding cursor\n");
88 BEGIN_NV04(evo
, 0, NV50_EVO_CRTC(nv_crtc
->index
, CURSOR_CTRL
), 2);
89 OUT_RING(evo
, NV50_EVO_CRTC_CURSOR_CTRL_HIDE
);
91 if (nv_device(drm
->device
)->chipset
!= 0x50) {
92 BEGIN_NV04(evo
, 0, NV84_EVO_CRTC(nv_crtc
->index
, CURSOR_DMA
), 1);
93 OUT_RING(evo
, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE
);
97 BEGIN_NV04(evo
, 0, NV50_EVO_UPDATE
, 1);
100 nv_crtc
->cursor
.visible
= false;
105 nv50_cursor_set_pos(struct nouveau_crtc
*nv_crtc
, int x
, int y
)
107 struct nouveau_device
*device
= nouveau_dev(nv_crtc
->base
.dev
);
109 nv_crtc
->cursor_saved_x
= x
; nv_crtc
->cursor_saved_y
= y
;
110 nv_wr32(device
, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc
->index
),
111 ((y
& 0xFFFF) << 16) | (x
& 0xFFFF));
112 /* Needed to make the cursor move. */
113 nv_wr32(device
, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc
->index
), 0);
117 nv50_cursor_set_offset(struct nouveau_crtc
*nv_crtc
, uint32_t offset
)
119 if (offset
== nv_crtc
->cursor
.offset
)
122 nv_crtc
->cursor
.offset
= offset
;
123 if (nv_crtc
->cursor
.visible
) {
124 nv_crtc
->cursor
.visible
= false;
125 nv_crtc
->cursor
.show(nv_crtc
, true);
130 nv50_cursor_init(struct nouveau_crtc
*nv_crtc
)
132 nv_crtc
->cursor
.set_offset
= nv50_cursor_set_offset
;
133 nv_crtc
->cursor
.set_pos
= nv50_cursor_set_pos
;
134 nv_crtc
->cursor
.hide
= nv50_cursor_hide
;
135 nv_crtc
->cursor
.show
= nv50_cursor_show
;