* Helge Deller <deller@xxxxxx>: > There have been various approaches to fix the radeon graphic cards > on C8000 workstations, e.g. this is the last thread: > https://marc.info/?l=linux-parisc&m=156971832128700&w=2 > > With the patch below the radeon ring and ib tests don't fail any longer. > It uses (relatively) lightweight pdc/fdc instructions. > > The patch below > - uses the pdc instruction (purge data cache) before reading back the > ring test result from memory. > - modifies the parisc-agp code, based on Thomas patch > > The patch is not intended to by applied as-is. attached is a cleaned up version of the patch. With that a Radeon PCI card successfully initializes the rings. ATI FireGL X1 AGP card doesn't work yet, although I start to believe it's a problem with the card in general (R300), e.g. it reports "Generation 1 PCI interface in multifunction mode" diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index d68d05d5d383..4d644c267d3f 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c @@ -90,6 +90,9 @@ parisc_agp_tlbflush(struct agp_memory *mem) { struct _parisc_agp_info *info = &parisc_agp_info; + /* force fdc ops to be visible to IOMMU */ + asm_io_sync(); + writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM); readq(info->ioc_regs+IOC_PCOM); /* flush */ } @@ -158,6 +161,7 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type) info->gatt[j] = parisc_agp_mask_memory(agp_bridge, paddr, type); + asm_io_fdc(&info->gatt[j]); } } @@ -191,7 +195,16 @@ static unsigned long parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, int type) { - return SBA_PDIR_VALID_BIT | addr; + unsigned ci; /* coherent index */ + dma_addr_t pa; + + pa = addr & IOVP_MASK; + asm("lci 0(%1), %0" : "=r" (ci) : "r" (phys_to_virt(pa))); + + pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */ + pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ + + return cpu_to_le64(pa); } static void diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 7051c9c909c2..a84eba2fb429 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -174,6 +174,8 @@ drm_clflush_virt_range(void *addr, unsigned long length) if (wbinvd_on_all_cpus()) pr_err("Timed out waiting for cache flush\n"); +#elif defined(CONFIG_PARISC) + flush_kernel_dcache_range((unsigned long) addr, length); #else WARN_ONCE(1, "Architecture has no drm_cache.c support\n"); #endif diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d4f09ecc3d22..45711c9b7cfe 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -642,6 +642,10 @@ void r100_hpd_fini(struct radeon_device *rdev) */ void r100_pci_gart_tlb_flush(struct radeon_device *rdev) { + /* flush gtt[] gart table entries from r100_pci_gart_set_page() */ + dma_sync_single_for_device(&rdev->pdev->dev, rdev->gart.table_addr, + rdev->gart.table_size, DMA_TO_DEVICE); + /* TODO: can we do somethings here ? */ /* It seems hw only cache one entry so we should discard this * entry otherwise if first GPU GART read hit this entry it diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 7e207276df37..35652286244d 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -29,6 +29,7 @@ #include <drm/drm_device.h> #include <drm/drm_file.h> +#include <drm/drm_cache.h> #include "radeon.h" @@ -177,6 +178,9 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, ring->nop); } mb(); + if (IS_ENABLED(CONFIG_PARISC)) + drm_clflush_virt_range((void *)&ring->ring[0], ring->wptr * sizeof(uint32_t)); + /* If we are emitting the HDP flush via MMIO, we need to do it after * all CPU writes to VRAM finished. */