Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/nve0/fifo: support engine selection when creating fifo channels

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

+64 -13
+1 -1
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
··· 182 182 struct nouveau_oclass *oclass, void *data, u32 size, 183 183 struct nouveau_object **pobject) 184 184 { 185 - struct nv_channel_ind_class *args = data; 185 + struct nv50_channel_ind_class *args = data; 186 186 struct nouveau_bar *bar = nouveau_bar(parent); 187 187 struct nv50_fifo_base *base = (void *)parent; 188 188 struct nv50_fifo_chan *chan;
+1 -1
drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
··· 150 150 struct nouveau_bar *bar = nouveau_bar(parent); 151 151 struct nv50_fifo_base *base = (void *)parent; 152 152 struct nv50_fifo_chan *chan; 153 - struct nv_channel_ind_class *args = data; 153 + struct nv50_channel_ind_class *args = data; 154 154 u64 ioffset, ilength; 155 155 int ret; 156 156
+1 -1
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
··· 163 163 struct nvc0_fifo_priv *priv = (void *)engine; 164 164 struct nvc0_fifo_base *base = (void *)parent; 165 165 struct nvc0_fifo_chan *chan; 166 - struct nv_channel_ind_class *args = data; 166 + struct nv50_channel_ind_class *args = data; 167 167 u64 usermem, ioffset, ilength; 168 168 int ret, i; 169 169
+39 -6
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
··· 38 38 #include <engine/dmaobj.h> 39 39 #include <engine/fifo.h> 40 40 41 + #define _(a,b) { (a), ((1 << (a)) | (b)) } 42 + static const struct { 43 + int subdev; 44 + u32 mask; 45 + } fifo_engine[] = { 46 + _(NVDEV_ENGINE_GR , (1 << NVDEV_ENGINE_SW)), 47 + _(NVDEV_ENGINE_VP , 0), 48 + _(NVDEV_ENGINE_PPP , 0), 49 + _(NVDEV_ENGINE_BSP , 0), 50 + _(NVDEV_ENGINE_COPY0 , 0), 51 + _(NVDEV_ENGINE_COPY1 , 0), 52 + _(NVDEV_ENGINE_VENC , 0), 53 + }; 54 + #undef _ 55 + #define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine) 56 + 41 57 struct nve0_fifo_engn { 42 58 struct nouveau_gpuobj *playlist[2]; 43 59 int cur_playlist; ··· 61 45 62 46 struct nve0_fifo_priv { 63 47 struct nouveau_fifo base; 64 - struct nve0_fifo_engn engine[16]; 48 + struct nve0_fifo_engn engine[FIFO_ENGINE_NR]; 65 49 struct { 66 50 struct nouveau_gpuobj *mem; 67 51 struct nouveau_vma bar; ··· 135 119 136 120 switch (nv_engidx(object->engine)) { 137 121 case NVDEV_ENGINE_SW : return 0; 138 - case NVDEV_ENGINE_GR : addr = 0x0210; break; 122 + case NVDEV_ENGINE_GR : 123 + case NVDEV_ENGINE_COPY0: 124 + case NVDEV_ENGINE_COPY1: addr = 0x0210; break; 139 125 default: 140 126 return -EINVAL; 141 127 } ··· 167 149 168 150 switch (nv_engidx(object->engine)) { 169 151 case NVDEV_ENGINE_SW : return 0; 170 - case NVDEV_ENGINE_GR : addr = 0x0210; break; 152 + case NVDEV_ENGINE_GR : 153 + case NVDEV_ENGINE_COPY0: 154 + case NVDEV_ENGINE_COPY1: addr = 0x0210; break; 171 155 default: 172 156 return -EINVAL; 173 157 } ··· 198 178 struct nve0_fifo_priv *priv = (void *)engine; 199 179 struct nve0_fifo_base *base = (void *)parent; 200 180 struct nve0_fifo_chan *chan; 201 - struct nv_channel_ind_class *args = data; 181 + struct nve0_channel_ind_class *args = data; 202 182 u64 usermem, ioffset, ilength; 203 183 int ret, i; 204 184 205 185 if (size < sizeof(*args)) 206 186 return -EINVAL; 207 187 188 + for (i = 0; i < FIFO_ENGINE_NR; i++) { 189 + if (args->engine & (1 << i)) { 190 + if (nouveau_engine(parent, fifo_engine[i].subdev)) { 191 + args->engine = (1 << i); 192 + break; 193 + } 194 + } 195 + } 196 + 197 + if (i == FIFO_ENGINE_NR) 198 + return -ENODEV; 199 + 208 200 ret = nouveau_fifo_channel_create(parent, engine, oclass, 1, 209 201 priv->user.bar.offset, 0x200, 210 202 args->pushbuf, 211 - (1 << NVDEV_ENGINE_SW) | 212 - (1 << NVDEV_ENGINE_GR), &chan); 203 + fifo_engine[i].mask, &chan); 213 204 *pobject = nv_object(chan); 214 205 if (ret) 215 206 return ret; 216 207 217 208 nv_parent(chan)->context_attach = nve0_fifo_context_attach; 218 209 nv_parent(chan)->context_detach = nve0_fifo_context_detach; 210 + chan->engine = i; 219 211 220 212 usermem = chan->base.chid * 0x200; 221 213 ioffset = args->ioffset; ··· 267 235 if (ret) 268 236 return ret; 269 237 238 + nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16); 270 239 nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12); 271 240 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); 272 241 nve0_fifo_playlist_update(priv, chan->engine);
+19 -2
drivers/gpu/drm/nouveau/core/include/core/class.h
··· 65 65 /* 506f: NV50_CHANNEL_IND 66 66 * 826f: NV84_CHANNEL_IND 67 67 * 906f: NVC0_CHANNEL_IND 68 - * a06f: NVE0_CHANNEL_IND 69 68 */ 70 69 71 - struct nv_channel_ind_class { 70 + struct nv50_channel_ind_class { 72 71 u32 pushbuf; 73 72 u32 ilength; 74 73 u64 ioffset; 74 + }; 75 + 76 + /* a06f: NVE0_CHANNEL_IND 77 + */ 78 + 79 + #define NVE0_CHANNEL_IND_ENGINE_GR 0x00000001 80 + #define NVE0_CHANNEL_IND_ENGINE_VP 0x00000002 81 + #define NVE0_CHANNEL_IND_ENGINE_PPP 0x00000004 82 + #define NVE0_CHANNEL_IND_ENGINE_BSP 0x00000008 83 + #define NVE0_CHANNEL_IND_ENGINE_CE0 0x00000010 84 + #define NVE0_CHANNEL_IND_ENGINE_CE1 0x00000020 85 + #define NVE0_CHANNEL_IND_ENGINE_ENC 0x00000040 86 + 87 + struct nve0_channel_ind_class { 88 + u32 pushbuf; 89 + u32 ilength; 90 + u64 ioffset; 91 + u32 engine; 75 92 }; 76 93 77 94 #endif
+1 -1
drivers/gpu/drm/nouveau/core/include/core/device.h
··· 36 36 NVDEV_ENGINE_COPY0, 37 37 NVDEV_ENGINE_COPY1, 38 38 NVDEV_ENGINE_UNK1C1, 39 - NVDEV_ENGINE_FENCE, 39 + NVDEV_ENGINE_VENC, 40 40 NVDEV_ENGINE_DISP, 41 41 NVDEV_SUBDEV_NR, 42 42 };
+2 -1
drivers/gpu/drm/nouveau/nouveau_chan.c
··· 188 188 { 189 189 static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 }; 190 190 const u16 *oclass = oclasses; 191 - struct nv_channel_ind_class args; 191 + struct nve0_channel_ind_class args; 192 192 struct nouveau_channel *chan; 193 193 int ret; 194 194 ··· 202 202 args.pushbuf = chan->push.handle; 203 203 args.ioffset = 0x10000 + chan->push.vma.offset; 204 204 args.ilength = 0x02000; 205 + args.engine = NVE0_CHANNEL_IND_ENGINE_GR; 205 206 206 207 do { 207 208 ret = nouveau_object_new(nv_object(cli), parent, handle,