From ec47832fd71f6bd26a6dfd2de3eccc3c2ecb1fb7 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Thu, 5 Jun 2025 00:25:37 +0800 Subject: [PATCH 1/5] RISCV64: SG2042: HACK: pcie: sg2042: add PCIE_SG2042_HACK option Signed-off-by: Han Gao --- drivers/pci/controller/cadence/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig index 292eb2b20e9c52..93a0969220f65d 100644 --- a/drivers/pci/controller/cadence/Kconfig +++ b/drivers/pci/controller/cadence/Kconfig @@ -54,6 +54,16 @@ config PCIE_SG2042 controller in host mode. Sophgo SG2042 PCIe controller uses Cadence PCIe core. +config PCIE_SG2042_HACK + bool "Sophgo SG2042 PCIe controller (host mode) with hack" + depends on ARCH_SOPHGO || COMPILE_TEST + depends on OF + depends on PCIE_SG2042 + default n + help + To enable support for graphics cards and some peripherals on the + Sophgo SG2042, some "hacks" are required. Say "Y" to enable it. + config PCI_J721E bool From 47afc791512379e19c567ae30e619172a5015f1d Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 5 Jun 2025 00:25:03 +0800 Subject: [PATCH 2/5] RISCV64: SG2042: 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 Signed-off-by: Han Gao --- drivers/gpu/drm/drm_gem_vram_helper.c | 5 ++++- drivers/gpu/drm/ttm/ttm_bo_util.c | 3 +++ drivers/gpu/drm/ttm/ttm_module.c | 3 ++- drivers/gpu/drm/ttm/ttm_resource.c | 10 ++++++++++ drivers/gpu/drm/ttm/ttm_tt.c | 4 ++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 22b1fe9c03b81e..885d5bdaeef8ac 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -797,8 +797,11 @@ static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo, tt = kzalloc(sizeof(*tt), GFP_KERNEL); if (!tt) return NULL; - +#if !defined(CONFIG_PCIE_SG2042_HACK) ret = ttm_tt_init(tt, bo, page_flags, ttm_cached, 0); +#else + ret = ttm_tt_init(tt, bo, page_flags, ttm_write_combined, 0); +#endif 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 15cab9bda17fb9..f9540e48821f19 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -354,6 +354,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, if (ret) return ret; +#if !defined(CONFIG_PCIE_SG2042_HACK) if (num_pages == 1 && ttm->caching == ttm_cached && !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) { /* @@ -365,6 +366,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_module.c b/drivers/gpu/drm/ttm/ttm_module.c index b3fffe7b5062a9..aa137ead5cc596 100644 --- a/drivers/gpu/drm/ttm/ttm_module.c +++ b/drivers/gpu/drm/ttm/ttm_module.c @@ -74,7 +74,8 @@ pgprot_t ttm_prot_from_caching(enum ttm_caching caching, pgprot_t tmp) #endif /* CONFIG_UML */ #endif /* __i386__ || __x86_64__ */ #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \ - defined(__powerpc__) || defined(__mips__) || defined(__loongarch__) + defined(__powerpc__) || defined(__mips__) || defined(__loongarch__) || \ + defined(__riscv) if (caching == ttm_write_combined) tmp = pgprot_writecombine(tmp); else diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 7e5a60c5581396..fda6b05681a5d9 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -335,7 +335,11 @@ void ttm_resource_init(struct ttm_buffer_object *bo, res->bus.addr = NULL; res->bus.offset = 0; res->bus.is_iomem = false; +#if !defined(CONFIG_PCIE_SG2042_HACK) res->bus.caching = ttm_cached; +#else + res->bus.caching = ttm_write_combined; +#endif res->bo = bo; man = ttm_manager_type(bo->bdev, place->mem_type); @@ -840,16 +844,22 @@ 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 !defined(CONFIG_PCIE_SG2042_HACK) if (mem->bus.caching == ttm_write_combined) +#else + if (mem->bus.caching == ttm_write_combined || mem->bus.caching == ttm_cached) +#endif iosys_map_set_vaddr_iomem(&iter_io->dmap, ioremap_wc(mem->bus.offset, mem->size)); +#if !defined(CONFIG_PCIE_SG2042_HACK) 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 698cd4bf5e4648..afa33b98cd131d 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -158,7 +158,11 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm, ttm->dma_address = NULL; ttm->swap_storage = NULL; ttm->sg = bo->sg; +#if !defined(CONFIG_PCIE_SG2042_HACK) ttm->caching = caching; +#else + ttm->caching = ttm_write_combined; +#endif ttm->restore = NULL; ttm->backup = NULL; } From 584a95b57092861fd6feb79b450891e4e27c0858 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 5 Jun 2025 00:15:02 +0800 Subject: [PATCH 3/5] RISCV64: SG2042: HACK: radeon: force 64-bit msi to fit top intc Signed-off-by: Icenowy Zheng Signed-off-by: Han Gao --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 2 ++ sound/pci/hda/hda_intel.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index d4ad1fa8264542..ff68bd0950749b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -251,10 +251,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) * of address for "64-bit" MSIs which breaks on some platforms, notably * IBM POWER servers, so we limit them */ +#if !defined(CONFIG_PCIE_SG2042_HACK) if (rdev->family < CHIP_BONAIRE) { dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n"); rdev->pdev->no_64bit_msi = 1; } +#endif /* force MSI on */ if (radeon_msi == 1) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 512fb22f5e5eb9..b039e03f5e40ad 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -301,9 +301,14 @@ enum { AZX_DCAPS_SNOOP_TYPE(ATI)) /* quirks for ATI/AMD HDMI */ +#if defined(CONFIG_PCIE_SG2042_HACK) +#define AZX_DCAPS_PRESET_ATI_HDMI \ + (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB) +#else #define AZX_DCAPS_PRESET_ATI_HDMI \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\ AZX_DCAPS_NO_MSI64) +#endif /* quirks for ATI HDMI with snoop off */ #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ From 7b4d4ade267967eb99af7b95b1a28e884334c81e Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 5 Jun 2025 00:15:15 +0800 Subject: [PATCH 4/5] RISCV64: SG2042: HACK: nvidia hda: force msi Signed-off-by: Icenowy Zheng Signed-off-by: Han Gao --- sound/pci/hda/hda_intel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b039e03f5e40ad..56ebac107e20eb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -321,9 +321,15 @@ enum { AZX_DCAPS_RETRY_PROBE) /* quirks for Nvidia */ +#if defined(CONFIG_PCIE_SG2042_HACK) +#define AZX_DCAPS_PRESET_NVIDIA \ + (AZX_DCAPS_CORBRP_SELF_CLEAR |\ + AZX_DCAPS_SNOOP_TYPE(NVIDIA)) +#else #define AZX_DCAPS_PRESET_NVIDIA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ AZX_DCAPS_SNOOP_TYPE(NVIDIA)) +#endif #define AZX_DCAPS_PRESET_CTHDA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ From a96577443674355149a11d51e07dae39b39f4a87 Mon Sep 17 00:00:00 2001 From: Chen Wang Date: Thu, 5 Jun 2025 00:14:33 +0800 Subject: [PATCH 5/5] RISCV64: SG2042: HACK: disable Warning firmware error detected FWSM: 0x00000000 from ixgbe FIXME: maybe my PCI ethernet card need upgrade firmware. Signed-off-by: Chen Wang Signed-off-by: Han Gao --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index a2718218963ed6..780cded70119f4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -8378,10 +8378,12 @@ static bool ixgbe_check_fw_error(struct ixgbe_adapter *adapter) /* read fwsm.ext_err_ind register and log errors */ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw)); +#if !defined(CONFIG_PCIE_SG2042_HACK) if (fwsm & IXGBE_FWSM_EXT_ERR_IND_MASK || !(fwsm & IXGBE_FWSM_FW_VAL_BIT)) e_dev_warn("Warning firmware error detected FWSM: 0x%08X\n", fwsm); +#endif if (hw->mac.ops.fw_recovery_mode && hw->mac.ops.fw_recovery_mode(hw)) { e_dev_err("Firmware recovery mode detected. Limiting functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n");