aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-09-22 21:03:01 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-02 23:18:39 -0500
commit7c74cbd01b2698583fb74ebdfcd7ef4c768e6346 (patch)
treef507a89cdc646bf03c551c37e56505a0a9c15978
parentf7eb0c55416aba7478932cedbaccc2bdacd8a95d (diff)
drm/nouveau: tidy fifo swmthd handler a little
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c56
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 7bfd9e6c9d6..a4fa9e14d66 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
110static bool 110static bool
111nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data) 111nouveau_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
143static void 152static 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,