Skip to content

Commit e021ae7

Browse files
prabhakarladpalmer-dabbelt
authored andcommitted
riscv: errata: Add Andes alternative ports
Add required ports of the Alternative scheme for Andes CPU cores. I/O Coherence Port (IOCP) provides an AXI interface for connecting external non-caching masters, such as DMA controllers. IOCP is a specification option and is disabled on the Renesas RZ/Five SoC due to this reason cache management needs a software workaround. Signed-off-by: Lad Prabhakar <[email protected]> Reviewed-by: Conor Dooley <[email protected]> Tested-by: Conor Dooley <[email protected]> # tyre-kicking on a d1 Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent d6ca3a5 commit e021ae7

File tree

7 files changed

+102
-0
lines changed

7 files changed

+102
-0
lines changed

arch/riscv/Kconfig.errata

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
menu "CPU errata selection"
22

3+
config ERRATA_ANDES
4+
bool "Andes AX45MP errata"
5+
depends on RISCV_ALTERNATIVE
6+
help
7+
All Andes errata Kconfig depend on this Kconfig. Disabling
8+
this Kconfig will disable all Andes errata. Please say "Y"
9+
here if your platform uses Andes CPU cores.
10+
11+
Otherwise, please say "N" here to avoid unnecessary overhead.
12+
13+
config ERRATA_ANDES_CMO
14+
bool "Apply Andes cache management errata"
15+
depends on ERRATA_ANDES && MMU && ARCH_R9A07G043
16+
select RISCV_DMA_NONCOHERENT
17+
default y
18+
help
19+
This will apply the cache management errata to handle the
20+
non-standard handling on non-coherent operations on Andes cores.
21+
22+
If you don't know what to do here, say "Y".
23+
324
config ERRATA_SIFIVE
425
bool "SiFive errata"
526
depends on RISCV_ALTERNATIVE

arch/riscv/errata/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ ifdef CONFIG_RELOCATABLE
22
KBUILD_CFLAGS += -fno-pie
33
endif
44

5+
obj-$(CONFIG_ERRATA_ANDES) += andes/
56
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
67
obj-$(CONFIG_ERRATA_THEAD) += thead/

arch/riscv/errata/andes/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
obj-y += errata.o

arch/riscv/errata/andes/errata.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Erratas to be applied for Andes CPU cores
4+
*
5+
* Copyright (C) 2023 Renesas Electronics Corporation.
6+
*
7+
* Author: Lad Prabhakar <[email protected]>
8+
*/
9+
10+
#include <linux/memory.h>
11+
#include <linux/module.h>
12+
13+
#include <asm/alternative.h>
14+
#include <asm/cacheflush.h>
15+
#include <asm/errata_list.h>
16+
#include <asm/patch.h>
17+
#include <asm/processor.h>
18+
#include <asm/sbi.h>
19+
#include <asm/vendorid_list.h>
20+
21+
#define ANDESTECH_AX45MP_MARCHID 0x8000000000008a45UL
22+
#define ANDESTECH_AX45MP_MIMPID 0x500UL
23+
#define ANDESTECH_SBI_EXT_ANDES 0x0900031E
24+
25+
#define ANDES_SBI_EXT_IOCP_SW_WORKAROUND 1
26+
27+
static long ax45mp_iocp_sw_workaround(void)
28+
{
29+
struct sbiret ret;
30+
31+
/*
32+
* ANDES_SBI_EXT_IOCP_SW_WORKAROUND SBI EXT checks if the IOCP is missing and
33+
* cache is controllable only then CMO will be applied to the platform.
34+
*/
35+
ret = sbi_ecall(ANDESTECH_SBI_EXT_ANDES, ANDES_SBI_EXT_IOCP_SW_WORKAROUND,
36+
0, 0, 0, 0, 0, 0);
37+
38+
return ret.error ? 0 : ret.value;
39+
}
40+
41+
static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid)
42+
{
43+
if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO))
44+
return false;
45+
46+
if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID)
47+
return false;
48+
49+
if (!ax45mp_iocp_sw_workaround())
50+
return false;
51+
52+
/* Set this just to make core cbo code happy */
53+
riscv_cbom_block_size = 1;
54+
riscv_noncoherent_supported();
55+
56+
return true;
57+
}
58+
59+
void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
60+
unsigned long archid, unsigned long impid,
61+
unsigned int stage)
62+
{
63+
errata_probe_iocp(stage, archid, impid);
64+
65+
/* we have nothing to patch here ATM so just return back */
66+
}

arch/riscv/include/asm/alternative.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ struct alt_entry {
4646
u32 patch_id; /* The patch ID (erratum ID or cpufeature ID) */
4747
};
4848

49+
void andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
50+
unsigned long archid, unsigned long impid,
51+
unsigned int stage);
4952
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
5053
unsigned long archid, unsigned long impid,
5154
unsigned int stage);

arch/riscv/include/asm/errata_list.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
#include <asm/hwcap.h>
1212
#include <asm/vendorid_list.h>
1313

14+
#ifdef CONFIG_ERRATA_ANDES
15+
#define ERRATA_ANDESTECH_NO_IOCP 0
16+
#define ERRATA_ANDESTECH_NUMBER 1
17+
#endif
18+
1419
#ifdef CONFIG_ERRATA_SIFIVE
1520
#define ERRATA_SIFIVE_CIP_453 0
1621
#define ERRATA_SIFIVE_CIP_1200 1

arch/riscv/kernel/alternative.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info
4545

4646
cpu_mfr_info->feature_probe_func = NULL;
4747
switch (cpu_mfr_info->vendor_id) {
48+
#ifdef CONFIG_ERRATA_ANDES
49+
case ANDESTECH_VENDOR_ID:
50+
cpu_mfr_info->patch_func = andes_errata_patch_func;
51+
break;
52+
#endif
4853
#ifdef CONFIG_ERRATA_SIFIVE
4954
case SIFIVE_VENDOR_ID:
5055
cpu_mfr_info->patch_func = sifive_errata_patch_func;

0 commit comments

Comments
 (0)