platform: generic: andes: add Andes SBI call to probe Andes PMA feature

Add a new Andes SBI call to check whether PPMA is supported by hardware
or not.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Ben Zong-You Xie
2024-07-23 15:57:26 +08:00
committed by Anup Patel
parent 17100394f9
commit 4a72abb5f4
4 changed files with 25 additions and 2 deletions

View File

@@ -19,6 +19,7 @@
#include <sbi/sbi_ipi.h> #include <sbi/sbi_ipi.h>
#include <sbi/sbi_init.h> #include <sbi/sbi_init.h>
#include <andes/andes.h> #include <andes/andes.h>
#include <andes/andes_sbi.h>
static struct smu_data smu = { 0 }; static struct smu_data smu = { 0 };
extern void __ae350_enable_coherency_warmboot(void); extern void __ae350_enable_coherency_warmboot(void);
@@ -120,4 +121,5 @@ const struct platform_override andes_ae350 = {
.final_init = ae350_final_init, .final_init = ae350_final_init,
.extensions_init = andes_pmu_extensions_init, .extensions_init = andes_pmu_extensions_init,
.pmu_init = andes_pmu_init, .pmu_init = andes_pmu_init,
.vendor_ext_provider = andes_sbi_vendor_ext_provider,
}; };

View File

@@ -241,7 +241,6 @@ static int andes_fdt_reserved_memory_fixup(void *fdt,
int andes_pma_setup_regions(const struct andes_pma_region *pma_regions, int andes_pma_setup_regions(const struct andes_pma_region *pma_regions,
unsigned int pma_regions_count) unsigned int pma_regions_count)
{ {
unsigned long mmsc = csr_read(CSR_MMSC_CFG);
unsigned int dt_populate_cnt; unsigned int dt_populate_cnt;
unsigned int i, j; unsigned int i, j;
unsigned long pa; unsigned long pa;
@@ -254,7 +253,7 @@ int andes_pma_setup_regions(const struct andes_pma_region *pma_regions,
if (pma_regions_count > ANDES_MAX_PMA_REGIONS) if (pma_regions_count > ANDES_MAX_PMA_REGIONS)
return SBI_EINVAL; return SBI_EINVAL;
if ((mmsc & MMSC_CFG_PPMA_MASK) == 0) if (!andes_sbi_probe_pma())
return SBI_ENOTSUPP; return SBI_ENOTSUPP;
/* Configure the PMA regions */ /* Configure the PMA regions */
@@ -290,3 +289,8 @@ int andes_pma_setup_regions(const struct andes_pma_region *pma_regions,
return 0; return 0;
} }
bool andes_sbi_probe_pma(void)
{
return (csr_read(CSR_MMSC_CFG) & MMSC_CFG_PPMA_MASK) ? true : false;
}

View File

@@ -5,12 +5,14 @@
*/ */
#include <andes/andes.h> #include <andes/andes.h>
#include <andes/andes_sbi.h> #include <andes/andes_sbi.h>
#include <andes/andes_pma.h>
#include <sbi/riscv_asm.h> #include <sbi/riscv_asm.h>
#include <sbi/sbi_error.h> #include <sbi/sbi_error.h>
enum sbi_ext_andes_fid { enum sbi_ext_andes_fid {
SBI_EXT_ANDES_FID0 = 0, /* Reserved for future use */ SBI_EXT_ANDES_FID0 = 0, /* Reserved for future use */
SBI_EXT_ANDES_IOCP_SW_WORKAROUND, SBI_EXT_ANDES_IOCP_SW_WORKAROUND,
SBI_EXT_ANDES_PMA_PROBE,
}; };
static bool andes_cache_controllable(void) static bool andes_cache_controllable(void)
@@ -41,6 +43,9 @@ int andes_sbi_vendor_ext_provider(long funcid,
case SBI_EXT_ANDES_IOCP_SW_WORKAROUND: case SBI_EXT_ANDES_IOCP_SW_WORKAROUND:
out->value = andes_apply_iocp_sw_workaround(); out->value = andes_apply_iocp_sw_workaround();
break; break;
case SBI_EXT_ANDES_PMA_PROBE:
out->value = andes_sbi_probe_pma();
break;
default: default:
return SBI_EINVAL; return SBI_EINVAL;

View File

@@ -47,4 +47,16 @@ struct andes_pma_region {
int andes_pma_setup_regions(const struct andes_pma_region *pma_regions, int andes_pma_setup_regions(const struct andes_pma_region *pma_regions,
unsigned int pma_regions_count); unsigned int pma_regions_count);
/**
* Programmable PMA(PPMA) is a feature for Andes. PPMA allows dynamic adjustment
* of memory attributes in the runtime. It contains a configurable amount of PMA
* entries implemented as CSRs to control the attributes of memory locations.
*
* Check if hardware supports PPMA
*
* @return true if PPMA is supported
* @return false if PPMA is not supported
*/
bool andes_sbi_probe_pma(void);
#endif /* _ANDES_PMA_H_ */ #endif /* _ANDES_PMA_H_ */