From 8e941e7fe3b8244107832b931980006bf9b0dc55 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Sat, 7 Oct 2023 11:06:29 +0800 Subject: [PATCH] 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 Reviewed-by: Anup Patel --- platform/generic/Kconfig | 2 + platform/generic/allwinner/sun20i-d1.c | 51 +---------------- platform/generic/include/thead/c9xx_pmu.h | 7 +++ platform/generic/thead/Kconfig | 5 ++ platform/generic/thead/objects.mk | 2 + platform/generic/thead/thead_c9xx_pmu.c | 69 +++++++++++++++++++++++ 6 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 platform/generic/include/thead/c9xx_pmu.h create mode 100644 platform/generic/thead/Kconfig create mode 100644 platform/generic/thead/thead_c9xx_pmu.c diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig index e7bd94eb..ea3b5cf4 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 b9602843..e9388dba 100644 --- a/platform/generic/allwinner/sun20i-d1.c +++ b/platform/generic/allwinner/sun20i-d1.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -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 00000000..bb1d831a --- /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 00000000..e54e6210 --- /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 854bfbde..df2c61ba 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 00000000..d2058022 --- /dev/null +++ b/platform/generic/thead/thead_c9xx_pmu.c @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Authors: + * Inochi Amaoto + * Haijiao Liu + * + */ + +#include +#include +#include +#include +#include +#include + +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); +}