commit 95a153ee7623241a9f0ca6f394812fe2adfda2dd Author: Icenowy Zheng Date: Fri Oct 18 15:16:43 2024 +0800 DON'T UPSTERAM: HACK: ttm: disallow cached mapping FIXME: this hack fixed the issue when booting PCIe radeon GPU card, it will report: [ 2.909876] [drm:r600_ring_test] *ERROR* radeon: ring 0 test failed (scratch(0x8504)=0xCAFEDEAD) Rootcasue Analysis: The radeon/amdgpu driver expects pcie to snoop cpu cache, which means the contents of cpu cache should also be seen by pcie. But sg2042 does not meet this requirement. When the GPU is being initialized, the GPU's ring_test tries to write a value to a certain memory address, and then read back to check whether it is written in (before that, the cpu writes another value in). Due to SG2042's issue, gpu cannot snoop cpu cache, check fails. The hack solution is to change the memory mapped by the ttm memory manager to uncached mode to workaround this SoC issue. Signed-off-by: Icenowy Zheng Tested-by: Chen Wang diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 5e5b70518dbe..812b33a85e44 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -725,7 +725,7 @@ static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo, if (!tt) return NULL; - ret = ttm_tt_init(tt, bo, page_flags, ttm_cached, 0); + ret = ttm_tt_init(tt, bo, page_flags, ttm_write_combined, 0); if (ret < 0) goto err_ttm_tt_init; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index cabcfeaa70dc..54c2c4bb8b01 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -356,6 +356,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, if (ret) return ret; +#if 0 if (num_pages == 1 && ttm->caching == ttm_cached && !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) { /* @@ -367,6 +368,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, map->page = ttm->pages[start_page]; map->virtual = kmap(map->page); } else { +#endif + { /* * We need to use vmap to get the desired page protection * or to make the buffer object look contiguous. diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 192fca24f37e..3ac4dcb26a96 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -337,7 +337,7 @@ void ttm_resource_init(struct ttm_buffer_object *bo, res->bus.addr = NULL; res->bus.offset = 0; res->bus.is_iomem = false; - res->bus.caching = ttm_cached; + res->bus.caching = ttm_write_combined; res->bo = bo; man = ttm_manager_type(bo->bdev, place->mem_type); @@ -848,16 +848,18 @@ ttm_kmap_iter_linear_io_init(struct ttm_kmap_iter_linear_io *iter_io, } else { iter_io->needs_unmap = true; memset(&iter_io->dmap, 0, sizeof(iter_io->dmap)); - if (mem->bus.caching == ttm_write_combined) + if (mem->bus.caching == ttm_write_combined || mem->bus.caching == ttm_cached) iosys_map_set_vaddr_iomem(&iter_io->dmap, ioremap_wc(mem->bus.offset, mem->size)); +#if 0 else if (mem->bus.caching == ttm_cached) iosys_map_set_vaddr(&iter_io->dmap, memremap(mem->bus.offset, mem->size, MEMREMAP_WB | MEMREMAP_WT | MEMREMAP_WC)); +#endif /* If uncached requested or if mapping cached or wc failed */ if (iosys_map_is_null(&iter_io->dmap)) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index fbf713abd547..d31b86eab7dd 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -162,7 +162,7 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm, ttm->dma_address = NULL; ttm->swap_storage = NULL; ttm->sg = bo->sg; - ttm->caching = caching; + ttm->caching = ttm_write_combined; ttm->restore = NULL; ttm->backup = NULL; }