xref: /linux/drivers/gpu/drm/nouveau/nouveau_display.c (revision f2ee442115c9b6219083c019939a9cc0c9abb2f8)
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_crtc_helper.h"
29 #include "nouveau_drv.h"
30 #include "nouveau_fb.h"
31 #include "nouveau_fbcon.h"
32 #include "nouveau_hw.h"
33 #include "nouveau_crtc.h"
34 #include "nouveau_dma.h"
35 #include "nv50_display.h"
36 
37 static void
38 nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
39 {
40 	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
41 
42 	if (fb->nvbo)
43 		drm_gem_object_unreference_unlocked(fb->nvbo->gem);
44 
45 	drm_framebuffer_cleanup(drm_fb);
46 	kfree(fb);
47 }
48 
49 static int
50 nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
51 				       struct drm_file *file_priv,
52 				       unsigned int *handle)
53 {
54 	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
55 
56 	return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle);
57 }
58 
59 static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
60 	.destroy = nouveau_user_framebuffer_destroy,
61 	.create_handle = nouveau_user_framebuffer_create_handle,
62 };
63 
64 int
65 nouveau_framebuffer_init(struct drm_device *dev,
66 			 struct nouveau_framebuffer *nv_fb,
67 			 struct drm_mode_fb_cmd *mode_cmd,
68 			 struct nouveau_bo *nvbo)
69 {
70 	struct drm_nouveau_private *dev_priv = dev->dev_private;
71 	struct drm_framebuffer *fb = &nv_fb->base;
72 	int ret;
73 
74 	ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
75 	if (ret) {
76 		return ret;
77 	}
78 
79 	drm_helper_mode_fill_fb_struct(fb, mode_cmd);
80 	nv_fb->nvbo = nvbo;
81 
82 	if (dev_priv->card_type >= NV_50) {
83 		u32 tile_flags = nouveau_bo_tile_layout(nvbo);
84 		if (tile_flags == 0x7a00 ||
85 		    tile_flags == 0xfe00)
86 			nv_fb->r_dma = NvEvoFB32;
87 		else
88 		if (tile_flags == 0x7000)
89 			nv_fb->r_dma = NvEvoFB16;
90 		else
91 			nv_fb->r_dma = NvEvoVRAM_LP;
92 
93 		switch (fb->depth) {
94 		case  8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break;
95 		case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break;
96 		case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break;
97 		case 24:
98 		case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
99 		case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
100 		default:
101 			 NV_ERROR(dev, "unknown depth %d\n", fb->depth);
102 			 return -EINVAL;
103 		}
104 
105 		if (dev_priv->chipset == 0x50)
106 			nv_fb->r_format |= (tile_flags << 8);
107 
108 		if (!tile_flags) {
109 			if (dev_priv->card_type < NV_D0)
110 				nv_fb->r_pitch = 0x00100000 | fb->pitch;
111 			else
112 				nv_fb->r_pitch = 0x01000000 | fb->pitch;
113 		} else {
114 			u32 mode = nvbo->tile_mode;
115 			if (dev_priv->card_type >= NV_C0)
116 				mode >>= 4;
117 			nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
118 		}
119 	}
120 
121 	return 0;
122 }
123 
124 static struct drm_framebuffer *
125 nouveau_user_framebuffer_create(struct drm_device *dev,
126 				struct drm_file *file_priv,
127 				struct drm_mode_fb_cmd *mode_cmd)
128 {
129 	struct nouveau_framebuffer *nouveau_fb;
130 	struct drm_gem_object *gem;
131 	int ret;
132 
133 	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
134 	if (!gem)
135 		return ERR_PTR(-ENOENT);
136 
137 	nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
138 	if (!nouveau_fb)
139 		return ERR_PTR(-ENOMEM);
140 
141 	ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
142 	if (ret) {
143 		drm_gem_object_unreference(gem);
144 		return ERR_PTR(ret);
145 	}
146 
147 	return &nouveau_fb->base;
148 }
149 
150 const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
151 	.fb_create = nouveau_user_framebuffer_create,
152 	.output_poll_changed = nouveau_fbcon_output_poll_changed,
153 };
154 
155 int
156 nouveau_vblank_enable(struct drm_device *dev, int crtc)
157 {
158 	struct drm_nouveau_private *dev_priv = dev->dev_private;
159 
160 	if (dev_priv->card_type >= NV_50)
161 		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
162 			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc));
163 	else
164 		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0,
165 			    NV_PCRTC_INTR_0_VBLANK);
166 
167 	return 0;
168 }
169 
170 void
171 nouveau_vblank_disable(struct drm_device *dev, int crtc)
172 {
173 	struct drm_nouveau_private *dev_priv = dev->dev_private;
174 
175 	if (dev_priv->card_type >= NV_50)
176 		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1,
177 			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0);
178 	else
179 		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0);
180 }
181 
182 static int
183 nouveau_page_flip_reserve(struct nouveau_bo *old_bo,
184 			  struct nouveau_bo *new_bo)
185 {
186 	int ret;
187 
188 	ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
189 	if (ret)
190 		return ret;
191 
192 	ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0);
193 	if (ret)
194 		goto fail;
195 
196 	ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
197 	if (ret)
198 		goto fail_unreserve;
199 
200 	return 0;
201 
202 fail_unreserve:
203 	ttm_bo_unreserve(&new_bo->bo);
204 fail:
205 	nouveau_bo_unpin(new_bo);
206 	return ret;
207 }
208 
209 static void
210 nouveau_page_flip_unreserve(struct nouveau_bo *old_bo,
211 			    struct nouveau_bo *new_bo,
212 			    struct nouveau_fence *fence)
213 {
214 	nouveau_bo_fence(new_bo, fence);
215 	ttm_bo_unreserve(&new_bo->bo);
216 
217 	nouveau_bo_fence(old_bo, fence);
218 	ttm_bo_unreserve(&old_bo->bo);
219 
220 	nouveau_bo_unpin(old_bo);
221 }
222 
223 static int
224 nouveau_page_flip_emit(struct nouveau_channel *chan,
225 		       struct nouveau_bo *old_bo,
226 		       struct nouveau_bo *new_bo,
227 		       struct nouveau_page_flip_state *s,
228 		       struct nouveau_fence **pfence)
229 {
230 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
231 	struct drm_device *dev = chan->dev;
232 	unsigned long flags;
233 	int ret;
234 
235 	/* Queue it to the pending list */
236 	spin_lock_irqsave(&dev->event_lock, flags);
237 	list_add_tail(&s->head, &chan->nvsw.flip);
238 	spin_unlock_irqrestore(&dev->event_lock, flags);
239 
240 	/* Synchronize with the old framebuffer */
241 	ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan);
242 	if (ret)
243 		goto fail;
244 
245 	/* Emit the pageflip */
246 	ret = RING_SPACE(chan, 2);
247 	if (ret)
248 		goto fail;
249 
250 	if (dev_priv->card_type < NV_C0)
251 		BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
252 	else
253 		BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
254 	OUT_RING  (chan, 0);
255 	FIRE_RING (chan);
256 
257 	ret = nouveau_fence_new(chan, pfence, true);
258 	if (ret)
259 		goto fail;
260 
261 	return 0;
262 fail:
263 	spin_lock_irqsave(&dev->event_lock, flags);
264 	list_del(&s->head);
265 	spin_unlock_irqrestore(&dev->event_lock, flags);
266 	return ret;
267 }
268 
269 int
270 nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
271 		       struct drm_pending_vblank_event *event)
272 {
273 	struct drm_device *dev = crtc->dev;
274 	struct drm_nouveau_private *dev_priv = dev->dev_private;
275 	struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
276 	struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
277 	struct nouveau_page_flip_state *s;
278 	struct nouveau_channel *chan;
279 	struct nouveau_fence *fence;
280 	int ret;
281 
282 	if (!dev_priv->channel)
283 		return -ENODEV;
284 
285 	s = kzalloc(sizeof(*s), GFP_KERNEL);
286 	if (!s)
287 		return -ENOMEM;
288 
289 	/* Don't let the buffers go away while we flip */
290 	ret = nouveau_page_flip_reserve(old_bo, new_bo);
291 	if (ret)
292 		goto fail_free;
293 
294 	/* Initialize a page flip struct */
295 	*s = (struct nouveau_page_flip_state)
296 		{ { }, event, nouveau_crtc(crtc)->index,
297 		  fb->bits_per_pixel, fb->pitch, crtc->x, crtc->y,
298 		  new_bo->bo.offset };
299 
300 	/* Choose the channel the flip will be handled in */
301 	chan = nouveau_fence_channel(new_bo->bo.sync_obj);
302 	if (!chan)
303 		chan = nouveau_channel_get_unlocked(dev_priv->channel);
304 	mutex_lock(&chan->mutex);
305 
306 	/* Emit a page flip */
307 	if (dev_priv->card_type >= NV_50) {
308 		ret = nv50_display_flip_next(crtc, fb, chan);
309 		if (ret) {
310 			nouveau_channel_put(&chan);
311 			goto fail_unreserve;
312 		}
313 	}
314 
315 	ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
316 	nouveau_channel_put(&chan);
317 	if (ret)
318 		goto fail_unreserve;
319 
320 	/* Update the crtc struct and cleanup */
321 	crtc->fb = fb;
322 
323 	nouveau_page_flip_unreserve(old_bo, new_bo, fence);
324 	nouveau_fence_unref(&fence);
325 	return 0;
326 
327 fail_unreserve:
328 	nouveau_page_flip_unreserve(old_bo, new_bo, NULL);
329 fail_free:
330 	kfree(s);
331 	return ret;
332 }
333 
334 int
335 nouveau_finish_page_flip(struct nouveau_channel *chan,
336 			 struct nouveau_page_flip_state *ps)
337 {
338 	struct drm_device *dev = chan->dev;
339 	struct nouveau_page_flip_state *s;
340 	unsigned long flags;
341 
342 	spin_lock_irqsave(&dev->event_lock, flags);
343 
344 	if (list_empty(&chan->nvsw.flip)) {
345 		NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
346 		spin_unlock_irqrestore(&dev->event_lock, flags);
347 		return -EINVAL;
348 	}
349 
350 	s = list_first_entry(&chan->nvsw.flip,
351 			     struct nouveau_page_flip_state, head);
352 	if (s->event) {
353 		struct drm_pending_vblank_event *e = s->event;
354 		struct timeval now;
355 
356 		do_gettimeofday(&now);
357 		e->event.sequence = 0;
358 		e->event.tv_sec = now.tv_sec;
359 		e->event.tv_usec = now.tv_usec;
360 		list_add_tail(&e->base.link, &e->base.file_priv->event_list);
361 		wake_up_interruptible(&e->base.file_priv->event_wait);
362 	}
363 
364 	list_del(&s->head);
365 	if (ps)
366 		*ps = *s;
367 	kfree(s);
368 
369 	spin_unlock_irqrestore(&dev->event_lock, flags);
370 	return 0;
371 }
372