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

drm/nvd0/disp: use single, shared, sync bo for all evo channels

This simplifies some things, and hopefully won't come back to bite me.

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

+32 -31
+32 -31
drivers/gpu/drm/nouveau/nvd0_display.c
··· 43 43 #define EVO_OIMM(c) (0x09 + (c)) 44 44 #define EVO_CURS(c) (0x0d + (c)) 45 45 46 + /* offsets in shared sync bo of various structures */ 47 + #define EVO_SYNC(c, o) ((c) * 0x0100 + (o)) 48 + #define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) 49 + #define EVO_FLIP_SEM0(c) EVO_SYNC((c), 0x00) 50 + #define EVO_FLIP_SEM1(c) EVO_SYNC((c), 0x10) 51 + 46 52 struct evo { 47 53 int idx; 48 54 dma_addr_t handle; 49 55 u32 *ptr; 50 56 struct { 51 - struct nouveau_bo *bo; 52 57 u32 offset; 53 58 u16 value; 54 59 } sem; ··· 61 56 62 57 struct nvd0_display { 63 58 struct nouveau_gpuobj *mem; 59 + struct nouveau_bo *sync; 64 60 struct evo evo[9]; 65 61 66 62 struct tasklet_struct tasklet; ··· 218 212 static bool 219 213 evo_sync_wait(void *data) 220 214 { 221 - return nouveau_bo_rd32(data, 0) != 0x00000000; 215 + return nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000; 222 216 } 223 217 224 218 static int 225 219 evo_sync(struct drm_device *dev, int ch) 226 220 { 227 221 struct nvd0_display *disp = nvd0_display(dev); 228 - struct evo *evo = &disp->evo[ch]; 229 - u32 *push; 230 - 231 - nouveau_bo_wr32(evo->sem.bo, 0, 0x00000000); 232 - 233 - push = evo_wait(dev, ch, 8); 222 + u32 *push = evo_wait(dev, ch, 8); 234 223 if (push) { 224 + nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000); 235 225 evo_mthd(push, 0x0084, 1); 236 - evo_data(push, 0x80000000); 226 + evo_data(push, 0x80000000 | EVO_MAST_NTFY); 237 227 evo_mthd(push, 0x0080, 2); 238 228 evo_data(push, 0x00000000); 239 229 evo_data(push, 0x00000000); 240 230 evo_kick(push, dev, ch); 241 - if (nv_wait_cb(dev, evo_sync_wait, evo->sem.bo)) 231 + if (nv_wait_cb(dev, evo_sync_wait, disp->sync)) 242 232 return 0; 243 233 } 244 234 ··· 247 245 struct nouveau_bo * 248 246 nvd0_display_crtc_sema(struct drm_device *dev, int crtc) 249 247 { 250 - struct nvd0_display *disp = nvd0_display(dev); 251 - struct evo *evo = &disp->evo[EVO_FLIP(crtc)]; 252 - return evo->sem.bo; 248 + return nvd0_display(dev)->sync; 253 249 } 254 250 255 251 void ··· 313 313 OUT_RING (chan, 0x1001); 314 314 FIRE_RING (chan); 315 315 } else { 316 - nouveau_bo_wr32(evo->sem.bo, evo->sem.offset / 4, 316 + nouveau_bo_wr32(disp->sync, evo->sem.offset / 4, 317 317 0xf00d0000 | evo->sem.value); 318 318 evo_sync(crtc->dev, EVO_MASTER); 319 319 } ··· 1752 1752 1753 1753 for (i = 0; i < EVO_DMA_NR; i++) { 1754 1754 struct evo *evo = &disp->evo[i]; 1755 - nouveau_bo_unmap(evo->sem.bo); 1756 - nouveau_bo_ref(NULL, &evo->sem.bo); 1757 1755 pci_free_consistent(pdev, PAGE_SIZE, evo->ptr, evo->handle); 1758 1756 } 1759 1757 1760 1758 nouveau_gpuobj_ref(NULL, &disp->mem); 1759 + nouveau_bo_unmap(disp->sync); 1760 + nouveau_bo_ref(NULL, &disp->sync); 1761 1761 nouveau_irq_unregister(dev, 26); 1762 1762 1763 1763 dev_priv->engine.display.priv = NULL; ··· 1829 1829 tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev); 1830 1830 nouveau_irq_register(dev, 26, nvd0_display_intr); 1831 1831 1832 + /* small shared memory area we use for notifiers and semaphores */ 1833 + ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, 1834 + 0, 0x0000, &disp->sync); 1835 + if (!ret) { 1836 + ret = nouveau_bo_pin(disp->sync, TTM_PL_FLAG_VRAM); 1837 + if (!ret) 1838 + ret = nouveau_bo_map(disp->sync); 1839 + if (ret) 1840 + nouveau_bo_ref(NULL, &disp->sync); 1841 + } 1842 + 1843 + if (ret) 1844 + goto out; 1845 + 1832 1846 /* hash table and dma objects for the memory areas we care about */ 1833 1847 ret = nouveau_gpuobj_new(dev, NULL, 0x4000, 0x10000, 1834 1848 NVOBJ_FLAG_ZERO_ALLOC, &disp->mem); ··· 1852 1838 /* create evo dma channels */ 1853 1839 for (i = 0; i < EVO_DMA_NR; i++) { 1854 1840 struct evo *evo = &disp->evo[i]; 1841 + u64 offset = disp->sync->bo.offset; 1855 1842 u32 dmao = 0x1000 + (i * 0x100); 1856 1843 u32 hash = 0x0000 + (i * 0x040); 1857 - u64 offset; 1858 1844 1859 1845 evo->idx = i; 1846 + evo->sem.offset = EVO_SYNC(evo->idx, 0x00); 1860 1847 evo->ptr = pci_alloc_consistent(pdev, PAGE_SIZE, &evo->handle); 1861 1848 if (!evo->ptr) { 1862 1849 ret = -ENOMEM; 1863 1850 goto out; 1864 1851 } 1865 - 1866 - ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, 1867 - 0, 0x0000, &evo->sem.bo); 1868 - if (!ret) { 1869 - ret = nouveau_bo_pin(evo->sem.bo, TTM_PL_FLAG_VRAM); 1870 - if (!ret) 1871 - ret = nouveau_bo_map(evo->sem.bo); 1872 - if (ret) 1873 - nouveau_bo_ref(NULL, &evo->sem.bo); 1874 - offset = evo->sem.bo->bo.offset; 1875 - } 1876 - 1877 - if (ret) 1878 - goto out; 1879 1852 1880 1853 nv_wo32(disp->mem, dmao + 0x00, 0x00000049); 1881 1854 nv_wo32(disp->mem, dmao + 0x04, (offset + 0x0000) >> 8);