Update for v1.0.11

This commit is contained in:
James Deng 2024-08-01 22:09:26 +08:00
parent 94bf83cc0b
commit 1600b3620d
10 changed files with 245 additions and 45 deletions

1
debian/control vendored
View file

@ -11,6 +11,7 @@ Rules-Requires-Root: no
Vcs-Browser: https://salsa.debian.org/opensbi-team/opensbi
Vcs-Git: https://salsa.debian.org/opensbi-team/opensbi.git
Homepage: https://github.com/riscv-software-src/opensbi
XBS-Commit-Id:
Package: opensbi-spacemit
Architecture: all

10
debian/rules vendored
View file

@ -10,9 +10,19 @@ else
VERBOSE=0
endif
# 检查是否在 Git 仓库中,并获取 commit ID
GIT_INSIDE := $(shell git rev-parse --is-inside-work-tree 2>/dev/null)
ifeq ($(GIT_INSIDE),true)
COMMIT_ID := $(shell git rev-parse --short HEAD)
endif
%:
dh $@
override_dh_auto_configure:
sed -i "s/XBS-Commit-Id:.*/XBS-Commit-Id: $(COMMIT_ID)/" debian/control
dh_auto_configure
override_dh_auto_build:
make \
V=$(VERBOSE) \

View file

@ -197,4 +197,33 @@ static inline void csi_flush_l2_cache(bool hw)
writel((1 << L2_CACHE_FLUSH_HW_TYPE_BIT_OFFSET) | (1 << L2_CACHE_FLUSH_HW_EN_BIT_OFFSET), cr);
}
}
static inline void csi_flush_l2_cache_hart(bool hw, int hartid)
{
uintptr_t *cr =(MPIDR_AFFLVL1_VAL(hartid) == 0) ? (uintptr_t *)CLUSTER0_L2_CACHE_FLUSH_REG_BASE :
(uintptr_t *)CLUSTER1_L2_CACHE_FLUSH_REG_BASE;
if (!hw) {
writel(0x0, cr);
/* flush l2 cache */
writel(readl(cr) | (1 << L2_CACHE_FLUSH_REQUEST_BIT_OFFSET), cr);
/* k1pro */
if (L2_CACHE_FLUSH_REQUEST_BIT_OFFSET == L2_CACHE_FLUSH_DONE_BIT_OFFSET)
while (readl(cr) & (1 << L2_CACHE_FLUSH_DONE_BIT_OFFSET));
else /* k1x */ {
/* clear the request */
while (1) {
if ((readl(cr) & (1 << L2_CACHE_FLUSH_DONE_BIT_OFFSET)) == 0)
break;
__mdelay();
}
writel(readl(cr) & ~(1 << L2_CACHE_FLUSH_REQUEST_BIT_OFFSET), cr);
}
} else {
/* k1pro */
if (L2_CACHE_FLUSH_REQUEST_BIT_OFFSET == L2_CACHE_FLUSH_DONE_BIT_OFFSET)
return /* do nothing */;
writel((1 << L2_CACHE_FLUSH_HW_TYPE_BIT_OFFSET) | (1 << L2_CACHE_FLUSH_HW_EN_BIT_OFFSET), cr);
}
}
#endif

View file

@ -81,10 +81,10 @@ int psci_cpu_off(void)
* The only error cpu_off can return is E_DENIED. So check if that's
* indeed the case.
*/
if (rc != PSCI_E_DENIED) {
sbi_printf("%s:%d, err\n", __func__, __LINE__);
sbi_hart_hang();
}
// if (rc != PSCI_E_DENIED) {
// sbi_printf("%s:%d, err\n", __func__, __LINE__);
// sbi_hart_hang();
// }
return rc;
}

View file

