2 * Copyright (C) 2007 Ben Skeggs.
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.
29 #include "nouveau_drv.h"
30 #include "nouveau_dma.h"
33 nouveau_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags)
35 struct drm_nouveau_private *dev_priv = dev->dev_private;
37 DRM_DEBUG("class=%d, flags=0x%08x\n", class, flags);
39 /* DRM's channel always uses IRQs to signal fences */
40 if (class == dev_priv->channel.chan->id)
43 /* Other channels don't use IRQs at all yet */
48 nouveau_fence_emit(struct drm_device *dev, uint32_t class, uint32_t flags,
49 uint32_t *breadcrumb, uint32_t *native_type)
51 struct drm_nouveau_private *dev_priv = dev->dev_private;
52 struct nouveau_channel *chan = dev_priv->fifos[class];
53 struct nouveau_drm_channel *dchan = &dev_priv->channel;
55 DRM_DEBUG("class=%d, flags=0x%08x\n", class, flags);
57 /* We can't emit fences on client channels, update sequence number
58 * and userspace will emit the fence
60 *breadcrumb = ++chan->next_sequence;
61 *native_type = DRM_FENCE_TYPE_EXE;
62 if (chan != dchan->chan) {
63 DRM_DEBUG("user fence 0x%08x\n", *breadcrumb);
67 DRM_DEBUG("emit 0x%08x\n", *breadcrumb);
68 BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_REF, 1);
69 OUT_RING (*breadcrumb);
70 BEGIN_RING(NvSubM2MF, 0x0150, 1);
78 nouveau_fence_poll(struct drm_device *dev, uint32_t class, uint32_t waiting_types)
80 struct drm_nouveau_private *dev_priv = dev->dev_private;
81 struct drm_fence_class_manager *fc = &dev->fm.fence_class[class];
82 struct nouveau_channel *chan = dev_priv->fifos[class];
83 uint32_t pending_types = 0;
85 DRM_DEBUG("class=%d\n", class);
86 DRM_DEBUG("pending: 0x%08x 0x%08x\n", waiting_types, fc->waiting_types);
89 uint32_t sequence = NV_READ(chan->ref_cnt);
91 DRM_DEBUG("got 0x%08x\n", sequence);
92 drm_fence_handler(dev, class, sequence, waiting_types, 0);
97 nouveau_fence_handler(struct drm_device *dev, int channel)
99 struct drm_fence_manager *fm = &dev->fm;
100 struct drm_fence_class_manager *fc = &fm->fence_class[channel];
102 DRM_DEBUG("class=%d\n", channel);
104 write_lock(&fm->lock);
105 nouveau_fence_poll(dev, channel, fc->waiting_types);
106 write_unlock(&fm->lock);
109 struct drm_fence_driver nouveau_fence_driver = {
111 .wrap_diff = (1 << 30),
112 .flush_diff = (1 << 29),
113 .sequence_mask = 0xffffffffU,
114 .has_irq = nouveau_fence_has_irq,
115 .emit = nouveau_fence_emit,
117 .poll = nouveau_fence_poll,
118 .needed_flush = NULL,