mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-11-22 19:01:33 +00:00
platform: generic: spacemit: add K1
Add initial platform support for the SpacemiT K1 SoC, including early/final init hooks, cold boot handling, and CCI-550 snoop/DVM enablement. Co-authored-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> Signed-off-by: Xianbin Zhu <xianbin.zhu@linux.spacemit.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/all/15169E392597D319+aOcKujCl8mz4XK4L@kernel.org/ [1] Link: https://lore.kernel.org/r/20250925-smt-k1-8-cores-v3-1-0885a8a70f8e@linux.spacemit.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
113
platform/generic/spacemit/k1.c
Normal file
113
platform/generic/spacemit/k1.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 SpacemiT
|
||||
* Authors:
|
||||
* Xianbin Zhu <xianbin.zhu@linux.spacemit.com>
|
||||
* Troy Mitchell <troy.mitchell@linux.spacemit.com>
|
||||
*/
|
||||
|
||||
#include <platform_override.h>
|
||||
#include <sbi/riscv_io.h>
|
||||
#include <sbi/sbi_hsm.h>
|
||||
#include <spacemit/k1.h>
|
||||
|
||||
/* only use 0-1 cluster in SpacemiT K1 */
|
||||
static const int cci_map[] = {
|
||||
PLAT_CCI_CLUSTER0_IFACE_IX,
|
||||
PLAT_CCI_CLUSTER1_IFACE_IX,
|
||||
};
|
||||
|
||||
static void cci_enable_snoop_dvm_reqs(unsigned int master_id)
|
||||
{
|
||||
int slave_if_id = cci_map[master_id];
|
||||
|
||||
/*
|
||||
* Enable Snoops and DVM messages, no need for Read/Modify/Write as
|
||||
* rest of bits are write ignore
|
||||
*/
|
||||
writel(CCI_550_SNOOP_CTRL_ENABLE_DVMS | CCI_550_SNOOP_CTRL_ENABLE_SNOOPS,
|
||||
(void *)(u64)CCI_550_PLATFORM_CCI_ADDR +
|
||||
CCI_550_SLAVE_IFACE_OFFSET(slave_if_id) + CCI_550_SNOOP_CTRL);
|
||||
|
||||
/*
|
||||
* Wait for the completion of the write to the Snoop Control Register
|
||||
* before testing the change_pending bit
|
||||
*/
|
||||
mb();
|
||||
|
||||
/* Wait for the dust to settle down */
|
||||
while ((readl((void *)(u64)CCI_550_PLATFORM_CCI_ADDR + CCI_550_STATUS) &
|
||||
CCI_550_STATUS_CHANGE_PENDING))
|
||||
;
|
||||
}
|
||||
|
||||
static void spacemit_k1_pre_init(void)
|
||||
{
|
||||
unsigned int clusterid, cluster_enabled = 0;
|
||||
struct sbi_scratch *scratch;
|
||||
int i;
|
||||
|
||||
scratch = sbi_scratch_thishart_ptr();
|
||||
|
||||
writel(scratch->warmboot_addr, (unsigned int *)C0_RVBADDR_LO_ADDR);
|
||||
writel(scratch->warmboot_addr >> 32, (unsigned int *)C0_RVBADDR_HI_ADDR);
|
||||
|
||||
writel(scratch->warmboot_addr, (unsigned int *)C1_RVBADDR_LO_ADDR);
|
||||
writel(scratch->warmboot_addr >> 32, (unsigned int *)C1_RVBADDR_HI_ADDR);
|
||||
|
||||
for (i = 0; i < PLATFORM_MAX_CPUS; i++) {
|
||||
clusterid = CPU_TO_CLUSTER(i);
|
||||
|
||||
if (!(cluster_enabled & (1 << clusterid))) {
|
||||
cluster_enabled |= 1 << clusterid;
|
||||
cci_enable_snoop_dvm_reqs(clusterid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform early initialization.
|
||||
*/
|
||||
static int spacemit_k1_early_init(bool cold_boot)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = generic_early_init(cold_boot);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
csr_set(CSR_MSETUP, MSETUP_DE | MSETUP_IE | MSETUP_BPE |
|
||||
MSETUP_PFE | MSETUP_MME | MSETUP_ECCE);
|
||||
|
||||
if (cold_boot)
|
||||
spacemit_k1_pre_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool spacemit_cold_boot_allowed(u32 hartid)
|
||||
{
|
||||
csr_set(CSR_ML2SETUP, 1 << (hartid % PLATFORM_MAX_CPUS_PER_CLUSTER));
|
||||
|
||||
return !hartid;
|
||||
}
|
||||
|
||||
static int spacemit_k1_platform_init(const void *fdt, int nodeoff,
|
||||
const struct fdt_match *match)
|
||||
{
|
||||
generic_platform_ops.early_init = spacemit_k1_early_init;
|
||||
generic_platform_ops.cold_boot_allowed = spacemit_cold_boot_allowed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct fdt_match spacemit_k1_match[] = {
|
||||
{ .compatible = "spacemit,k1" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
const struct fdt_driver spacemit_k1 = {
|
||||
.match_table = spacemit_k1_match,
|
||||
.init = spacemit_k1_platform_init,
|
||||
};
|
||||
Reference in New Issue
Block a user