diff options
Diffstat (limited to '')
-rw-r--r-- | drivers/marvell/mg_conf_cm3/mg_conf_cm3.c | 97 | ||||
-rw-r--r-- | drivers/marvell/mg_conf_cm3/mg_conf_cm3.h | 9 |
2 files changed, 106 insertions, 0 deletions
diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c new file mode 100644 index 0000000..98e1896 --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include <a8k_plat_def.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <mss_scp_bl2_format.h> + +/* CONFI REGISTERS */ +#define MG_CM3_CONFI_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) +#define MG_CM3_SRAM_BASE(CP) MG_CM3_CONFI_BASE(CP) +#define MG_CM3_CONFI_GLOB_CFG_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B500) +#define CM3_CPU_EN_BIT BIT(28) +#define MG_CM3_MG_INT_MFX_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B054) +#define CM3_SYS_RESET_BIT BIT(0) + +#define MG_CM3_SHARED_MEM_BASE(CP) (MG_CM3_SRAM_BASE(CP) + 0x1FC00ULL) + +#define MG_SRAM_SIZE 0x20000 /* 128KB */ + +#define MG_ACK_TIMEOUT 10 + +/** + * struct ap_sharedmem_ctrl - used to pass information between the HOST and CM3 + * @init_done: Set by CM3 when ap_proces initialzied. Host check if CM3 set + * this flag to confirm that the process is running + * @lane_nr: Set by Host to mark which comphy lane should be configure. E.g.: + * - A8K development board uses comphy lane 2 for eth0 + * - CN913x development board uses comphy lane 4 for eth0 + */ +struct ap_sharedmem_ctrl { + uint32_t init_done; + uint32_t lane_nr; +}; + +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index) +{ + uintptr_t mg_regs = MG_CM3_SRAM_BASE(cp_index); + + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index) +{ + volatile struct ap_sharedmem_ctrl *ap_shared_ctrl = + (void *)MG_CM3_SHARED_MEM_BASE(cp_nr); + int timeout = MG_ACK_TIMEOUT; + + if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) { + VERBOSE("cm3 already running\n"); + return; /* cm3 already running */ + } + + /* + * Mark which comphy lane should be used - it will be read via shared + * mem by ap process + */ + ap_shared_ctrl->lane_nr = comphy_index; + /* Make sure it took place before enabling cm3 */ + dmbst(); + + mmio_setbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), CM3_CPU_EN_BIT); + mmio_setbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), CM3_SYS_RESET_BIT); + + /* Check for ap process initialization by fw */ + while (ap_shared_ctrl->init_done != 1 && timeout--) + VERBOSE("Waiting for ap process ack, timeout %d\n", timeout); + + if (timeout == 0) { + ERROR("AP process failed, disabling cm3\n"); + mmio_clrbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), + CM3_SYS_RESET_BIT); + mmio_clrbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), + CM3_CPU_EN_BIT); + } +} diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h new file mode 100644 index 0000000..e2756de --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index); +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index); |