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
nouveau_user_framebuffer_destroy(struct drm_framebuffer * drm_fb)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
nouveau_user_framebuffer_create_handle(struct drm_framebuffer * drm_fb,struct drm_file * file_priv,unsigned int * handle)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
nouveau_framebuffer_init(struct drm_device * dev,struct nouveau_framebuffer * nv_fb,struct drm_mode_fb_cmd * mode_cmd,struct nouveau_bo * nvbo)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 			nv_fb->r_pitch = 0x00100000 | fb->pitch;
110 		else {
111 			u32 mode = nvbo->tile_mode;
112 			if (dev_priv->card_type >= NV_C0)
113 				mode >>= 4;
114 			nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
115 		}
116 	}
117 
118 	return 0;
119 }
120 
121 static struct drm_framebuffer *
nouveau_user_framebuffer_create(struct drm_device * dev,struct drm_file * file_priv,struct drm_mode_fb_cmd * mode_cmd)122 nouveau_user_framebuffer_create(struct drm_device *dev,
123 				struct drm_file *file_priv,
124 				struct drm_mode_fb_cmd *mode_cmd)
125 {
126 	struct nouveau_framebuffer *nouveau_fb;
127 	struct drm_gem_object *gem;
128 	int ret;
129 
130 	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
131 	if (!gem)
132 		return ERR_PTR(-ENOENT);
133 
134 	nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
135 	if (!nouveau_fb)
136 		return ERR_PTR(-ENOMEM);
137 
138 	ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
139 	if (ret) {
140 		drm_gem_object_unreference(gem);
141 		return ERR_PTR(ret);
142 	}
143 
144 	return &nouveau_fb->base;
145 }
146 
147 const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
148 	.fb_create = nouveau_user_framebuffer_create,
149 	.output_poll_changed = nouveau_fbcon_output_poll_changed,
150 };
151 
152 int
nouveau_vblank_enable(struct drm_device * dev,int crtc)153 nouveau_vblank_enable(struct drm_device *dev, int crtc)
154 {
155 	struct drm_nouveau_private *dev_priv = dev->dev_private;
156 
157 	if (dev_priv->card_type >= NV_50)
158 		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
159 			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc));
160 	else
161 		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0,
162 			    NV_PCRTC_INTR_0_VBLANK);
163 
164 	return 0;
165 }
166 
167 void
nouveau_vblank_disable(struct drm_device * dev,int crtc)168 nouveau_vblank_disable(struct drm_device *dev, int crtc)
169 {
170 	struct drm_nouveau_private *dev_priv = dev->dev_private;
171 
172 	if (dev_priv->card_type >= NV_50)
173 		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1,
174 			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0);
175 	else
176 		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0);
177 }
178 
179 static int
nouveau_page_flip_reserve(struct nouveau_bo * old_bo,struct nouveau_bo * new_bo)180 nouveau_page_flip_reserve(struct nouveau_bo *old_bo,
181 			  struct nouveau_bo *new_bo)
182 {
183 	int ret;
184 
185 	ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
186 	if (ret)
187 		return ret;
188 
189 	ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0);
190 	if (ret)
191 		goto fail;
192 
193 	ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
194 	if (ret)
195 		goto fail_unreserve;
196 
197 	return 0;
198 
199 fail_unreserve:
200 	ttm_bo_unreserve(&new_bo->bo);
201 fail:
202 	nouveau_bo_unpin(new_bo);
203 	return ret;
204 }
205 
206 static void
nouveau_page_flip_unreserve(struct nouveau_bo * old_bo,struct nouveau_bo * new_bo,struct nouveau_fence * fence)207 nouveau_page_flip_unreserve(struct nouveau_bo *old_bo,
208 			    struct nouveau_bo *new_bo,
209 			    struct nouveau_fence *fence)
210 {
211 	nouveau_bo_fence(new_bo, fence);
212 	ttm_bo_unreserve(&new_bo->bo);
213 
214 	nouveau_bo_fence(old_bo, fence);
215 	ttm_bo_unreserve(&old_bo->bo);
216 
217 	nouveau_bo_unpin(old_bo);
218 }
219 
220 static int
nouveau_page_flip_emit(struct nouveau_channel * chan,struct nouveau_bo * old_bo,struct nouveau_bo * new_bo,struct nouveau_page_flip_state * s,struct nouveau_fence ** pfence)221 nouveau_page_flip_emit(struct nouveau_channel *chan,
222 		       struct nouveau_bo *old_bo,
223 		       struct nouveau_bo *new_bo,
224 		       struct nouveau_page_flip_state *s,
225 		       struct nouveau_fence **pfence)
226 {
227 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
228 	struct drm_device *dev = chan->dev;
229 	unsigned long flags;
230 	int ret;
231 
232 	/* Queue it to the pending list */
233 	spin_lock_irqsave(&dev->event_lock, flags);
234 	list_add_tail(&s->head, &chan->nvsw.flip);
235 	spin_unlock_irqrestore(&dev->event_lock, flags);
236 
237 	/* Synchronize with the old framebuffer */
238 	ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan);
239 	if (ret)
240 		goto fail;
241 
242 	/* Emit the pageflip */
243 	ret = RING_SPACE(chan, 2);
244 	if (ret)
245 		goto fail;
246 
247 	if (dev_priv->card_type < NV_C0)
248 		BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
249 	else
250 		BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
251 	OUT_RING  (chan, 0);
252 	FIRE_RING (chan);
253 
254 	ret = nouveau_fence_new(chan, pfence, true);
255 	if (ret)
256 		goto fail;
257 
258 	return 0;
259 fail:
260 	spin_lock_irqsave(&dev->event_lock, flags);
261 	list_del(&s->head);
262 	spin_unlock_irqrestore(&dev->event_lock, flags);
263 	return ret;
264 }
265 
266 int
nouveau_crtc_page_flip(struct drm_crtc * crtc,struct drm_framebuffer * fb,struct drm_pending_vblank_event * event)267 nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
268 		       struct drm_pending_vblank_event *event)
269 {
270 	struct drm_device *dev = crtc->dev;
271 	struct drm_nouveau_private *dev_priv = dev->dev_private;
272 	struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
273 	struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
274 	struct nouveau_page_flip_state *s;
275 	struct nouveau_channel *chan;
276 	struct nouveau_fence *fence;
277 	int ret;
278 
279 	if (dev_priv->engine.graph.accel_blocked)
280 		return -ENODEV;
281 
282 	s = kzalloc(sizeof(*s), GFP_KERNEL);
283 	if (!s)
284 		return -ENOMEM;
285 
286 	/* Don't let the buffers go away while we flip */
287 	ret = nouveau_page_flip_reserve(old_bo, new_bo);
288 	if (ret)
289 		goto fail_free;
290 
291 	/* Initialize a page flip struct */
292 	*s = (struct nouveau_page_flip_state)
293 		{ { }, event, nouveau_crtc(crtc)->index,
294 		  fb->bits_per_pixel, fb->pitch, crtc->x, crtc->y,
295 		  new_bo->bo.offset };
296 
297 	/* Choose the channel the flip will be handled in */
298 	chan = nouveau_fence_channel(new_bo->bo.sync_obj);
299 	if (!chan)
300 		chan = nouveau_channel_get_unlocked(dev_priv->channel);
301 	mutex_lock(&chan->mutex);
302 
303 	/* Emit a page flip */
304 	if (dev_priv->card_type >= NV_50) {
305 		ret = nv50_display_flip_next(crtc, fb, chan);
306 		if (ret) {
307 			nouveau_channel_put(&chan);
308 			goto fail_unreserve;
309 		}
310 	}
311 
312 	ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
313 	nouveau_channel_put(&chan);
314 	if (ret)
315 		goto fail_unreserve;
316 
317 	/* Update the crtc struct and cleanup */
318 	crtc->fb = fb;
319 
320 	nouveau_page_flip_unreserve(old_bo, new_bo, fence);
321 	nouveau_fence_unref(&fence);
322 	return 0;
323 
324 fail_unreserve:
325 	nouveau_page_flip_unreserve(old_bo, new_bo, NULL);
326 fail_free:
327 	kfree(s);
328 	return ret;
329 }
330 
331 int
nouveau_finish_page_flip(struct nouveau_channel * chan,struct nouveau_page_flip_state * ps)332 nouveau_finish_page_flip(struct nouveau_channel *chan,
333 			 struct nouveau_page_flip_state *ps)
334 {
335 	struct drm_device *dev = chan->dev;
336 	struct nouveau_page_flip_state *s;
337 	unsigned long flags;
338 
339 	spin_lock_irqsave(&dev->event_lock, flags);
340 
341 	if (list_empty(&chan->nvsw.flip)) {
342 		NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
343 		spin_unlock_irqrestore(&dev->event_lock, flags);
344 		return -EINVAL;
345 	}
346 
347 	s = list_first_entry(&chan->nvsw.flip,
348 			     struct nouveau_page_flip_state, head);
349 	if (s->event) {
350 		struct drm_pending_vblank_event *e = s->event;
351 		struct timeval now;
352 
353 		do_gettimeofday(&now);
354 		e->event.sequence = 0;
355 		e->event.tv_sec = now.tv_sec;
356 		e->event.tv_usec = now.tv_usec;
357 		list_add_tail(&e->base.link, &e->base.file_priv->event_list);
358 		wake_up_interruptible(&e->base.file_priv->event_wait);
359 	}
360 
361 	list_del(&s->head);
362 	if (ps)
363 		*ps = *s;
364 	kfree(s);
365 
366 	spin_unlock_irqrestore(&dev->event_lock, flags);
367 	return 0;
368 }
369