diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-09-22 21:03:01 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-02 23:18:39 -0500 |
commit | 7c74cbd01b2698583fb74ebdfcd7ef4c768e6346 (patch) | |
tree | f507a89cdc646bf03c551c37e56505a0a9c15978 /drivers/gpu/drm/nouveau/nouveau_irq.c | |
parent | f7eb0c55416aba7478932cedbaccc2bdacd8a95d (diff) |
drm/nouveau: tidy fifo swmthd handler a little
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_irq.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 7bfd9e6c9d67..a4fa9e14d66d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -108,36 +108,45 @@ nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | static bool | 110 | static bool |
111 | nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data) | 111 | nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) |
112 | { | 112 | { |
113 | struct drm_device *dev = chan->dev; | 113 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
114 | struct nouveau_channel *chan = NULL; | ||
115 | struct nouveau_gpuobj *obj; | ||
114 | const int subc = (addr >> 13) & 0x7; | 116 | const int subc = (addr >> 13) & 0x7; |
115 | const int mthd = addr & 0x1ffc; | 117 | const int mthd = addr & 0x1ffc; |
118 | bool handled = false; | ||
119 | u32 engine; | ||
116 | 120 | ||
117 | if (mthd == 0x0000) { | 121 | if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) |
118 | struct nouveau_gpuobj *gpuobj; | 122 | chan = dev_priv->fifos[chid]; |
119 | 123 | if (unlikely(!chan)) | |
120 | gpuobj = nouveau_ramht_find(chan, data); | 124 | return false; |
121 | if (!gpuobj) | ||
122 | return false; | ||
123 | 125 | ||
124 | if (gpuobj->engine != NVOBJ_ENGINE_SW) | 126 | switch (mthd) { |
125 | return false; | 127 | case 0x0000: /* bind object to subchannel */ |
128 | obj = nouveau_ramht_find(chan, data); | ||
129 | if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW)) | ||
130 | break; | ||
126 | 131 | ||
127 | chan->sw_subchannel[subc] = gpuobj->class; | 132 | chan->sw_subchannel[subc] = obj->class; |
128 | nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev, | 133 | engine = 0x0000000f << (subc * 4); |
129 | NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4)); | ||
130 | return true; | ||
131 | } | ||
132 | 134 | ||
133 | /* hw object */ | 135 | nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000); |
134 | if (nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE) & (1 << (subc*4))) | 136 | handled = true; |
135 | return false; | 137 | break; |
138 | default: | ||
139 | engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE); | ||
140 | if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) | ||
141 | break; | ||
136 | 142 | ||
137 | if (nouveau_call_method(chan, chan->sw_subchannel[subc], mthd, data)) | 143 | if (!nouveau_call_method(chan, chan->sw_subchannel[subc], |
138 | return false; | 144 | mthd, data)) |
145 | handled = true; | ||
146 | break; | ||
147 | } | ||
139 | 148 | ||
140 | return true; | 149 | return handled; |
141 | } | 150 | } |
142 | 151 | ||
143 | static void | 152 | static void |
@@ -150,14 +159,11 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
150 | 159 | ||
151 | reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; | 160 | reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; |
152 | while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { | 161 | while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { |
153 | struct nouveau_channel *chan = NULL; | ||
154 | uint32_t chid, get; | 162 | uint32_t chid, get; |
155 | 163 | ||
156 | nv_wr32(dev, NV03_PFIFO_CACHES, 0); | 164 | nv_wr32(dev, NV03_PFIFO_CACHES, 0); |
157 | 165 | ||
158 | chid = engine->fifo.channel_id(dev); | 166 | chid = engine->fifo.channel_id(dev); |
159 | if (chid >= 0 && chid < engine->fifo.channels) | ||
160 | chan = dev_priv->fifos[chid]; | ||
161 | get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); | 167 | get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); |
162 | 168 | ||
163 | if (status & NV_PFIFO_INTR_CACHE_ERROR) { | 169 | if (status & NV_PFIFO_INTR_CACHE_ERROR) { |
@@ -184,7 +190,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
184 | NV40_PFIFO_CACHE1_DATA(ptr)); | 190 | NV40_PFIFO_CACHE1_DATA(ptr)); |
185 | } | 191 | } |
186 | 192 | ||
187 | if (!chan || !nouveau_fifo_swmthd(chan, mthd, data)) { | 193 | if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) { |
188 | NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " | 194 | NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " |
189 | "Mthd 0x%04x Data 0x%08x\n", | 195 | "Mthd 0x%04x Data 0x%08x\n", |
190 | chid, (mthd >> 13) & 7, mthd & 0x1ffc, | 196 | chid, (mthd >> 13) & 7, mthd & 0x1ffc, |