Commit 278be836 authored by Icenowy Zheng's avatar Icenowy Zheng Committed by Huacai Chen
Browse files

LoongArch: Disable WUC for pgprot_writecombine() like ioremap_wc()



Currently the code disables WUC only disables it for ioremap_wc(), which
is only used when mapping writecombine pages like ioremap() (mapped to
the kernel space). But for VRAM mapped in TTM/GEM, it is mapped with a
crafted pgprot by the pgprot_writecombine() function, in which case WUC
isn't disabled now.

Disable WUC for pgprot_writecombine() (fallback to SUC) if needed, like
ioremap_wc().

This improves the AMDGPU driver's stability (solves some misrendering)
on Loongson-3A5000/3A6000 machines.

Signed-off-by: default avatarIcenowy Zheng <uwu@icenowy.me>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 477a0ebe
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -52,10 +52,9 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 * @offset:    bus address of the memory
 * @size:      size of the resource to map
 */
extern pgprot_t pgprot_wc;

#define ioremap_wc(offset, size)	\
	ioremap_prot((offset), (size), pgprot_val(pgprot_wc))
	ioremap_prot((offset), (size),	\
		pgprot_val(wc_enabled ? PAGE_KERNEL_WUC : PAGE_KERNEL_SUC))

#define ioremap_cache(offset, size)	\
	ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL))
+3 −1
Original line number Diff line number Diff line
@@ -105,13 +105,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
	return __pgprot(prot);
}

extern bool wc_enabled;

#define pgprot_writecombine pgprot_writecombine

static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
{
	unsigned long prot = pgprot_val(_prot);

	prot = (prot & ~_CACHE_MASK) | _CACHE_WUC;
	prot = (prot & ~_CACHE_MASK) | (wc_enabled ? _CACHE_WUC : _CACHE_SUC);

	return __pgprot(prot);
}
+5 −5
Original line number Diff line number Diff line
@@ -161,19 +161,19 @@ static void __init smbios_parse(void)
}

#ifdef CONFIG_ARCH_WRITECOMBINE
pgprot_t pgprot_wc = PAGE_KERNEL_WUC;
bool wc_enabled = true;
#else
pgprot_t pgprot_wc = PAGE_KERNEL_SUC;
bool wc_enabled = false;
#endif

EXPORT_SYMBOL(pgprot_wc);
EXPORT_SYMBOL(wc_enabled);

static int __init setup_writecombine(char *p)
{
	if (!strcmp(p, "on"))
		pgprot_wc = PAGE_KERNEL_WUC;
		wc_enabled = true;
	else if (!strcmp(p, "off"))
		pgprot_wc = PAGE_KERNEL_SUC;
		wc_enabled = false;
	else
		pr_warn("Unknown writecombine setting \"%s\".\n", p);