mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-12-22 06:12:02 +00:00
Hifive Premier P550[1] is a Mini-DTX form factor board with EIC7700X. It has a STM32F407VET6 onboard MCU acting as the BMC, controlling ATX power on/off while providing remote management features. The EIC7700X SoC/SoM communicates with the BMC via UART2, using ESWIN's protocol. The messages transmitted are fixed sizes (267 bytes), and depending on the type, can be directional or bi-directional. The shutdown and cold reboot requests are directional messages from SoC to BMC (NOTIFY type) with CMD_POWER_OFF or CMD_RESTART. The payload of shutdown/cold reboot requests should be empty and are ignored by the BMC at the moment. A HFP (Hifive Premier) specific reset device is registered in addition to the SoC reset device. For shutdown and cold reboot, the board-level reset takes precedence. The definitions of the SoC <-> BMC message protocol is taken from ESWIN's repo [2]. The only file used from that repo is `hf_common.h` It's disjunctively dual licensed as (GPL-2.0-only OR BSD-2-Clause), hence, compatible with the license of OpenSBI. It's heavily modified and renamed as platform/generic/include/eswin/hfp.h. The author and copyright in the original file are retained. Validated shutdown/cold reboot working on Hifive Premier P550. [1] https://www.sifive.com/boards/hifive-premier-p550#documentation [2] https://github.com/eswincomputing/hifive-premier-p550-mcu-patches.git Signed-off-by: Bo Gan <ganboing@gmail.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20251218104243.562667-8-ganboing@gmail.com Signed-off-by: Anup Patel <anup@brainfault.org>
102 lines
3.6 KiB
C
102 lines
3.6 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2025 Bo Gan <ganboing@gmail.com>
|
|
*
|
|
*/
|
|
|
|
#ifndef __EIC770X_H__
|
|
#define __EIC770X_H__
|
|
|
|
#include <sbi/riscv_asm.h>
|
|
|
|
struct eic770x_board_override {
|
|
struct sbi_system_reset_device *reset_dev;
|
|
};
|
|
|
|
/* CSRs */
|
|
#define EIC770X_CSR_BRPREDICT 0x7c0
|
|
#define EIC770X_CSR_FEAT0 0x7c1
|
|
#define EIC770X_CSR_FEAT1 0x7c2
|
|
#define EIC770X_CSR_L1_HWPF 0x7c3
|
|
#define EIC770X_CSR_L2_HWPF 0x7c4
|
|
|
|
/* Hart ID to core/die conversion */
|
|
#define CPU_CORE_BITS 2
|
|
#define CPU_CORE_MASK ((1 << CPU_CORE_BITS) - 1)
|
|
#define CPU_DIE_SHIFT CPU_CORE_BITS
|
|
#define CPU_DIE_BITS 1
|
|
#define CPU_DIE_MASK ((1 << CPU_DIE_BITS) - 1)
|
|
|
|
#define hart_core(i) ((i) & CPU_CORE_MASK)
|
|
#define hart_die(i) (((i) >> CPU_DIE_SHIFT) & CPU_DIE_MASK)
|
|
#define current_hart_core() hart_core(current_hartid())
|
|
#define current_hart_die() hart_die(current_hartid())
|
|
|
|
/* P550 Internal and System Port 0 */
|
|
#define EIC770X_P550INT_SIZE 0x20000000UL
|
|
#define EIC770X_P550INT_BASE(d) (0UL + EIC770X_P550INT_SIZE * (d))
|
|
#define EIC770X_P550INT_LOCAL EIC770X_P550INT_BASE(current_hart_die())
|
|
#define EIC770X_TL64D2D_OUT (EIC770X_P550INT_LOCAL + 0x200000)
|
|
#define EIC770X_TL256D2D_OUT (EIC770X_P550INT_LOCAL + 0x202000)
|
|
#define EIC770X_TL256D2D_IN (EIC770X_P550INT_LOCAL + 0x204000)
|
|
#define EIC770X_L3_ZERO_SIZE 0x400000UL
|
|
#define EIC770X_L3_ZERO_BASE(d) (EIC770X_P550INT_BASE(d) + 0x1a000000)
|
|
#define EIC770X_L3_ZERO_LOCAL EIC770X_L3_ZERO_BASE(current_hart_die())
|
|
#define EIC770X_L3_ZERO_REMOTE EIC770X_L3_ZERO_BASE(1 - current_hart_die())
|
|
|
|
#define EIC770X_SYSPORT_SIZE 0x20000000UL
|
|
#define EIC770X_SYSPORT_BASE(d) (0x40000000UL + EIC770X_SYSPORT_SIZE * (d))
|
|
#define EIC770X_SYSPORT_LOCAL EIC770X_SYSPORT_BASE(current_hart_die())
|
|
|
|
#define EIC770X_UART0 (EIC770X_SYSPORT_LOCAL + 0x10900000UL)
|
|
#define EIC770X_UART_SIZE 0x10000UL
|
|
#define EIC770X_UART(x) (EIC770X_UART0 + EIC770X_UART_SIZE * (x))
|
|
#define EIC770X_UART_REG_SHIFT 2
|
|
#define EIC770X_UART_REG_WIDTH 4
|
|
|
|
#define EIC770X_SYSCRG (EIC770X_SYSPORT_LOCAL + 0x11828000UL)
|
|
#define EIC770X_SYSCRG_LSPCLK0 (EIC770X_SYSCRG + 0x200UL)
|
|
#define EIC770X_SYSCRG_SYSCLK (EIC770X_SYSCRG + 0x20cUL)
|
|
#define EIC770X_SYSCRG_RST (EIC770X_SYSCRG + 0x300UL)
|
|
#define EIC770X_SYSCRG_RST_VAL 0x1AC0FFE6UL
|
|
|
|
/* Memory Ports */
|
|
#define EIC770X_MEMPORT_BASE 0x0080000000UL // 2G
|
|
#define EIC770X_MEMPORT_SIZE 0x7f80000000UL // +510G
|
|
#define EIC770X_MEMPORT_LIMIT (EIC770X_MEMPORT_BASE + EIC770X_MEMPORT_SIZE)
|
|
#define EIC770X_D0_MEM_BASE 0x0080000000UL // 2G
|
|
#define EIC770X_D0_MEM_SIZE 0x0f80000000UL // +62G
|
|
#define EIC770X_D0_MEM_LIMIT (EIC770X_D0_MEM_BASE + EIC770X_D0_MEM_SIZE)
|
|
#define EIC770X_D1_MEM_BASE 0x2000000000UL // 128G
|
|
#define EIC770X_D1_MEM_SIZE 0x1000000000UL // +64G
|
|
#define EIC770X_D1_MEM_LIMIT (EIC770X_D1_MEM_BASE + EIC770X_D1_MEM_SIZE)
|
|
#define EIC770X_CACHED_BASE (current_hart_die() ? \
|
|
EIC770X_D1_MEM_BASE : \
|
|
EIC770X_D0_MEM_BASE)
|
|
|
|
/* Uncached memory mapped in System Port 1 */
|
|
#define EIC770X_D0_UC_BASE 0xc000000000UL
|
|
#define EIC770X_D1_UC_BASE 0xe000000000UL
|
|
#define EIC770X_UNCACHED_BASE (current_hart_die() ? \
|
|
EIC770X_D1_UC_BASE : \
|
|
EIC770X_D0_UC_BASE)
|
|
|
|
#define EIC770X_TO_UNCACHED(x) ((x) - EIC770X_CACHED_BASE + \
|
|
EIC770X_UNCACHED_BASE)
|
|
|
|
/* Clock definitions */
|
|
#define EIC770X_XTAL_CLK_RATE 24000000UL
|
|
#define EIC770X_SPLL0_OUT1_RATE 1600000000UL
|
|
#define EIC770X_SPLL0_OUT2_RATE 800000000UL
|
|
#define EIC770X_SPLL0_OUT3_RATE 400000000UL
|
|
#define EIC770X_UART_CLK_BIT(x) (1UL << ((x) + 17))
|
|
#define EIC770X_SYSCLK_SEL(x) ((x) & 1)
|
|
#define EIC770X_SYSCLK_DIV(x) \
|
|
({ \
|
|
uint32_t divisor = ((x) >> 4) & 7; \
|
|
divisor > 2 ? divisor : 2; \
|
|
})
|
|
|
|
#endif
|