1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2018 Marvell International Ltd. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu * https://spdx.org/licenses 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <common/debug.h> 9*91f16700Schasinglulu #include <drivers/marvell/mci.h> 10*91f16700Schasinglulu #include <drivers/marvell/mochi/ap_setup.h> 11*91f16700Schasinglulu #include <drivers/marvell/mochi/cp110_setup.h> 12*91f16700Schasinglulu #include <lib/mmio.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <armada_common.h> 15*91f16700Schasinglulu #include <marvell_plat_priv.h> 16*91f16700Schasinglulu #include <marvell_pm.h> 17*91f16700Schasinglulu #include <mc_trustzone/mc_trustzone.h> 18*91f16700Schasinglulu #include <plat_marvell.h> 19*91f16700Schasinglulu #if MSS_SUPPORT 20*91f16700Schasinglulu #include <mss_ipc_drv.h> 21*91f16700Schasinglulu #include <mss_mem.h> 22*91f16700Schasinglulu #include <mss_defs.h> 23*91f16700Schasinglulu #endif 24*91f16700Schasinglulu 25*91f16700Schasinglulu /* In Armada-8k family AP806/AP807, CP0 connected to PIDI 26*91f16700Schasinglulu * and CP1 connected to IHB via MCI #0 27*91f16700Schasinglulu */ 28*91f16700Schasinglulu #define MVEBU_MCI0 0 29*91f16700Schasinglulu 30*91f16700Schasinglulu static _Bool pm_fw_running; 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* Set a weak stub for platforms that don't need to configure GPIO */ 33*91f16700Schasinglulu #pragma weak marvell_gpio_config 34*91f16700Schasinglulu int marvell_gpio_config(void) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu return 0; 37*91f16700Schasinglulu } 38*91f16700Schasinglulu 39*91f16700Schasinglulu static void marvell_bl31_mpp_init(int cp) 40*91f16700Schasinglulu { 41*91f16700Schasinglulu uint32_t reg; 42*91f16700Schasinglulu 43*91f16700Schasinglulu /* need to do for CP#0 only */ 44*91f16700Schasinglulu if (cp) 45*91f16700Schasinglulu return; 46*91f16700Schasinglulu 47*91f16700Schasinglulu 48*91f16700Schasinglulu /* 49*91f16700Schasinglulu * Enable CP0 I2C MPPs (MPP: 37-38) 50*91f16700Schasinglulu * U-Boot rely on proper MPP settings for I2C EEPROM usage 51*91f16700Schasinglulu * (only for CP0) 52*91f16700Schasinglulu */ 53*91f16700Schasinglulu reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4)); 54*91f16700Schasinglulu mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); 55*91f16700Schasinglulu } 56*91f16700Schasinglulu 57*91f16700Schasinglulu #if MSS_SUPPORT 58*91f16700Schasinglulu void marvell_bl31_mss_init(void) 59*91f16700Schasinglulu { 60*91f16700Schasinglulu struct mss_pm_ctrl_block *mss_pm_crtl = 61*91f16700Schasinglulu (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; 62*91f16700Schasinglulu 63*91f16700Schasinglulu /* Check that the image was loaded successfully */ 64*91f16700Schasinglulu if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) { 65*91f16700Schasinglulu NOTICE("MSS PM is not supported in this build\n"); 66*91f16700Schasinglulu return; 67*91f16700Schasinglulu } 68*91f16700Schasinglulu 69*91f16700Schasinglulu /* If we got here it means that the PM firmware is running */ 70*91f16700Schasinglulu pm_fw_running = 1; 71*91f16700Schasinglulu 72*91f16700Schasinglulu INFO("MSS IPC init\n"); 73*91f16700Schasinglulu 74*91f16700Schasinglulu if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) 75*91f16700Schasinglulu mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu #endif 78*91f16700Schasinglulu 79*91f16700Schasinglulu _Bool is_pm_fw_running(void) 80*91f16700Schasinglulu { 81*91f16700Schasinglulu return pm_fw_running; 82*91f16700Schasinglulu } 83*91f16700Schasinglulu 84*91f16700Schasinglulu /* For TrusTzone we treat the "target" field of addr_map_win 85*91f16700Schasinglulu * struct as attribute 86*91f16700Schasinglulu */ 87*91f16700Schasinglulu static const struct addr_map_win tz_map[] = { 88*91f16700Schasinglulu {PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT} 89*91f16700Schasinglulu }; 90*91f16700Schasinglulu 91*91f16700Schasinglulu /* Configure MC TrustZone regions */ 92*91f16700Schasinglulu static void marvell_bl31_security_setup(void) 93*91f16700Schasinglulu { 94*91f16700Schasinglulu int tz_nr, win_id; 95*91f16700Schasinglulu 96*91f16700Schasinglulu tz_nr = ARRAY_SIZE(tz_map); 97*91f16700Schasinglulu 98*91f16700Schasinglulu for (win_id = 0; win_id < tz_nr; win_id++) 99*91f16700Schasinglulu tz_enable_win(MVEBU_AP0, tz_map, win_id); 100*91f16700Schasinglulu } 101*91f16700Schasinglulu 102*91f16700Schasinglulu /* This function overruns the same function in marvell_bl31_setup.c */ 103*91f16700Schasinglulu void bl31_plat_arch_setup(void) 104*91f16700Schasinglulu { 105*91f16700Schasinglulu int cp; 106*91f16700Schasinglulu uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; 107*91f16700Schasinglulu 108*91f16700Schasinglulu /* initialize the timer for mdelay/udelay functionality */ 109*91f16700Schasinglulu plat_delay_timer_init(); 110*91f16700Schasinglulu 111*91f16700Schasinglulu /* configure apn806 */ 112*91f16700Schasinglulu ap_init(); 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* In marvell_bl31_plat_arch_setup, el3 mmu is configured. 115*91f16700Schasinglulu * el3 mmu configuration MUST be called after apn806_init, if not, 116*91f16700Schasinglulu * this will cause an hang in init_io_win 117*91f16700Schasinglulu * (after setting the IO windows GCR values). 118*91f16700Schasinglulu */ 119*91f16700Schasinglulu if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || 120*91f16700Schasinglulu mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) 121*91f16700Schasinglulu marvell_bl31_plat_arch_setup(); 122*91f16700Schasinglulu 123*91f16700Schasinglulu for (cp = 0; cp < CP_COUNT; cp++) { 124*91f16700Schasinglulu cp110_init(MVEBU_CP_REGS_BASE(cp), 125*91f16700Schasinglulu STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); 126*91f16700Schasinglulu 127*91f16700Schasinglulu marvell_bl31_mpp_init(cp); 128*91f16700Schasinglulu 129*91f16700Schasinglulu #if MSS_SUPPORT 130*91f16700Schasinglulu /* Release CP MSS CPU from reset once the CP init is done */ 131*91f16700Schasinglulu mss_start_cp_cm3(cp); 132*91f16700Schasinglulu #endif 133*91f16700Schasinglulu } 134*91f16700Schasinglulu 135*91f16700Schasinglulu for (cp = 1; cp < CP_COUNT; cp++) 136*91f16700Schasinglulu mci_link_tune(cp - 1); 137*91f16700Schasinglulu 138*91f16700Schasinglulu #if MSS_SUPPORT 139*91f16700Schasinglulu /* initialize IPC between MSS and ATF */ 140*91f16700Schasinglulu if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || 141*91f16700Schasinglulu mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) 142*91f16700Schasinglulu marvell_bl31_mss_init(); 143*91f16700Schasinglulu #endif 144*91f16700Schasinglulu /* Configure GPIO */ 145*91f16700Schasinglulu marvell_gpio_config(); 146*91f16700Schasinglulu 147*91f16700Schasinglulu marvell_bl31_security_setup(); 148*91f16700Schasinglulu } 149