Commit e021ae7f authored by Lad Prabhakar's avatar Lad Prabhakar Committed by Palmer Dabbelt

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: default avatarLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: default avatarConor Dooley <conor.dooley@microchip.com>
Tested-by: Conor Dooley <conor.dooley@microchip.com> # tyre-kicking on a d1
Link: https://lore.kernel.org/r/20230818135723.80612-3-prabhakar.mahadev-lad.rj@bp.renesas.comSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent d6ca3a56
menu "CPU errata selection" menu "CPU errata selection"
config ERRATA_ANDES
bool "Andes AX45MP errata"
depends on RISCV_ALTERNATIVE
help
All Andes errata Kconfig depend on this Kconfig. Disabling
this Kconfig will disable all Andes errata. Please say "Y"
here if your platform uses Andes CPU cores.
Otherwise, please say "N" here to avoid unnecessary overhead.
config ERRATA_ANDES_CMO
bool "Apply Andes cache management errata"
depends on ERRATA_ANDES && MMU && ARCH_R9A07G043
select RISCV_DMA_NONCOHERENT
default y
help
This will apply the cache management errata to handle the
non-standard handling on non-coherent operations on Andes cores.
If you don't know what to do here, say "Y".
config ERRATA_SIFIVE config ERRATA_SIFIVE
bool "SiFive errata" bool "SiFive errata"
depends on RISCV_ALTERNATIVE depends on RISCV_ALTERNATIVE
......
...@@ -2,5 +2,6 @@ ifdef CONFIG_RELOCATABLE ...@@ -2,5 +2,6 @@ ifdef CONFIG_RELOCATABLE
KBUILD_CFLAGS += -fno-pie KBUILD_CFLAGS += -fno-pie
endif endif
obj-$(CONFIG_ERRATA_ANDES) += andes/
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/ obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
obj-$(CONFIG_ERRATA_THEAD) += thead/ obj-$(CONFIG_ERRATA_THEAD) += thead/
// SPDX-License-Identifier: GPL-2.0-only
/*
* Erratas to be applied for Andes CPU cores
*
* Copyright (C) 2023 Renesas Electronics Corporation.
*
* Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
*/
#include <linux/memory.h>
#include <linux/module.h>
#include <asm/alternative.h>
#include <asm/cacheflush.h>
#include <asm/errata_list.h>
#include <asm/patch.h>
#include <asm/processor.h>
#include <asm/sbi.h>
#include <asm/vendorid_list.h>
#define ANDESTECH_AX45MP_MARCHID 0x8000000000008a45UL
#define ANDESTECH_AX45MP_MIMPID 0x500UL
#define ANDESTECH_SBI_EXT_ANDES 0x0900031E
#define ANDES_SBI_EXT_IOCP_SW_WORKAROUND 1
static long ax45mp_iocp_sw_workaround(void)
{
struct sbiret ret;
/*
* ANDES_SBI_EXT_IOCP_SW_WORKAROUND SBI EXT checks if the IOCP is missing and
* cache is controllable only then CMO will be applied to the platform.
*/
ret = sbi_ecall(ANDESTECH_SBI_EXT_ANDES, ANDES_SBI_EXT_IOCP_SW_WORKAROUND,
0, 0, 0, 0, 0, 0);
return ret.error ? 0 : ret.value;
}
static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid)
{
if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO))
return false;
if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID)
return false;
if (!ax45mp_iocp_sw_workaround())
return false;
/* Set this just to make core cbo code happy */
riscv_cbom_block_size = 1;
riscv_noncoherent_supported();
return true;
}
void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage)
{
errata_probe_iocp(stage, archid, impid);
/* we have nothing to patch here ATM so just return back */
}
...@@ -46,6 +46,9 @@ struct alt_entry { ...@@ -46,6 +46,9 @@ struct alt_entry {
u32 patch_id; /* The patch ID (erratum ID or cpufeature ID) */ u32 patch_id; /* The patch ID (erratum ID or cpufeature ID) */
}; };
void andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid, unsigned long archid, unsigned long impid,
unsigned int stage); unsigned int stage);
......
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <asm/vendorid_list.h> #include <asm/vendorid_list.h>
#ifdef CONFIG_ERRATA_ANDES
#define ERRATA_ANDESTECH_NO_IOCP 0
#define ERRATA_ANDESTECH_NUMBER 1
#endif
#ifdef CONFIG_ERRATA_SIFIVE #ifdef CONFIG_ERRATA_SIFIVE
#define ERRATA_SIFIVE_CIP_453 0 #define ERRATA_SIFIVE_CIP_453 0
#define ERRATA_SIFIVE_CIP_1200 1 #define ERRATA_SIFIVE_CIP_1200 1
......
...@@ -45,6 +45,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info ...@@ -45,6 +45,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info
cpu_mfr_info->feature_probe_func = NULL; cpu_mfr_info->feature_probe_func = NULL;
switch (cpu_mfr_info->vendor_id) { switch (cpu_mfr_info->vendor_id) {
#ifdef CONFIG_ERRATA_ANDES
case ANDESTECH_VENDOR_ID:
cpu_mfr_info->patch_func = andes_errata_patch_func;
break;
#endif
#ifdef CONFIG_ERRATA_SIFIVE #ifdef CONFIG_ERRATA_SIFIVE
case SIFIVE_VENDOR_ID: case SIFIVE_VENDOR_ID:
cpu_mfr_info->patch_func = sifive_errata_patch_func; cpu_mfr_info->patch_func = sifive_errata_patch_func;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment