|
@@ -16,6 +16,7 @@
|
|
|
#include <sbi_utils/fdt/fdt_domain.h>
|
|
|
#include <sbi_utils/fdt/fdt_fixup.h>
|
|
|
#include <sbi_utils/fdt/fdt_helper.h>
|
|
|
+#include <sbi_utils/fdt/fdt_pmu.h>
|
|
|
#include <sbi_utils/irqchip/fdt_irqchip.h>
|
|
|
#include <sbi_utils/serial/fdt_serial.h>
|
|
|
#include <sbi_utils/timer/fdt_timer.h>
|
|
@@ -184,6 +185,33 @@ static u64 generic_tlbr_flush_limit(void)
|
|
|
return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
|
|
|
}
|
|
|
|
|
|
+static int generic_pmu_init(void)
|
|
|
+{
|
|
|
+ return fdt_pmu_setup(sbi_scratch_thishart_arg1_ptr());
|
|
|
+}
|
|
|
+
|
|
|
+static uint64_t generic_pmu_xlate_to_mhpmevent(uint32_t event_idx,
|
|
|
+ uint64_t data)
|
|
|
+{
|
|
|
+ uint64_t evt_val = 0;
|
|
|
+
|
|
|
+ /* data is valid only for raw events and is equal to event selector */
|
|
|
+ if (event_idx == SBI_PMU_EVENT_RAW_IDX)
|
|
|
+ evt_val = data;
|
|
|
+ else {
|
|
|
+ /**
|
|
|
+ * Generic platform follows the SBI specification recommendation
|
|
|
+ * i.e. zero extended event_idx is used as mhpmevent value for
|
|
|
+ * hardware general/cache events if platform does't define one.
|
|
|
+ */
|
|
|
+ evt_val = fdt_pmu_get_select_value(event_idx);
|
|
|
+ if (!evt_val)
|
|
|
+ evt_val = (uint64_t)event_idx;
|
|
|
+ }
|
|
|
+
|
|
|
+ return evt_val;
|
|
|
+}
|
|
|
+
|
|
|
const struct sbi_platform_operations platform_ops = {
|
|
|
.early_init = generic_early_init,
|
|
|
.final_init = generic_final_init,
|
|
@@ -195,6 +223,8 @@ const struct sbi_platform_operations platform_ops = {
|
|
|
.irqchip_exit = fdt_irqchip_exit,
|
|
|
.ipi_init = fdt_ipi_init,
|
|
|
.ipi_exit = fdt_ipi_exit,
|
|
|
+ .pmu_init = generic_pmu_init,
|
|
|
+ .pmu_xlate_to_mhpmevent = generic_pmu_xlate_to_mhpmevent,
|
|
|
.get_tlbr_flush_limit = generic_tlbr_flush_limit,
|
|
|
.timer_init = fdt_timer_init,
|
|
|
.timer_exit = fdt_timer_exit,
|