Skip to content

Commit 278be83

Browse files
Icenowychenhuacai
authored andcommitted
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: Icenowy Zheng <uwu@icenowy.me> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 477a0eb commit 278be83

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

arch/loongarch/include/asm/io.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
5252
* @offset: bus address of the memory
5353
* @size: size of the resource to map
5454
*/
55-
extern pgprot_t pgprot_wc;
56-
5755
#define ioremap_wc(offset, size) \
58-
ioremap_prot((offset), (size), pgprot_val(pgprot_wc))
56+
ioremap_prot((offset), (size), \
57+
pgprot_val(wc_enabled ? PAGE_KERNEL_WUC : PAGE_KERNEL_SUC))
5958

6059
#define ioremap_cache(offset, size) \
6160
ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL))

arch/loongarch/include/asm/pgtable-bits.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
105105
return __pgprot(prot);
106106
}
107107

108+
extern bool wc_enabled;
109+
108110
#define pgprot_writecombine pgprot_writecombine
109111

110112
static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
111113
{
112114
unsigned long prot = pgprot_val(_prot);
113115

114-
prot = (prot & ~_CACHE_MASK) | _CACHE_WUC;
116+
prot = (prot & ~_CACHE_MASK) | (wc_enabled ? _CACHE_WUC : _CACHE_SUC);
115117

116118
return __pgprot(prot);
117119
}

arch/loongarch/kernel/setup.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,19 @@ static void __init smbios_parse(void)
161161
}
162162

163163
#ifdef CONFIG_ARCH_WRITECOMBINE
164-
pgprot_t pgprot_wc = PAGE_KERNEL_WUC;
164+
bool wc_enabled = true;
165165
#else
166-
pgprot_t pgprot_wc = PAGE_KERNEL_SUC;
166+
bool wc_enabled = false;
167167
#endif
168168

169-
EXPORT_SYMBOL(pgprot_wc);
169+
EXPORT_SYMBOL(wc_enabled);
170170

171171
static int __init setup_writecombine(char *p)
172172
{
173173
if (!strcmp(p, "on"))
174-
pgprot_wc = PAGE_KERNEL_WUC;
174+
wc_enabled = true;
175175
else if (!strcmp(p, "off"))
176-
pgprot_wc = PAGE_KERNEL_SUC;
176+
wc_enabled = false;
177177
else
178178
pr_warn("Unknown writecombine setting \"%s\".\n", p);
179179

0 commit comments

Comments
 (0)