diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 7ca7460..1d5b6f5 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -2251,7 +2251,7 @@ /* Start AP Firmware */ mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); - mg_start_ap_fw(cp_nr); + mg_start_ap_fw(cp_nr, comphy_index); return 0; } diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c index 0efa30e..98e1896 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -18,8 +19,25 @@ #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); @@ -43,17 +61,37 @@ return 0; } -void mg_start_ap_fw(int cp_nr) +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); - /* TODO: add some routine for checking if ap process is running, if not - * disable cm3. - */ + /* 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 index 8dfaa32..e2756de 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -5,5 +5,5 @@ * https://spdx.org/licenses */ -void mg_start_ap_fw(int cp_nr); +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);