summaryrefslogtreecommitdiff
path: root/platform/andes/ae350/plicsw.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/andes/ae350/plicsw.c')
-rw-r--r--platform/andes/ae350/plicsw.c139
1 files changed, 0 insertions, 139 deletions
diff --git a/platform/andes/ae350/plicsw.c b/platform/andes/ae350/plicsw.c
deleted file mode 100644
index edbbb11..0000000
--- a/platform/andes/ae350/plicsw.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Andes Technology Corporation
- *
- * Authors:
- * Zong Li <zong@andestech.com>
- * Nylon Chen <nylon7@andestech.com>
- */
-
-#include <sbi/riscv_asm.h>
-#include <sbi/riscv_io.h>
-#include <sbi/sbi_types.h>
-#include "plicsw.h"
-#include "platform.h"
-
-static u32 plicsw_ipi_hart_count;
-static struct plicsw plicsw_dev[AE350_HART_COUNT];
-
-static inline void plicsw_claim(void)
-{
- u32 source_hart = current_hartid();
-
- plicsw_dev[source_hart].source_id =
- readl(plicsw_dev[source_hart].plicsw_claim);
-}
-
-static inline void plicsw_complete(void)
-{
- u32 source_hart = current_hartid();
- u32 source = plicsw_dev[source_hart].source_id;
-
- writel(source, plicsw_dev[source_hart].plicsw_claim);
-}
-
-static inline void plic_sw_pending(u32 target_hart)
-{
- /*
- * The pending array registers are w1s type.
- * IPI pending array mapping as following:
- *
- * Pending array start address: base + 0x1000
- * -------------------------------------
- * | hart 3 | hart 2 | hart 1 | hart 0 |
- * -------------------------------------
- * Each hart X can send IPI to another hart by setting the
- * corresponding bit in hart X own region(see the below).
- *
- * In each hart region:
- * -----------------------------------------------
- * | bit 7 | bit 6 | bit 5 | bit 4 | ... | bit 0 |
- * -----------------------------------------------
- * The bit 7 is used to send IPI to hart 0
- * The bit 6 is used to send IPI to hart 1
- * The bit 5 is used to send IPI to hart 2
- * The bit 4 is used to send IPI to hart 3
- */
- u32 source_hart = current_hartid();
- u32 target_offset = (PLICSW_PENDING_PER_HART - 1) - target_hart;
- u32 per_hart_offset = PLICSW_PENDING_PER_HART * source_hart;
- u32 val = 1 << target_offset << per_hart_offset;
-
- writel(val, plicsw_dev[source_hart].plicsw_pending);
-}
-
-void plicsw_ipi_send(u32 target_hart)
-{
- if (plicsw_ipi_hart_count <= target_hart)
- return;
-
- /* Set PLICSW IPI */
- plic_sw_pending(target_hart);
-}
-
-void plicsw_ipi_clear(u32 target_hart)
-{
- if (plicsw_ipi_hart_count <= target_hart)
- return;
-
- /* Clear PLICSW IPI */
- plicsw_claim();
- plicsw_complete();
-}
-
-int plicsw_warm_ipi_init(void)
-{
- u32 hartid = current_hartid();
-
- if (!plicsw_dev[hartid].plicsw_pending
- && !plicsw_dev[hartid].plicsw_enable
- && !plicsw_dev[hartid].plicsw_claim)
- return -1;
-
- /* Clear PLICSW IPI */
- plicsw_ipi_clear(hartid);
-
- return 0;
-}
-
-int plicsw_cold_ipi_init(unsigned long base, u32 hart_count)
-{
- /* Setup source priority */
- uint32_t *priority = (void *)base + PLICSW_PRIORITY_BASE;
-
- for (int i = 0; i < AE350_HART_COUNT * PLICSW_PENDING_PER_HART; i++)
- writel(1, &priority[i]);
-
- /* Setup target enable */
- uint32_t enable_mask = PLICSW_HART_MASK;
-
- for (int i = 0; i < AE350_HART_COUNT; i++) {
- uint32_t *enable = (void *)base + PLICSW_ENABLE_BASE
- + PLICSW_ENABLE_PER_HART * i;
- writel(enable_mask, &enable[0]);
- enable_mask >>= 1;
- }
-
- /* Figure-out PLICSW IPI register address */
- plicsw_ipi_hart_count = hart_count;
-
- for (u32 hartid = 0; hartid < AE350_HART_COUNT; hartid++) {
- plicsw_dev[hartid].source_id = 0;
- plicsw_dev[hartid].plicsw_pending =
- (void *)base
- + PLICSW_PENDING_BASE
- + ((hartid / 4) * 4);
- plicsw_dev[hartid].plicsw_enable =
- (void *)base
- + PLICSW_ENABLE_BASE
- + PLICSW_ENABLE_PER_HART * hartid;
- plicsw_dev[hartid].plicsw_claim =
- (void *)base
- + PLICSW_CONTEXT_BASE
- + PLICSW_CONTEXT_CLAIM
- + PLICSW_CONTEXT_PER_HART * hartid;
- }
-
- return 0;
-}