diff options
author | Inochi Amaoto <inochiama@outlook.com> | 2023-10-07 11:06:29 +0800 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2023-11-14 21:53:45 +0530 |
commit | 8e941e7fe3b8244107832b931980006bf9b0dc55 (patch) | |
tree | 174bb0093473c4390bf42569e0103357ac2c345e /platform | |
parent | c1a69874476810aa47bb1ca8bbe7697f855dba5f (diff) | |
download | opensbi-8e941e7fe3b8244107832b931980006bf9b0dc55.zip opensbi-8e941e7fe3b8244107832b931980006bf9b0dc55.tar.gz opensbi-8e941e7fe3b8244107832b931980006bf9b0dc55.tar.bz2 |
platform: generic: thead: separate implement of T-HEAD c9xx pmu
Separate the implement of T-HEAD c9xx pmu to allow any platform with
c9xx cores can use it.
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'platform')
-rw-r--r-- | platform/generic/Kconfig | 2 | ||||
-rw-r--r-- | platform/generic/allwinner/sun20i-d1.c | 51 | ||||
-rw-r--r-- | platform/generic/include/thead/c9xx_pmu.h | 7 | ||||
-rw-r--r-- | platform/generic/thead/Kconfig | 5 | ||||
-rw-r--r-- | platform/generic/thead/objects.mk | 2 | ||||
-rw-r--r-- | platform/generic/thead/thead_c9xx_pmu.c | 69 |
6 files changed, 87 insertions, 49 deletions
diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig index e7bd94e..ea3b5cf 100644 --- a/platform/generic/Kconfig +++ b/platform/generic/Kconfig @@ -26,6 +26,7 @@ config PLATFORM_GENERIC_MINOR_VER config PLATFORM_ALLWINNER_D1 bool "Allwinner D1 support" depends on FDT_IRQCHIP_PLIC + select THEAD_C9XX_PMU default n config PLATFORM_ANDES_AE350 @@ -57,5 +58,6 @@ config PLATFORM_THEAD default n source "$(OPENSBI_SRC_DIR)/platform/generic/andes/Kconfig" +source "$(OPENSBI_SRC_DIR)/platform/generic/thead/Kconfig" endif diff --git a/platform/generic/allwinner/sun20i-d1.c b/platform/generic/allwinner/sun20i-d1.c index b960284..e9388db 100644 --- a/platform/generic/allwinner/sun20i-d1.c +++ b/platform/generic/allwinner/sun20i-d1.c @@ -6,6 +6,7 @@ #include <platform_override.h> #include <thead/c9xx_encoding.h> +#include <thead/c9xx_pmu.h> #include <sbi/riscv_asm.h> #include <sbi/riscv_io.h> #include <sbi/sbi_bitops.h> @@ -223,58 +224,10 @@ static int sun20i_d1_fdt_fixup(void *fdt, const struct fdt_match *match) return fdt_add_cpu_idle_states(fdt, sun20i_d1_cpu_idle_states); } -static void thead_c9xx_pmu_ctr_enable_irq(uint32_t ctr_idx) -{ - if (ctr_idx >= SBI_PMU_HW_CTR_MAX) - return; - - /** - * Clear out the OF bit so that next interrupt can be enabled. - * This should be done before starting interrupt to avoid unexcepted - * overflow interrupt. - */ - csr_clear(THEAD_C9XX_CSR_MCOUNTEROF, BIT(ctr_idx)); - - /** - * This register is described in C9xx document as the control register - * for enabling writes to the superuser state counter. However, if the - * corresponding bit is not set to 1, scounterof will always read as 0 - * when the counter register overflows. - */ - csr_set(THEAD_C9XX_CSR_MCOUNTERWEN, BIT(ctr_idx)); - - /** - * SSCOFPMF uses the OF bit for enabling/disabling the interrupt, - * while the C9XX has designated enable bits. - * So enable per-counter interrupt on C9xx here. - */ - csr_set(THEAD_C9XX_CSR_MCOUNTERINTEN, BIT(ctr_idx)); -} - -static void thead_c9xx_pmu_ctr_disable_irq(uint32_t ctr_idx) -{ - /** - * There is no need to clear the bit of mcounterwen, it will expire - * after setting the csr mcountinhibit. - */ - csr_clear(THEAD_C9XX_CSR_MCOUNTERINTEN, BIT(ctr_idx)); -} - -static int thead_c9xx_pmu_irq_bit(void) -{ - return THEAD_C9XX_MIP_MOIP; -} - -const struct sbi_pmu_device thead_c9xx_pmu_device = { - .hw_counter_enable_irq = thead_c9xx_pmu_ctr_enable_irq, - .hw_counter_disable_irq = thead_c9xx_pmu_ctr_disable_irq, - .hw_counter_irq_bit = thead_c9xx_pmu_irq_bit, -}; - static int sun20i_d1_extensions_init(const struct fdt_match *match, struct sbi_hart_features *hfeatures) { - sbi_pmu_set_device(&thead_c9xx_pmu_device); + thead_c9xx_register_pmu_device(); /* auto-detection doesn't work on t-head c9xx cores */ /* D1 has 29 mhpmevent csrs, but only 3-9,13-17 have valid value */ diff --git a/platform/generic/include/thead/c9xx_pmu.h b/platform/generic/include/thead/c9xx_pmu.h new file mode 100644 index 0000000..bb1d831 --- /dev/null +++ b/platform/generic/include/thead/c9xx_pmu.h @@ -0,0 +1,7 @@ + +#ifndef __RISCV_THEAD_C9XX_PMU_H____ +#define __RISCV_THEAD_C9XX_PMU_H____ + +void thead_c9xx_register_pmu_device(void); + +#endif // __RISCV_THEAD_C9XX_PMU_H____ diff --git a/platform/generic/thead/Kconfig b/platform/generic/thead/Kconfig new file mode 100644 index 0000000..e54e621 --- /dev/null +++ b/platform/generic/thead/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-2-Clause + +config THEAD_C9XX_PMU + bool "T-HEAD c9xx M-mode PMU support" + default n diff --git a/platform/generic/thead/objects.mk b/platform/generic/thead/objects.mk index 854bfbd..df2c61b 100644 --- a/platform/generic/thead/objects.mk +++ b/platform/generic/thead/objects.mk @@ -5,6 +5,8 @@ # Copyright (C) 2023 Alibaba Group Holding Limited. # +platform-objs-$(CONFIG_THEAD_C9XX_PMU) += thead/thead_c9xx_pmu.o + carray-platform_override_modules-$(CONFIG_PLATFORM_THEAD) += thead_generic platform-objs-$(CONFIG_PLATFORM_THEAD) += thead/thead-generic.o platform-objs-$(CONFIG_PLATFORM_THEAD) += thead/thead-trap-handler.o diff --git a/platform/generic/thead/thead_c9xx_pmu.c b/platform/generic/thead/thead_c9xx_pmu.c new file mode 100644 index 0000000..d205802 --- /dev/null +++ b/platform/generic/thead/thead_c9xx_pmu.c @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Authors: + * Inochi Amaoto <inochiama@outlook.com> + * Haijiao Liu <haijiao.liu@sophgo.com> + * + */ + +#include <thead/c9xx_encoding.h> +#include <thead/c9xx_pmu.h> +#include <sbi/riscv_asm.h> +#include <sbi/sbi_bitops.h> +#include <sbi/sbi_ecall_interface.h> +#include <sbi/sbi_pmu.h> + +static void thead_c9xx_pmu_ctr_enable_irq(uint32_t ctr_idx) +{ + if (ctr_idx >= SBI_PMU_HW_CTR_MAX) + return; + + /** + * Clear out the OF bit so that next interrupt can be enabled. + * This should be done before starting interrupt to avoid unexcepted + * overflow interrupt. + */ + csr_clear(THEAD_C9XX_CSR_MCOUNTEROF, BIT(ctr_idx)); + + /** + * This register is described in C9xx document as the control register + * for enabling writes to the superuser state counter. However, if the + * corresponding bit is not set to 1, scounterof will always read as 0 + * when the counter register overflows. + */ + csr_set(THEAD_C9XX_CSR_MCOUNTERWEN, BIT(ctr_idx)); + + /** + * SSCOFPMF uses the OF bit for enabling/disabling the interrupt, + * while the C9XX has designated enable bits. + * So enable per-counter interrupt on C9xx here. + */ + csr_set(THEAD_C9XX_CSR_MCOUNTERINTEN, BIT(ctr_idx)); +} + +static void thead_c9xx_pmu_ctr_disable_irq(uint32_t ctr_idx) +{ + /** + * There is no need to clear the bit of mcounterwen, it will expire + * after setting the csr mcountinhibit. + */ + csr_clear(THEAD_C9XX_CSR_MCOUNTERINTEN, BIT(ctr_idx)); +} + +static int thead_c9xx_pmu_irq_bit(void) +{ + return THEAD_C9XX_MIP_MOIP; +} + +static const struct sbi_pmu_device thead_c9xx_pmu_device = { + .name = "thead,c900-pmu", + .hw_counter_enable_irq = thead_c9xx_pmu_ctr_enable_irq, + .hw_counter_disable_irq = thead_c9xx_pmu_ctr_disable_irq, + .hw_counter_irq_bit = thead_c9xx_pmu_irq_bit, +}; + +void thead_c9xx_register_pmu_device(void) +{ + sbi_pmu_set_device(&thead_c9xx_pmu_device); +} |