@ -30,7 +30,8 @@ void spacemit_top_on(u_register_t mpidr)
(1 << CLUSTER_BIT14_OFFSET) |
(1 << CLUSTER_BIT30_OFFSET) |
(1 << CLUSTER_BIT25_OFFSET) |
(1 << CLUSTER_BIT13_OFFSET));
(1 << CLUSTER_BIT13_OFFSET) |
(1 << CLUSTER_VOTE_AP_SLPEN));
writel(value, cluster0_acpr);
value = readl(cluster1_acpr);
@ -42,7 +43,8 @@ void spacemit_top_on(u_register_t mpidr)
(1 << CLUSTER_BIT14_OFFSET) |
(1 << CLUSTER_BIT30_OFFSET) |
(1 << CLUSTER_BIT25_OFFSET) |
(1 << CLUSTER_BIT13_OFFSET));
(1 << CLUSTER_BIT13_OFFSET) |
(1 << CLUSTER_VOTE_AP_SLPEN));
writel(value, cluster1_acpr);
}
@ -60,7 +62,7 @@ void spacemit_top_off(u_register_t mpidr)
(1 << CLUSTER_DDRSD_OFFSET) |
(1 << CLUSTER_APBSD_OFFSET) |
(1 << CLUSTER_VCXOSD_OFFSET) |
(1 << 3) |
(1 << CLUSTER_VOTE_AP_SLPEN) |
(1 << CLUSTER_BIT29_OFFSET) |
(1 << CLUSTER_BIT14_OFFSET) |
(1 << CLUSTER_BIT30_OFFSET) |
@ -73,7 +75,7 @@ void spacemit_top_off(u_register_t mpidr)
(1 << CLUSTER_DDRSD_OFFSET) |
(1 << CLUSTER_APBSD_OFFSET) |
(1 << CLUSTER_VCXOSD_OFFSET) |
(1 << 3) |
(1 << CLUSTER_VOTE_AP_SLPEN) |
(1 << CLUSTER_BIT29_OFFSET) |
(1 << CLUSTER_BIT14_OFFSET) |
(1 << CLUSTER_BIT30_OFFSET) |
@ -279,6 +281,82 @@ void spacemit_wakeup_cpu(u_register_t mpidr)
writel(1 << target_cpu_idx, cpu_reset_base);
}
int spacemit_core_enter_c2(u_register_t mpidr)
{
unsigned int value;
/* wait the cpu enter c2 */
value = readl((unsigned int *)0xd4282890);
if (mpidr == 0) {
if (value & (1 << 6))
return 1;
} else if (mpidr == 1) {
if (value & (1 << 9))
return 1;
} else if (mpidr == 2) {
if (value & (1 << 12))
return 1;
} else if (mpidr == 3) {
if (value & (1 << 15))
return 1;
} else if (mpidr == 4) {
if (value & (1 << 22))
return 1;
} else if (mpidr == 5) {
if (value & (1 << 25))
return 1;
} else if (mpidr == 6) {
if (value & (1 << 28))
return 1;
} else if (mpidr == 7) {
if (value & (1 << 31))
return 1;
} else {
return 0;
}
return 0;
}
void spacemit_wait_core_enter_c2(u_register_t mpidr)
{
unsigned int value;
while (1) {
/* wait the cpu enter c2 */
value = readl((unsigned int *)0xd4282890);
if (mpidr == 0) {
if (value & (1 << 6))
return;
} else if (mpidr == 1) {
if (value & (1 << 9))
return;
} else if (mpidr == 2) {
if (value & (1 << 12))
return;
} else if (mpidr == 3) {
if (value & (1 << 15))
return;
} else if (mpidr == 4) {
if (value & (1 << 22))
return;
} else if (mpidr == 5) {
if (value & (1 << 25))
return;
} else if (mpidr == 6) {
if (value & (1 << 28))
return;
} else if (mpidr == 7) {
if (value & (1 << 31))
return;
} else {
;
}
}
}
void spacemit_assert_cpu(u_register_t mpidr)
{
unsigned int target_cpu_idx;

View file

@ -1,14 +1,20 @@
#include <sbi/sbi_types.h>
#include <sbi/riscv_locks.h>
#include <sbi/riscv_asm.h>
#include <sbi_utils/cci/cci.h>
#include <sbi_utils/psci/psci.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_ipi.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_hsm.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_hartmask.h>
#include <sbi_utils/psci/plat/arm/common/arm_def.h>
#include <sbi_utils/irqchip/fdt_irqchip_plic.h>
#include <sbi_utils/cache/cacheflush.h>
#include "underly_implement.h"
#include "../../psci_private.h"
#define CORE_PWR_STATE(state) \
((state)->pwr_domain_state[MPIDR_AFFLVL0])
@ -20,17 +26,39 @@
/* reserved for future used */
/* unsigned long __plic_regsave_offset_ptr; */
static spinlock_t psciipi_lock = SPIN_LOCK_INITIALIZER;
static struct sbi_hartmask psciipi_wait_hmask = { 0 };
static void wake_idle_harts(struct sbi_scratch *scratch, u32 hartid)
{
spin_lock(&psciipi_lock);
/* Send an IPI to all HARTs of the cluster that waiting for waked up */
for (u32 i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER * PLATFORM_CLUSTER_COUNT; i++) {
if (i != hartid) {
sbi_hartmask_set_hart(i, &psciipi_wait_hmask);
sbi_ipi_raw_send(i);
}
}
spin_unlock(&psciipi_lock);
}
static int spacemit_pwr_domain_on(u_register_t mpidr)
{
/* wakeup the cpu */
spacemit_wakeup_cpu(mpidr);
if (spacemit_core_enter_c2(mpidr)) {
spacemit_wakeup_cpu(mpidr);
} else {
sbi_ipi_raw_send(mpidr);
}
return 0;
}
static void spacemit_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
unsigned int hartid = current_hartid();
unsigned int hartid = current_hartid();
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
/* D1P */
@ -42,12 +70,12 @@ static void spacemit_pwr_domain_on_finish(const psci_power_state_t *target_state
* No need for locks as no other cpu is active at the moment.
*/
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
spacemit_cluster_on(hartid);
spacemit_cluster_on(hartid);
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* disable the tcm */
csr_write(CSR_TCMCFG, 0);
#endif
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(hartid));
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(hartid));
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* enable the tcm */
csr_write(CSR_TCMCFG, 1);
@ -62,6 +90,7 @@ static int spacemit_pwr_domain_off_early(const psci_power_state_t *target_state)
/* clear the external irq pending */
csr_clear(CSR_MIP, MIP_MEIP);
csr_clear(CSR_MIP, MIP_SEIP);
csr_clear(CSR_MIP, MIP_MSIP);
/* here we clear the sstimer pending if this core have */
if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC)) {
@ -76,28 +105,65 @@ static void spacemit_pwr_domain_off(const psci_power_state_t *target_state)
unsigned int hartid = current_hartid();
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* disable the tcm */
csr_write(CSR_TCMCFG, 0);
#endif
cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(hartid));
spacemit_cluster_off(hartid);
csi_flush_l2_cache(1);
/* power-off cluster */
spacemit_cluster_off(hartid);
}
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
/* D1P */
spacemit_top_off(hartid);
}
spacemit_assert_cpu(hartid);
}
static void spacemit_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
{
while (1) {
asm volatile ("wfi");
int hstate;
unsigned long saved_mie, cmip;
unsigned int hartid = current_hartid();
hstate = sbi_hsm_hart_get_state(sbi_domain_thishart_ptr(), hartid);
/* Save MIE CSR */
saved_mie = csr_read(CSR_MIE);
/* Set MSIE and MEIE bits to receive IPI */
if (hstate == SBI_HSM_STATE_SUSPENDED) {
csr_set(CSR_MIE, MIP_MSIP | MIP_MEIP);
/* Wait for wakeup source to finish using WFI */
do {
wfi();
cmip = csr_read(CSR_MIP);
} while (!(cmip & (MIP_MSIP | MIP_MEIP)));
} else {
csr_set(CSR_MIE, MIP_MSIP);
/* Wait for wakeup source to finish using WFI */
do {
wfi();
cmip = csr_read(CSR_MIP);
} while (!(cmip & (MIP_MSIP)));
spin_lock(&psciipi_lock);
if (sbi_hartmask_test_hart(hartid, &psciipi_wait_hmask)) {
sbi_ipi_raw_clear(hartid);
/* Restore MIE CSR */
csr_write(CSR_MIE, saved_mie);
spin_unlock(&psciipi_lock);
spacemit_assert_cpu(hartid);
while (1)
asm volatile ("wfi");
}
spin_unlock(&psciipi_lock);
}
/* Restore MIE CSR */
csr_write(CSR_MIE, saved_mie);
}
static void spacemit_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
@ -158,9 +224,8 @@ static int spacemit_validate_power_state(unsigned int power_state,
static void spacemit_pwr_domain_suspend(const psci_power_state_t *target_state)
{
unsigned int clusterid;
unsigned int hartid = current_hartid();
/*
* CSS currently supports retention only at cpu level. Just return
* as nothing is to be done for retention.
@ -168,30 +233,40 @@ static void spacemit_pwr_domain_suspend(const psci_power_state_t *target_state)
if (CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET)
return;
if (CORE_PWR_STATE(target_state) != ARM_LOCAL_STATE_OFF) {
sbi_printf("%s:%d\n", __func__, __LINE__);
sbi_hart_hang();
}
/* Cluster is to be turned off, so disable coherency */
if (CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
clusterid = MPIDR_AFFLVL1_VAL(hartid);
/* power-off cluster */
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
spacemit_cluster_off(hartid);
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* disable the tcm */
csr_write(CSR_TCMCFG, 0);
#endif
cci_disable_snoop_dvm_reqs(clusterid);
spacemit_cluster_off(hartid);
csi_flush_l2_cache(1);
}
wake_idle_harts(NULL, hartid);
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
/* D1P & D2 */
csi_flush_l2_cache_hart(0, 0);
csi_flush_l2_cache_hart(0, PLATFORM_MAX_CPUS_PER_CLUSTER);
cci_disable_snoop_dvm_reqs(0);
cci_disable_snoop_dvm_reqs(1);
/* assert othter cpu & wait other cpu enter c2 */
for (u32 i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER * PLATFORM_CLUSTER_COUNT; i++) {
if (i != hartid) {
spacemit_wait_core_enter_c2(i);
}
}
spacemit_assert_cpu(hartid);
spacemit_top_off(hartid);
}
spacemit_assert_cpu(hartid);
}
static void spacemit_pwr_domain_suspend_finish(const psci_power_state_t *target_state)

View file

@ -9,6 +9,8 @@ void spacemit_cluster_on(u_register_t mpidr);
void spacemit_cluster_off(u_register_t mpidr);
void spacemit_wakeup_cpu(u_register_t mpidr);
void spacemit_assert_cpu(u_register_t mpidr);
int spacemit_core_enter_c2(u_register_t mpidr);
void spacemit_wait_core_enter_c2(u_register_t mpidr);
void spacemit_deassert_cpu(void);
#endif

View file

@ -30,6 +30,7 @@ static const struct fdt_match serial_uart8250_match[] = {
{ .compatible = "ns16550" },
{ .compatible = "ns16550a" },
{ .compatible = "snps,dw-apb-uart" },
{ .compatible = "spacemit,pxa-uart" },
{ },
};

View file

@ -60,6 +60,7 @@
#define CLUSTER_BIT30_OFFSET (30)
#define CLUSTER_BIT25_OFFSET (25)
#define CLUSTER_BIT13_OFFSET (13)
#define CLUSTER_VOTE_AP_SLPEN (3)
#define L2_HARDWARE_CACHE_FLUSH_EN (13)

View file

@ -67,15 +67,15 @@ static void wakeup_other_core(void)
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* enable the hw l2 cache flush method for each core */
writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG0) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG0);
writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG1) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG1);
writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG2) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG2);
writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG3) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG3);
/* writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG0) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG0); */
/* writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG1) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG1); */
/* writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG2) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG2); */
/* writel(readl((u32 *)PMU_C0_CAPMP_IDLE_CFG3) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C0_CAPMP_IDLE_CFG3); */
writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG0) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG0);
writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG1) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG1);
writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG2) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG2);
writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG3) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG3);
/* writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG0) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG0); */
/* writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG1) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG1); */
/* writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG2) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG2); */
/* writel(readl((u32 *)PMU_C1_CAPMP_IDLE_CFG3) | (1 << L2_HARDWARE_CACHE_FLUSH_EN), (u32 *)PMU_C1_CAPMP_IDLE_CFG3); */
#endif
// hart0 is already boot up
@ -188,7 +188,8 @@ static int spacemit_hart_start(unsigned int hartid, unsigned long saddr)
static int spacemit_hart_stop(void)
{
psci_cpu_off();
return 0;
return SBI_ENOTSUPP;
}
static int spacemit_hart_suspend(unsigned int suspend_type)
@ -265,6 +266,8 @@ static bool spacemit_cold_boot_allowed(u32 hartid, const struct fdt_match *match
static const struct fdt_match spacemit_k1_match[] = {
{ .compatible = "spacemit,k1-pro" },
{ .compatible = "spacemit,k1x" },
{ .compatible = "spacemit,k1-x" },
{ .compatible = "spacemit,k1" },
{ },
};