diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 6f28721..bec0bcb 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -77,6 +77,13 @@ Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). +- LLC_SRAM + + Flag defining the LLC (L3) cache SRAM support. The feature is + disabled by default (``LLC_ENABLE=0``). + When LLC SRAM is enabled, the secure payload (BL32) is loaded into this + SRAM area instead of the DRAM. + - MARVELL_SECURE_BOOT Build trusted(=1)/non trusted(=0) image, default is non trusted. diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 3df93a4..836aae7 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -31,19 +31,19 @@ void llc_flush_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_clean_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_inv_all(int ap_index) { - mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } @@ -109,3 +109,41 @@ reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR(ap_index), reg); } + +#if LLC_SRAM +void llc_sram_enable(int ap_index) +{ + uint32_t tc, way; + uint32_t way_addr; + + /* Lockdown all available ways for all traffic classes */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_WAY_MASK); + + /* Clear the high bits of SRAM address */ + mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0); + + way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE; + for (way = 0; way < LLC_WAYS; way++) { + /* Trigger allocation block command */ + mmio_write_32(LLC_BLK_ALOC(ap_index), + LLC_BLK_ALOC_BASE_ADDR(way_addr) | + LLC_BLK_ALOC_WAY_DATA_CLR | + LLC_BLK_ALOC_WAY_ID(way)); + way_addr += LLC_WAY_SIZE; + } + llc_enable(ap_index, 1); +} + +void llc_sram_disable(int ap_index) +{ + uint32_t tc; + + /* Disable the line lockings */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), 0); + + /* Invalidate all ways */ + llc_inv_all(ap_index); +} +#endif /* LLC_SRAM */ diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index 1e4ab44..c73516e 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -54,8 +54,8 @@ win_id)); start = ((uint64_t)alr << ADDRESS_SHIFT); end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT); - printf("\tccu %02x 0x%016llx 0x%016llx\n", - target_id, start, end); + printf("\tccu%d %02x 0x%016llx 0x%016llx\n", + win_id, target_id, start, end); } } win_cr = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_index)); @@ -81,6 +81,12 @@ } } +int ccu_is_win_enabled(int ap_index, uint32_t win_id) +{ + return mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id)) & + WIN_ENABLE_BIT; +} + void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id) { uint32_t ccu_win_reg; diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 6eb7fd0..3678c90 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -659,18 +659,32 @@ (0x3f << HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET) #define HPIPE_CDR_CONTROL_REG 0x418 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) -#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 -#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ - (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET 0 +#define HPIPE_CRD_MIDPOINT_PHASE_OS_MASK \ + (0x3f << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET) #define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6 #define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 +#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ + (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) + + +#define HPIPE_CDR_CONTROL1_REG 0x41c +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF) + +#define HPIPE_CDR_CONTROL2_REG 0x420 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF) #define HPIPE_TX_TRAIN_CTRL_11_REG 0x438 #define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6 @@ -749,6 +763,30 @@ #define HPIPE_DFE_CTRL_28_PIPE4_MASK \ (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET) +#define HPIPE_TRX0_REG 0x4cc /*in doc 0x133*4*/ +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF 2 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF) +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF 0 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF) + +#define HPIPE_TRX_REG1 0x4d0 /*in doc 0x134*4*/ +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF 3 +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK \ + (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF) +#define HPIPE_TRX_REG1_SUMFTAP_EN_OFF 10 +#define HPIPE_TRX_REG1_SUMFTAP_EN_MASK \ + (0x3f << HPIPE_TRX_REG1_SUMFTAP_EN_OFF) + +#define HPIPE_TRX_REG2 0x4d8 /*in doc 0x136*4*/ +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF 11 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK \ + (0x1f << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF) +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF 7 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK \ + (0xf << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF) + #define HPIPE_G1_SETTING_5_REG 0x538 #define HPIPE_G1_SETTING_5_G1_ICP_OFFSET 0 #define HPIPE_G1_SETTING_5_G1_ICP_MASK \ diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index b682086..2760f46 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -209,8 +209,10 @@ * as SFI1/XFI1 available only for CP115. */ if ((mode == COMPHY_SGMII_MODE || - mode == COMPHY_HS_SGMII_MODE || - mode == COMPHY_SFI_MODE || mode == COMPHY_XFI_MODE) + mode == COMPHY_HS_SGMII_MODE || + mode == COMPHY_SFI_MODE || + mode == COMPHY_XFI_MODE || + mode == COMPHY_AP_MODE) && COMPHY_GET_ID(comphy_mode) == 1) reg |= COMMON_SELECTOR_COMPHY4_PORT1 << comphy_offset; @@ -2012,12 +2014,58 @@ return ret; } +static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index) +{ + uintptr_t hpipe_addr; + uint32_t mask, data; + + hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), + comphy_index); + + debug("rx_training preparation\n\n"); + + mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK; + data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF); + mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK; + data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF); + reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask); + + + mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK; + data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask); + + mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK; + data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask); + + mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK; + data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask); + + mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK; + data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); +} + int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index) { uint32_t mask, data, timeout; uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res; - uintptr_t hpipe_addr, sd_ip_addr; + uintptr_t hpipe_addr; uint8_t ap_nr, cp_nr; @@ -2025,30 +2073,10 @@ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), comphy_index); - sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), - comphy_index); debug_enter(); - debug("stage: RF Reset\n"); - - /* Release from hard reset */ - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - /* Wait 50ms - until band gap and ref clock ready */ - mdelay(50); + rx_pre_train(comphy_base, comphy_index); debug("Preparation for rx_training\n\n"); @@ -2068,34 +2096,10 @@ data = 0 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); - debug("PRBS31 loppback\n\n"); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mdelay(10); - debug("Enable TX/RX training\n\n"); + debug("Enable RX training\n\n"); mask = HPIPE_TRX_RX_TRAIN_EN_MASK; data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET; - mask |= HPIPE_TRX_RX_ANA_IF_CLK_ENE_MASK; - data |= 0x1 << HPIPE_TRX_RX_ANA_IF_CLK_ENE_OFFSET; - mask |= HPIPE_TRX_TX_CTRL_CLK_EN_MASK; - data |= 0x1 << HPIPE_TRX_TX_CTRL_CLK_EN_OFFSET; - mask |= HPIPE_TRX_UPDATE_THEN_HOLD_MASK; - data |= 0x1 << HPIPE_TRX_UPDATE_THEN_HOLD_OFFSET; - mask |= HPIPE_TRX_TX_F0T_EO_BASED_MASK; - data |= 0x1 << HPIPE_TRX_TX_F0T_EO_BASED_OFFSET; reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask); /* Check the result of RX training */ @@ -2180,21 +2184,9 @@ data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); - /* Use the value from CAL_OS_PH_EXT */ - mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK; - data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - - /* Update align90 */ - mask = HPIPE_CAL_OS_PH_EXT_MASK; - data = align90 << HPIPE_CAL_OS_PH_EXT_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - /* Force DFE resolution (use gen table value) */ mask = HPIPE_DFE_RES_FORCE_MASK; - data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET; + data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); /* 0x111-G1 DFE_Setting_4 */ @@ -2202,38 +2194,6 @@ data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); - debug("PRBS31 loppback\n\n"); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - /* Reset PRBS error counter */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - printf("########################################################\n"); printf("# To use trained values update the ATF sources:\n"); printf("# plat/marvell/armada/a8k//board/phy-porting-layer.h "); @@ -2252,12 +2212,6 @@ printf("};\n\n"); printf("########################################################\n"); - /* check */ - debug("PRBS error counter[0x%lx] 0x%x\n\n", - hpipe_addr + HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG, - mmio_read_32(hpipe_addr + - HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG)); - rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1; return 0; @@ -2273,12 +2227,16 @@ * the network registers like: MG, AP, MAC, PCS, Serdes etc.) */ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, - uint8_t comphy_index) + uint8_t comphy_index, + uint32_t comphy_mode) { uint32_t mask, data; uintptr_t comphy_addr = comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); + /* configure phy selector for XFI/SFI */ + mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index, + comphy_mode); debug_enter(); debug("stage: RFU configurations - hard reset comphy\n"); /* RFU configurations - hard reset comphy */ @@ -2371,7 +2329,8 @@ comphy_mode); break; case (COMPHY_AP_MODE): - err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index); + err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index, + comphy_mode); break; default: ERROR("comphy%d: unsupported comphy mode\n", comphy_index); diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index 85babb8..b326474 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -13,19 +13,35 @@ #define CACHE_LLC_H #define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100) +#define LLC_SECURE_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x10C) #define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700) -#define L2X0_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) -#define L2X0_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) -#define L2X0_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) -#define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920) +#define LLC_BANKED_MNT_AHR(ap) (MVEBU_LLC_BASE(ap) + 0x724) +#define LLC_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) +#define LLC_BLK_ALOC(ap) (MVEBU_LLC_BASE(ap) + 0x78c) +#define LLC_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) +#define LLC_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) +#define LLC_TCN_LOCK(ap, tc) (MVEBU_LLC_BASE(ap) + 0x920 + 4 * (tc)) #define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0) -#define MASTER_L2X0_INV_WAY L2X0_INV_WAY(MVEBU_AP0) -#define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0) +#define MASTER_LLC_INV_WAY LLC_INV_WAY(MVEBU_AP0) +#define MASTER_LLC_TC0_LOCK LLC_TCN_LOCK(MVEBU_AP0, 0) #define LLC_CTRL_EN 1 #define LLC_EXCLUSIVE_EN 0x100 -#define LLC_WAY_MASK 0xFFFFFFFF +#define LLC_ALL_WAYS_MASK 0xFFFFFFFF + +/* AP806/AP807 - 1MB 8-ways LLC */ +#define LLC_WAYS 8 +#define LLC_WAY_MASK ((1 << LLC_WAYS) - 1) +#define LLC_SIZE (1024 * 1024) +#define LLC_WAY_SIZE (LLC_SIZE / LLC_WAYS) +#define LLC_TC_NUM 15 + +#define LLC_BLK_ALOC_WAY_ID(way) ((way) & 0x1f) +#define LLC_BLK_ALOC_WAY_DATA_DSBL (0x0 << 6) +#define LLC_BLK_ALOC_WAY_DATA_CLR (0x1 << 6) +#define LLC_BLK_ALOC_WAY_DATA_SET (0x3 << 6) +#define LLC_BLK_ALOC_BASE_ADDR(addr) ((addr) & (LLC_WAY_SIZE - 1)) #ifndef __ASSEMBLER__ void llc_cache_sync(int ap_index); @@ -36,6 +52,10 @@ void llc_enable(int ap_index, int excl_mode); int llc_is_exclusive(int ap_index); void llc_runtime_enable(int ap_index); -#endif +#if LLC_SRAM +void llc_sram_enable(int ap_index); +void llc_sram_disable(int ap_index); +#endif /* LLC_SRAM */ +#endif /* __ASSEMBLY__ */ #endif /* CACHE_LLC_H */ diff --git a/include/drivers/marvell/ccu.h b/include/drivers/marvell/ccu.h index b0d1ec9..413ffb9 100644 --- a/include/drivers/marvell/ccu.h +++ b/include/drivers/marvell/ccu.h @@ -46,6 +46,7 @@ void ccu_dram_target_set(int ap_index, uint32_t target); void ccu_save_win_all(int ap_id); void ccu_restore_win_all(int ap_id); +int ccu_is_win_enabled(int ap_index, uint32_t win_id); #endif #endif /* CCU_H */ diff --git a/include/plat/marvell/armada/a3700/common/armada_common.h b/include/plat/marvell/armada/a3700/common/armada_common.h deleted file mode 100644 index c6953fb..0000000 --- a/include/plat/marvell/armada/a3700/common/armada_common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef ARMADA_COMMON_H -#define ARMADA_COMMON_H - -#include - -#include - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); - -#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a3700/common/board_marvell_def.h b/include/plat/marvell/armada/a3700/common/board_marvell_def.h deleted file mode 100644 index 1782596..0000000 --- a/include/plat/marvell/armada/a3700/common/board_marvell_def.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef BOARD_MARVELL_DEF_H -#define BOARD_MARVELL_DEF_H - -/* - * Required platform porting definitions common to all ARM - * development platforms - */ - -/* Size of cacheable stacks */ -#if IMAGE_BL1 -#if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -#else -# define PLATFORM_STACK_SIZE 0x440 -#endif -#elif IMAGE_BL2 -# if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -# else -# define PLATFORM_STACK_SIZE 0x400 -# endif -#elif IMAGE_BL31 -# define PLATFORM_STACK_SIZE 0x400 -#elif IMAGE_BL32 -# define PLATFORM_STACK_SIZE 0x440 -#endif - -/* - * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the - * plat_arm_mmap array defined for each BL stage. - */ -#if IMAGE_BLE -# define PLAT_MARVELL_MMAP_ENTRIES 3 -#endif -#if IMAGE_BL1 -# if TRUSTED_BOARD_BOOT -# define PLAT_MARVELL_MMAP_ENTRIES 7 -# else -# define PLAT_MARVELL_MMAP_ENTRIES 6 -# endif /* TRUSTED_BOARD_BOOT */ -#endif -#if IMAGE_BL2 -# define PLAT_MARVELL_MMAP_ENTRIES 8 -#endif -#if IMAGE_BL31 -#define PLAT_MARVELL_MMAP_ENTRIES 5 -#endif - -/* - * Platform specific page table and MMU setup constants - */ -#if IMAGE_BL1 -#define MAX_XLAT_TABLES 4 -#elif IMAGE_BLE -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL2 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL31 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL32 -# define MAX_XLAT_TABLES 4 -#endif - -#define MAX_IO_DEVICES 3 -#define MAX_IO_HANDLES 4 - -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - -#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/marvell_def.h b/include/plat/marvell/armada/a3700/common/marvell_def.h deleted file mode 100644 index eb13ba8..0000000 --- a/include/plat/marvell/armada/a3700/common/marvell_def.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_DEF_H -#define MARVELL_DEF_H - -#include - -#include -#include -#include -#include - -/**************************************************************************** - * Definitions common to all MARVELL standard platforms - **************************************************************************** - */ -/* Special value used to verify platform parameters from BL2 to BL31 */ -#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL - -#define PLAT_MARVELL_NORTHB_COUNT 1 - -#define PLAT_MARVELL_CLUSTER_COUNT 1 - -#define MARVELL_CACHE_WRITEBACK_SHIFT 6 - -/* - * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. - * The power levels have a 1:1 mapping with the MPIDR affinity levels. - */ -#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 -#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 -#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 - -/* - * Macros for local power states in Marvell platforms encoded by State-ID field - * within the power-state parameter. - */ -/* Local power state for power domains in Run state. */ -#define MARVELL_LOCAL_STATE_RUN 0 -/* Local power state for retention. Valid only for CPU power domains */ -#define MARVELL_LOCAL_STATE_RET 1 -/* Local power state for OFF/power-down. - * Valid for CPU and cluster power domains - */ -#define MARVELL_LOCAL_STATE_OFF 2 - -/* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE -#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ - -/* The remaining Trusted SRAM is used to load the BL images */ -#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ - MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ - MARVELL_SHARED_RAM_SIZE) - -#define MARVELL_DRAM_BASE ULL(0x0) -#define MARVELL_DRAM_SIZE ULL(0x20000000) -#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ - MARVELL_DRAM_SIZE - 1) - -#define MARVELL_IRQ_SEC_PHY_TIMER 29 - -#define MARVELL_IRQ_SEC_SGI_0 8 -#define MARVELL_IRQ_SEC_SGI_1 9 -#define MARVELL_IRQ_SEC_SGI_2 10 -#define MARVELL_IRQ_SEC_SGI_3 11 -#define MARVELL_IRQ_SEC_SGI_4 12 -#define MARVELL_IRQ_SEC_SGI_5 13 -#define MARVELL_IRQ_SEC_SGI_6 14 -#define MARVELL_IRQ_SEC_SGI_7 15 - -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE, \ - MARVELL_SHARED_RAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ - MARVELL_DRAM_BASE, \ - MARVELL_DRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - - -/* - * The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU. - */ -#if USE_COHERENT_MEM -#define MARVELL_BL_REGIONS 3 -#else -#define MARVELL_BL_REGIONS 2 -#endif - -#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ - MARVELL_BL_REGIONS) - -#define MARVELL_CONSOLE_BAUDRATE 115200 - -/**************************************************************************** - * Required platform porting definitions common to all MARVELL std. platforms - **************************************************************************** - */ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) - -/* - * This macro defines the deepest retention state possible. A higher state - * id will represent an invalid or a power down state. - */ -#define PLAT_MAX_RET_STATE MARVELL_LOCAL_STATE_RET - -/* - * This macro defines the deepest power down states possible. Any state ID - * higher than this is invalid. - */ -#define PLAT_MAX_OFF_STATE MARVELL_LOCAL_STATE_OFF - - -#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT - -/* - * Some data must be aligned on the biggest cache line size in the platform. - * This is known only to the platform as it might have a combination of - * integrated and external caches. - */ -#define CACHE_WRITEBACK_GRANULE (1 << MARVELL_CACHE_WRITEBACK_SHIFT) - - -/***************************************************************************** - * BL1 specific defines. - * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of - * addresses. - ***************************************************************************** - */ -#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE -#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ - + PLAT_MARVELL_TRUSTED_ROM_SIZE) -/* - * Put BL1 RW at the top of the Trusted SRAM. - */ -#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVELL_MAX_BL1_RW_SIZE) -#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) - -/***************************************************************************** - * BL2 specific defines. - ***************************************************************************** - */ -/* - * Put BL2 just below BL31. - */ -#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) -#define BL2_LIMIT BL31_BASE - -/***************************************************************************** - * BL31 specific defines. - ***************************************************************************** - */ -/* - * Put BL31 at the top of the Trusted SRAM. - */ -#define BL31_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVEL_MAX_BL31_SIZE) -#define BL31_PROGBITS_LIMIT BL1_RW_BASE -#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE) - - -#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/plat_marvell.h b/include/plat/marvell/armada/a3700/common/plat_marvell.h deleted file mode 100644 index ea7cdcd..0000000 --- a/include/plat/marvell/armada/a3700/common/plat_marvell.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MARVELL_H -#define PLAT_MARVELL_H - -#include - -#include -#include -#include -#include - -/* - * Extern declarations common to Marvell standard platforms - */ -extern const mmap_region_t plat_marvell_mmap[]; - -#define MARVELL_CASSERT_MMAP \ - CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ - <= MAX_MMAP_REGIONS, \ - assert_max_mmap_regions) - -/* - * Utility functions common to Marvell standard platforms - */ -void marvell_setup_page_tables(uintptr_t total_base, - size_t total_size, - uintptr_t code_start, - uintptr_t code_limit, - uintptr_t rodata_start, - uintptr_t rodata_limit -#if USE_COHERENT_MEM - , uintptr_t coh_start, - uintptr_t coh_limit -#endif -); - -/* Console utility functions */ -void marvell_console_boot_init(void); -void marvell_console_boot_end(void); -void marvell_console_runtime_init(void); -void marvell_console_runtime_end(void); - -/* IO storage utility functions */ -void marvell_io_setup(void); - -/* Systimer utility function */ -void marvell_configure_sys_timer(void); - -/* Topology utility function */ -int marvell_check_mpidr(u_register_t mpidr); - -/* BL1 utility functions */ -void marvell_bl1_early_platform_setup(void); -void marvell_bl1_platform_setup(void); -void marvell_bl1_plat_arch_setup(void); - -/* BL2 utility functions */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); -void marvell_bl2_platform_setup(void); -void marvell_bl2_plat_arch_setup(void); -uint32_t marvell_get_spsr_for_bl32_entry(void); -uint32_t marvell_get_spsr_for_bl33_entry(void); - -/* BL31 utility functions */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2); -void marvell_bl31_platform_setup(void); -void marvell_bl31_plat_runtime_setup(void); -void marvell_bl31_plat_arch_setup(void); - -/* FIP TOC validity check */ -int marvell_io_is_toc_valid(void); - -/* - * PSCI functionality - */ -void marvell_psci_arch_init(int idx); -void plat_marvell_system_reset(void); - -/* - * Optional functions required in Marvell standard platforms - */ -void plat_marvell_io_setup(void); -int plat_marvell_get_alt_image_source( - unsigned int image_id, - uintptr_t *dev_handle, - uintptr_t *image_spec); -unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); - -void plat_marvell_interconnect_init(void); -void plat_marvell_interconnect_enter_coherency(void); - -const mmap_region_t *plat_marvell_get_mmap(void); - -#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a3k/common/armada_common.h b/include/plat/marvell/armada/a3k/common/armada_common.h new file mode 100644 index 0000000..c6953fb --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/armada_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef ARMADA_COMMON_H +#define ARMADA_COMMON_H + +#include + +#include + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); + +#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a3k/common/board_marvell_def.h b/include/plat/marvell/armada/a3k/common/board_marvell_def.h new file mode 100644 index 0000000..bc3e04f --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/board_marvell_def.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef BOARD_MARVELL_DEF_H +#define BOARD_MARVELL_DEF_H + +/* + * Required platform porting definitions common to all ARM + * development platforms + */ + +/* Size of cacheable stacks */ +#if IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +#else +# define PLATFORM_STACK_SIZE 0x440 +#endif +#elif IMAGE_BL2 +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif IMAGE_BL31 +# define PLATFORM_STACK_SIZE 0x400 +#elif IMAGE_BL32 +# define PLATFORM_STACK_SIZE 0x440 +#endif + +/* + * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if IMAGE_BLE +# define PLAT_MARVELL_MMAP_ENTRIES 3 +#endif +#if IMAGE_BL1 +# if TRUSTED_BOARD_BOOT +# define PLAT_MARVELL_MMAP_ENTRIES 7 +# else +# define PLAT_MARVELL_MMAP_ENTRIES 6 +# endif /* TRUSTED_BOARD_BOOT */ +#endif +#if IMAGE_BL2 +# define PLAT_MARVELL_MMAP_ENTRIES 8 +#endif +#if IMAGE_BL31 +#define PLAT_MARVELL_MMAP_ENTRIES 5 +#endif + +/* + * Platform specific page table and MMU setup constants + */ +#if IMAGE_BL1 +#define MAX_XLAT_TABLES 4 +#elif IMAGE_BLE +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL2 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL31 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL32 +# define MAX_XLAT_TABLES 4 +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3k/common/marvell_def.h b/include/plat/marvell/armada/a3k/common/marvell_def.h new file mode 100644 index 0000000..1394c05 --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/marvell_def.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_DEF_H +#define MARVELL_DEF_H + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Definitions common to all MARVELL standard platforms + **************************************************************************** + */ +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define PLAT_MARVELL_NORTHB_COUNT 1 + +#define PLAT_MARVELL_CLUSTER_COUNT 1 + +#define MARVELL_CACHE_WRITEBACK_SHIFT 6 + +/* + * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. + * The power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 +#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 +#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in Marvell platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define MARVELL_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define MARVELL_LOCAL_STATE_RET 1 +/* Local power state for OFF/power-down. + * Valid for CPU and cluster power domains + */ +#define MARVELL_LOCAL_STATE_OFF 2 + +/* This leaves a gap between end of DRAM and start of ROM block */ +#define MARVELL_TRUSTED_DRAM_SIZE 0x80000 /* 512 KB */ + +/* The first 4KB of Trusted SRAM are used as shared memory */ +#define MARVELL_SHARED_RAM_BASE PLAT_MARVELL_ATF_BASE +#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ + MARVELL_SHARED_RAM_SIZE) +#define MARVELL_BL_RAM_SIZE (MARVELL_TRUSTED_DRAM_SIZE - \ + MARVELL_SHARED_RAM_SIZE) + +#define MARVELL_DRAM_BASE ULL(0x0) +#define MARVELL_DRAM_SIZE ULL(0x20000000) +#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ + MARVELL_DRAM_SIZE - 1) + +#define MARVELL_IRQ_SEC_PHY_TIMER 29 + +#define MARVELL_IRQ_SEC_SGI_0 8 +#define MARVELL_IRQ_SEC_SGI_1 9 +#define MARVELL_IRQ_SEC_SGI_2 10 +#define MARVELL_IRQ_SEC_SGI_3 11 +#define MARVELL_IRQ_SEC_SGI_4 12 +#define MARVELL_IRQ_SEC_SGI_5 13 +#define MARVELL_IRQ_SEC_SGI_6 14 +#define MARVELL_IRQ_SEC_SGI_7 15 + +#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE, \ + MARVELL_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ + MARVELL_DRAM_BASE, \ + MARVELL_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define MARVELL_BL_REGIONS 3 +#else +#define MARVELL_BL_REGIONS 2 +#endif + +#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ + MARVELL_BL_REGIONS) + +#define MARVELL_CONSOLE_BAUDRATE 115200 + +/**************************************************************************** + * Required platform porting definitions common to all MARVELL std. platforms + **************************************************************************** + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * This macro defines the deepest retention state possible. A higher state + * id will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE MARVELL_LOCAL_STATE_RET + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE MARVELL_LOCAL_STATE_OFF + + +#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_GRANULE (1 << MARVELL_CACHE_WRITEBACK_SHIFT) + + +/***************************************************************************** + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + ***************************************************************************** + */ +#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ + + PLAT_MARVELL_TRUSTED_ROM_SIZE) +/* + * Put BL1 RW at the top of the Trusted SRAM. + */ +#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVELL_MAX_BL1_RW_SIZE) +#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) + +/***************************************************************************** + * BL2 specific defines. + ***************************************************************************** + */ +/* + * Put BL2 just below BL31. + */ +#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) +#define BL2_LIMIT BL31_BASE + +/***************************************************************************** + * BL31 specific defines. + ***************************************************************************** + */ +/* + * Put BL31 at the top of the Trusted SRAM. + */ +#define BL31_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVEL_MAX_BL31_SIZE) +#define BL31_PROGBITS_LIMIT BL1_RW_BASE +#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE) + +/***************************************************************************** + * BL32 specific defines. + ***************************************************************************** + */ +#define BL32_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_RAM_SIZE) + +#ifdef SPD_none +#undef BL32_BASE +#endif /* SPD_none */ + +#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3k/common/plat_marvell.h b/include/plat/marvell/armada/a3k/common/plat_marvell.h new file mode 100644 index 0000000..ea7cdcd --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/plat_marvell.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MARVELL_H +#define PLAT_MARVELL_H + +#include + +#include +#include +#include +#include + +/* + * Extern declarations common to Marvell standard platforms + */ +extern const mmap_region_t plat_marvell_mmap[]; + +#define MARVELL_CASSERT_MMAP \ + CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ + <= MAX_MMAP_REGIONS, \ + assert_max_mmap_regions) + +/* + * Utility functions common to Marvell standard platforms + */ +void marvell_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , uintptr_t coh_start, + uintptr_t coh_limit +#endif +); + +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + +/* IO storage utility functions */ +void marvell_io_setup(void); + +/* Systimer utility function */ +void marvell_configure_sys_timer(void); + +/* Topology utility function */ +int marvell_check_mpidr(u_register_t mpidr); + +/* BL1 utility functions */ +void marvell_bl1_early_platform_setup(void); +void marvell_bl1_platform_setup(void); +void marvell_bl1_plat_arch_setup(void); + +/* BL2 utility functions */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); +void marvell_bl2_platform_setup(void); +void marvell_bl2_plat_arch_setup(void); +uint32_t marvell_get_spsr_for_bl32_entry(void); +uint32_t marvell_get_spsr_for_bl33_entry(void); + +/* BL31 utility functions */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2); +void marvell_bl31_platform_setup(void); +void marvell_bl31_plat_runtime_setup(void); +void marvell_bl31_plat_arch_setup(void); + +/* FIP TOC validity check */ +int marvell_io_is_toc_valid(void); + +/* + * PSCI functionality + */ +void marvell_psci_arch_init(int idx); +void plat_marvell_system_reset(void); + +/* + * Optional functions required in Marvell standard platforms + */ +void plat_marvell_io_setup(void); +int plat_marvell_get_alt_image_source( + unsigned int image_id, + uintptr_t *dev_handle, + uintptr_t *image_spec); +unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); + +void plat_marvell_interconnect_init(void); +void plat_marvell_interconnect_enter_coherency(void); + +const mmap_region_t *plat_marvell_get_mmap(void); + +#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a8k/common/board_marvell_def.h b/include/plat/marvell/armada/a8k/common/board_marvell_def.h index 0da56e7..7e90f5f 100644 --- a/include/plat/marvell/armada/a8k/common/board_marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/board_marvell_def.h @@ -71,7 +71,4 @@ #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - - #endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h index 4eda01f..1245b88 100644 --- a/include/plat/marvell/armada/a8k/common/marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -47,15 +47,17 @@ */ #define MARVELL_LOCAL_STATE_OFF 2 +/* This leaves a gap between end of DRAM and start of ROM block */ +#define MARVELL_TRUSTED_DRAM_SIZE 0x80000 /* 512 KB */ + /* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_BASE PLAT_MARVELL_ATF_BASE #define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ /* The remaining Trusted SRAM is used to load the BL images */ #define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ +#define MARVELL_BL_RAM_SIZE (MARVELL_TRUSTED_DRAM_SIZE - \ MARVELL_SHARED_RAM_SIZE) /* Non-shared DRAM */ #define MARVELL_DRAM_BASE ULL(0x0) @@ -75,9 +77,40 @@ #define MARVELL_IRQ_SEC_SGI_6 14 #define MARVELL_IRQ_SEC_SGI_7 15 -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE,\ - MARVELL_SHARED_RAM_SIZE,\ +#ifdef SPD_opteed +/* + * BL2 needs to map 4MB at the end of TZC_DRAM1 in order to + * load/authenticate the trusted os extra image. The first 512KB of + * TZC_DRAM1 are reserved for trusted os (OPTEE). The extra image loading + * for OPTEE is paged image which only include the paging part using + * virtual memory but without "init" data. OPTEE will copy the "init" data + * (from pager image) to the first 512KB of TZC_DRAM, and then copy the + * extra image behind the "init" data. + */ +#define MARVELL_OPTEE_PAGEABLE_LOAD_BASE \ + (PLAT_MARVELL_TRUSTED_RAM_BASE + \ + PLAT_MARVELL_TRUSTED_RAM_SIZE - \ + MARVELL_OPTEE_PAGEABLE_LOAD_SIZE) +#define MARVELL_OPTEE_PAGEABLE_LOAD_SIZE 0x400000 +#define MARVELL_OPTEE_PAGEABLE_LOAD_MEM \ + MAP_REGION_FLAT( \ + MARVELL_OPTEE_PAGEABLE_LOAD_BASE, \ + MARVELL_OPTEE_PAGEABLE_LOAD_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +/* + * Map the memory for the OP-TEE core (also known as OP-TEE pager when paging + * support is enabled). + */ +#define MARVELL_MAP_OPTEE_CORE_MEM MAP_REGION_FLAT( \ + BL32_BASE, \ + BL32_LIMIT - BL32_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) +#endif /* SPD_opteed */ + +#define MARVELL_MAP_SECURE_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE, \ + MARVELL_SHARED_RAM_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) #define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ @@ -85,7 +118,6 @@ MARVELL_DRAM_SIZE, \ MT_MEMORY | MT_RW | MT_NS) - /* * The number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. @@ -177,5 +209,14 @@ #define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ MARVELL_BL_RAM_SIZE) +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +#define BL32_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_RAM_SIZE) + +#ifdef SPD_none +#undef BL32_BASE +#endif /* SPD_none */ #endif /* MARVELL_DEF_H */ diff --git a/plat/marvell/armada/a3700/a3700/board/pm_src.c b/plat/marvell/armada/a3700/a3700/board/pm_src.c deleted file mode 100644 index d6eca5d..0000000 --- a/plat/marvell/armada/a3700/a3700/board/pm_src.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -/* This struct provides the PM wake up src configuration */ -static struct pm_wake_up_src_config wake_up_src_cfg = { - .wake_up_src_num = 3, - .wake_up_src[0] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 0, /* North Bridge */ - .gpio_data.gpio_num = 14 - } - }, - .wake_up_src[1] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 1, /* South Bridge */ - .gpio_data.gpio_num = 2 - } - }, - .wake_up_src[2] = { - .wake_up_src_type = WAKE_UP_SRC_UART1, - } -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) -{ - return &wake_up_src_cfg; -} - diff --git a/plat/marvell/armada/a3700/a3700/mvebu_def.h b/plat/marvell/armada/a3700/a3700/mvebu_def.h deleted file mode 100644 index dad1085..0000000 --- a/plat/marvell/armada/a3700/a3700/mvebu_def.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MVEBU_DEF_H -#define MVEBU_DEF_H - -#include - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c deleted file mode 100644 index 6862a86..0000000 --- a/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include - -/* This routine does MPP initialization */ -static void marvell_bl31_mpp_init(void) -{ - mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); - - /* Set hidden GPIO setting for SPI. - * In north_bridge_pin_out_en_high register 13804, - * bit 28 is the one which enables CS, CLK pins to be - * output, need to set it to 1. - * The initial value of this bit is 1, but in UART boot mode - * initialization, this bit is disabled and the SPI CS and CLK pins - * are used for downloading image purpose; so after downloading, - * we should set this bit to 1 again to enable SPI CS and CLK pins. - * And anyway, this bit value should be 1 in all modes, - * so here we does not judge boot mode and set this bit to 1 always. - */ - mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, - 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); -} - -/* This function overruns the same function in marvell_bl31_setup.c */ -void bl31_plat_arch_setup(void) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - marvell_bl31_plat_arch_setup(); - - /* MPP init */ - marvell_bl31_mpp_init(); - - /* initialize the timer for delay functionality */ - plat_delay_timer_init(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } -} diff --git a/plat/marvell/armada/a3700/a3700/platform.mk b/plat/marvell/armada/a3700/a3700/platform.mk deleted file mode 100644 index bd9464a..0000000 --- a/plat/marvell/armada/a3700/a3700/platform.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -include plat/marvell/armada/a3700/common/a3700_common.mk - -include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a3700/common/a3700_common.mk b/plat/marvell/armada/a3700/common/a3700_common.mk deleted file mode 100644 index 36865a8..0000000 --- a/plat/marvell/armada/a3700/common/a3700_common.mk +++ /dev/null @@ -1,170 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -MARVELL_PLAT_BASE := plat/marvell/armada -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada -PLAT_FAMILY := a3700 -PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) -PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY) -PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common -MARVELL_DRV_BASE := drivers/marvell -MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common -HANDLE_EA_EL3_FIRST := 1 - -include plat/marvell/marvell.mk - -#*********** A3700 ************* -DOIMAGEPATH := $(WTP) -DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux - -ifeq ($(MARVELL_SECURE_BOOT),1) -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/trusted - -TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt -TIMNSIG := $(IMAGESPATH)/timnsign.txt -TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) -TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) -else #MARVELL_SECURE_BOOT -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted -TIM2IMGARGS := -i $(DOIMAGE_CFG) -endif #MARVELL_SECURE_BOOT - -TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh -TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl - -# WTMI_IMG is used to specify the customized RTOS image running over -# Service CPU (CM3 processor). By the default, it points to a -# baremetal binary of fuse programming in A3700_utils. -WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin - -# WTMI_SYSINIT_IMG is used for the system early initialization, -# such as AVS settings, clock-tree setup and dynamic DDR PHY training. -# After the initialization is done, this image will be wiped out -# from the memory and CM3 will continue with RTOS image or other application. -WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin - -# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) -# and sys-init image (WTMI_SYSINIT_IMG). -WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin - -WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin -BUILD_UART := uart-images - -SRCPATH := $(dir $(BL33)) - -CLOCKSPRESET ?= CPU_800_DDR_800 - -DDR_TOPOLOGY ?= 0 - -BOOTDEV ?= SPINOR -PARTNUM ?= 0 - -TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) -TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 -TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 -DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D - -# GICV3 -$(eval $(call add_define,CONFIG_GICV3)) - -# CCI-400 -$(eval $(call add_define,USE_CCI)) - -# Include GICv3 driver files -include drivers/arm/gic/v3/gicv3.mk - -MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ - plat/common/plat_gicv3.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_DRV_BASE) \ - -I$/drivers/arm/gic/common/ - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ - $(MARVELL_COMMON_BASE)/marvell_cci.c \ - $(MARVELL_DRV_BASE)/uart/a3700_console.S - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a53.S - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c - -MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(PLAT_COMMON_BASE)/dram_win.c \ - $(PLAT_COMMON_BASE)/io_addr_dec.c \ - $(PLAT_COMMON_BASE)/marvell_plat_config.c \ - $(PLAT_COMMON_BASE)/a3700_ea.c \ - $(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \ - $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ - $(MARVELL_GIC_SOURCES) \ - drivers/arm/cci/cci.c \ - $(BL31_PORTING_SOURCES) \ - $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ - $(MARVELL_DRV) - -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 $(WTMI_IMG)) - @echo - @echo "Building uart images" - $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* - @mkdir $(BUILD_PLAT)/$(BUILD_UART) - @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) - @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) - @echo - @echo "Building flash image" - $(TIMBUILD) $(TIMBLDARGS) - sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) - @echo -e "\n\t=======================================================\n"; - @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; - @echo -e "\t=======================================================\n"; - @truncate -s %16 $(WTMI_MULTI_IMG) - @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ - -out $(WTMI_ENC_IMG) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p - @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); - @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ - -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi - $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) - @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi - @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/armada/a3700/common/a3700_ea.c b/plat/marvell/armada/a3700/common/a3700_ea.c deleted file mode 100644 index dd46beb..0000000 --- a/plat/marvell/armada/a3700/common/a3700_ea.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2019 Repk repk@triplefau.lt - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include -#include -#include - -#define ADVK_SERROR_SYNDROME 0xbf000002 - -void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, - void *handle, uint64_t flags) -{ - if (syndrome != ADVK_SERROR_SYNDROME) { - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, - syndrome); - panic(); - } -} diff --git a/plat/marvell/armada/a3700/common/a3700_sip_svc.c b/plat/marvell/armada/a3700/common/a3700_sip_svc.c deleted file mode 100644 index e8ac5fc..0000000 --- a/plat/marvell/armada/a3700/common/a3700_sip_svc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - -#include -#include - -#include "comphy/phy-comphy-3700.h" - -/* Comphy related FID's */ -#define MV_SIP_COMPHY_POWER_ON 0x82000001 -#define MV_SIP_COMPHY_POWER_OFF 0x82000002 -#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 - -/* Miscellaneous FID's' */ -#define MV_SIP_DRAM_SIZE 0x82000010 - -/* This macro is used to identify COMPHY related calls from SMC function ID */ -#define is_comphy_fid(fid) \ - ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) - -uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - u_register_t ret; - - VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", - __func__, smc_fid, x1, x2); - if (is_comphy_fid(smc_fid)) { - if (x1 >= MAX_LANE_NR) { - ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", - __func__, smc_fid, x2); - SMC_RET1(handle, SMC_UNK); - } - } - - switch (smc_fid) { - /* Comphy related FID's */ - case MV_SIP_COMPHY_POWER_ON: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_on(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_POWER_OFF: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_off(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_PLL_LOCK: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_is_pll_locked(x1, x2); - SMC_RET1(handle, ret); - /* Miscellaneous FID's' */ - case MV_SIP_DRAM_SIZE: - /* x1: ap_base_addr */ - ret = mvebu_get_dram_size(MVEBU_REGS_BASE); - SMC_RET1(handle, ret); - - default: - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); - } -} - -/* Define a runtime service descriptor for fast SMC calls */ -DECLARE_RT_SVC( - marvell_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - mrvl_sip_smc_handler -); diff --git a/plat/marvell/armada/a3700/common/aarch64/a3700_common.c b/plat/marvell/armada/a3700/common/aarch64/a3700_common.c deleted file mode 100644 index 6351285..0000000 --- a/plat/marvell/armada/a3700/common/aarch64/a3700_common.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include - -/* MMU entry for internal (register) space access */ -#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ - DEVICE0_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -/* - * Table of regions for various BL stages to map using the MMU. - */ -#if IMAGE_BL1 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL2 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL2U -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL31 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL32 -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S deleted file mode 100644 index 90d76f0..0000000 --- a/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); - * - * This function performs any platform specific actions - * needed for a secondary cpu after a cold reset. Right - * now this is a stub function. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - mov x0, #0 - ret -endfunc plat_secondary_cold_boot_setup - - /* --------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * - * Main job of this routine is to distinguish between cold and warm boot - * For a cold boot, return 0. - * For a warm boot, read the mailbox and return the address it contains. - * A magic number is placed before entrypoint to avoid mistake caused by - * uninitialized mailbox data area. - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* Read first word and compare it with magic num */ - mov_imm x0, PLAT_MARVELL_MAILBOX_BASE - ldr x1, [x0] - mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM - cmp x1, x2 - /* If compare failed, return 0, i.e. cold boot */ - beq entrypoint - mov x0, #0 - ret -entrypoint: - /* Second word contains the jump address */ - add x0, x0, #8 - ldr x0, [x0] - ret -endfunc plat_get_my_entrypoint - - /* ----------------------------------------------------- - * unsigned int plat_is_my_cpu_primary (void); - * - * Find out whether the current cpu is the primary - * cpu. - * ----------------------------------------------------- - */ -func plat_is_my_cpu_primary - mrs x0, mpidr_el1 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #MVEBU_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/armada/a3700/common/dram_win.c b/plat/marvell/armada/a3700/common/dram_win.c deleted file mode 100644 index 694f6d4..0000000 --- a/plat/marvell/armada/a3700/common/dram_win.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include - -/* Armada 3700 has 5 configurable windows */ -#define MV_CPU_WIN_NUM 5 - -#define CPU_WIN_DISABLED 0 -#define CPU_WIN_ENABLED 1 - -/* - * There are 2 different cpu decode window configuration cases: - * - DRAM size is not over 2GB; - * - DRAM size is 4GB. - */ -enum cpu_win_config_num { - CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, - CPU_WIN_CONFIG_DRAM_4GB, - CPU_WIN_CONFIG_MAX -}; - -enum cpu_win_target { - CPU_WIN_TARGET_DRAM = 0, - CPU_WIN_TARGET_INTERNAL_REG, - CPU_WIN_TARGET_PCIE, - CPU_WIN_TARGET_PCIE_OVER_MCI, - CPU_WIN_TARGET_BOOT_ROM, - CPU_WIN_TARGET_MCI_EXTERNAL, - CPU_WIN_TARGET_RWTM_RAM = 7, - CPU_WIN_TARGET_CCI400_REG -}; - -struct cpu_win_configuration { - uint32_t enabled; - enum cpu_win_target target; - uint64_t base_addr; - uint64_t size; - uint64_t remap_addr; -}; - -struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { - /* - * When total dram size is not over 2GB: - * DDR window 0 is configured in tim header, its size may be not 512MB, - * but the actual dram size, no need to configure it again; - * other cpu windows are kept as default. - */ - { - /* enabled - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x08000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_MCI_EXTERNAL, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_RWTM_RAM, - 0xf0000000, - 0x00020000, - 0x1fff0000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE_OVER_MCI, - 0x80000000, - 0x10000000, - 0x80000000}, - }, - - /* - * If total dram size is more than 2GB, now there is only one case - 4GB - * dram; we will use below cpu windows configurations: - * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as - * default; - * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; - * DDR window 0 is configured in tim header with 2GB size, no need to - * configure it again here; - * - * 0xFFFFFFFF ---> |-----------------------| - * | Boot ROM | 64KB - * 0xFFF00000 ---> +-----------------------+ - * : : - * 0xF0000000 ---> |-----------------------| - * | PCIE | 128 MB - * 0xE8000000 ---> |-----------------------| - * | DDR window 3 | 128 MB - * 0xE0000000 ---> +-----------------------+ - * : : - * 0xD8010000 ---> |-----------------------| - * | CCI Regs | 64 KB - * 0xD8000000 ---> +-----------------------+ - * : : - * : : - * 0xD2000000 ---> +-----------------------+ - * | Internal Regs | 32MB - * 0xD0000000 ---> |-----------------------| - * | DDR window 2 | 256 MB - * 0xC0000000 ---> |-----------------------| - * | | - * | DDR window 1 | 1 GB - * | | - * 0x80000000 ---> |-----------------------| - * | | - * | | - * | DDR window 0 | 2 GB - * | | - * | | - * 0x00000000 ---> +-----------------------+ - */ - { - /* win_id - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x80000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x80000000, - 0x40000000, - 0x80000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xc0000000, - 0x10000000, - 0xc0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - }, -}; - -/* - * dram_win_map_build - * - * This function builds cpu dram windows mapping - * which includes base address and window size by - * reading cpu dram decode windows registers. - * - * @input: N/A - * - * @output: - * - win_map: cpu dram windows mapping - * - * @return: N/A - */ -void dram_win_map_build(struct dram_win_map *win_map) -{ - int32_t win_id; - struct dram_win *win; - uint32_t base_reg, ctrl_reg, size_reg, enabled, target; - - memset(win_map, 0, sizeof(struct dram_win_map)); - for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> - CPU_DEC_CR_WIN_TARGET_OFFS; - enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; - /* Ignore invalid and non-dram windows*/ - if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) - continue; - - win = win_map->dram_windows + win_map->dram_win_num; - base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); - size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); - /* Base reg [15:0] corresponds to transaction address [39:16] */ - win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> - CPU_DEC_BR_BASE_OFFS; - win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - /* - * Size reg [15:0] is programmed from LSB to MSB as a sequence - * of 1s followed by a sequence of 0s and the number of 1s - * specifies the size of the window in 64 KB granularity, - * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB - */ - win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> - CPU_DEC_CR_WIN_SIZE_OFFS; - win->win_size = (win->win_size + 1) * - CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - - win_map->dram_win_num++; - } -} - -static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) -{ - uint32_t base_reg, ctrl_reg, size_reg, remap_reg; - - /* Disable window */ - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); - - /* For an disabled window, only disable it. */ - if (!win_cfg->enabled) - return; - - /* Set Base Register */ - base_reg = (uint32_t)(win_cfg->base_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - base_reg <<= CPU_DEC_BR_BASE_OFFS; - base_reg &= CPU_DEC_BR_BASE_MASK; - mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); - - /* Set Remap Register with the same value - * as the field in Base Register - */ - remap_reg = (uint32_t)(win_cfg->remap_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; - remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; - mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); - - /* Set Size Register */ - size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; - size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; - size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; - mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); - - /* Set Control Register - set target id and enable window */ - ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; - ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); - ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); -} - -void cpu_wins_init(void) -{ - uint32_t cfg_idx, win_id; - - if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) - cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; - else - cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; - - /* Window 0 is configured always for DRAM in tim header - * already, no need to configure it again here - */ - for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) - cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); -} - diff --git a/plat/marvell/armada/a3700/common/include/a3700_plat_def.h b/plat/marvell/armada/a3700/common/include/a3700_plat_def.h deleted file mode 100644 index c7f40ad..0000000 --- a/plat/marvell/armada/a3700/common/include/a3700_plat_def.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PLAT_DEF_H -#define A3700_PLAT_DEF_H - -#include - - -#define MVEBU_MAX_CPUS_PER_CLUSTER 2 - -#define MVEBU_PRIMARY_CPU 0x0 - -/* - * The counter on A3700 is always fed from reference 25M clock (XTAL). - * However minimal CPU counter prescaler is 2, so the counter - * frequency will be divided by 2, the number is 12.5M - */ -#define COUNTER_FREQUENCY 12500000 - -#define MVEBU_REGS_BASE 0xD0000000 - -/***************************************************************************** - * MVEBU memory map related constants - ***************************************************************************** - */ -/* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE MVEBU_REGS_BASE -#define DEVICE0_SIZE 0x10000000 - -/***************************************************************************** - * GIC-500 & interrupt handling related constants - ***************************************************************************** - */ -/* Base MVEBU compatible GIC memory map */ -#define MVEBU_GICD_BASE 0x1D00000 -#define MVEBU_GICR_BASE 0x1D40000 -#define MVEBU_GICC_BASE 0x1D80000 - -/* CCI-400 */ -#define MVEBU_CCI_BASE 0x8000000 - -/***************************************************************************** - * North and south bridge register base - ***************************************************************************** - */ -#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) -#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) - -/***************************************************************************** - * GPIO registers related constants - ***************************************************************************** - */ -/* North and south bridge GPIO register base address */ -#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) -#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) -#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) -#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) -#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) - -/* North Bridge GPIO selection register */ -#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) -#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) -/* I2C1 GPIO Enable bit offset */ -#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) -/* SPI pins mode bit offset */ -#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) - -/***************************************************************************** - * DRAM registers related constants - ***************************************************************************** - */ -#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) - -/***************************************************************************** - * SB wake-up registers related constants - ***************************************************************************** - */ -#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) - -/***************************************************************************** - * PMSU registers related constants - ***************************************************************************** - */ -#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) - -/***************************************************************************** - * North Bridge Step-Down Registers - ***************************************************************************** - */ -#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) - -/***************************************************************************** - * DRAM CS memory map register base - ***************************************************************************** - */ -#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) - -/***************************************************************************** - * CPU decoder window registers related constants - ***************************************************************************** - */ -#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) - - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) - -#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/include/a3700_pm.h b/plat/marvell/armada/a3700/common/include/a3700_pm.h deleted file mode 100644 index cc6cf43..0000000 --- a/plat/marvell/armada/a3700/common/include/a3700_pm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PM_H -#define A3700_PM_H - -#include - -/* supported wake up sources */ -enum pm_wake_up_src_type { - WAKE_UP_SRC_GPIO, - /* FOLLOWING SRC NOT SUPPORTED YET */ - WAKE_UP_SRC_TIMER, - WAKE_UP_SRC_UART0, - WAKE_UP_SRC_UART1, - WAKE_UP_SRC_MAX, -}; - -struct pm_gpio_data { - /* - * bank 0: North bridge GPIO - * bank 1: South bridge GPIO - */ - uint32_t bank_num; - uint32_t gpio_num; -}; - -union pm_wake_up_src_data { - struct pm_gpio_data gpio_data; - /* delay in seconds */ - uint32_t timer_delay; -}; - -struct pm_wake_up_src { - enum pm_wake_up_src_type wake_up_src_type; - - union pm_wake_up_src_data wake_up_data; -}; - -struct pm_wake_up_src_config { - uint32_t wake_up_src_num; - struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); - -#endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3700/common/include/ddr_info.h b/plat/marvell/armada/a3700/common/include/ddr_info.h deleted file mode 100644 index 254f78c..0000000 --- a/plat/marvell/armada/a3700/common/include/ddr_info.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DDR_INFO_H -#define DDR_INFO_H - -#define DRAM_MAX_IFACE 1 -#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 - -#endif /* DDR_INFO_H */ diff --git a/plat/marvell/armada/a3700/common/include/dram_win.h b/plat/marvell/armada/a3700/common/include/dram_win.h deleted file mode 100644 index 26a0137..0000000 --- a/plat/marvell/armada/a3700/common/include/dram_win.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DRAM_WIN_H -#define DRAM_WIN_H - -#include - -#include - -void dram_win_map_build(struct dram_win_map *win_map); -void cpu_wins_init(void); - -#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/armada/a3700/common/include/io_addr_dec.h b/plat/marvell/armada/a3700/common/include/io_addr_dec.h deleted file mode 100644 index 42ef30b..0000000 --- a/plat/marvell/armada/a3700/common/include/io_addr_dec.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef IO_ADDR_DEC_H -#define IO_ADDR_DEC_H - -#include - -/* There are 5 configurable cpu decoder windows. */ -#define DRAM_WIN_MAP_NUM_MAX 5 -/* Target number for dram in cpu decoder windows. */ -#define DRAM_CPU_DEC_TARGET_NUM 0 - -/* - * Not all configurable decode windows could be used for dram, some units have - * to reserve one decode window for other unit they have to communicate with; - * for example, DMA engineer has 3 configurable windows, but only two could be - * for dram while the last one has to be for pcie, so for DMA, its max_dram_win - * is 2. - */ -struct dec_win_config { - uint32_t dec_reg_base; /* IO address decoder register base address */ - uint32_t win_attr; /* IO address decoder windows attributes */ - /* How many configurable dram decoder windows that this unit has; */ - uint32_t max_dram_win; - /* The decoder windows number including remapping that this unit has */ - uint32_t max_remap; - /* The offset between continuous decode windows - * within the same unit, typically 0x10 - */ - uint32_t win_offset; -}; - -struct dram_win { - uintptr_t base_addr; - uintptr_t win_size; -}; - -struct dram_win_map { - int dram_win_num; - struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; -}; - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, - uint32_t io_unit_num); - -#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/armada/a3700/common/include/plat_macros.S b/plat/marvell/armada/a3700/common/include/plat_macros.S deleted file mode 100644 index f689b4f..0000000 --- a/plat/marvell/armada/a3700/common/include/plat_macros.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include - -/* --------------------------------------------- - * The below macro prints out relevant GIC and - * CCI registers registers whenever an unhandled - * exception is taken in BL31. - * --------------------------------------------- - */ -.macro plat_crash_print_regs - mov_imm x17, MVEBU_GICC_BASE - mov_imm x16, MVEBU_GICD_BASE - marvell_print_gic_regs - print_cci_regs -.endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a3700/common/include/platform_def.h b/plat/marvell/armada/a3700/common/include/platform_def.h deleted file mode 100644 index e6660d4..0000000 --- a/plat/marvell/armada/a3700/common/include/platform_def.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2016-2019 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#ifndef __ASSEMBLER__ -#include -#endif /* __ASSEMBLER__ */ - -#include -#include - -/* - * Most platform porting definitions provided by included headers - */ - -/* - * DRAM Memory layout: - * +-----------------------+ - * : : - * : Linux : - * 0x04X00000-->+-----------------------+ - * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - * |-----------------------| } | - * | BL3-[0,1, 2] | }---------------------------------> | - * |-----------------------| } || | - * | BL2 | }->FIP (loaded by || | - * |-----------------------| } BootROM to DRAM) || | - * | FIP_TOC | } || | - * 0x04120000-->|-----------------------| || | - * | BL1 (RO) | || | - * 0x04100000-->+-----------------------+ || | - * : : || | - * : Trusted SRAM section : \/ | - * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | - * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | - * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | - * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | - * 0x04023000-->|-----------------------| +----------------+ | - * | BL2 | | - * |-----------------------| | - * | | | - * 0x04001000-->|-----------------------| | - * | Shared | | - * 0x04000000-->+-----------------------+ | - * : : | - * : Linux : | - * : : | - * |-----------------------| | - * | | U-Boot(BL3-3) Loaded by BL2 | - * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - * 0x00000000-->+-----------------------+ - * - * Trusted SRAM section 0x4000000..0x4200000: - * ---------------------------------------- - * SRAM_BASE = 0x4001000 - * BL2_BASE = 0x4006000 - * BL2_LIMIT = BL31_BASE - * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) - * BL31_PROGBITS_LIMIT = BL1_RW_BASE - * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) - * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 - * - * - * PLAT_MARVELL_FIP_BASE = 0x4120000 - */ - -#define PLAT_MARVELL_ATF_BASE 0x4000000 -#define PLAT_MARVELL_ATF_LOAD_ADDR \ - (PLAT_MARVELL_ATF_BASE + 0x100000) - -#define PLAT_MARVELL_FIP_BASE \ - (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) -#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 - -#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) -/* DRAM[2MB..66MB] is used as Trusted ROM */ -#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ - -/* - * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size - * plus a little space for growth. - */ -#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 - -/* - * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a - * little space for growth. - */ -#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 - -/* - * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a - * little space for growth. - */ -#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 - -#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE - -/* GIC related definitions */ -#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) -#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) -#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) - -#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - -#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - - -#define PLAT_MARVELL_SHARED_RAM_CACHED 1 - -/* CCI related constants */ -#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) -#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 -#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 - -/* - * Load address of BL3-3 for this platform port - */ -#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 - -/* System Reference Clock*/ -#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY - -/* - * PL011 related constants - */ -#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) -#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 - -#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -/* Required platform porting definitions */ -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 - -/* System timer related constants */ -#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 - -/* Mailbox base address */ -#define PLAT_MARVELL_MAILBOX_BASE \ - (MARVELL_TRUSTED_SRAM_BASE + 0x400) -#define PLAT_MARVELL_MAILBOX_SIZE 0x100 -#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ - -/* DRAM CS memory map registers related constants */ -#define MVEBU_CS_MMAP_LOW(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) -#define MVEBU_CS_MMAP_ENABLE 0x1 -#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 -#define MVEBU_CS_MMAP_AREA_LEN_MASK \ - (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) -#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 -#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ - (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) - -#define MVEBU_CS_MMAP_HIGH(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) - -/* DRAM max CS number */ -#define MVEBU_MAX_CS_MMAP_NUM (2) - -/* CPU decoder window related constants */ -#define CPU_DEC_WIN_CTRL_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_ENABLE 0x1 -#define CPU_DEC_CR_WIN_TARGET_OFFS 4 -#define CPU_DEC_CR_WIN_TARGET_MASK \ - (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) - -#define CPU_DEC_WIN_SIZE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_SIZE_OFFS 0 -#define CPU_DEC_CR_WIN_SIZE_MASK \ - (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) -#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 - -#define CPU_DEC_WIN_BASE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) -#define CPU_DEC_BR_BASE_OFFS 0 -#define CPU_DEC_BR_BASE_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -#define CPU_DEC_REMAP_LOW_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) -#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 -#define CPU_DEC_RLR_REMAP_LOW_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -/* Securities */ -#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER - -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/io_addr_dec.c b/plat/marvell/armada/a3700/common/io_addr_dec.c deleted file mode 100644 index b27633c..0000000 --- a/plat/marvell/armada/a3700/common/io_addr_dec.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off)) -#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x4) -#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x8) - -#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) -#define MVEBU_DEC_WIN_ENABLE (0x1) -#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) -#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) -#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) -#define MVEBU_DEC_WIN_BASE_OFF (16) - -#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) - -/* There are up to 14 IO unit which need address decode in Armada-3700 */ -#define IO_UNIT_NUM_MAX (14) - -#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) - - -static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, - uintptr_t win_size, - struct dec_win_config *dec_win) -{ - uint32_t ctrl = 0; - uint32_t base = 0; - - /* set size */ - ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << - MVEBU_DEC_WIN_CTRL_SIZE_OFF; - /* set attr according to IO decode window */ - ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; - /* set target */ - ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; - /* set base */ - base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << - MVEBU_DEC_WIN_BASE_OFF; - - /* set base address*/ - mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), - base); - /* set remap window, some unit does not have remap window */ - if (win_id < dec_win->max_remap) - mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), base); - /* set control register */ - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - /* enable the address decode window at last to make it effective */ - ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - - INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", - win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset)), - mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - if (win_id < dec_win->max_remap) - INFO(" remap(%x)\n", - mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - else - INFO("\n"); -} - -/* Set io decode window */ -static int set_io_addr_dec(struct dram_win_map *win_map, - struct dec_win_config *dec_win) -{ - struct dram_win *win; - int id; - - /* disable all windows first */ - for (id = 0; id < dec_win->max_dram_win; id++) - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, - dec_win->win_offset), 0); - - /* configure IO decode windows for DRAM, inheritate DRAM size, - * base and target from CPU-DRAM decode window and others - * from hard coded IO decode window settings array. - */ - if (win_map->dram_win_num > dec_win->max_dram_win) { - /* - * If cpu dram windows number exceeds the io decode windows - * max number, then fill the first io decode window - * with base(0) and size(4GB). - */ - set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); - - return 0; - } - - for (id = 0; id < win_map->dram_win_num; id++, win++) { - win = &win_map->dram_windows[id]; - set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); - } - - return 0; -} - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, uint32_t io_unit_num) -{ - int32_t index; - struct dec_win_config *io_dec_win; - int32_t ret; - - INFO("Initializing IO address decode windows\n"); - - if (io_dec_config == NULL || io_unit_num == 0) { - ERROR("No IO address decoder windows configurations!\n"); - return -1; - } - - if (io_unit_num > IO_UNIT_NUM_MAX) { - ERROR("IO address decoder windows number %d is over max %d\n", - io_unit_num, IO_UNIT_NUM_MAX); - return -1; - } - - if (dram_wins_map == NULL) { - ERROR("No cpu dram decoder windows map!\n"); - return -1; - } - - for (index = 0; index < dram_wins_map->dram_win_num; index++) - INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", - index, dram_wins_map->dram_windows[index].base_addr, - dram_wins_map->dram_windows[index].win_size); - - /* Set address decode window for each IO */ - for (index = 0; index < io_unit_num; index++) { - io_dec_win = io_dec_config + index; - ret = set_io_addr_dec(dram_wins_map, io_dec_win); - if (ret) { - ERROR("Failed to set IO address decode\n"); - return -1; - } - INFO("Set IO decode window successfully, base(0x%x)", - io_dec_win->dec_reg_base); - INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", - io_dec_win->win_attr, io_dec_win->max_dram_win, - io_dec_win->max_remap); - INFO(" win_offset(%d)\n", io_dec_win->win_offset); - } - - return 0; -} diff --git a/plat/marvell/armada/a3700/common/marvell_plat_config.c b/plat/marvell/armada/a3700/common/marvell_plat_config.c deleted file mode 100644 index 3bf3d96..0000000 --- a/plat/marvell/armada/a3700/common/marvell_plat_config.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -struct dec_win_config io_dec_win_conf[] = { - /* dec_reg_base win_attr max_dram_win max_remap win_offset */ - {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ - {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ - {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ - {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ - {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ - {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ - {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ - {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ - {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ - {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ -}; - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) -{ - *win = io_dec_win_conf; - *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); - - return 0; -} - diff --git a/plat/marvell/armada/a3700/common/plat_pm.c b/plat/marvell/armada/a3700/common/plat_pm.c deleted file mode 100644 index f8ce6fe..0000000 --- a/plat/marvell/armada/a3700/common/plat_pm.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#ifdef USE_CCI -#include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Warm reset register */ -#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) -#define MVEBU_WARM_RESET_MAGIC 0x1D1E - -/* North Bridge GPIO1 SEL register */ -#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) - #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) - #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) - #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) - #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) - -/* CPU 1 reset register */ -#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) -#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) -#define MVEBU_CPU_1_RESET_BIT 31 - -/* IRQ register */ -#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) -#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x40) -#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x50) -#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xC8) -#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xD8) -#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xE8) -#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) -#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x04) -#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x14) -#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x1C) -#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) -#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x18) - -/* PMU registers */ -#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) - #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) - #define MVEBU_PM_SB_PWR_DWN BIT(4) - #define MVEBU_PM_INTERFACE_IDLE BIT(0) -#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) - #define MVEBU_PM_L2_FLUSH_EN BIT(22) -#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) - #define MVEBU_PM_DDR_SR_EN BIT(29) - #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) - #define MVEBU_PM_WARM_RESET_EN BIT(27) - #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) - #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) - #define MVEBU_PM_OSC_OFF_EN BIT(21) - #define MVEBU_PM_TBG_OFF_EN BIT(20) - #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) - #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) - #define MVEBU_PM_AVS_VDD2_MODE BIT(13) - #define MVEBU_PM_AVS_HOLD_MODE BIT(12) - #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) - #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ - MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ - MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) -#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) - #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) - #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) - #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) -#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) - #define MVEBU_PM_SB_WKP_NB_EN BIT(31) - #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) - #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) - #define MVEBU_PM_UART_WKP_EN BIT(25) - #define MVEBU_PM_UART2_WKP_EN BIT(19) - #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) - #define MVEBU_PM_NB_WKP_EN BIT(16) - #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) - #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) -#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) -#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) - #define MVEBU_PM_CORE_SOC_PD BIT(2) - #define MVEBU_PM_CORE_PROC_PD BIT(1) - #define MVEBU_PM_CORE_PD BIT(0) -#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) -#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) -#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) - #define MVEBU_PM_LOW_POWER_STATE BIT(0) -#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) - #define MVEBU_PM_CORE1_WAKEUP BIT(13) - #define MVEBU_PM_CORE0_WAKEUP BIT(12) -#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) -#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) - #define MVEBU_PM_SB_PM_START BIT(0) -#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) - #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) - #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) - #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) - #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) - #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) - #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ - MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ - MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) -#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) - #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) - #define MVEBU_PM_SB_WKP_EN BIT(20) - -/* DRAM registers */ -#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) - #define MVEBU_DRAM_WCP_EMPTY BIT(19) -#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) - #define MVEBU_DRAM_CH0_CMD0 BIT(28) - #define MVEBU_DRAM_CS_CMD0 BIT(24) - #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) -#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) - #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) - #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) - -/* AVS registers */ -#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) - #define MVEBU_LOW_VDD_MODE_EN BIT(6) - -/* Clock registers */ -#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) - #define MVEBU_A53_CPU_CLK_SEL BIT(15) - -/* North Bridge Step-Down Registers */ -#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE - #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) - -#define MVEBU_NB_GPIO_18 18 -#define MVEBU_NB_GPIO_19 19 -#define MVEBU_NB_GPIO_25 25 -#define MVEBU_NB_GPIO_26 26 - -typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); - -struct wake_up_src_func_map { - enum pm_wake_up_src_type type; - wake_up_src_func func; -}; - -void marvell_psci_arch_init(int die_index) -{ -} - -static void a3700_pm_ack_irq(void) -{ - uint32_t reg; - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); - - reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); - if (reg) - mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); -} - -/***************************************************************************** - * A3700 handler called to check the validity of the power state - * parameter. - ***************************************************************************** - */ -int a3700_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a CPU is about to enter standby. - ***************************************************************************** - */ -void a3700_cpu_standby(plat_local_state_t cpu_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ***************************************************************************** - */ -int a3700_pwr_domain_on(u_register_t mpidr) -{ - /* Set barrier */ - dsbsy(); - - /* Set the cpu start address to BL1 entry point */ - mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, - PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); - - /* Get the cpu out of reset */ - mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - - return 0; -} - -/***************************************************************************** - * A3700 handler called to validate the entry point. - ***************************************************************************** - */ -int a3700_validate_ns_entrypoint(uintptr_t entrypoint) -{ - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_off(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Core can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); -} - -static void a3700_set_gen_pwr_off_option(void) -{ - /* Enable L2 flush -> processor state-machine option */ - mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); - - /* - * North bridge cannot be VDD off (always ON). - * The NB state machine support low power mode by its state machine. - * This bit MUST be set for north bridge power down, e.g., - * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. - * It is not related to CPU VDD OFF!! - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); - - /* - * MUST: Switch CPU/AXI clock to OSC - * NB state machine clock is always connected to OSC (slow clock). - * But Core0/1/processor state machine's clock are connected to AXI - * clock. Now, AXI clock takes the TBG as clock source. - * If using AXI clock, Core0/1/processor state machine may much faster - * than NB state machine. It will cause problem in this case if cores - * are released before north bridge gets ready. - */ - mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); - - /* - * These register bits will trigger north bridge - * power-down state machine regardless CM3 status. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); - - /* - * SRAM => controlled by north bridge state machine. - * Core VDD OFF is not related to CPU SRAM power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); - - /* - * Idle AXI interface in order to get L2_WFI - * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. - * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) - * Once L2 WFI asserted, this bit is used for signalling assertion - * to AXI IO masters. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); - - /* Enable core0 and core1 VDD_OFF */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - - /* Enable North bridge power down - - * Both Cores MUST enable this bit to power down north bridge! - */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - - /* CA53 (processor domain) power down */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); -} - -static void a3700_en_ddr_self_refresh(void) -{ - /* - * Both count is 16 bits and configurable. By default, osc stb cnt - * is 0xFFF for lower 12 bits. - * Thus, powerdown count is smaller than osc count. - * This count is used for exiting DDR SR mode on wakeup event. - * The powerdown count also has impact on the following - * state changes: idle -> count-down -> ... (power-down, vdd off, etc) - * Here, make stable counter shorter - * Use power down count value instead of osc_stb_cnt to speed up - * DDR self refresh exit - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); - - /* - * Enable DDR SR mode => controlled by north bridge state machine - * Therefore, we must powerdown north bridge to trigger the DDR SR - * mode switching. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); - /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); - /* Power down DDR PHY (PAD) */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, - MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); - - /* Set wait time for DDR ready in ROM code */ - mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, - MVEBU_PM_WAIT_DDR_RDY_VALUE); - - /* DDR flush write buffer - mandatory */ - mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | - MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); - while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & - MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) - ; - - /* Trigger PHY reset after ddr out of self refresh => - * supply reset pulse for DDR phy after wake up - */ - mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | - MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); -} - -static void a3700_pwr_dn_avs(void) -{ - /* - * AVS power down - controlled by north bridge statemachine - * Enable AVS power down by clear the AVS disable bit. - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); - /* - * Should set BIT[12:13] to powerdown AVS. - * 1. Enable AVS VDD2 mode - * 2. After power down AVS, we must hold AVS output voltage. - * 3. We can choose the lower VDD for AVS power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); - - /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ - mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); -} - -static void a3700_pwr_dn_tbg(void) -{ - /* Power down TBG */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); -} - -static void a3700_pwr_dn_sb(void) -{ - /* Enable south bridge power down option */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); - - /* Enable SDIO_PHY_PWRDWN */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); - - /* Enable SRAM LRM on SB */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); - - /* Enable SB Power Off */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); - - /* Kick off South Bridge Power Off */ - mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); -} - -static void a3700_set_pwr_off_option(void) -{ - /* Set general power off option */ - a3700_set_gen_pwr_off_option(); - - /* Enable DDR self refresh in low power mode */ - a3700_en_ddr_self_refresh(); - - /* Power down AVS */ - a3700_pwr_dn_avs(); - - /* Power down TBG */ - a3700_pwr_dn_tbg(); - - /* Power down south bridge, pay attention south bridge setting - * should be done before - */ - a3700_pwr_dn_sb(); -} - -static void a3700_set_wake_up_option(void) -{ - /* - * Enable the wakeup event for NB SOC => north-bridge - * state-machine enablement on wake-up event - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); - - /* Enable both core0 and core1 wakeup on demand */ - mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, - MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); - - /* Enable warm reset in low power mode */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); -} - -static void a3700_pm_en_nb_gpio(uint32_t gpio) -{ - /* For GPIO1 interrupt -- North bridge only */ - if (gpio >= 32) { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); - } else { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); - } - - mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, - MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); - - /* Enable using GPIO as wakeup event - * (actually not only for north bridge) - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); -} - -static void a3700_pm_en_sb_gpio(uint32_t gpio) -{ - /* Enable using GPIO as wakeup event */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); - - /* SB GPIO Wake UP | South Bridge Wake Up Enable */ - mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | - MVEBU_PM_SB_GPIO_WKP_EN); - - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); -} - -int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) -{ - if (src_data->gpio_data.bank_num == 0) - /* North Bridge GPIO */ - a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); - else - a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); - return 0; -} - -int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) -{ - /* Clear Uart1 select */ - mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); - /* set pin 19 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); - /* set pin 18 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); - - return 0; -} - -int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) -{ - /* set pin 25/26 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); - - return 0; -} - -struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { - {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, - {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, - {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, - /* FOLLOWING SRC NOT SUPPORTED YET */ - {WAKE_UP_SRC_TIMER, NULL} -}; - -static wake_up_src_func a3700_get_wake_up_src_func( - enum pm_wake_up_src_type type) -{ - uint32_t loop; - - for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { - if (src_func_table[loop].type == type) - return src_func_table[loop].func; - } - return NULL; -} - -static void a3700_set_wake_up_source(void) -{ - struct pm_wake_up_src_config *wake_up_src; - uint32_t loop; - wake_up_src_func src_func = NULL; - - wake_up_src = mv_wake_up_src_config_get(); - for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { - src_func = a3700_get_wake_up_src_func( - wake_up_src->wake_up_src[loop].wake_up_src_type); - if (src_func) - src_func( - &(wake_up_src->wake_up_src[loop].wake_up_data)); - } -} - -static void a3700_pm_save_lp_flag(void) -{ - /* Save the flag for enter the low power mode */ - mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static void a3700_pm_clear_lp_flag(void) -{ - /* Clear the flag for enter the low power mode */ - mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static uint32_t a3700_pm_get_lp_flag(void) -{ - /* Get the flag for enter the low power mode */ - return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & - MVEBU_PM_LOW_POWER_STATE; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Save IRQ states */ - plat_marvell_gic_irq_save(); - - /* Set wake up options */ - a3700_set_wake_up_option(); - - /* Set wake up sources */ - a3700_set_wake_up_source(); - - /* SoC can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); - - /* Set power off options */ - a3700_set_pwr_off_option(); - - /* Save the flag for enter the low power mode */ - a3700_pm_save_lp_flag(); - - isb(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ***************************************************************************** - */ -void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Per-CPU interrupt initialization */ - plat_marvell_gic_pcpu_init(); - plat_marvell_gic_cpuif_enable(); - - /* Restore the per-cpu IRQ state */ - if (a3700_pm_get_lp_flag()) - plat_marvell_gic_irq_pcpu_restore(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - * TODO: At the moment we reuse the on finisher and reinitialize the secure - * context. Need to implement a separate suspend finisher. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - plat_marvell_gic_init(); - - /* Restore IRQ states */ - plat_marvell_gic_irq_restore(); - - /* - * Initialize CCI for this cluster after resume from suspend state. - * No need for locks as no other CPU is active. - */ - plat_marvell_interconnect_init(); - /* - * Enable CCI coherency for the primary CPU's cluster. - * Platform specific PSCI code will enable coherency for other - * clusters. - */ - plat_marvell_interconnect_enter_coherency(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } - - /* Clear low power mode flag */ - a3700_pm_clear_lp_flag(); -} - -/***************************************************************************** - * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND - * call to get the `power_state` parameter. This allows the platform to encode - * the appropriate State-ID field within the `power_state` parameter which can - * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. - ***************************************************************************** - */ -void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - /* lower affinities use PLAT_MAX_OFF_STATE */ - for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; -} - -/***************************************************************************** - * A3700 handlers to shutdown/reboot the system - ***************************************************************************** - */ -static void __dead2 a3700_system_off(void) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handlers to reset the system - ***************************************************************************** - */ -static void __dead2 a3700_system_reset(void) -{ - /* Clean the mailbox magic number to let it as act like cold boot */ - mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); - - dsbsy(); - - /* Flush data cache if the mail box shared RAM is cached */ -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, - 2 * sizeof(uint64_t)); -#endif - - /* Trigger the warm reset */ - mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); - - /* Shouldn't get to this point */ - panic(); -} - -/***************************************************************************** - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ***************************************************************************** - */ -const plat_psci_ops_t plat_arm_psci_pm_ops = { - .cpu_standby = a3700_cpu_standby, - .pwr_domain_on = a3700_pwr_domain_on, - .pwr_domain_off = a3700_pwr_domain_off, - .pwr_domain_suspend = a3700_pwr_domain_suspend, - .pwr_domain_on_finish = a3700_pwr_domain_on_finish, - .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, - .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, - .system_off = a3700_system_off, - .system_reset = a3700_system_reset, - .validate_power_state = a3700_validate_power_state, - .validate_ns_entrypoint = a3700_validate_ns_entrypoint -}; diff --git a/plat/marvell/armada/a3k/a3700/board/pm_src.c b/plat/marvell/armada/a3k/a3700/board/pm_src.c new file mode 100644 index 0000000..d6eca5d --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/board/pm_src.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +/* This struct provides the PM wake up src configuration */ +static struct pm_wake_up_src_config wake_up_src_cfg = { + .wake_up_src_num = 3, + .wake_up_src[0] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 0, /* North Bridge */ + .gpio_data.gpio_num = 14 + } + }, + .wake_up_src[1] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 1, /* South Bridge */ + .gpio_data.gpio_num = 2 + } + }, + .wake_up_src[2] = { + .wake_up_src_type = WAKE_UP_SRC_UART1, + } +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) +{ + return &wake_up_src_cfg; +} + diff --git a/plat/marvell/armada/a3k/a3700/mvebu_def.h b/plat/marvell/armada/a3k/a3700/mvebu_def.h new file mode 100644 index 0000000..dad1085 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/mvebu_def.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_DEF_H +#define MVEBU_DEF_H + +#include + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c new file mode 100644 index 0000000..6862a86 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include + +/* This routine does MPP initialization */ +static void marvell_bl31_mpp_init(void) +{ + mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); + + /* Set hidden GPIO setting for SPI. + * In north_bridge_pin_out_en_high register 13804, + * bit 28 is the one which enables CS, CLK pins to be + * output, need to set it to 1. + * The initial value of this bit is 1, but in UART boot mode + * initialization, this bit is disabled and the SPI CS and CLK pins + * are used for downloading image purpose; so after downloading, + * we should set this bit to 1 again to enable SPI CS and CLK pins. + * And anyway, this bit value should be 1 in all modes, + * so here we does not judge boot mode and set this bit to 1 always. + */ + mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, + 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); +} + +/* This function overruns the same function in marvell_bl31_setup.c */ +void bl31_plat_arch_setup(void) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + marvell_bl31_plat_arch_setup(); + + /* MPP init */ + marvell_bl31_mpp_init(); + + /* initialize the timer for delay functionality */ + plat_delay_timer_init(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } +} diff --git a/plat/marvell/armada/a3k/a3700/platform.mk b/plat/marvell/armada/a3k/a3700/platform.mk new file mode 100644 index 0000000..050af41 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/platform.mk @@ -0,0 +1,10 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +include plat/marvell/armada/a3k/common/a3700_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk new file mode 100644 index 0000000..9965567 --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -0,0 +1,170 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +MARVELL_PLAT_BASE := plat/marvell/armada +MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada +PLAT_FAMILY := a3k +PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) +PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY) +PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common +MARVELL_DRV_BASE := drivers/marvell +MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common +HANDLE_EA_EL3_FIRST := 1 + +include plat/marvell/marvell.mk + +#*********** A3700 ************* +DOIMAGEPATH := $(WTP) +DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux + +ifeq ($(MARVELL_SECURE_BOOT),1) +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/trusted + +TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt +TIMNSIG := $(IMAGESPATH)/timnsign.txt +TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) +TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) +else #MARVELL_SECURE_BOOT +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted +TIM2IMGARGS := -i $(DOIMAGE_CFG) +endif #MARVELL_SECURE_BOOT + +TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh +TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl + +# WTMI_IMG is used to specify the customized RTOS image running over +# Service CPU (CM3 processor). By the default, it points to a +# baremetal binary of fuse programming in A3700_utils. +WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin + +# WTMI_SYSINIT_IMG is used for the system early initialization, +# such as AVS settings, clock-tree setup and dynamic DDR PHY training. +# After the initialization is done, this image will be wiped out +# from the memory and CM3 will continue with RTOS image or other application. +WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin + +# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) +# and sys-init image (WTMI_SYSINIT_IMG). +WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin + +WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin +BUILD_UART := uart-images + +SRCPATH := $(dir $(BL33)) + +CLOCKSPRESET ?= CPU_800_DDR_800 + +DDR_TOPOLOGY ?= 0 + +BOOTDEV ?= SPINOR +PARTNUM ?= 0 + +TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) +TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 +TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 +DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D + +# GICV3 +$(eval $(call add_define,CONFIG_GICV3)) + +# CCI-400 +$(eval $(call add_define,USE_CCI)) + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_DRV_BASE) \ + -I$/drivers/arm/gic/common/ + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ + $(MARVELL_COMMON_BASE)/marvell_cci.c \ + $(MARVELL_DRV_BASE)/uart/a3700_console.S + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a53.S + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c + +MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(PLAT_COMMON_BASE)/dram_win.c \ + $(PLAT_COMMON_BASE)/io_addr_dec.c \ + $(PLAT_COMMON_BASE)/marvell_plat_config.c \ + $(PLAT_COMMON_BASE)/a3700_ea.c \ + $(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \ + $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ + $(MARVELL_GIC_SOURCES) \ + drivers/arm/cci/cci.c \ + $(BL31_PORTING_SOURCES) \ + $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ + $(MARVELL_DRV) + +mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} + $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) + $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 $(WTMI_IMG)) + @echo + @echo "Building uart images" + $(TIMBUILD) $(TIMBLDUARTARGS) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* + @mkdir $(BUILD_PLAT)/$(BUILD_UART) + @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) + @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) + @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin + @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) + @echo + @echo "Building flash image" + $(TIMBUILD) $(TIMBLDARGS) + sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) + @echo -e "\n\t=======================================================\n"; + @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; + @echo -e "\t=======================================================\n"; + @truncate -s %16 $(WTMI_MULTI_IMG) + @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ + -out $(WTMI_ENC_IMG) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p + @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); + @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ + -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi + $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) + @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi + @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c new file mode 100644 index 0000000..dd46beb --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 Repk repk@triplefau.lt + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include +#include +#include + +#define ADVK_SERROR_SYNDROME 0xbf000002 + +void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, + void *handle, uint64_t flags) +{ + if (syndrome != ADVK_SERROR_SYNDROME) { + ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", + read_mpidr_el1()); + ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, + syndrome); + panic(); + } +} diff --git a/plat/marvell/armada/a3k/common/a3700_sip_svc.c b/plat/marvell/armada/a3k/common/a3700_sip_svc.c new file mode 100644 index 0000000..e8ac5fc --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_sip_svc.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#include +#include + +#include "comphy/phy-comphy-3700.h" + +/* Comphy related FID's */ +#define MV_SIP_COMPHY_POWER_ON 0x82000001 +#define MV_SIP_COMPHY_POWER_OFF 0x82000002 +#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 + +/* Miscellaneous FID's' */ +#define MV_SIP_DRAM_SIZE 0x82000010 + +/* This macro is used to identify COMPHY related calls from SMC function ID */ +#define is_comphy_fid(fid) \ + ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) + +uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + u_register_t ret; + + VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", + __func__, smc_fid, x1, x2); + if (is_comphy_fid(smc_fid)) { + if (x1 >= MAX_LANE_NR) { + ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", + __func__, smc_fid, x2); + SMC_RET1(handle, SMC_UNK); + } + } + + switch (smc_fid) { + /* Comphy related FID's */ + case MV_SIP_COMPHY_POWER_ON: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_on(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_POWER_OFF: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_off(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_PLL_LOCK: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_is_pll_locked(x1, x2); + SMC_RET1(handle, ret); + /* Miscellaneous FID's' */ + case MV_SIP_DRAM_SIZE: + /* x1: ap_base_addr */ + ret = mvebu_get_dram_size(MVEBU_REGS_BASE); + SMC_RET1(handle, ret); + + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Define a runtime service descriptor for fast SMC calls */ +DECLARE_RT_SVC( + marvell_sip_svc, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + mrvl_sip_smc_handler +); diff --git a/plat/marvell/armada/a3k/common/aarch64/a3700_common.c b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c new file mode 100644 index 0000000..6351285 --- /dev/null +++ b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include + +/* MMU entry for internal (register) space access */ +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Table of regions for various BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL2U +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL32 +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S new file mode 100644 index 0000000..90d76f0 --- /dev/null +++ b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset. Right + * now this is a stub function. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + mov x0, #0 + ret +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between cold and warm boot + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * A magic number is placed before entrypoint to avoid mistake caused by + * uninitialized mailbox data area. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* Read first word and compare it with magic num */ + mov_imm x0, PLAT_MARVELL_MAILBOX_BASE + ldr x1, [x0] + mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM + cmp x1, x2 + /* If compare failed, return 0, i.e. cold boot */ + beq entrypoint + mov x0, #0 + ret +entrypoint: + /* Second word contains the jump address */ + add x0, x0, #8 + ldr x0, [x0] + ret +endfunc plat_get_my_entrypoint + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #MVEBU_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/armada/a3k/common/dram_win.c b/plat/marvell/armada/a3k/common/dram_win.c new file mode 100644 index 0000000..694f6d4 --- /dev/null +++ b/plat/marvell/armada/a3k/common/dram_win.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include + +/* Armada 3700 has 5 configurable windows */ +#define MV_CPU_WIN_NUM 5 + +#define CPU_WIN_DISABLED 0 +#define CPU_WIN_ENABLED 1 + +/* + * There are 2 different cpu decode window configuration cases: + * - DRAM size is not over 2GB; + * - DRAM size is 4GB. + */ +enum cpu_win_config_num { + CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, + CPU_WIN_CONFIG_DRAM_4GB, + CPU_WIN_CONFIG_MAX +}; + +enum cpu_win_target { + CPU_WIN_TARGET_DRAM = 0, + CPU_WIN_TARGET_INTERNAL_REG, + CPU_WIN_TARGET_PCIE, + CPU_WIN_TARGET_PCIE_OVER_MCI, + CPU_WIN_TARGET_BOOT_ROM, + CPU_WIN_TARGET_MCI_EXTERNAL, + CPU_WIN_TARGET_RWTM_RAM = 7, + CPU_WIN_TARGET_CCI400_REG +}; + +struct cpu_win_configuration { + uint32_t enabled; + enum cpu_win_target target; + uint64_t base_addr; + uint64_t size; + uint64_t remap_addr; +}; + +struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { + /* + * When total dram size is not over 2GB: + * DDR window 0 is configured in tim header, its size may be not 512MB, + * but the actual dram size, no need to configure it again; + * other cpu windows are kept as default. + */ + { + /* enabled + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x08000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_MCI_EXTERNAL, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_RWTM_RAM, + 0xf0000000, + 0x00020000, + 0x1fff0000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE_OVER_MCI, + 0x80000000, + 0x10000000, + 0x80000000}, + }, + + /* + * If total dram size is more than 2GB, now there is only one case - 4GB + * dram; we will use below cpu windows configurations: + * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as + * default; + * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; + * DDR window 0 is configured in tim header with 2GB size, no need to + * configure it again here; + * + * 0xFFFFFFFF ---> |-----------------------| + * | Boot ROM | 64KB + * 0xFFF00000 ---> +-----------------------+ + * : : + * 0xF0000000 ---> |-----------------------| + * | PCIE | 128 MB + * 0xE8000000 ---> |-----------------------| + * | DDR window 3 | 128 MB + * 0xE0000000 ---> +-----------------------+ + * : : + * 0xD8010000 ---> |-----------------------| + * | CCI Regs | 64 KB + * 0xD8000000 ---> +-----------------------+ + * : : + * : : + * 0xD2000000 ---> +-----------------------+ + * | Internal Regs | 32MB + * 0xD0000000 ---> |-----------------------| + * | DDR window 2 | 256 MB + * 0xC0000000 ---> |-----------------------| + * | | + * | DDR window 1 | 1 GB + * | | + * 0x80000000 ---> |-----------------------| + * | | + * | | + * | DDR window 0 | 2 GB + * | | + * | | + * 0x00000000 ---> +-----------------------+ + */ + { + /* win_id + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x80000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x80000000, + 0x40000000, + 0x80000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xc0000000, + 0x10000000, + 0xc0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + }, +}; + +/* + * dram_win_map_build + * + * This function builds cpu dram windows mapping + * which includes base address and window size by + * reading cpu dram decode windows registers. + * + * @input: N/A + * + * @output: + * - win_map: cpu dram windows mapping + * + * @return: N/A + */ +void dram_win_map_build(struct dram_win_map *win_map) +{ + int32_t win_id; + struct dram_win *win; + uint32_t base_reg, ctrl_reg, size_reg, enabled, target; + + memset(win_map, 0, sizeof(struct dram_win_map)); + for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> + CPU_DEC_CR_WIN_TARGET_OFFS; + enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; + /* Ignore invalid and non-dram windows*/ + if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) + continue; + + win = win_map->dram_windows + win_map->dram_win_num; + base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); + size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); + /* Base reg [15:0] corresponds to transaction address [39:16] */ + win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> + CPU_DEC_BR_BASE_OFFS; + win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + /* + * Size reg [15:0] is programmed from LSB to MSB as a sequence + * of 1s followed by a sequence of 0s and the number of 1s + * specifies the size of the window in 64 KB granularity, + * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB + */ + win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> + CPU_DEC_CR_WIN_SIZE_OFFS; + win->win_size = (win->win_size + 1) * + CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + + win_map->dram_win_num++; + } +} + +static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) +{ + uint32_t base_reg, ctrl_reg, size_reg, remap_reg; + + /* Disable window */ + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); + + /* For an disabled window, only disable it. */ + if (!win_cfg->enabled) + return; + + /* Set Base Register */ + base_reg = (uint32_t)(win_cfg->base_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + base_reg <<= CPU_DEC_BR_BASE_OFFS; + base_reg &= CPU_DEC_BR_BASE_MASK; + mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); + + /* Set Remap Register with the same value + * as the field in Base Register + */ + remap_reg = (uint32_t)(win_cfg->remap_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; + remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; + mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); + + /* Set Size Register */ + size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; + size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; + size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; + mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); + + /* Set Control Register - set target id and enable window */ + ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; + ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); + ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); +} + +void cpu_wins_init(void) +{ + uint32_t cfg_idx, win_id; + + if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) + cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; + else + cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; + + /* Window 0 is configured always for DRAM in tim header + * already, no need to configure it again here + */ + for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) + cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); +} + diff --git a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h new file mode 100644 index 0000000..c7f40ad --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PLAT_DEF_H +#define A3700_PLAT_DEF_H + +#include + + +#define MVEBU_MAX_CPUS_PER_CLUSTER 2 + +#define MVEBU_PRIMARY_CPU 0x0 + +/* + * The counter on A3700 is always fed from reference 25M clock (XTAL). + * However minimal CPU counter prescaler is 2, so the counter + * frequency will be divided by 2, the number is 12.5M + */ +#define COUNTER_FREQUENCY 12500000 + +#define MVEBU_REGS_BASE 0xD0000000 + +/***************************************************************************** + * MVEBU memory map related constants + ***************************************************************************** + */ +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE MVEBU_REGS_BASE +#define DEVICE0_SIZE 0x10000000 + +/***************************************************************************** + * GIC-500 & interrupt handling related constants + ***************************************************************************** + */ +/* Base MVEBU compatible GIC memory map */ +#define MVEBU_GICD_BASE 0x1D00000 +#define MVEBU_GICR_BASE 0x1D40000 +#define MVEBU_GICC_BASE 0x1D80000 + +/* CCI-400 */ +#define MVEBU_CCI_BASE 0x8000000 + +/***************************************************************************** + * North and south bridge register base + ***************************************************************************** + */ +#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) +#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) + +/***************************************************************************** + * GPIO registers related constants + ***************************************************************************** + */ +/* North and south bridge GPIO register base address */ +#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) +#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) +#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) +#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) +#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) + +/* North Bridge GPIO selection register */ +#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) +#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) +/* I2C1 GPIO Enable bit offset */ +#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) +/* SPI pins mode bit offset */ +#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) + +/***************************************************************************** + * DRAM registers related constants + ***************************************************************************** + */ +#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) + +/***************************************************************************** + * SB wake-up registers related constants + ***************************************************************************** + */ +#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) + +/***************************************************************************** + * PMSU registers related constants + ***************************************************************************** + */ +#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) + +/***************************************************************************** + * North Bridge Step-Down Registers + ***************************************************************************** + */ +#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) + +/***************************************************************************** + * DRAM CS memory map register base + ***************************************************************************** + */ +#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) + +/***************************************************************************** + * CPU decoder window registers related constants + ***************************************************************************** + */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) + + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) + +#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h new file mode 100644 index 0000000..cc6cf43 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PM_H +#define A3700_PM_H + +#include + +/* supported wake up sources */ +enum pm_wake_up_src_type { + WAKE_UP_SRC_GPIO, + /* FOLLOWING SRC NOT SUPPORTED YET */ + WAKE_UP_SRC_TIMER, + WAKE_UP_SRC_UART0, + WAKE_UP_SRC_UART1, + WAKE_UP_SRC_MAX, +}; + +struct pm_gpio_data { + /* + * bank 0: North bridge GPIO + * bank 1: South bridge GPIO + */ + uint32_t bank_num; + uint32_t gpio_num; +}; + +union pm_wake_up_src_data { + struct pm_gpio_data gpio_data; + /* delay in seconds */ + uint32_t timer_delay; +}; + +struct pm_wake_up_src { + enum pm_wake_up_src_type wake_up_src_type; + + union pm_wake_up_src_data wake_up_data; +}; + +struct pm_wake_up_src_config { + uint32_t wake_up_src_num; + struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); + +#endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3k/common/include/ddr_info.h b/plat/marvell/armada/a3k/common/include/ddr_info.h new file mode 100644 index 0000000..254f78c --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/ddr_info.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DDR_INFO_H +#define DDR_INFO_H + +#define DRAM_MAX_IFACE 1 +#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 + +#endif /* DDR_INFO_H */ diff --git a/plat/marvell/armada/a3k/common/include/dram_win.h b/plat/marvell/armada/a3k/common/include/dram_win.h new file mode 100644 index 0000000..26a0137 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/dram_win.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DRAM_WIN_H +#define DRAM_WIN_H + +#include + +#include + +void dram_win_map_build(struct dram_win_map *win_map); +void cpu_wins_init(void); + +#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/armada/a3k/common/include/io_addr_dec.h b/plat/marvell/armada/a3k/common/include/io_addr_dec.h new file mode 100644 index 0000000..42ef30b --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/io_addr_dec.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef IO_ADDR_DEC_H +#define IO_ADDR_DEC_H + +#include + +/* There are 5 configurable cpu decoder windows. */ +#define DRAM_WIN_MAP_NUM_MAX 5 +/* Target number for dram in cpu decoder windows. */ +#define DRAM_CPU_DEC_TARGET_NUM 0 + +/* + * Not all configurable decode windows could be used for dram, some units have + * to reserve one decode window for other unit they have to communicate with; + * for example, DMA engineer has 3 configurable windows, but only two could be + * for dram while the last one has to be for pcie, so for DMA, its max_dram_win + * is 2. + */ +struct dec_win_config { + uint32_t dec_reg_base; /* IO address decoder register base address */ + uint32_t win_attr; /* IO address decoder windows attributes */ + /* How many configurable dram decoder windows that this unit has; */ + uint32_t max_dram_win; + /* The decoder windows number including remapping that this unit has */ + uint32_t max_remap; + /* The offset between continuous decode windows + * within the same unit, typically 0x10 + */ + uint32_t win_offset; +}; + +struct dram_win { + uintptr_t base_addr; + uintptr_t win_size; +}; + +struct dram_win_map { + int dram_win_num; + struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; +}; + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, + uint32_t io_unit_num); + +#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/armada/a3k/common/include/plat_macros.S b/plat/marvell/armada/a3k/common/include/plat_macros.S new file mode 100644 index 0000000..f689b4f --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/plat_macros.S @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* --------------------------------------------- + * The below macro prints out relevant GIC and + * CCI registers registers whenever an unhandled + * exception is taken in BL31. + * --------------------------------------------- + */ +.macro plat_crash_print_regs + mov_imm x17, MVEBU_GICC_BASE + mov_imm x16, MVEBU_GICD_BASE + marvell_print_gic_regs + print_cci_regs +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h new file mode 100644 index 0000000..7f8f79a --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2016-2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +#include +#include + +/* + * Most platform porting definitions provided by included headers + */ + +/* + * DRAM Memory layout: + * +-----------------------+ + * : : + * : Linux : + * 0x04X00000-->+-----------------------+ + * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * |-----------------------| } | + * | BL3-[0,1, 2] | }---------------------------------> | + * |-----------------------| } || | + * | BL2 | }->FIP (loaded by || | + * |-----------------------| } BootROM to DRAM) || | + * | FIP_TOC | } || | + * 0x04120000-->|-----------------------| || | + * | BL1 (RO) | || | + * 0x04100000-->+-----------------------+ || | + * : : || | + * : Trusted SRAM section : \/ | + * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | + * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | + * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | + * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | + * 0x04023000-->|-----------------------| +----------------+ | + * | BL2 | | + * |-----------------------| | + * | | | + * 0x04001000-->|-----------------------| | + * | Shared | | + * 0x04000000-->+-----------------------+ | + * : : | + * : Linux : | + * : : | + * |-----------------------| | + * | | U-Boot(BL3-3) Loaded by BL2 | + * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * 0x00000000-->+-----------------------+ + * + * Trusted SRAM section 0x4000000..0x4200000: + * ---------------------------------------- + * SRAM_BASE = 0x4001000 + * BL2_BASE = 0x4006000 + * BL2_LIMIT = BL31_BASE + * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) + * BL31_PROGBITS_LIMIT = BL1_RW_BASE + * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) + * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 + * + * + * PLAT_MARVELL_FIP_BASE = 0x4120000 + */ + +#define PLAT_MARVELL_ATF_BASE 0x4000000 +#define PLAT_MARVELL_ATF_LOAD_ADDR \ + (PLAT_MARVELL_ATF_BASE + 0x100000) + +#define PLAT_MARVELL_FIP_BASE \ + (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) +#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 + +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) +/* DRAM[2MB..66MB] is used as Trusted ROM */ +#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR +/* 4 MB for FIP image */ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 +/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ +#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB */ + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 + +#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE + +/* GIC related definitions */ +#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) +#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) +#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) + +#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + + +#define PLAT_MARVELL_SHARED_RAM_CACHED 1 + +/* CCI related constants */ +#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) +#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 +#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 + +/* + * Load address of BL3-3 for this platform port + */ +#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 + +/* System Reference Clock*/ +#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY + +/* + * PL011 related constants + */ +#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) +#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 + +#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +/* Required platform porting definitions */ +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +/* System timer related constants */ +#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 + +/* Mailbox base address */ +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE + 0x400) +#define PLAT_MARVELL_MAILBOX_SIZE 0x100 +#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ + +/* DRAM CS memory map registers related constants */ +#define MVEBU_CS_MMAP_LOW(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) +#define MVEBU_CS_MMAP_ENABLE 0x1 +#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 +#define MVEBU_CS_MMAP_AREA_LEN_MASK \ + (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) +#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 +#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ + (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) + +#define MVEBU_CS_MMAP_HIGH(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) + +/* DRAM max CS number */ +#define MVEBU_MAX_CS_MMAP_NUM (2) + +/* CPU decoder window related constants */ +#define CPU_DEC_WIN_CTRL_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_ENABLE 0x1 +#define CPU_DEC_CR_WIN_TARGET_OFFS 4 +#define CPU_DEC_CR_WIN_TARGET_MASK \ + (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) + +#define CPU_DEC_WIN_SIZE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_SIZE_OFFS 0 +#define CPU_DEC_CR_WIN_SIZE_MASK \ + (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) +#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 + +#define CPU_DEC_WIN_BASE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) +#define CPU_DEC_BR_BASE_OFFS 0 +#define CPU_DEC_BR_BASE_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +#define CPU_DEC_REMAP_LOW_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) +#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 +#define CPU_DEC_RLR_REMAP_LOW_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +/* Securities */ +#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/io_addr_dec.c b/plat/marvell/armada/a3k/common/io_addr_dec.c new file mode 100644 index 0000000..b27633c --- /dev/null +++ b/plat/marvell/armada/a3k/common/io_addr_dec.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off)) +#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x4) +#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x8) + +#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) +#define MVEBU_DEC_WIN_ENABLE (0x1) +#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) +#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) +#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) +#define MVEBU_DEC_WIN_BASE_OFF (16) + +#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) + +/* There are up to 14 IO unit which need address decode in Armada-3700 */ +#define IO_UNIT_NUM_MAX (14) + +#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) + + +static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, + uintptr_t win_size, + struct dec_win_config *dec_win) +{ + uint32_t ctrl = 0; + uint32_t base = 0; + + /* set size */ + ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << + MVEBU_DEC_WIN_CTRL_SIZE_OFF; + /* set attr according to IO decode window */ + ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; + /* set target */ + ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; + /* set base */ + base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << + MVEBU_DEC_WIN_BASE_OFF; + + /* set base address*/ + mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), + base); + /* set remap window, some unit does not have remap window */ + if (win_id < dec_win->max_remap) + mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), base); + /* set control register */ + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + /* enable the address decode window at last to make it effective */ + ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + + INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", + win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset)), + mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + if (win_id < dec_win->max_remap) + INFO(" remap(%x)\n", + mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + else + INFO("\n"); +} + +/* Set io decode window */ +static int set_io_addr_dec(struct dram_win_map *win_map, + struct dec_win_config *dec_win) +{ + struct dram_win *win; + int id; + + /* disable all windows first */ + for (id = 0; id < dec_win->max_dram_win; id++) + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, + dec_win->win_offset), 0); + + /* configure IO decode windows for DRAM, inheritate DRAM size, + * base and target from CPU-DRAM decode window and others + * from hard coded IO decode window settings array. + */ + if (win_map->dram_win_num > dec_win->max_dram_win) { + /* + * If cpu dram windows number exceeds the io decode windows + * max number, then fill the first io decode window + * with base(0) and size(4GB). + */ + set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); + + return 0; + } + + for (id = 0; id < win_map->dram_win_num; id++, win++) { + win = &win_map->dram_windows[id]; + set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); + } + + return 0; +} + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, uint32_t io_unit_num) +{ + int32_t index; + struct dec_win_config *io_dec_win; + int32_t ret; + + INFO("Initializing IO address decode windows\n"); + + if (io_dec_config == NULL || io_unit_num == 0) { + ERROR("No IO address decoder windows configurations!\n"); + return -1; + } + + if (io_unit_num > IO_UNIT_NUM_MAX) { + ERROR("IO address decoder windows number %d is over max %d\n", + io_unit_num, IO_UNIT_NUM_MAX); + return -1; + } + + if (dram_wins_map == NULL) { + ERROR("No cpu dram decoder windows map!\n"); + return -1; + } + + for (index = 0; index < dram_wins_map->dram_win_num; index++) + INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", + index, dram_wins_map->dram_windows[index].base_addr, + dram_wins_map->dram_windows[index].win_size); + + /* Set address decode window for each IO */ + for (index = 0; index < io_unit_num; index++) { + io_dec_win = io_dec_config + index; + ret = set_io_addr_dec(dram_wins_map, io_dec_win); + if (ret) { + ERROR("Failed to set IO address decode\n"); + return -1; + } + INFO("Set IO decode window successfully, base(0x%x)", + io_dec_win->dec_reg_base); + INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", + io_dec_win->win_attr, io_dec_win->max_dram_win, + io_dec_win->max_remap); + INFO(" win_offset(%d)\n", io_dec_win->win_offset); + } + + return 0; +} diff --git a/plat/marvell/armada/a3k/common/marvell_plat_config.c b/plat/marvell/armada/a3k/common/marvell_plat_config.c new file mode 100644 index 0000000..3bf3d96 --- /dev/null +++ b/plat/marvell/armada/a3k/common/marvell_plat_config.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +struct dec_win_config io_dec_win_conf[] = { + /* dec_reg_base win_attr max_dram_win max_remap win_offset */ + {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ + {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ + {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ + {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ + {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ + {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ + {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ + {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ + {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ + {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ +}; + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) +{ + *win = io_dec_win_conf; + *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); + + return 0; +} + diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c new file mode 100644 index 0000000..f8ce6fe --- /dev/null +++ b/plat/marvell/armada/a3k/common/plat_pm.c @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#ifdef USE_CCI +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Warm reset register */ +#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) +#define MVEBU_WARM_RESET_MAGIC 0x1D1E + +/* North Bridge GPIO1 SEL register */ +#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) + #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) + #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) + #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) + #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) + +/* CPU 1 reset register */ +#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) +#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) +#define MVEBU_CPU_1_RESET_BIT 31 + +/* IRQ register */ +#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) +#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x40) +#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x50) +#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xC8) +#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xD8) +#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xE8) +#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) +#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x04) +#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x14) +#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x1C) +#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) +#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x18) + +/* PMU registers */ +#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) + #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) + #define MVEBU_PM_SB_PWR_DWN BIT(4) + #define MVEBU_PM_INTERFACE_IDLE BIT(0) +#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) + #define MVEBU_PM_L2_FLUSH_EN BIT(22) +#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) + #define MVEBU_PM_DDR_SR_EN BIT(29) + #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) + #define MVEBU_PM_WARM_RESET_EN BIT(27) + #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) + #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) + #define MVEBU_PM_OSC_OFF_EN BIT(21) + #define MVEBU_PM_TBG_OFF_EN BIT(20) + #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) + #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) + #define MVEBU_PM_AVS_VDD2_MODE BIT(13) + #define MVEBU_PM_AVS_HOLD_MODE BIT(12) + #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) + #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ + MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ + MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) +#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) + #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) + #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) + #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) +#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) + #define MVEBU_PM_SB_WKP_NB_EN BIT(31) + #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) + #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) + #define MVEBU_PM_UART_WKP_EN BIT(25) + #define MVEBU_PM_UART2_WKP_EN BIT(19) + #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) + #define MVEBU_PM_NB_WKP_EN BIT(16) + #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) + #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) +#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) +#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) + #define MVEBU_PM_CORE_SOC_PD BIT(2) + #define MVEBU_PM_CORE_PROC_PD BIT(1) + #define MVEBU_PM_CORE_PD BIT(0) +#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) +#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) +#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) + #define MVEBU_PM_LOW_POWER_STATE BIT(0) +#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) + #define MVEBU_PM_CORE1_WAKEUP BIT(13) + #define MVEBU_PM_CORE0_WAKEUP BIT(12) +#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) +#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) + #define MVEBU_PM_SB_PM_START BIT(0) +#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) + #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) + #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) + #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) + #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) + #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) + #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ + MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ + MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) +#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) + #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) + #define MVEBU_PM_SB_WKP_EN BIT(20) + +/* DRAM registers */ +#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) + #define MVEBU_DRAM_WCP_EMPTY BIT(19) +#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) + #define MVEBU_DRAM_CH0_CMD0 BIT(28) + #define MVEBU_DRAM_CS_CMD0 BIT(24) + #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) +#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) + #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) + #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) + +/* AVS registers */ +#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) + #define MVEBU_LOW_VDD_MODE_EN BIT(6) + +/* Clock registers */ +#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) + #define MVEBU_A53_CPU_CLK_SEL BIT(15) + +/* North Bridge Step-Down Registers */ +#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE + #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) + +#define MVEBU_NB_GPIO_18 18 +#define MVEBU_NB_GPIO_19 19 +#define MVEBU_NB_GPIO_25 25 +#define MVEBU_NB_GPIO_26 26 + +typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); + +struct wake_up_src_func_map { + enum pm_wake_up_src_type type; + wake_up_src_func func; +}; + +void marvell_psci_arch_init(int die_index) +{ +} + +static void a3700_pm_ack_irq(void) +{ + uint32_t reg; + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); + + reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); + if (reg) + mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); +} + +/***************************************************************************** + * A3700 handler called to check the validity of the power state + * parameter. + ***************************************************************************** + */ +int a3700_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a CPU is about to enter standby. + ***************************************************************************** + */ +void a3700_cpu_standby(plat_local_state_t cpu_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ***************************************************************************** + */ +int a3700_pwr_domain_on(u_register_t mpidr) +{ + /* Set barrier */ + dsbsy(); + + /* Set the cpu start address to BL1 entry point */ + mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, + PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); + + /* Get the cpu out of reset */ + mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + + return 0; +} + +/***************************************************************************** + * A3700 handler called to validate the entry point. + ***************************************************************************** + */ +int a3700_validate_ns_entrypoint(uintptr_t entrypoint) +{ + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Core can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); +} + +static void a3700_set_gen_pwr_off_option(void) +{ + /* Enable L2 flush -> processor state-machine option */ + mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); + + /* + * North bridge cannot be VDD off (always ON). + * The NB state machine support low power mode by its state machine. + * This bit MUST be set for north bridge power down, e.g., + * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. + * It is not related to CPU VDD OFF!! + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); + + /* + * MUST: Switch CPU/AXI clock to OSC + * NB state machine clock is always connected to OSC (slow clock). + * But Core0/1/processor state machine's clock are connected to AXI + * clock. Now, AXI clock takes the TBG as clock source. + * If using AXI clock, Core0/1/processor state machine may much faster + * than NB state machine. It will cause problem in this case if cores + * are released before north bridge gets ready. + */ + mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); + + /* + * These register bits will trigger north bridge + * power-down state machine regardless CM3 status. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); + + /* + * SRAM => controlled by north bridge state machine. + * Core VDD OFF is not related to CPU SRAM power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); + + /* + * Idle AXI interface in order to get L2_WFI + * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. + * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) + * Once L2 WFI asserted, this bit is used for signalling assertion + * to AXI IO masters. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); + + /* Enable core0 and core1 VDD_OFF */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + + /* Enable North bridge power down - + * Both Cores MUST enable this bit to power down north bridge! + */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + + /* CA53 (processor domain) power down */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); +} + +static void a3700_en_ddr_self_refresh(void) +{ + /* + * Both count is 16 bits and configurable. By default, osc stb cnt + * is 0xFFF for lower 12 bits. + * Thus, powerdown count is smaller than osc count. + * This count is used for exiting DDR SR mode on wakeup event. + * The powerdown count also has impact on the following + * state changes: idle -> count-down -> ... (power-down, vdd off, etc) + * Here, make stable counter shorter + * Use power down count value instead of osc_stb_cnt to speed up + * DDR self refresh exit + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); + + /* + * Enable DDR SR mode => controlled by north bridge state machine + * Therefore, we must powerdown north bridge to trigger the DDR SR + * mode switching. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); + /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); + /* Power down DDR PHY (PAD) */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, + MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); + + /* Set wait time for DDR ready in ROM code */ + mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, + MVEBU_PM_WAIT_DDR_RDY_VALUE); + + /* DDR flush write buffer - mandatory */ + mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | + MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); + while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & + MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) + ; + + /* Trigger PHY reset after ddr out of self refresh => + * supply reset pulse for DDR phy after wake up + */ + mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | + MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); +} + +static void a3700_pwr_dn_avs(void) +{ + /* + * AVS power down - controlled by north bridge statemachine + * Enable AVS power down by clear the AVS disable bit. + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); + /* + * Should set BIT[12:13] to powerdown AVS. + * 1. Enable AVS VDD2 mode + * 2. After power down AVS, we must hold AVS output voltage. + * 3. We can choose the lower VDD for AVS power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); + + /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ + mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); +} + +static void a3700_pwr_dn_tbg(void) +{ + /* Power down TBG */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); +} + +static void a3700_pwr_dn_sb(void) +{ + /* Enable south bridge power down option */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); + + /* Enable SDIO_PHY_PWRDWN */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); + + /* Enable SRAM LRM on SB */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); + + /* Enable SB Power Off */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); + + /* Kick off South Bridge Power Off */ + mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); +} + +static void a3700_set_pwr_off_option(void) +{ + /* Set general power off option */ + a3700_set_gen_pwr_off_option(); + + /* Enable DDR self refresh in low power mode */ + a3700_en_ddr_self_refresh(); + + /* Power down AVS */ + a3700_pwr_dn_avs(); + + /* Power down TBG */ + a3700_pwr_dn_tbg(); + + /* Power down south bridge, pay attention south bridge setting + * should be done before + */ + a3700_pwr_dn_sb(); +} + +static void a3700_set_wake_up_option(void) +{ + /* + * Enable the wakeup event for NB SOC => north-bridge + * state-machine enablement on wake-up event + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); + + /* Enable both core0 and core1 wakeup on demand */ + mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, + MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); + + /* Enable warm reset in low power mode */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); +} + +static void a3700_pm_en_nb_gpio(uint32_t gpio) +{ + /* For GPIO1 interrupt -- North bridge only */ + if (gpio >= 32) { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); + } else { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); + } + + mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, + MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); + + /* Enable using GPIO as wakeup event + * (actually not only for north bridge) + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); +} + +static void a3700_pm_en_sb_gpio(uint32_t gpio) +{ + /* Enable using GPIO as wakeup event */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); + + /* SB GPIO Wake UP | South Bridge Wake Up Enable */ + mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | + MVEBU_PM_SB_GPIO_WKP_EN); + + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); +} + +int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) +{ + if (src_data->gpio_data.bank_num == 0) + /* North Bridge GPIO */ + a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); + else + a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); + return 0; +} + +int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) +{ + /* Clear Uart1 select */ + mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); + /* set pin 19 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); + /* set pin 18 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); + + return 0; +} + +int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) +{ + /* set pin 25/26 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); + + return 0; +} + +struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { + {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, + {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, + {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, + /* FOLLOWING SRC NOT SUPPORTED YET */ + {WAKE_UP_SRC_TIMER, NULL} +}; + +static wake_up_src_func a3700_get_wake_up_src_func( + enum pm_wake_up_src_type type) +{ + uint32_t loop; + + for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { + if (src_func_table[loop].type == type) + return src_func_table[loop].func; + } + return NULL; +} + +static void a3700_set_wake_up_source(void) +{ + struct pm_wake_up_src_config *wake_up_src; + uint32_t loop; + wake_up_src_func src_func = NULL; + + wake_up_src = mv_wake_up_src_config_get(); + for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { + src_func = a3700_get_wake_up_src_func( + wake_up_src->wake_up_src[loop].wake_up_src_type); + if (src_func) + src_func( + &(wake_up_src->wake_up_src[loop].wake_up_data)); + } +} + +static void a3700_pm_save_lp_flag(void) +{ + /* Save the flag for enter the low power mode */ + mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static void a3700_pm_clear_lp_flag(void) +{ + /* Clear the flag for enter the low power mode */ + mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static uint32_t a3700_pm_get_lp_flag(void) +{ + /* Get the flag for enter the low power mode */ + return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & + MVEBU_PM_LOW_POWER_STATE; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Save IRQ states */ + plat_marvell_gic_irq_save(); + + /* Set wake up options */ + a3700_set_wake_up_option(); + + /* Set wake up sources */ + a3700_set_wake_up_source(); + + /* SoC can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); + + /* Set power off options */ + a3700_set_pwr_off_option(); + + /* Save the flag for enter the low power mode */ + a3700_pm_save_lp_flag(); + + isb(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ***************************************************************************** + */ +void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Per-CPU interrupt initialization */ + plat_marvell_gic_pcpu_init(); + plat_marvell_gic_cpuif_enable(); + + /* Restore the per-cpu IRQ state */ + if (a3700_pm_get_lp_flag()) + plat_marvell_gic_irq_pcpu_restore(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + plat_marvell_gic_init(); + + /* Restore IRQ states */ + plat_marvell_gic_irq_restore(); + + /* + * Initialize CCI for this cluster after resume from suspend state. + * No need for locks as no other CPU is active. + */ + plat_marvell_interconnect_init(); + /* + * Enable CCI coherency for the primary CPU's cluster. + * Platform specific PSCI code will enable coherency for other + * clusters. + */ + plat_marvell_interconnect_enter_coherency(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } + + /* Clear low power mode flag */ + a3700_pm_clear_lp_flag(); +} + +/***************************************************************************** + * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND + * call to get the `power_state` parameter. This allows the platform to encode + * the appropriate State-ID field within the `power_state` parameter which can + * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. + ***************************************************************************** + */ +void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + /* lower affinities use PLAT_MAX_OFF_STATE */ + for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; +} + +/***************************************************************************** + * A3700 handlers to shutdown/reboot the system + ***************************************************************************** + */ +static void __dead2 a3700_system_off(void) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handlers to reset the system + ***************************************************************************** + */ +static void __dead2 a3700_system_reset(void) +{ + /* Clean the mailbox magic number to let it as act like cold boot */ + mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); + + dsbsy(); + + /* Flush data cache if the mail box shared RAM is cached */ +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, + 2 * sizeof(uint64_t)); +#endif + + /* Trigger the warm reset */ + mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); + + /* Shouldn't get to this point */ + panic(); +} + +/***************************************************************************** + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ***************************************************************************** + */ +const plat_psci_ops_t plat_arm_psci_pm_ops = { + .cpu_standby = a3700_cpu_standby, + .pwr_domain_on = a3700_pwr_domain_on, + .pwr_domain_off = a3700_pwr_domain_off, + .pwr_domain_suspend = a3700_pwr_domain_suspend, + .pwr_domain_on_finish = a3700_pwr_domain_on_finish, + .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, + .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, + .system_off = a3700_system_off, + .system_reset = a3700_system_reset, + .validate_power_state = a3700_validate_power_state, + .validate_ns_entrypoint = a3700_validate_ns_entrypoint +}; diff --git a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c index d126f55..7d30ebe 100644 --- a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c @@ -102,6 +102,9 @@ #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c index f8a1c40..7fc33f1 100644 --- a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c @@ -93,6 +93,9 @@ #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c index 7901dd2..856c07a 100644 --- a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c @@ -131,6 +131,9 @@ #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c index fa4e144..0edc977 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -165,6 +165,9 @@ #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 8731aa6..dcbf9a6 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -52,6 +52,7 @@ plat/common/plat_gicv2.c PLAT_INCLUDES := -I$(BOARD_DIR) \ + -I$(BOARD_DIR)/board \ -I$(PLAT_COMMON_BASE)/include \ -I$(PLAT_INCLUDE_BASE)/common diff --git a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c index 7c2bf31..4332a76 100644 --- a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c +++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c @@ -18,22 +18,27 @@ */ #if IMAGE_BL1 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; #endif #if IMAGE_BL2 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, MARVELL_MAP_DRAM, +#ifdef SPD_opteed + MARVELL_MAP_OPTEE_CORE_MEM, + MARVELL_OPTEE_PAGEABLE_LOAD_MEM, +#endif {0} }; #endif #if IMAGE_BL2U const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; @@ -48,7 +53,7 @@ #if IMAGE_BL31 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, MARVELL_MAP_DRAM, {0} @@ -56,6 +61,7 @@ #endif #if IMAGE_BL32 const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index ec1c903..b26e3ea 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -92,13 +92,16 @@ #define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ PLAT_MARVELL_CLUSTER_CORE_COUNT) -/* DRAM[2MB..66MB] is used as Trusted ROM */ +/* Part of DRAM that is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size */ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ +/* 4 MB for FIP image */ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 +/* Reserve 16M for SCP (Secure PayLoad) Trusted RAM */ +#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB DRAM */ + +#define PLAT_MARVELL_LLC_SRAM_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define PLAT_MARVELL_LLC_SRAM_SIZE 0x00100000 /* 1 MB SRAM */ /* * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size @@ -182,22 +185,14 @@ /* Mailbox base address (note the lower memory space * is reserved for BLE data) */ -#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \ - + 0x400) +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE \ + + 0x400) #define PLAT_MARVELL_MAILBOX_SIZE 0x100 #define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ /* Securities */ #define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - #define MVEBU_PMU_IRQ_WA #endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index 09b8446..c2cd933 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -18,9 +19,6 @@ #include "mss_scp_bootloader.h" -/* IO windows configuration */ -#define IOW_GCR_OFFSET (0x70) - /* MSS windows configuration */ #define MSS_AEBR(base) (base + 0x160) #define MSS_AIBR(base) (base + 0x164) @@ -51,7 +49,7 @@ */ static int bl2_plat_mmap_init(void) { - int cfg_num, win_id, cfg_idx; + int cfg_num, win_id, cfg_idx, cp; cfg_num = ARRAY_SIZE(ccu_mem_map); @@ -65,20 +63,29 @@ * Do not touch CCU window 0, * it's used for the internal registers access */ - for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) { + for (cfg_idx = 0, win_id = 1; + (win_id < MVEBU_CCU_MAX_WINS) && (cfg_idx < cfg_num); win_id++) { + /* Skip already enabled CCU windows */ + if (ccu_is_win_enabled(MVEBU_AP0, win_id)) + continue; /* Enable required CCU windows */ ccu_win_check(&ccu_mem_map[cfg_idx]); ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); + cfg_idx++; } - /* Set the default target id to PIDI */ - mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); + /* Config address for each cp other than cp0 */ + for (cp = 1; cp < CP_COUNT; cp++) + update_cp110_default_win(cp); + + /* There is need to configure IO_WIN windows again to overwrite + * temporary configuration done during update_cp110_default_win + */ + init_io_win(MVEBU_AP0); /* Open AMB bridge required for MG access */ - cp110_amb_init(MVEBU_CP_REGS_BASE(0)); - - if (CP_COUNT == 2) - cp110_amb_init(MVEBU_CP_REGS_BASE(1)); + for (cp = 0; cp < CP_COUNT; cp++) + cp110_amb_init(MVEBU_CP_REGS_BASE(cp)); return 0; } diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 621f43c..552c9b2 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -116,21 +116,12 @@ marvell_bl31_plat_arch_setup(); for (cp = 0; cp < CP_COUNT; cp++) { - if (cp >= 1) - update_cp110_default_win(cp); - cp110_init(MVEBU_CP_REGS_BASE(cp), STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); marvell_bl31_mpp_init(cp); } - /* - * There is need to configure IO_WIN windows again to overwrite - * temporary configuration done during update_cp110_default_win - */ - init_io_win(MVEBU_AP0); - for (cp = 1; cp < CP_COUNT; cp++) mci_link_tune(cp - 1); diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S index 6f625b9..4ddc73d 100644 --- a/plat/marvell/armada/common/aarch64/marvell_helpers.S +++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S @@ -185,7 +185,7 @@ /* Invalidate all ways */ ldr w1, =LLC_WAY_MASK - ldr x0, =MASTER_L2X0_INV_WAY + ldr x0, =MASTER_LLC_INV_WAY str w1, [x0] /* Finally disable LLC */ diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index f5f0c41..fcc97ac 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -16,8 +16,21 @@ # flag to switch from PLL to ARO ARO_ENABLE := 0 $(eval $(call add_define,ARO_ENABLE)) + +# Convert LLC to secure SRAM +LLC_SRAM := 0 +$(eval $(call add_define,LLC_SRAM)) + # Enable/Disable LLC +ifeq (${LLC_SRAM}, 0) LLC_ENABLE := 1 +else +# When LLC_SRAM=1, the entire LLC converted to SRAM and enabled at BL1. +# All existing cases activating LLC at BL31 stage should be disabled. +# The below assignment does not allow changing the LLC_ENABLE +# value in the command line. +LLC_ENABLE = 0 +endif $(eval $(call add_define,LLC_ENABLE)) include lib/xlat_tables_v2/xlat_tables.mk