diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/gpu/drm/nouveau/nv50_cursor.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_cursor.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_cursor.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c new file mode 100644 index 00000000000..9752c35bb84 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_cursor.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Maarten Maathuis. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
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: | ||
12 | * | ||
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. | ||
16 | * | ||
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. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "drmP.h" | ||
28 | #include "drm_mode.h" | ||
29 | |||
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" | ||
35 | |||
36 | static void | ||
37 | nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) | ||
38 | { | ||
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; | ||
42 | int ret; | ||
43 | |||
44 | NV_DEBUG_KMS(dev, "\n"); | ||
45 | |||
46 | if (update && nv_crtc->cursor.visible) | ||
47 | return; | ||
48 | |||
49 | ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2); | ||
50 | if (ret) { | ||
51 | NV_ERROR(dev, "no space while unhiding cursor\n"); | ||
52 | return; | ||
53 | } | ||
54 | |||
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); | ||
58 | } | ||
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); | ||
62 | |||
63 | if (update) { | ||
64 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
65 | OUT_RING(evo, 0); | ||
66 | FIRE_RING(evo); | ||
67 | nv_crtc->cursor.visible = true; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static void | ||
72 | nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) | ||
73 | { | ||
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; | ||
77 | int ret; | ||
78 | |||
79 | NV_DEBUG_KMS(dev, "\n"); | ||
80 | |||
81 | if (update && !nv_crtc->cursor.visible) | ||
82 | return; | ||
83 | |||
84 | ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2); | ||
85 | if (ret) { | ||
86 | NV_ERROR(dev, "no space while hiding cursor\n"); | ||
87 | return; | ||
88 | } | ||
89 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2); | ||
90 | OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE); | ||
91 | OUT_RING(evo, 0); | ||
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); | ||
95 | } | ||
96 | |||
97 | if (update) { | ||
98 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
99 | OUT_RING(evo, 0); | ||
100 | FIRE_RING(evo); | ||
101 | nv_crtc->cursor.visible = false; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) | ||
107 | { | ||
108 | struct drm_device *dev = nv_crtc->base.dev; | ||
109 | |||
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); | ||
115 | } | ||
116 | |||
117 | static void | ||
118 | nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) | ||
119 | { | ||
120 | NV_DEBUG_KMS(nv_crtc->base.dev, "\n"); | ||
121 | if (offset == nv_crtc->cursor.offset) | ||
122 | return; | ||
123 | |||
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); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | int | ||
132 | nv50_cursor_init(struct nouveau_crtc *nv_crtc) | ||
133 | { | ||
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; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | void | ||
142 | nv50_cursor_fini(struct nouveau_crtc *nv_crtc) | ||
143 | { | ||
144 | struct drm_device *dev = nv_crtc->base.dev; | ||
145 | int idx = nv_crtc->index; | ||
146 | |||
147 | NV_DEBUG_KMS(dev, "\n"); | ||
148 | |||
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))); | ||
155 | } | ||
156 | } | ||
157 | |||