diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst new file mode 100644 index 0000000..1b60fc5 --- /dev/null +++ b/docs/plat/marvell/armada/build.rst @@ -0,0 +1,253 @@ +TF-A Build Instructions for Marvell Platforms +============================================= + +This section describes how to compile the Trusted Firmware-A (TF-A) project for Marvell's platforms. + +Build Instructions +------------------ +(1) Set the cross compiler + + .. code:: shell + + > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu- + +(2) Set path for FIP images: + +Set U-Boot image path (relatively to TF-A root or absolute path) + + .. code:: shell + + > export BL33=path/to/u-boot.bin + +For example: if U-Boot project (and its images) is located at ``~/project/u-boot``, +BL33 should be ``~/project/u-boot/u-boot.bin`` + + .. note:: + + *u-boot.bin* should be used and not *u-boot-spl.bin* + +Set MSS/SCP image path (mandatory only for Armada80x0) + + .. code:: shell + + > export SCP_BL2=path/to/mrvl_scp_bl2*.img + +(3) Armada-37x0 build requires WTP tools installation. + +See below in the section "Tools and external components installation". +Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3 + + .. code:: shell + + > sudo apt-get install gcc-arm-linux-gnueabi + +(4) Clean previous build residuals (if any) + + .. code:: shell + + > make distclean + +(5) Build TF-A + +There are several build options: + +- DEBUG + + Default is without debug information (=0). in order to enable it use ``DEBUG=1``. + Must be disabled when building UART recovery images due to current console driver + implementation that is not compatible with Xmodem protocol used for boot image download. + +- LOG_LEVEL + + Defines the level of logging which will be purged to the default output port. + + LOG_LEVEL_NONE 0 + LOG_LEVEL_ERROR 10 + LOG_LEVEL_NOTICE 20 + LOG_LEVEL_WARNING 30 + LOG_LEVEL_INFO 40 + LOG_LEVEL_VERBOSE 50 + +- USE_COHERENT_MEM + + This flag determines whether to include the coherent memory region in the + BL memory map or not. + +- LLC_ENABLE + + Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). + +- MARVELL_SECURE_BOOT + + Build trusted(=1)/non trusted(=0) image, default is non trusted. + +- BLE_PATH + + Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. + The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``. + +- MV_DDR_PATH + + For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, + it is used for ddr_tool build. + + Usage example: MV_DDR_PATH=path/to/mv_ddr + + The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr + sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter + is necessary for A37x0. + + For the mv_ddr source location, check the section "Tools and external components installation" + +- DDR_TOPOLOGY + + For Armada37x0 only, the DDR topology map index/name, default is 0. + + Supported Options: + - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) + - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) + - DDR3 2CS (2): EspressoBIN V3-V5 (1GB) + - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) + - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB) + - DDR4 1CS (5): EspressoBin V7 (1GB) + - DDR4 2CS (6): EspressoBin V7 (2GB) + - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB + +- CLOCKSPRESET + + For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency, + default is CPU_800_DDR_800. + + - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz + - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz + - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz + - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz + +- BOOTDEV + + For Armada37x0 only, the flash boot device, default is ``SPINOR``. + + Currently, Armada37x0 only supports ``SPINOR``, ``SPINAND``, ``EMMCNORM`` and ``SATA``: + + - SPINOR - SPI NOR flash boot + - SPINAND - SPI NAND flash boot + - EMMCNORM - eMMC Download Mode + + Download boot loader or program code from eMMC flash into CM3 or CA53 + Requires full initialization and command sequence + + - SATA - SATA device boot + +- PARTNUM + + For Armada37x0 only, the boot partition number, default is 0. + + To boot from eMMC, the value should be aligned with the parameter in + U-Boot with name of ``CONFIG_SYS_MMC_ENV_PART``, whose value by default is + 1. For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot + build instructions. + +- WTMI_IMG + + For Armada37x0 only, the path of the WTMI image can point to an image which + does nothing, an image which supports EFUSE or a customized CM3 firmware + binary. The default image is wtmi.bin that built from sources in WTP + folder, which is the next option. If the default image is OK, then this + option should be skipped. + +- WTP + + For Armada37x0 only, use this parameter to point to wtptools source code + directory, which can be found as a3700_utils.zip in the release. Usage + example: ``WTP=/path/to/a3700_utils`` + + For example, in order to build the image in debug mode with log level up to 'notice' level run + + .. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= all fip + + And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, + the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, + the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command + line is as following + + .. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ + MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip + + Supported MARVELL_PLATFORM are: + - a3700 (for both A3720 DB and EspressoBin) + - a70x0 + - a70x0_amc (for AMC board) + - a80x0 + - a80x0_mcbin (for MacciatoBin) + +Special Build Flags +-------------------- + +- PLAT_RECOVERY_IMAGE_ENABLE + When set this option to enable secondary recovery function when build atf. + In order to build UART recovery image this operation should be disabled for + a70x0 and a80x0 because of hardware limitation (boot from secondary image + can interrupt UART recovery process). This MACRO definition is set in + ``plat/marvell/armada/a8k/common/include/platform_def.h`` file. + +For more information about build options, please refer to the +:ref:`Build Options` document. + + +Build output +------------ +Marvell's TF-A compilation generates 7 files: + + - ble.bin - BLe image + - bl1.bin - BL1 image + - bl2.bin - BL2 image + - bl31.bin - BL31 image + - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images) + - boot-image.bin - TF-A image (contains BL1 and FIP images) + - flash-image.bin - Image which contains boot-image.bin and SPL image. + Should be placed on the boot flash/device. + + +Tools and external components installation +------------------------------------------ + +Armada37x0 Builds require installation of 3 components +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(1) ARM cross compiler capable of building images for the service CPU (CM3). + This component is usually included in the Linux host packages. + On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed + using the following command + + .. code:: shell + + > sudo apt-get install gcc-arm-linux-gnueabi + + Only if required, the default tool chain prefix ``arm-linux-gnueabi-`` can be + overwritten using the environment variable ``CROSS_CM3``. + Example for BASH shell + + .. code:: shell + + > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi + +(2) DDR initialization library sources (mv_ddr) available at the following repository + (use the "mv_ddr-armada-atf-mainline" branch): + + https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git + +(3) Armada3700 tools available at the following repository (use the latest release branch): + + https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git + +Armada70x0 and Armada80x0 Builds require installation of an additional component +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(1) DDR initialization library sources (mv_ddr) available at the following repository + (use the "mv_ddr-armada-atf-mainline" branch): + + https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git diff --git a/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst b/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst new file mode 100644 index 0000000..e88a458 --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst @@ -0,0 +1,49 @@ +Address decoding flow and address translation units of Marvell Armada 8K SoC family +=================================================================================== + +:: + + +--------------------------------------------------------------------------------------------------+ + | +-------------+ +--------------+ | + | | Memory +----- DRAM CS | | + |+------------+ +-----------+ +-----------+ | Controller | +--------------+ | + || AP DMA | | | | | +-------------+ | + || SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ | + || MCI-0/1 | | | | | | Memory | | + |+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ | + | | | | | +----- Translaton | |AP | | + | | | | | | +-------------+ |Configuration| | + | | | +-----+ +-------------------------Space | | + | | | +-------------+ | CCU | +-------------+ | + | | | | MMU +---------+ Windows | +-----------+ +-------------+ | + | | +-| translation | | Lookup +---- +--------- AP SPI | | + | | +-------------+ | | | | +-------------+ | + | | +-------------+ | | | IO | +-------------+ | + | +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | | + | | translation | +------------+ | Lookup | +-------------+ | + | +---------+---+ | | +-------------+ | + | - | | +--------- AP STM | | + | +----------------- | | +-------------+ | + | AP | | +-+---------+ | + +---------------------------------------------------------------|----------------------------------+ + +-------------|-------------------------------------------------|----------------------------------+ + | CP | +-------------+ +------+-----+ +-------------------+ | + | | | | | +------- SB CFG Space | | + | | | DIOB | | | +-------------------+ | + | | | Windows ----------------- IOB | +-------------------+ | + | | | Control | | Windows +------| SB PCIe-0 - PCIe2 | | + | | | | | Lookup | +-------------------+ | + | | +------+------+ | | +-------------------+ | + | | | | +------+ SB NAND | | + | | | +------+-----+ +-------------------+ | + | | | | | + | | | | | + | +------------------+ +------------+ +------+-----+ +-------------------+ | + | | Network Engine | | | | +------- SB SPI-0/SPI-1 | | + | | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ | + | | SATA, USB | | DMA | | Windows | +-------------------+ | + | | SD/eMMC | | | | Lookup +------- SB Device Bus | | + | | TDM, I2C | | | | | +-------------------+ | + | +------------------+ +------------+ +------------+ | + | | + +--------------------------------------------------------------------------------------------------+ diff --git a/docs/plat/marvell/armada/misc/mvebu-amb.rst b/docs/plat/marvell/armada/misc/mvebu-amb.rst new file mode 100644 index 0000000..d734003 --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-amb.rst @@ -0,0 +1,58 @@ +AMB - AXI MBUS address decoding +=============================== + +AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs. + +The Runit offers a second level of address windows lookup. It is used to map +transaction towards the CD BootROM, SPI0, SPI1 and Device bus (NOR). + +The Runit contains eight configurable windows. Each window defines a contiguous, +address space and the properties associated with that address space. + +:: + + Unit Bank ATTR + Device-Bus DEV_BOOT_CS 0x2F + DEV_CS0 0x3E + DEV_CS1 0x3D + DEV_CS2 0x3B + DEV_CS3 0x37 + SPI-0 SPI_A_CS0 0x1E + SPI_A_CS1 0x5E + SPI_A_CS2 0x9E + SPI_A_CS3 0xDE + SPI_A_CS4 0x1F + SPI_A_CS5 0x5F + SPI_A_CS6 0x9F + SPI_A_CS7 0xDF + SPI SPI_B_CS0 0x1A + SPI_B_CS1 0x5A + SPI_B_CS2 0x9A + SPI_B_CS3 0xDA + BOOT_ROM BOOT_ROM 0x1D + UART UART 0x01 + +Mandatory functions +------------------- + +- marvell_get_amb_memory_map + Returns the AMB windows configuration and the number of windows + +Mandatory structures +-------------------- + +- amb_memory_map + Array that include the configuration of the windows. Every window/entry is a + struct which has 2 parameters: + + - Base address of the window + - Attribute of the window + +Examples +-------- + +.. code:: c + + struct addr_map_win amb_memory_map[] = { + {0xf900, AMB_DEV_CS0_ID}, + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-ccu.rst b/docs/plat/marvell/armada/misc/mvebu-ccu.rst new file mode 100644 index 0000000..5bac11f --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-ccu.rst @@ -0,0 +1,33 @@ +Marvell CCU address decoding bindings +===================================== + +CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The CCU node includes a description of the address decoding configuration. + +Mandatory functions +------------------- + +- marvell_get_ccu_memory_map + Return the CCU windows configuration and the number of windows of the + specific AP. + +Mandatory structures +-------------------- + +- ccu_memory_map + Array that includes the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Example +------- + +.. code:: c + + struct addr_map_win ccu_memory_map[] = { + {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */ + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-io-win.rst b/docs/plat/marvell/armada/misc/mvebu-io-win.rst new file mode 100644 index 0000000..52845ca --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-io-win.rst @@ -0,0 +1,46 @@ +Marvell IO WIN address decoding bindings +======================================== + +IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The IO WIN includes a description of the address decoding configuration. + +Transactions that are decoded by CCU windows as IO peripheral, have an additional +layer of decoding. This additional address decoding layer defines one of the +following targets: + +- **0x0** = BootRom +- **0x1** = STM (Serial Trace Macro-cell, a programmer's port into trace stream) +- **0x2** = SPI direct access +- **0x3** = PCIe registers +- **0x4** = MCI Port +- **0x5** = PCIe port + +Mandatory functions +------------------- + +- marvell_get_io_win_memory_map + Returns the IO windows configuration and the number of windows of the + specific AP. + +Mandatory structures +-------------------- + +- io_win_memory_map + Array that include the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Example +------- + +.. code:: c + + struct addr_map_win io_win_memory_map[] = { + {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/ + {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/ + {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/ + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-iob.rst b/docs/plat/marvell/armada/misc/mvebu-iob.rst new file mode 100644 index 0000000..d02a7e8 --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-iob.rst @@ -0,0 +1,52 @@ +Marvell IOB address decoding bindings +===================================== + +IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The IOB includes a description of the address decoding configuration. + +IOB supports up to n (in CP110 n=24) windows for external memory transaction. +When a transaction passes through the IOB, its address is compared to each of +the enabled windows. If there is a hit and it passes the security checks, it is +advanced to the target port. + +Mandatory functions +------------------- + +- marvell_get_iob_memory_map + Returns the IOB windows configuration and the number of windows + +Mandatory structures +-------------------- + +- iob_memory_map + Array that includes the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Target ID options +----------------- + +- **0x0** = Internal configuration space +- **0x1** = MCI0 +- **0x2** = PEX1_X1 +- **0x3** = PEX2_X1 +- **0x4** = PEX0_X4 +- **0x5** = NAND flash +- **0x6** = RUNIT (NOR/SPI/BootRoom) +- **0x7** = MCI1 + +Example +------- + +.. code:: c + + struct addr_map_win iob_memory_map[] = { + {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */ + {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */ + {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */ + {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */ + }; diff --git a/docs/plat/marvell/armada/porting.rst b/docs/plat/marvell/armada/porting.rst new file mode 100644 index 0000000..1723ebb --- /dev/null +++ b/docs/plat/marvell/armada/porting.rst @@ -0,0 +1,163 @@ +TF-A Porting Guide for Marvell Platforms +======================================== + +This section describes how to port TF-A to a customer board, assuming that the +SoC being used is already supported in TF-A. + + +Source Code Structure +--------------------- + +- The customer platform specific code shall reside under ``plat/marvell/armada//_cust`` + (e.g. 'plat/marvell/armada/a8k/a7040_cust'). +- The platform name for build purposes is called ``_cust`` (e.g. ``a7040_cust``). +- The build system will reuse all files from within the soc directory, and take only the porting + files from the customer platform directory. + +Files that require porting are located at ``plat/marvell/armada//_cust`` directory. + + +Armada-70x0/Armada-80x0 Porting +------------------------------- + +SoC Physical Address Map (marvell_plat_config.c) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This file describes the SoC physical memory mapping to be used for the CCU, +IOWIN, AXI-MBUS and IOB address decode units (Refer to the functional spec for +more details). + +In most cases, using the default address decode windows should work OK. + +In cases where a special physical address map is needed (e.g. Special size for +PCIe MEM windows, large memory mapped SPI flash...), then porting of the SoC +memory map is required. + +.. note:: + For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please + refer to the SoC functional spec, and under + ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files. + +boot loader recovery (marvell_plat_config.c) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Background: + + Boot rom can skip the current image and choose to boot from next position if a + specific value (``0xDEADB002``) is returned by the ble main function. This + feature is used for boot loader recovery by booting from a valid flash-image + saved in next position on flash (e.g. address 2M in SPI flash). + + Supported options to implement the skip request are: + - GPIO + - I2C + - User defined + +- Porting: + + Under marvell_plat_config.c, implement struct skip_image that includes + specific board parameters. + + .. warning:: + To disable this feature make sure the struct skip_image is not implemented. + +- Example: + +In A7040-DB specific implementation +(``plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c``), the image skip is +implemented using GPIO: mpp 33 (SW5). + +Before resetting the board make sure there is a valid image on the next flash +address: + + -tftp [valid address] flash-image.bin + -sf update [valid address] 0x2000000 [size] + +Press reset and keep pressing the button connected to the chosen GPIO pin. A +skip image request message is printed on the screen and boot rom boots from the +saved image at the next position. + +DDR Porting (dram_port.c) +~~~~~~~~~~~~~~~~~~~~~~~~~ + +This file defines the dram topology and parameters of the target board. + +The DDR code is part of the BLE component, which is an extension of ARM Trusted +Firmware (TF-A). + +The DDR driver called mv_ddr is released separately apart from TF-A sources. + +The BLE and consequently, the DDR init code is executed at the early stage of +the boot process. + +Each supported platform of the TF-A has its own DDR porting file called +dram_port.c located at ``atf/plat/marvell/armada/a8k//board`` directory. + +Please refer to '/doc/porting_guide.txt' for detailed +porting description. + +The build target directory is "build//release/ble". + +Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Background: + Some of the comphy's parameters value depend on the HW connection between + the SoC and the PHY. Every board type has specific HW characteristics like + wire length. Due to those differences some comphy parameters vary between + board types. Therefore each board type can have its own list of values for + all relevant comphy parameters. The PHY porting layer specifies which + parameters need to be suited and the board designer should provide relevant + values. + + .. seealso:: + For XFI/SFI comphy type there is procedure "rx_training" which eases + process of suiting some of the parameters. Please see *uboot_cmd* + section: rx_training. + + The PHY porting layer simplifies updating static values per board type, + which are now grouped in one place. + + .. note:: + The parameters for the same type of comphy may vary even for the same + board type, it is because the lanes from comphy-x to some PHY may have + different HW characteristic than lanes from comphy-y to the same + (multiplexed) or other PHY. + +- Porting: + The porting layer for PHY was introduced in TF-A. There is one file + ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the + defaults. Those default parameters are used only if there is no appropriate + phy-porting-layer.h file under: ``plat/marvell/armada///board/phy-porting-layer.h``. If the phy-porting-layer.h + exists, the phy-default-porting-layer.h is not going to be included. + + .. warning:: + Not all comphy types are already reworked to support the PHY porting + layer, currently the porting layer is supported for XFI/SFI and SATA + comphy types. + + The easiest way to prepare the PHY porting layer for custom board is to copy + existing example to a new platform: + + - cp ``plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell/armada///board/phy-porting-layer.h" + - adjust relevant parameters or + - if different comphy index is used for specific feature, move it to proper table entry and then adjust. + + .. note:: + The final table size with comphy parameters can be different, depending + on the CP module count for given SoC type. + +- Example: + Example porting layer for armada-8040-db is under: + ``plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h`` + + .. note:: + If there is no PHY porting layer for new platform (missing + phy-porting-layer.h), the default values are used + (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is + warned: + + .. warning:: + "Using default comphy parameters - it may be required to suit them for + your board". diff --git a/docs/plat/marvell/build.rst b/docs/plat/marvell/build.rst deleted file mode 100644 index c10bcff..0000000 --- a/docs/plat/marvell/build.rst +++ /dev/null @@ -1,253 +0,0 @@ -TF-A Build Instructions for Marvell Platforms -============================================= - -This section describes how to compile the Trusted Firmware-A (TF-A) project for Marvell's platforms. - -Build Instructions ------------------- -(1) Set the cross compiler - - .. code:: shell - - > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu- - -(2) Set path for FIP images: - -Set U-Boot image path (relatively to TF-A root or absolute path) - - .. code:: shell - - > export BL33=path/to/u-boot.bin - -For example: if U-Boot project (and its images) is located at ``~/project/u-boot``, -BL33 should be ``~/project/u-boot/u-boot.bin`` - - .. note:: - - *u-boot.bin* should be used and not *u-boot-spl.bin* - -Set MSS/SCP image path (mandatory only for Armada80x0) - - .. code:: shell - - > export SCP_BL2=path/to/mrvl_scp_bl2*.img - -(3) Armada-37x0 build requires WTP tools installation. - -See below in the section "Tools and external components installation". -Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3 - - .. code:: shell - - > sudo apt-get install gcc-arm-linux-gnueabi - -(4) Clean previous build residuals (if any) - - .. code:: shell - - > make distclean - -(5) Build TF-A - -There are several build options: - -- DEBUG - - Default is without debug information (=0). in order to enable it use ``DEBUG=1``. - Must be disabled when building UART recovery images due to current console driver - implementation that is not compatible with Xmodem protocol used for boot image download. - -- LOG_LEVEL - - Defines the level of logging which will be purged to the default output port. - - LOG_LEVEL_NONE 0 - LOG_LEVEL_ERROR 10 - LOG_LEVEL_NOTICE 20 - LOG_LEVEL_WARNING 30 - LOG_LEVEL_INFO 40 - LOG_LEVEL_VERBOSE 50 - -- USE_COHERENT_MEM - - This flag determines whether to include the coherent memory region in the - BL memory map or not. - -- LLC_ENABLE - - Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). - -- MARVELL_SECURE_BOOT - - Build trusted(=1)/non trusted(=0) image, default is non trusted. - -- BLE_PATH - - Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. - The parameter is optional, its default value is ``plat/marvell/a8k/common/ble``. - -- MV_DDR_PATH - - For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, - it is used for ddr_tool build. - - Usage example: MV_DDR_PATH=path/to/mv_ddr - - The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr - sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter - is necessary for A37x0. - - For the mv_ddr source location, check the section "Tools and external components installation" - -- DDR_TOPOLOGY - - For Armada37x0 only, the DDR topology map index/name, default is 0. - - Supported Options: - - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) - - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) - - DDR3 2CS (2): EspressoBIN V3-V5 (1GB) - - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) - - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB) - - DDR4 1CS (5): EspressoBin V7 (1GB) - - DDR4 2CS (6): EspressoBin V7 (2GB) - - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB - -- CLOCKSPRESET - - For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency, - default is CPU_800_DDR_800. - - - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz - - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz - - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz - - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz - -- BOOTDEV - - For Armada37x0 only, the flash boot device, default is ``SPINOR``. - - Currently, Armada37x0 only supports ``SPINOR``, ``SPINAND``, ``EMMCNORM`` and ``SATA``: - - - SPINOR - SPI NOR flash boot - - SPINAND - SPI NAND flash boot - - EMMCNORM - eMMC Download Mode - - Download boot loader or program code from eMMC flash into CM3 or CA53 - Requires full initialization and command sequence - - - SATA - SATA device boot - -- PARTNUM - - For Armada37x0 only, the boot partition number, default is 0. - - To boot from eMMC, the value should be aligned with the parameter in - U-Boot with name of ``CONFIG_SYS_MMC_ENV_PART``, whose value by default is - 1. For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot - build instructions. - -- WTMI_IMG - - For Armada37x0 only, the path of the WTMI image can point to an image which - does nothing, an image which supports EFUSE or a customized CM3 firmware - binary. The default image is wtmi.bin that built from sources in WTP - folder, which is the next option. If the default image is OK, then this - option should be skipped. - -- WTP - - For Armada37x0 only, use this parameter to point to wtptools source code - directory, which can be found as a3700_utils.zip in the release. Usage - example: ``WTP=/path/to/a3700_utils`` - - For example, in order to build the image in debug mode with log level up to 'notice' level run - - .. code:: shell - - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= all fip - - And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, - the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, - the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command - line is as following - - .. code:: shell - - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ - MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip - - Supported MARVELL_PLATFORM are: - - a3700 (for both A3720 DB and EspressoBin) - - a70x0 - - a70x0_amc (for AMC board) - - a80x0 - - a80x0_mcbin (for MacciatoBin) - -Special Build Flags --------------------- - -- PLAT_RECOVERY_IMAGE_ENABLE - When set this option to enable secondary recovery function when build atf. - In order to build UART recovery image this operation should be disabled for - a70x0 and a80x0 because of hardware limitation (boot from secondary image - can interrupt UART recovery process). This MACRO definition is set in - ``plat/marvell/a8k/common/include/platform_def.h`` file. - -For more information about build options, please refer to the -:ref:`Build Options` document. - - -Build output ------------- -Marvell's TF-A compilation generates 7 files: - - - ble.bin - BLe image - - bl1.bin - BL1 image - - bl2.bin - BL2 image - - bl31.bin - BL31 image - - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images) - - boot-image.bin - TF-A image (contains BL1 and FIP images) - - flash-image.bin - Image which contains boot-image.bin and SPL image. - Should be placed on the boot flash/device. - - -Tools and external components installation ------------------------------------------- - -Armada37x0 Builds require installation of 3 components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -(1) ARM cross compiler capable of building images for the service CPU (CM3). - This component is usually included in the Linux host packages. - On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed - using the following command - - .. code:: shell - - > sudo apt-get install gcc-arm-linux-gnueabi - - Only if required, the default tool chain prefix ``arm-linux-gnueabi-`` can be - overwritten using the environment variable ``CROSS_CM3``. - Example for BASH shell - - .. code:: shell - - > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi - -(2) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): - - https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git - -(3) Armada3700 tools available at the following repository (use the latest release branch): - - https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git - -Armada70x0 and Armada80x0 Builds require installation of an additional component -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -(1) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): - - https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git diff --git a/docs/plat/marvell/index.rst b/docs/plat/marvell/index.rst index 89ebdc0..0d33432 100644 --- a/docs/plat/marvell/index.rst +++ b/docs/plat/marvell/index.rst @@ -5,10 +5,10 @@ :maxdepth: 1 :caption: Contents - build - porting - misc/mvebu-a8k-addr-map - misc/mvebu-amb - misc/mvebu-ccu - misc/mvebu-io-win - misc/mvebu-iob + armada/build + armada/porting + armada/misc/mvebu-a8k-addr-map + armada/misc/mvebu-amb + armada/misc/mvebu-ccu + armada/misc/mvebu-io-win + armada/misc/mvebu-iob diff --git a/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst b/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst deleted file mode 100644 index e88a458..0000000 --- a/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst +++ /dev/null @@ -1,49 +0,0 @@ -Address decoding flow and address translation units of Marvell Armada 8K SoC family -=================================================================================== - -:: - - +--------------------------------------------------------------------------------------------------+ - | +-------------+ +--------------+ | - | | Memory +----- DRAM CS | | - |+------------+ +-----------+ +-----------+ | Controller | +--------------+ | - || AP DMA | | | | | +-------------+ | - || SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ | - || MCI-0/1 | | | | | | Memory | | - |+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ | - | | | | | +----- Translaton | |AP | | - | | | | | | +-------------+ |Configuration| | - | | | +-----+ +-------------------------Space | | - | | | +-------------+ | CCU | +-------------+ | - | | | | MMU +---------+ Windows | +-----------+ +-------------+ | - | | +-| translation | | Lookup +---- +--------- AP SPI | | - | | +-------------+ | | | | +-------------+ | - | | +-------------+ | | | IO | +-------------+ | - | +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | | - | | translation | +------------+ | Lookup | +-------------+ | - | +---------+---+ | | +-------------+ | - | - | | +--------- AP STM | | - | +----------------- | | +-------------+ | - | AP | | +-+---------+ | - +---------------------------------------------------------------|----------------------------------+ - +-------------|-------------------------------------------------|----------------------------------+ - | CP | +-------------+ +------+-----+ +-------------------+ | - | | | | | +------- SB CFG Space | | - | | | DIOB | | | +-------------------+ | - | | | Windows ----------------- IOB | +-------------------+ | - | | | Control | | Windows +------| SB PCIe-0 - PCIe2 | | - | | | | | Lookup | +-------------------+ | - | | +------+------+ | | +-------------------+ | - | | | | +------+ SB NAND | | - | | | +------+-----+ +-------------------+ | - | | | | | - | | | | | - | +------------------+ +------------+ +------+-----+ +-------------------+ | - | | Network Engine | | | | +------- SB SPI-0/SPI-1 | | - | | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ | - | | SATA, USB | | DMA | | Windows | +-------------------+ | - | | SD/eMMC | | | | Lookup +------- SB Device Bus | | - | | TDM, I2C | | | | | +-------------------+ | - | +------------------+ +------------+ +------------+ | - | | - +--------------------------------------------------------------------------------------------------+ diff --git a/docs/plat/marvell/misc/mvebu-amb.rst b/docs/plat/marvell/misc/mvebu-amb.rst deleted file mode 100644 index d734003..0000000 --- a/docs/plat/marvell/misc/mvebu-amb.rst +++ /dev/null @@ -1,58 +0,0 @@ -AMB - AXI MBUS address decoding -=============================== - -AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs. - -The Runit offers a second level of address windows lookup. It is used to map -transaction towards the CD BootROM, SPI0, SPI1 and Device bus (NOR). - -The Runit contains eight configurable windows. Each window defines a contiguous, -address space and the properties associated with that address space. - -:: - - Unit Bank ATTR - Device-Bus DEV_BOOT_CS 0x2F - DEV_CS0 0x3E - DEV_CS1 0x3D - DEV_CS2 0x3B - DEV_CS3 0x37 - SPI-0 SPI_A_CS0 0x1E - SPI_A_CS1 0x5E - SPI_A_CS2 0x9E - SPI_A_CS3 0xDE - SPI_A_CS4 0x1F - SPI_A_CS5 0x5F - SPI_A_CS6 0x9F - SPI_A_CS7 0xDF - SPI SPI_B_CS0 0x1A - SPI_B_CS1 0x5A - SPI_B_CS2 0x9A - SPI_B_CS3 0xDA - BOOT_ROM BOOT_ROM 0x1D - UART UART 0x01 - -Mandatory functions -------------------- - -- marvell_get_amb_memory_map - Returns the AMB windows configuration and the number of windows - -Mandatory structures --------------------- - -- amb_memory_map - Array that include the configuration of the windows. Every window/entry is a - struct which has 2 parameters: - - - Base address of the window - - Attribute of the window - -Examples --------- - -.. code:: c - - struct addr_map_win amb_memory_map[] = { - {0xf900, AMB_DEV_CS0_ID}, - }; diff --git a/docs/plat/marvell/misc/mvebu-ccu.rst b/docs/plat/marvell/misc/mvebu-ccu.rst deleted file mode 100644 index 5bac11f..0000000 --- a/docs/plat/marvell/misc/mvebu-ccu.rst +++ /dev/null @@ -1,33 +0,0 @@ -Marvell CCU address decoding bindings -===================================== - -CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The CCU node includes a description of the address decoding configuration. - -Mandatory functions -------------------- - -- marvell_get_ccu_memory_map - Return the CCU windows configuration and the number of windows of the - specific AP. - -Mandatory structures --------------------- - -- ccu_memory_map - Array that includes the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Example -------- - -.. code:: c - - struct addr_map_win ccu_memory_map[] = { - {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */ - }; diff --git a/docs/plat/marvell/misc/mvebu-io-win.rst b/docs/plat/marvell/misc/mvebu-io-win.rst deleted file mode 100644 index 52845ca..0000000 --- a/docs/plat/marvell/misc/mvebu-io-win.rst +++ /dev/null @@ -1,46 +0,0 @@ -Marvell IO WIN address decoding bindings -======================================== - -IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The IO WIN includes a description of the address decoding configuration. - -Transactions that are decoded by CCU windows as IO peripheral, have an additional -layer of decoding. This additional address decoding layer defines one of the -following targets: - -- **0x0** = BootRom -- **0x1** = STM (Serial Trace Macro-cell, a programmer's port into trace stream) -- **0x2** = SPI direct access -- **0x3** = PCIe registers -- **0x4** = MCI Port -- **0x5** = PCIe port - -Mandatory functions -------------------- - -- marvell_get_io_win_memory_map - Returns the IO windows configuration and the number of windows of the - specific AP. - -Mandatory structures --------------------- - -- io_win_memory_map - Array that include the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Example -------- - -.. code:: c - - struct addr_map_win io_win_memory_map[] = { - {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/ - {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/ - {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/ - }; diff --git a/docs/plat/marvell/misc/mvebu-iob.rst b/docs/plat/marvell/misc/mvebu-iob.rst deleted file mode 100644 index d02a7e8..0000000 --- a/docs/plat/marvell/misc/mvebu-iob.rst +++ /dev/null @@ -1,52 +0,0 @@ -Marvell IOB address decoding bindings -===================================== - -IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The IOB includes a description of the address decoding configuration. - -IOB supports up to n (in CP110 n=24) windows for external memory transaction. -When a transaction passes through the IOB, its address is compared to each of -the enabled windows. If there is a hit and it passes the security checks, it is -advanced to the target port. - -Mandatory functions -------------------- - -- marvell_get_iob_memory_map - Returns the IOB windows configuration and the number of windows - -Mandatory structures --------------------- - -- iob_memory_map - Array that includes the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Target ID options ------------------ - -- **0x0** = Internal configuration space -- **0x1** = MCI0 -- **0x2** = PEX1_X1 -- **0x3** = PEX2_X1 -- **0x4** = PEX0_X4 -- **0x5** = NAND flash -- **0x6** = RUNIT (NOR/SPI/BootRoom) -- **0x7** = MCI1 - -Example -------- - -.. code:: c - - struct addr_map_win iob_memory_map[] = { - {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */ - {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */ - {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */ - {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */ - }; diff --git a/docs/plat/marvell/porting.rst b/docs/plat/marvell/porting.rst deleted file mode 100644 index 0a71dbd..0000000 --- a/docs/plat/marvell/porting.rst +++ /dev/null @@ -1,163 +0,0 @@ -TF-A Porting Guide for Marvell Platforms -======================================== - -This section describes how to port TF-A to a customer board, assuming that the -SoC being used is already supported in TF-A. - - -Source Code Structure ---------------------- - -- The customer platform specific code shall reside under ``plat/marvell//_cust`` - (e.g. 'plat/marvell/a8k/a7040_cust'). -- The platform name for build purposes is called ``_cust`` (e.g. ``a7040_cust``). -- The build system will reuse all files from within the soc directory, and take only the porting - files from the customer platform directory. - -Files that require porting are located at ``plat/marvell//_cust`` directory. - - -Armada-70x0/Armada-80x0 Porting -------------------------------- - -SoC Physical Address Map (marvell_plat_config.c) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This file describes the SoC physical memory mapping to be used for the CCU, -IOWIN, AXI-MBUS and IOB address decode units (Refer to the functional spec for -more details). - -In most cases, using the default address decode windows should work OK. - -In cases where a special physical address map is needed (e.g. Special size for -PCIe MEM windows, large memory mapped SPI flash...), then porting of the SoC -memory map is required. - -.. note:: - For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please - refer to the SoC functional spec, and under - ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files. - -boot loader recovery (marvell_plat_config.c) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Background: - - Boot rom can skip the current image and choose to boot from next position if a - specific value (``0xDEADB002``) is returned by the ble main function. This - feature is used for boot loader recovery by booting from a valid flash-image - saved in next position on flash (e.g. address 2M in SPI flash). - - Supported options to implement the skip request are: - - GPIO - - I2C - - User defined - -- Porting: - - Under marvell_plat_config.c, implement struct skip_image that includes - specific board parameters. - - .. warning:: - To disable this feature make sure the struct skip_image is not implemented. - -- Example: - -In A7040-DB specific implementation -(``plat/marvell/a8k/a70x0/board/marvell_plat_config.c``), the image skip is -implemented using GPIO: mpp 33 (SW5). - -Before resetting the board make sure there is a valid image on the next flash -address: - - -tftp [valid address] flash-image.bin - -sf update [valid address] 0x2000000 [size] - -Press reset and keep pressing the button connected to the chosen GPIO pin. A -skip image request message is printed on the screen and boot rom boots from the -saved image at the next position. - -DDR Porting (dram_port.c) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -This file defines the dram topology and parameters of the target board. - -The DDR code is part of the BLE component, which is an extension of ARM Trusted -Firmware (TF-A). - -The DDR driver called mv_ddr is released separately apart from TF-A sources. - -The BLE and consequently, the DDR init code is executed at the early stage of -the boot process. - -Each supported platform of the TF-A has its own DDR porting file called -dram_port.c located at ``atf/plat/marvell/a8k//board`` directory. - -Please refer to '/doc/porting_guide.txt' for detailed -porting description. - -The build target directory is "build//release/ble". - -Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Background: - Some of the comphy's parameters value depend on the HW connection between - the SoC and the PHY. Every board type has specific HW characteristics like - wire length. Due to those differences some comphy parameters vary between - board types. Therefore each board type can have its own list of values for - all relevant comphy parameters. The PHY porting layer specifies which - parameters need to be suited and the board designer should provide relevant - values. - - .. seealso:: - For XFI/SFI comphy type there is procedure "rx_training" which eases - process of suiting some of the parameters. Please see *uboot_cmd* - section: rx_training. - - The PHY porting layer simplifies updating static values per board type, - which are now grouped in one place. - - .. note:: - The parameters for the same type of comphy may vary even for the same - board type, it is because the lanes from comphy-x to some PHY may have - different HW characteristic than lanes from comphy-y to the same - (multiplexed) or other PHY. - -- Porting: - The porting layer for PHY was introduced in TF-A. There is one file - ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the - defaults. Those default parameters are used only if there is no appropriate - phy-porting-layer.h file under: ``plat/marvell///board/phy-porting-layer.h``. If the phy-porting-layer.h - exists, the phy-default-porting-layer.h is not going to be included. - - .. warning:: - Not all comphy types are already reworked to support the PHY porting - layer, currently the porting layer is supported for XFI/SFI and SATA - comphy types. - - The easiest way to prepare the PHY porting layer for custom board is to copy - existing example to a new platform: - - - cp ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell///board/phy-porting-layer.h" - - adjust relevant parameters or - - if different comphy index is used for specific feature, move it to proper table entry and then adjust. - - .. note:: - The final table size with comphy parameters can be different, depending - on the CP module count for given SoC type. - -- Example: - Example porting layer for armada-8040-db is under: - ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` - - .. note:: - If there is no PHY porting layer for new platform (missing - phy-porting-layer.h), the default values are used - (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is - warned: - - .. warning:: - "Using default comphy parameters - it may be required to suit them for - your board". diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 384dd39..b682086 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -2236,7 +2236,7 @@ printf("########################################################\n"); printf("# To use trained values update the ATF sources:\n"); - printf("# plat/marvell/a8k//board/phy-porting-layer.h "); + printf("# plat/marvell/armada/a8k//board/phy-porting-layer.h "); printf("file\n# with new values as below (for appropriate AP nr %d", ap_nr); printf("and CP nr: %d comphy_index %d\n\n", diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index 407909b..63aef12 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -7,7 +7,7 @@ /* Those are parameters for xfi mode, which need to be tune for each board type. * For known DB boards the parameters was already calibrated and placed under - * the plat/marvell/a8k//board/phy-porting-layer.h + * the plat/marvell/armada/a8k//board/phy-porting-layer.h */ struct xfi_params { uint8_t g1_ffe_res_sel; diff --git a/include/plat/marvell/a3700/common/armada_common.h b/include/plat/marvell/a3700/common/armada_common.h deleted file mode 100644 index c6953fb..0000000 --- a/include/plat/marvell/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/a3700/common/board_marvell_def.h b/include/plat/marvell/a3700/common/board_marvell_def.h deleted file mode 100644 index 1782596..0000000 --- a/include/plat/marvell/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/a3700/common/marvell_def.h b/include/plat/marvell/a3700/common/marvell_def.h deleted file mode 100644 index eb13ba8..0000000 --- a/include/plat/marvell/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/a3700/common/plat_marvell.h b/include/plat/marvell/a3700/common/plat_marvell.h deleted file mode 100644 index ea7cdcd..0000000 --- a/include/plat/marvell/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/a8k/common/armada_common.h b/include/plat/marvell/a8k/common/armada_common.h deleted file mode 100644 index 709d009..0000000 --- a/include/plat/marvell/a8k/common/armada_common.h +++ /dev/null @@ -1,129 +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 -#include -#include - -/* - * This struct supports skip image request - * detection_method: the method used to detect the request "signal". - * info: - * GPIO: - * detection_method: HIGH (pressed button), LOW (unpressed button), - * num (button mpp number). - * i2c: - * i2c_addr: the address of the i2c chosen. - * i2d_reg: the i2c register chosen. - * test: - * choose the DIE you picked the button in (AP or CP). - * in case of CP(cp_index = 0 if CP0, cp_index = 1 if CP1) - */ -struct skip_image { - enum { - GPIO, - I2C, - USER_DEFINED - } detection_method; - - struct { - struct { - int num; - enum { - HIGH, - LOW - } button_state; - - } gpio; - - struct { - int i2c_addr; - int i2c_reg; - } i2c; - - struct { - enum { - CP, - AP - } cp_ap; - int cp_index; - } test; - } info; -}; - -/* - * This struct supports SoC power off method - * type: the method used to power off the SoC - * cfg: - * PMIC_GPIO: - * pin_count: current GPIO pin number used for toggling the signal for - * notifying external PMIC - * info: holds the GPIOs information, CP GPIO should be used and - * all GPIOs should be within same GPIO config. register - * step_count: current step number to toggle the GPIO for PMIC - * seq: GPIO toggling values in sequence, each bit represents a GPIO. - * For example, bit0 represents first GPIO used for toggling - * the GPIO the last step is used to trigger the power off - * signal - * delay_ms: transition interval for the GPIO setting to take effect - * in unit of ms - */ -/* Max GPIO number used to notify PMIC to power off the SoC */ -#define PMIC_GPIO_MAX_NUMBER 8 -/* Max GPIO toggling steps in sequence to power off the SoC */ -#define PMIC_GPIO_MAX_TOGGLE_STEP 8 - -enum gpio_output_state { - GPIO_LOW = 0, - GPIO_HIGH -}; - -typedef struct gpio_info { - int cp_index; - int gpio_index; -} gpio_info_t; - -struct power_off_method { - enum { - PMIC_GPIO, - } type; - - struct { - struct { - int pin_count; - struct gpio_info info[PMIC_GPIO_MAX_NUMBER]; - int step_count; - uint32_t seq[PMIC_GPIO_MAX_TOGGLE_STEP]; - int delay_ms; - } gpio; - } cfg; -}; - -int marvell_gpio_config(void); -uint32_t marvell_get_io_win_gcr_target(int ap_idx); -uint32_t marvell_get_ccu_gcr_target(int ap_idx); - - -/* - * The functions below are defined as Weak and may be overridden - * in specific Marvell standard platform - */ -int marvell_get_amb_memory_map(struct addr_map_win **win, - uint32_t *size, uintptr_t base); -int marvell_get_io_win_memory_map(int ap_idx, struct addr_map_win **win, - uint32_t *size); -int marvell_get_iob_memory_map(struct addr_map_win **win, - uint32_t *size, uintptr_t base); -int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win, - uint32_t *size); -int system_power_off(void); - -#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/a8k/common/board_marvell_def.h b/include/plat/marvell/a8k/common/board_marvell_def.h deleted file mode 100644 index 0da56e7..0000000 --- a/include/plat/marvell/a8k/common/board_marvell_def.h +++ /dev/null @@ -1,77 +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/a8k/common/marvell_def.h b/include/plat/marvell/a8k/common/marvell_def.h deleted file mode 100644 index 4eda01f..0000000 --- a/include/plat/marvell/a8k/common/marvell_def.h +++ /dev/null @@ -1,181 +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 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) -/* Non-shared DRAM */ -#define MARVELL_DRAM_BASE ULL(0x0) -#define MARVELL_DRAM_SIZE ULL(0x80000000) -#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ - MARVELL_DRAM_SIZE - 1) - -#define MARVELL_IRQ_PIC0 28 -#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_CORE_COUNT -#define PLAT_NUM_PWR_DOMAINS (PLAT_MARVELL_CLUSTER_COUNT + \ - PLATFORM_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) - -/******************************************************************************* - * BLE specific defines. - ******************************************************************************/ -#define BLE_BASE PLAT_MARVELL_SRAM_BASE -#define BLE_LIMIT PLAT_MARVELL_SRAM_END - -/******************************************************************************* - * 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/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h deleted file mode 100644 index 5d805a7..0000000 --- a/include/plat/marvell/a8k/common/plat_marvell.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2018 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) - -struct marvell_bl31_params { - param_header_t h; - image_info_t *bl31_image_info; - entry_point_info_t *bl32_ep_info; - image_info_t *bl32_image_info; - entry_point_info_t *bl33_ep_info; - image_info_t *bl33_image_info; -}; - -/* - * 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); - -/* BLE utility functions */ -int ble_plat_setup(int *skip); -void plat_marvell_dram_update_topology(void); -void ble_plat_pcie_ep_setup(void); -struct pci_hw_cfg *plat_get_pcie_hw_data(void); - -/* 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); - -/* Power management config to power off the SoC */ -void *plat_marvell_get_pm_cfg(void); - -/* Check if MSS AP CM3 firmware contains PM support */ -_Bool is_pm_fw_running(void); - -/* Bootrom image recovery utility functions */ -void *plat_marvell_get_skip_image_data(void); - -/* FIP TOC validity check */ -int marvell_io_is_toc_valid(void); - -/* - * PSCI functionality - */ -void marvell_psci_arch_init(int ap_idx); -void plat_marvell_system_reset(void); - -/* - * Miscellaneous platform SMC routines - */ -#ifdef MVEBU_PMU_IRQ_WA -void mvebu_pmu_interrupt_enable(void); -void mvebu_pmu_interrupt_disable(void); -#endif - -/* - * 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); - -const mmap_region_t *plat_marvell_get_mmap(void); -void marvell_ble_prepare_exit(void); -void marvell_exit_bootrom(uintptr_t base); - -int plat_marvell_early_cpu_powerdown(void); -int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info); - -#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/a8k/common/plat_pm_trace.h b/include/plat/marvell/a8k/common/plat_pm_trace.h deleted file mode 100644 index a954914..0000000 --- a/include/plat/marvell/a8k/common/plat_pm_trace.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_PM_TRACE_H -#define PLAT_PM_TRACE_H - -/* - * PM Trace is for Debug purpose only!!! - * It should not be enabled during System Run time - */ -#undef PM_TRACE_ENABLE - - -/* trace entry time */ -struct pm_trace_entry { - /* trace entry time stamp */ - unsigned int timestamp; - - /* trace info - * [16-31] - API Trace Id - * [00-15] - API Step Id - */ - unsigned int trace_info; -}; - -struct pm_trace_ctrl { - /* trace pointer - points to next free entry in trace cyclic queue */ - unsigned int trace_pointer; - - /* trace count - number of entries in the queue, clear upon read */ - unsigned int trace_count; -}; - -/* trace size definition */ -#define AP_MSS_ATF_CORE_INFO_SIZE (256) -#define AP_MSS_ATF_CORE_ENTRY_SIZE (8) -#define AP_MSS_ATF_TRACE_SIZE_MASK (0xFF) - -/* trace address definition */ -#define AP_MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) - -#define AP_MSS_ATF_CORE_0_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520140) -#define AP_MSS_ATF_CORE_1_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520150) -#define AP_MSS_ATF_CORE_2_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520160) -#define AP_MSS_ATF_CORE_3_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520170) -#define AP_MSS_ATF_CORE_CTRL_BASE (AP_MSS_ATF_CORE_0_CTRL_BASE) - -#define AP_MSS_ATF_CORE_0_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5201C0) -#define AP_MSS_ATF_CORE_0_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5201C4) -#define AP_MSS_ATF_CORE_1_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5209C0) -#define AP_MSS_ATF_CORE_1_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5209C4) -#define AP_MSS_ATF_CORE_2_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5211C0) -#define AP_MSS_ATF_CORE_2_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5211C4) -#define AP_MSS_ATF_CORE_3_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5219C0) -#define AP_MSS_ATF_CORE_3_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5219C4) -#define AP_MSS_ATF_CORE_INFO_BASE (AP_MSS_ATF_CORE_0_INFO_BASE) - -/* trace info definition */ -#define TRACE_PWR_DOMAIN_OFF (0x10000) -#define TRACE_PWR_DOMAIN_SUSPEND (0x20000) -#define TRACE_PWR_DOMAIN_SUSPEND_FINISH (0x30000) -#define TRACE_PWR_DOMAIN_ON (0x40000) -#define TRACE_PWR_DOMAIN_ON_FINISH (0x50000) - -#define TRACE_PWR_DOMAIN_ON_MASK (0xFF) - -#ifdef PM_TRACE_ENABLE - -/* trace API definition */ -void pm_core_0_trace(unsigned int trace); -void pm_core_1_trace(unsigned int trace); -void pm_core_2_trace(unsigned int trace); -void pm_core_3_trace(unsigned int trace); - -typedef void (*core_trace_func)(unsigned int); - -extern core_trace_func funcTbl[PLATFORM_CORE_COUNT]; - -#define PM_TRACE(trace) funcTbl[plat_my_core_pos()](trace) - -#else - -#define PM_TRACE(trace) - -#endif - -/******************************************************************************* - * pm_trace_add - * - * DESCRIPTION: Add PM trace - ****************************************************************************** - */ -void pm_trace_add(unsigned int trace, unsigned int core); - -#endif /* PLAT_PM_TRACE_H */ diff --git a/include/plat/marvell/armada/a3700/common/armada_common.h b/include/plat/marvell/armada/a3700/common/armada_common.h new file mode 100644 index 0000000..c6953fb --- /dev/null +++ b/include/plat/marvell/armada/a3700/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/a3700/common/board_marvell_def.h b/include/plat/marvell/armada/a3700/common/board_marvell_def.h new file mode 100644 index 0000000..1782596 --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/board_marvell_def.h @@ -0,0 +1,76 @@ +/* + * 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 new file mode 100644 index 0000000..eb13ba8 --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/marvell_def.h @@ -0,0 +1,177 @@ +/* + * 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 new file mode 100644 index 0000000..ea7cdcd --- /dev/null +++ b/include/plat/marvell/armada/a3700/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/armada_common.h b/include/plat/marvell/armada/a8k/common/armada_common.h new file mode 100644 index 0000000..709d009 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/armada_common.h @@ -0,0 +1,129 @@ +/* + * 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 +#include +#include + +/* + * This struct supports skip image request + * detection_method: the method used to detect the request "signal". + * info: + * GPIO: + * detection_method: HIGH (pressed button), LOW (unpressed button), + * num (button mpp number). + * i2c: + * i2c_addr: the address of the i2c chosen. + * i2d_reg: the i2c register chosen. + * test: + * choose the DIE you picked the button in (AP or CP). + * in case of CP(cp_index = 0 if CP0, cp_index = 1 if CP1) + */ +struct skip_image { + enum { + GPIO, + I2C, + USER_DEFINED + } detection_method; + + struct { + struct { + int num; + enum { + HIGH, + LOW + } button_state; + + } gpio; + + struct { + int i2c_addr; + int i2c_reg; + } i2c; + + struct { + enum { + CP, + AP + } cp_ap; + int cp_index; + } test; + } info; +}; + +/* + * This struct supports SoC power off method + * type: the method used to power off the SoC + * cfg: + * PMIC_GPIO: + * pin_count: current GPIO pin number used for toggling the signal for + * notifying external PMIC + * info: holds the GPIOs information, CP GPIO should be used and + * all GPIOs should be within same GPIO config. register + * step_count: current step number to toggle the GPIO for PMIC + * seq: GPIO toggling values in sequence, each bit represents a GPIO. + * For example, bit0 represents first GPIO used for toggling + * the GPIO the last step is used to trigger the power off + * signal + * delay_ms: transition interval for the GPIO setting to take effect + * in unit of ms + */ +/* Max GPIO number used to notify PMIC to power off the SoC */ +#define PMIC_GPIO_MAX_NUMBER 8 +/* Max GPIO toggling steps in sequence to power off the SoC */ +#define PMIC_GPIO_MAX_TOGGLE_STEP 8 + +enum gpio_output_state { + GPIO_LOW = 0, + GPIO_HIGH +}; + +typedef struct gpio_info { + int cp_index; + int gpio_index; +} gpio_info_t; + +struct power_off_method { + enum { + PMIC_GPIO, + } type; + + struct { + struct { + int pin_count; + struct gpio_info info[PMIC_GPIO_MAX_NUMBER]; + int step_count; + uint32_t seq[PMIC_GPIO_MAX_TOGGLE_STEP]; + int delay_ms; + } gpio; + } cfg; +}; + +int marvell_gpio_config(void); +uint32_t marvell_get_io_win_gcr_target(int ap_idx); +uint32_t marvell_get_ccu_gcr_target(int ap_idx); + + +/* + * The functions below are defined as Weak and may be overridden + * in specific Marvell standard platform + */ +int marvell_get_amb_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base); +int marvell_get_io_win_memory_map(int ap_idx, struct addr_map_win **win, + uint32_t *size); +int marvell_get_iob_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base); +int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win, + uint32_t *size); +int system_power_off(void); + +#endif /* ARMADA_COMMON_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 new file mode 100644 index 0000000..0da56e7 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/board_marvell_def.h @@ -0,0 +1,77 @@ +/* + * 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/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h new file mode 100644 index 0000000..4eda01f --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -0,0 +1,181 @@ +/* + * 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 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) +/* Non-shared DRAM */ +#define MARVELL_DRAM_BASE ULL(0x0) +#define MARVELL_DRAM_SIZE ULL(0x80000000) +#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ + MARVELL_DRAM_SIZE - 1) + +#define MARVELL_IRQ_PIC0 28 +#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_CORE_COUNT +#define PLAT_NUM_PWR_DOMAINS (PLAT_MARVELL_CLUSTER_COUNT + \ + PLATFORM_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) + +/******************************************************************************* + * BLE specific defines. + ******************************************************************************/ +#define BLE_BASE PLAT_MARVELL_SRAM_BASE +#define BLE_LIMIT PLAT_MARVELL_SRAM_END + +/******************************************************************************* + * 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/a8k/common/plat_marvell.h b/include/plat/marvell/armada/a8k/common/plat_marvell.h new file mode 100644 index 0000000..5d805a7 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/plat_marvell.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 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) + +struct marvell_bl31_params { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; +}; + +/* + * 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); + +/* BLE utility functions */ +int ble_plat_setup(int *skip); +void plat_marvell_dram_update_topology(void); +void ble_plat_pcie_ep_setup(void); +struct pci_hw_cfg *plat_get_pcie_hw_data(void); + +/* 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); + +/* Power management config to power off the SoC */ +void *plat_marvell_get_pm_cfg(void); + +/* Check if MSS AP CM3 firmware contains PM support */ +_Bool is_pm_fw_running(void); + +/* Bootrom image recovery utility functions */ +void *plat_marvell_get_skip_image_data(void); + +/* FIP TOC validity check */ +int marvell_io_is_toc_valid(void); + +/* + * PSCI functionality + */ +void marvell_psci_arch_init(int ap_idx); +void plat_marvell_system_reset(void); + +/* + * Miscellaneous platform SMC routines + */ +#ifdef MVEBU_PMU_IRQ_WA +void mvebu_pmu_interrupt_enable(void); +void mvebu_pmu_interrupt_disable(void); +#endif + +/* + * 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); + +const mmap_region_t *plat_marvell_get_mmap(void); +void marvell_ble_prepare_exit(void); +void marvell_exit_bootrom(uintptr_t base); + +int plat_marvell_early_cpu_powerdown(void); +int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info); + +#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a8k/common/plat_pm_trace.h b/include/plat/marvell/armada/a8k/common/plat_pm_trace.h new file mode 100644 index 0000000..a954914 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/plat_pm_trace.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_PM_TRACE_H +#define PLAT_PM_TRACE_H + +/* + * PM Trace is for Debug purpose only!!! + * It should not be enabled during System Run time + */ +#undef PM_TRACE_ENABLE + + +/* trace entry time */ +struct pm_trace_entry { + /* trace entry time stamp */ + unsigned int timestamp; + + /* trace info + * [16-31] - API Trace Id + * [00-15] - API Step Id + */ + unsigned int trace_info; +}; + +struct pm_trace_ctrl { + /* trace pointer - points to next free entry in trace cyclic queue */ + unsigned int trace_pointer; + + /* trace count - number of entries in the queue, clear upon read */ + unsigned int trace_count; +}; + +/* trace size definition */ +#define AP_MSS_ATF_CORE_INFO_SIZE (256) +#define AP_MSS_ATF_CORE_ENTRY_SIZE (8) +#define AP_MSS_ATF_TRACE_SIZE_MASK (0xFF) + +/* trace address definition */ +#define AP_MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) + +#define AP_MSS_ATF_CORE_0_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520140) +#define AP_MSS_ATF_CORE_1_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520150) +#define AP_MSS_ATF_CORE_2_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520160) +#define AP_MSS_ATF_CORE_3_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520170) +#define AP_MSS_ATF_CORE_CTRL_BASE (AP_MSS_ATF_CORE_0_CTRL_BASE) + +#define AP_MSS_ATF_CORE_0_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5201C0) +#define AP_MSS_ATF_CORE_0_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5201C4) +#define AP_MSS_ATF_CORE_1_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5209C0) +#define AP_MSS_ATF_CORE_1_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5209C4) +#define AP_MSS_ATF_CORE_2_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5211C0) +#define AP_MSS_ATF_CORE_2_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5211C4) +#define AP_MSS_ATF_CORE_3_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5219C0) +#define AP_MSS_ATF_CORE_3_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5219C4) +#define AP_MSS_ATF_CORE_INFO_BASE (AP_MSS_ATF_CORE_0_INFO_BASE) + +/* trace info definition */ +#define TRACE_PWR_DOMAIN_OFF (0x10000) +#define TRACE_PWR_DOMAIN_SUSPEND (0x20000) +#define TRACE_PWR_DOMAIN_SUSPEND_FINISH (0x30000) +#define TRACE_PWR_DOMAIN_ON (0x40000) +#define TRACE_PWR_DOMAIN_ON_FINISH (0x50000) + +#define TRACE_PWR_DOMAIN_ON_MASK (0xFF) + +#ifdef PM_TRACE_ENABLE + +/* trace API definition */ +void pm_core_0_trace(unsigned int trace); +void pm_core_1_trace(unsigned int trace); +void pm_core_2_trace(unsigned int trace); +void pm_core_3_trace(unsigned int trace); + +typedef void (*core_trace_func)(unsigned int); + +extern core_trace_func funcTbl[PLATFORM_CORE_COUNT]; + +#define PM_TRACE(trace) funcTbl[plat_my_core_pos()](trace) + +#else + +#define PM_TRACE(trace) + +#endif + +/******************************************************************************* + * pm_trace_add + * + * DESCRIPTION: Add PM trace + ****************************************************************************** + */ +void pm_trace_add(unsigned int trace, unsigned int core); + +#endif /* PLAT_PM_TRACE_H */ diff --git a/include/plat/marvell/armada/common/aarch64/cci_macros.S b/include/plat/marvell/armada/common/aarch64/cci_macros.S new file mode 100644 index 0000000..b0a909b --- /dev/null +++ b/include/plat/marvell/armada/common/aarch64/cci_macros.S @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef CCI_MACROS_S +#define CCI_MACROS_S + +#include +#include + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro print_cci_regs + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + .endm + +#endif /* CCI_MACROS_S */ diff --git a/include/plat/marvell/armada/common/aarch64/marvell_macros.S b/include/plat/marvell/armada/common/aarch64/marvell_macros.S new file mode 100644 index 0000000..bfe2d41 --- /dev/null +++ b/include/plat/marvell/armada/common/aarch64/marvell_macros.S @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_MACROS_S +#define MARVELL_MACROS_S + +#include +#include +#include +#include +#include + +/* + * These Macros are required by ATF + */ + +.section .rodata.gic_reg_name, "aS" +/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */ +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" + +#ifdef USE_CCI +/* Applicable only to GICv3 with SRE enabled */ +icc_regs: + .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", "" +#endif +/* Registers common to both GICv2 and GICv3 */ +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ + " Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + + /* --------------------------------------------- + * The below utility macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL31 on ARM standard platforms. + * Expects: GICD base in x16, GICC base in x17 + * Clobbers: x0 - x10, sp + * --------------------------------------------- + */ + .macro marvell_print_gic_regs + /* Check for GICv3 system register access */ + mrs x7, id_aa64pfr0_el1 + ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH + cmp x7, #1 + b.ne print_gicv2 + + /* Check for SRE enable */ + mrs x8, ICC_SRE_EL3 + tst x8, #ICC_SRE_SRE_BIT + b.eq print_gicv2 + +#ifdef USE_CCI + /* Load the icc reg list to x6 */ + adr x6, icc_regs + /* Load the icc regs to gp regs used by str_in_crash_buf_print */ + mrs x8, ICC_HPPIR0_EL1 + mrs x9, ICC_HPPIR1_EL1 + mrs x10, ICC_CTLR_EL3 + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print +#endif + b print_gic_common + +print_gicv2: + /* Load the gicc reg list to x6 */ + adr x6, gicc_regs + /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ + ldr w8, [x17, #GICC_HPPIR] + ldr w9, [x17, #GICC_AHPPIR] + ldr w10, [x17, #GICC_CTLR] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + +print_gic_common: + /* Print the GICD_ISPENDR regs */ + add x7, x16, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str +gicd_ispendr_loop: + sub x4, x7, x16 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + + adr x4, spacer + bl asm_print_str + + ldr x4, [x7], #8 + bl asm_print_hex + + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + .endm + + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro print_cci_regs +#ifdef USE_CCI + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print +#endif + .endm + + +#endif /* MARVELL_MACROS_S */ diff --git a/include/plat/marvell/armada/common/marvell_plat_priv.h b/include/plat/marvell/armada/common/marvell_plat_priv.h new file mode 100644 index 0000000..78b5331 --- /dev/null +++ b/include/plat/marvell/armada/common/marvell_plat_priv.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_PLAT_PRIV_H +#define MARVELL_PLAT_PRIV_H + +#include + +/***************************************************************************** + * Function and variable prototypes + ***************************************************************************** + */ +void plat_delay_timer_init(void); + +uint64_t mvebu_get_dram_size(uint64_t ap_base_addr); + +/* + * GIC operation, mandatory functions required in Marvell standard platforms + */ +void plat_marvell_gic_driver_init(void); +void plat_marvell_gic_init(void); +void plat_marvell_gic_cpuif_enable(void); +void plat_marvell_gic_cpuif_disable(void); +void plat_marvell_gic_pcpu_init(void); +void plat_marvell_gic_irq_save(void); +void plat_marvell_gic_irq_restore(void); +void plat_marvell_gic_irq_pcpu_save(void); +void plat_marvell_gic_irq_pcpu_restore(void); + +#endif /* MARVELL_PLAT_PRIV_H */ diff --git a/include/plat/marvell/armada/common/marvell_pm.h b/include/plat/marvell/armada/common/marvell_pm.h new file mode 100644 index 0000000..8f16607 --- /dev/null +++ b/include/plat/marvell/armada/common/marvell_pm.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_PM_H +#define MARVELL_PM_H + +#define MVEBU_MAILBOX_MAGIC_NUM PLAT_MARVELL_MAILBOX_MAGIC_NUM +#define MVEBU_MAILBOX_SUSPEND_STATE 0xb007de7c + +/* Mailbox entry indexes */ +/* Magic number for validity check */ +#define MBOX_IDX_MAGIC 0 +/* Recovery from suspend entry point */ +#define MBOX_IDX_SEC_ADDR 1 +/* Suspend state magic number */ +#define MBOX_IDX_SUSPEND_MAGIC 2 +/* Recovery jump address for ROM bypass */ +#define MBOX_IDX_ROM_EXIT_ADDR 3 +/* BLE execution start counter value */ +#define MBOX_IDX_START_CNT 4 + +#endif /* MARVELL_PM_H */ diff --git a/include/plat/marvell/armada/common/mvebu.h b/include/plat/marvell/armada/common/mvebu.h new file mode 100644 index 0000000..35a0200 --- /dev/null +++ b/include/plat/marvell/armada/common/mvebu.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_H +#define MVEBU_H + +/* Use this functions only when printf is allowed */ +#define debug_enter() VERBOSE("----> Enter %s\n", __func__) +#define debug_exit() VERBOSE("<---- Exit %s\n", __func__) + +/* Macro for testing alignment. Positive if number is NOT aligned */ +#define IS_NOT_ALIGN(number, align) ((number) & ((align) - 1)) + +/* Macro for alignment up. For example, ALIGN_UP(0x0330, 0x20) = 0x0340 */ +#define ALIGN_UP(number, align) (((number) & ((align) - 1)) ? \ + (((number) + (align)) & ~((align)-1)) : (number)) + +/* Macro for testing whether a number is a power of 2. Positive if so */ +#define IS_POWER_OF_2(number) ((number) != 0 && \ + (((number) & ((number) - 1)) == 0)) + +/* + * Macro for ronding up to next power of 2 + * it is done by count leading 0 (clz assembly opcode) and see msb set bit. + * then you can shift it left and get number which power of 2 + * Note: this Macro is for 32 bit number + */ +#define ROUND_UP_TO_POW_OF_2(number) (1 << \ + (32 - __builtin_clz((number) - 1))) + +#define _1MB_ (1024ULL * 1024ULL) +#define _1GB_ (_1MB_ * 1024ULL) +#define _2GB_ (2 * _1GB_) + +#endif /* MVEBU_H */ diff --git a/include/plat/marvell/common/aarch64/cci_macros.S b/include/plat/marvell/common/aarch64/cci_macros.S deleted file mode 100644 index b0a909b..0000000 --- a/include/plat/marvell/common/aarch64/cci_macros.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef CCI_MACROS_S -#define CCI_MACROS_S - -#include -#include - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below required platform porting macro prints - * out relevant interconnect registers whenever an - * unhandled exception is taken in BL31. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro print_cci_regs - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - .endm - -#endif /* CCI_MACROS_S */ diff --git a/include/plat/marvell/common/aarch64/marvell_macros.S b/include/plat/marvell/common/aarch64/marvell_macros.S deleted file mode 100644 index bfe2d41..0000000 --- a/include/plat/marvell/common/aarch64/marvell_macros.S +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_MACROS_S -#define MARVELL_MACROS_S - -#include -#include -#include -#include -#include - -/* - * These Macros are required by ATF - */ - -.section .rodata.gic_reg_name, "aS" -/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */ -gicc_regs: - .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" - -#ifdef USE_CCI -/* Applicable only to GICv3 with SRE enabled */ -icc_regs: - .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", "" -#endif -/* Registers common to both GICv2 and GICv3 */ -gicd_pend_reg: - .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ - " Offset:\t\t\tvalue\n" -newline: - .asciz "\n" -spacer: - .asciz ":\t\t0x" - - /* --------------------------------------------- - * The below utility macro prints out relevant GIC - * registers whenever an unhandled exception is - * taken in BL31 on ARM standard platforms. - * Expects: GICD base in x16, GICC base in x17 - * Clobbers: x0 - x10, sp - * --------------------------------------------- - */ - .macro marvell_print_gic_regs - /* Check for GICv3 system register access */ - mrs x7, id_aa64pfr0_el1 - ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH - cmp x7, #1 - b.ne print_gicv2 - - /* Check for SRE enable */ - mrs x8, ICC_SRE_EL3 - tst x8, #ICC_SRE_SRE_BIT - b.eq print_gicv2 - -#ifdef USE_CCI - /* Load the icc reg list to x6 */ - adr x6, icc_regs - /* Load the icc regs to gp regs used by str_in_crash_buf_print */ - mrs x8, ICC_HPPIR0_EL1 - mrs x9, ICC_HPPIR1_EL1 - mrs x10, ICC_CTLR_EL3 - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print -#endif - b print_gic_common - -print_gicv2: - /* Load the gicc reg list to x6 */ - adr x6, gicc_regs - /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ - ldr w8, [x17, #GICC_HPPIR] - ldr w9, [x17, #GICC_AHPPIR] - ldr w10, [x17, #GICC_CTLR] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - -print_gic_common: - /* Print the GICD_ISPENDR regs */ - add x7, x16, #GICD_ISPENDR - adr x4, gicd_pend_reg - bl asm_print_str -gicd_ispendr_loop: - sub x4, x7, x16 - cmp x4, #0x280 - b.eq exit_print_gic_regs - bl asm_print_hex - - adr x4, spacer - bl asm_print_str - - ldr x4, [x7], #8 - bl asm_print_hex - - adr x4, newline - bl asm_print_str - b gicd_ispendr_loop -exit_print_gic_regs: - .endm - - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below required platform porting macro prints - * out relevant interconnect registers whenever an - * unhandled exception is taken in BL31. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro print_cci_regs -#ifdef USE_CCI - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print -#endif - .endm - - -#endif /* MARVELL_MACROS_S */ diff --git a/include/plat/marvell/common/marvell_plat_priv.h b/include/plat/marvell/common/marvell_plat_priv.h deleted file mode 100644 index 78b5331..0000000 --- a/include/plat/marvell/common/marvell_plat_priv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_PLAT_PRIV_H -#define MARVELL_PLAT_PRIV_H - -#include - -/***************************************************************************** - * Function and variable prototypes - ***************************************************************************** - */ -void plat_delay_timer_init(void); - -uint64_t mvebu_get_dram_size(uint64_t ap_base_addr); - -/* - * GIC operation, mandatory functions required in Marvell standard platforms - */ -void plat_marvell_gic_driver_init(void); -void plat_marvell_gic_init(void); -void plat_marvell_gic_cpuif_enable(void); -void plat_marvell_gic_cpuif_disable(void); -void plat_marvell_gic_pcpu_init(void); -void plat_marvell_gic_irq_save(void); -void plat_marvell_gic_irq_restore(void); -void plat_marvell_gic_irq_pcpu_save(void); -void plat_marvell_gic_irq_pcpu_restore(void); - -#endif /* MARVELL_PLAT_PRIV_H */ diff --git a/include/plat/marvell/common/marvell_pm.h b/include/plat/marvell/common/marvell_pm.h deleted file mode 100644 index 8f16607..0000000 --- a/include/plat/marvell/common/marvell_pm.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_PM_H -#define MARVELL_PM_H - -#define MVEBU_MAILBOX_MAGIC_NUM PLAT_MARVELL_MAILBOX_MAGIC_NUM -#define MVEBU_MAILBOX_SUSPEND_STATE 0xb007de7c - -/* Mailbox entry indexes */ -/* Magic number for validity check */ -#define MBOX_IDX_MAGIC 0 -/* Recovery from suspend entry point */ -#define MBOX_IDX_SEC_ADDR 1 -/* Suspend state magic number */ -#define MBOX_IDX_SUSPEND_MAGIC 2 -/* Recovery jump address for ROM bypass */ -#define MBOX_IDX_ROM_EXIT_ADDR 3 -/* BLE execution start counter value */ -#define MBOX_IDX_START_CNT 4 - -#endif /* MARVELL_PM_H */ diff --git a/include/plat/marvell/common/mvebu.h b/include/plat/marvell/common/mvebu.h deleted file mode 100644 index 35a0200..0000000 --- a/include/plat/marvell/common/mvebu.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MVEBU_H -#define MVEBU_H - -/* Use this functions only when printf is allowed */ -#define debug_enter() VERBOSE("----> Enter %s\n", __func__) -#define debug_exit() VERBOSE("<---- Exit %s\n", __func__) - -/* Macro for testing alignment. Positive if number is NOT aligned */ -#define IS_NOT_ALIGN(number, align) ((number) & ((align) - 1)) - -/* Macro for alignment up. For example, ALIGN_UP(0x0330, 0x20) = 0x0340 */ -#define ALIGN_UP(number, align) (((number) & ((align) - 1)) ? \ - (((number) + (align)) & ~((align)-1)) : (number)) - -/* Macro for testing whether a number is a power of 2. Positive if so */ -#define IS_POWER_OF_2(number) ((number) != 0 && \ - (((number) & ((number) - 1)) == 0)) - -/* - * Macro for ronding up to next power of 2 - * it is done by count leading 0 (clz assembly opcode) and see msb set bit. - * then you can shift it left and get number which power of 2 - * Note: this Macro is for 32 bit number - */ -#define ROUND_UP_TO_POW_OF_2(number) (1 << \ - (32 - __builtin_clz((number) - 1))) - -#define _1MB_ (1024ULL * 1024ULL) -#define _1GB_ (_1MB_ * 1024ULL) -#define _2GB_ (2 * _1GB_) - -#endif /* MVEBU_H */ diff --git a/plat/marvell/a3700/a3700/board/pm_src.c b/plat/marvell/a3700/a3700/board/pm_src.c deleted file mode 100644 index d6eca5d..0000000 --- a/plat/marvell/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/a3700/a3700/mvebu_def.h b/plat/marvell/a3700/a3700/mvebu_def.h deleted file mode 100644 index dad1085..0000000 --- a/plat/marvell/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/a3700/a3700/plat_bl31_setup.c b/plat/marvell/a3700/a3700/plat_bl31_setup.c deleted file mode 100644 index 6862a86..0000000 --- a/plat/marvell/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/a3700/a3700/platform.mk b/plat/marvell/a3700/a3700/platform.mk deleted file mode 100644 index 4f7ac08..0000000 --- a/plat/marvell/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/a3700/common/a3700_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk deleted file mode 100644 index 76c0677..0000000 --- a/plat/marvell/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 -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell -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 $(MARVELL_PLAT_BASE)/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/a3700/common/a3700_ea.c b/plat/marvell/a3700/common/a3700_ea.c deleted file mode 100644 index dd46beb..0000000 --- a/plat/marvell/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/a3700/common/a3700_sip_svc.c b/plat/marvell/a3700/common/a3700_sip_svc.c deleted file mode 100644 index e8ac5fc..0000000 --- a/plat/marvell/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/a3700/common/aarch64/a3700_common.c b/plat/marvell/a3700/common/aarch64/a3700_common.c deleted file mode 100644 index 6351285..0000000 --- a/plat/marvell/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/a3700/common/aarch64/plat_helpers.S b/plat/marvell/a3700/common/aarch64/plat_helpers.S deleted file mode 100644 index 90d76f0..0000000 --- a/plat/marvell/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/a3700/common/dram_win.c b/plat/marvell/a3700/common/dram_win.c deleted file mode 100644 index 694f6d4..0000000 --- a/plat/marvell/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/a3700/common/include/a3700_plat_def.h b/plat/marvell/a3700/common/include/a3700_plat_def.h deleted file mode 100644 index c7f40ad..0000000 --- a/plat/marvell/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/a3700/common/include/a3700_pm.h b/plat/marvell/a3700/common/include/a3700_pm.h deleted file mode 100644 index cc6cf43..0000000 --- a/plat/marvell/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/a3700/common/include/ddr_info.h b/plat/marvell/a3700/common/include/ddr_info.h deleted file mode 100644 index 254f78c..0000000 --- a/plat/marvell/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/a3700/common/include/dram_win.h b/plat/marvell/a3700/common/include/dram_win.h deleted file mode 100644 index 26a0137..0000000 --- a/plat/marvell/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/a3700/common/include/io_addr_dec.h b/plat/marvell/a3700/common/include/io_addr_dec.h deleted file mode 100644 index 42ef30b..0000000 --- a/plat/marvell/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/a3700/common/include/plat_macros.S b/plat/marvell/a3700/common/include/plat_macros.S deleted file mode 100644 index f689b4f..0000000 --- a/plat/marvell/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/a3700/common/include/platform_def.h b/plat/marvell/a3700/common/include/platform_def.h deleted file mode 100644 index e6660d4..0000000 --- a/plat/marvell/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/a3700/common/io_addr_dec.c b/plat/marvell/a3700/common/io_addr_dec.c deleted file mode 100644 index b27633c..0000000 --- a/plat/marvell/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/a3700/common/marvell_plat_config.c b/plat/marvell/a3700/common/marvell_plat_config.c deleted file mode 100644 index 3bf3d96..0000000 --- a/plat/marvell/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/a3700/common/plat_pm.c b/plat/marvell/a3700/common/plat_pm.c deleted file mode 100644 index f8ce6fe..0000000 --- a/plat/marvell/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/a8k/a70x0/board/dram_port.c b/plat/marvell/a8k/a70x0/board/dram_port.c deleted file mode 100644 index 4fca7e3..0000000 --- a/plat/marvell/a8k/a70x0/board/dram_port.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -/* - * This function may modify the default DRAM parameters - * based on information received from SPD or bootloader - * configuration located on non volatile storage - */ -void plat_marvell_dram_update_topology(void) -{ -} - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { -/* FIXME: MISL board 2CS 4Gb x8 devices of micron - 2133P */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0} }, - SPEED_BIN_DDR_2133P, /* speed_bin */ - MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ - MV_DDR_DIE_CAP_4GBIT, /* die capacity */ - MV_DDR_FREQ_SAR, /* frequency */ - 0, 0, /* cas_l, cas_wl */ - MV_DDR_TEMP_LOW} }, /* temperature */ - MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ - { {0} }, /* raw spd data */ - {0}, /* timing parameters */ - { /* electrical configuration */ - { /* memory electrical configuration */ - MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ - { - MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ - MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ - }, - { - MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ - MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ - }, - MV_DDR_DIC_RZQ_DIV7 /* dic */ - }, - { /* phy electrical configuration */ - MV_DDR_OHM_30, /* data_drv_p */ - MV_DDR_OHM_30, /* data_drv_n */ - MV_DDR_OHM_30, /* ctrl_drv_p */ - MV_DDR_OHM_30, /* ctrl_drv_n */ - { - MV_DDR_OHM_60, /* odt_p 1cs */ - MV_DDR_OHM_120 /* odt_p 2cs */ - }, - { - MV_DDR_OHM_60, /* odt_n 1cs */ - MV_DDR_OHM_120 /* odt_n 2cs */ - }, - }, - { /* mac electrical configuration */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ - MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} diff --git a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0/board/marvell_plat_config.c deleted file mode 100644 index d126f55..0000000 --- a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -/* - * If bootrom is currently at BLE there's no need to include the memory - * maps structure at this point - */ -#include -#ifndef IMAGE_BLE - -/***************************************************************************** - * AMB Configuration - ***************************************************************************** - */ -struct addr_map_win amb_memory_map[] = { - /* CP0 SPI1 CS0 Direct Mode access */ - {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, -}; - -int marvell_get_amb_memory_map(struct addr_map_win **win, - uint32_t *size, uintptr_t base) -{ - *win = amb_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(amb_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * IO_WIN Configuration - ***************************************************************************** - */ -struct addr_map_win io_win_memory_map[] = { -#ifndef IMAGE_BLE - /* MCI 0 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, - /* MCI 1 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, -#endif -}; - -uint32_t marvell_get_io_win_gcr_target(int ap_index) -{ - return PIDI_TID; -} - -int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = io_win_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(io_win_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * IOB Configuration - ***************************************************************************** - */ -struct addr_map_win iob_memory_map[] = { - /* PEX1_X1 window */ - {0x00000000f7000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000f8000000, 0x1000000, PEX2_TID}, - {0x00000000c0000000, 0x30000000, PEX2_TID}, - {0x0000000800000000, 0x100000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000f6000000, 0x1000000, PEX0_TID}, - /* SPI1_CS0 (RUNIT) window */ - {0x00000000f9000000, 0x1000000, RUNIT_TID}, -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - *win = iob_memory_map; - *size = ARRAY_SIZE(iob_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { /* IO window */ -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, - {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ - {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ -#endif -}; - -uint32_t marvell_get_ccu_gcr_target(int ap) -{ - return DRAM_0_TID; -} - -int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = ccu_memory_map; - *size = ARRAY_SIZE(ccu_memory_map); - - return 0; -} - -#ifdef IMAGE_BLE -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -#if PLAT_RECOVERY_IMAGE_ENABLE -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a70x0/mvebu_def.h b/plat/marvell/a8k/a70x0/mvebu_def.h deleted file mode 100644 index 72bca12..0000000 --- a/plat/marvell/a8k/a70x0/mvebu_def.h +++ /dev/null @@ -1,15 +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 - -#define CP_COUNT 1 /* A70x0 has single CP0 */ - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a70x0/platform.mk b/plat/marvell/a8k/a70x0/platform.mk deleted file mode 100644 index d3a0167..0000000 --- a/plat/marvell/a8k/a70x0/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 1 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/a8k/a70x0_amc/board/dram_port.c deleted file mode 100644 index aecf6c5..0000000 --- a/plat/marvell/a8k/a70x0_amc/board/dram_port.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -/* - * This function may modify the default DRAM parameters - * based on information received from SPD or bootloader - * configuration located on non volatile storage - */ -void plat_marvell_dram_update_topology(void) -{ -} - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { -/* FIXME: MISL board 2CS 8Gb x8 devices of micron - 2133P */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0}, - {0x3, 0x2, 0, 0} }, - SPEED_BIN_DDR_2400T, /* speed_bin */ - MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ - MV_DDR_DIE_CAP_8GBIT, /* die capacity */ - MV_DDR_FREQ_SAR, /* frequency */ - 0, 0, /* cas_l, cas_wl */ - MV_DDR_TEMP_LOW} }, /* temperature */ - MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ - { {0} }, /* raw spd data */ - {0}, /* timing parameters */ - { /* electrical configuration */ - { /* memory electrical configuration */ - MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ - { - MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ - MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ - }, - { - MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ - MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ - }, - MV_DDR_DIC_RZQ_DIV7 /* dic */ - }, - { /* phy electrical configuration */ - MV_DDR_OHM_30, /* data_drv_p */ - MV_DDR_OHM_30, /* data_drv_n */ - MV_DDR_OHM_30, /* ctrl_drv_p */ - MV_DDR_OHM_30, /* ctrl_drv_n */ - { - MV_DDR_OHM_60, /* odt_p 1cs */ - MV_DDR_OHM_120 /* odt_p 2cs */ - }, - { - MV_DDR_OHM_60, /* odt_n 1cs */ - MV_DDR_OHM_120 /* odt_n 2cs */ - }, - }, - { /* mac electrical configuration */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ - MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} diff --git a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c deleted file mode 100644 index f8a1c40..0000000 --- a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -/* - * If bootrom is currently at BLE there's no need to include the memory - * maps structure at this point - */ -#include -#ifndef IMAGE_BLE - -/***************************************************************************** - * AMB Configuration - ***************************************************************************** - */ -struct addr_map_win *amb_memory_map; - -int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - *win = amb_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(amb_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * IO WIN Configuration - ***************************************************************************** - */ -struct addr_map_win io_win_memory_map[] = { -#ifndef IMAGE_BLE - /* MCI 0 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, - /* MCI 1 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, -#endif -}; - -uint32_t marvell_get_io_win_gcr_target(int ap_index) -{ - return PIDI_TID; -} - -int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = io_win_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(io_win_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * IOB Configuration - ***************************************************************************** - */ -struct addr_map_win iob_memory_map[] = { - /* PEX0_X4 window */ - {0x00000000f6000000, 0x6000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x200000000, PEX0_TID}, -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - *win = iob_memory_map; - *size = ARRAY_SIZE(iob_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, - {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ - {0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */ -#endif -}; - -uint32_t marvell_get_ccu_gcr_target(int ap) -{ - return DRAM_0_TID; -} - -int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = ccu_memory_map; - *size = ARRAY_SIZE(ccu_memory_map); - - return 0; -} - -#ifdef IMAGE_BLE - -struct pci_hw_cfg *plat_get_pcie_hw_data(void) -{ - return NULL; -} - -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -#if PLAT_RECOVERY_IMAGE_ENABLE -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/a8k/a70x0_amc/mvebu_def.h deleted file mode 100644 index cedf323..0000000 --- a/plat/marvell/a8k/a70x0_amc/mvebu_def.h +++ /dev/null @@ -1,31 +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 - -#define CP_COUNT 1 /* A70x0 has single CP0 */ - -/*********************************************************************** - * Required platform porting definitions common to all - * Management Compute SubSystems (MSS) - *********************************************************************** - */ -/* - * Load address of SCP_BL2 - * SCP_BL2 is loaded to the same place as BL31. - * Once SCP_BL2 is transferred to the SCP, - * it is discarded and BL31 is loaded over the top. - */ -#ifdef SCP_IMAGE -#define SCP_BL2_BASE BL31_BASE -#endif - - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a70x0_amc/platform.mk b/plat/marvell/a8k/a70x0_amc/platform.mk deleted file mode 100644 index d3a0167..0000000 --- a/plat/marvell/a8k/a70x0_amc/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 1 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/a80x0/board/dram_port.c b/plat/marvell/a8k/a80x0/board/dram_port.c deleted file mode 100644 index 02f4ffb..0000000 --- a/plat/marvell/a8k/a80x0/board/dram_port.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include -#include -#include - -#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0) -#define MVEBU_AP_MPP_CTRL4_OFFS 16 -#define MVEBU_AP_MPP_CTRL5_OFFS 20 -#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3 -#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3 - -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 -#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 - -#define MVEBU_MPP_CTRL_MASK 0xf - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { - /* MISL board with 1CS 8Gb x4 devices of Micron 2400T */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0} }, - /* TODO: double check if the speed bin is 2400T */ - SPEED_BIN_DDR_2400T, /* speed_bin */ - MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ - MV_DDR_DIE_CAP_8GBIT, /* die capacity */ - MV_DDR_FREQ_SAR, /* frequency */ - 0, 0, /* cas_l, cas_wl */ - MV_DDR_TEMP_LOW} }, /* temperature */ - MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_SPD, /* ddr configuration data source */ - { {0} }, /* raw spd data */ - {0}, /* timing parameters */ - { /* electrical configuration */ - { /* memory electrical configuration */ - MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ - { - MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ - MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ - }, - { - MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ - MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ - }, - MV_DDR_DIC_RZQ_DIV7 /* dic */ - }, - { /* phy electrical configuration */ - MV_DDR_OHM_30, /* data_drv_p */ - MV_DDR_OHM_30, /* data_drv_n */ - MV_DDR_OHM_30, /* ctrl_drv_p */ - MV_DDR_OHM_30, /* ctrl_drv_n */ - { - MV_DDR_OHM_60, /* odt_p 1cs */ - MV_DDR_OHM_120 /* odt_p 2cs */ - }, - { - MV_DDR_OHM_60, /* odt_n 1cs */ - MV_DDR_OHM_120 /* odt_n 2cs */ - }, - }, - { /* mac electrical configuration */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ - MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} - -static void mpp_config(void) -{ - uintptr_t reg; - uint32_t val; - - reg = MVEBU_CP_MPP_REGS(0, 4); - /* configure CP0 MPP 37 and 38 to i2c */ - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << - MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << - MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); -} - -/* - * This function may modify the default DRAM parameters - * based on information received from SPD or bootloader - * configuration located on non volatile storage - */ -void plat_marvell_dram_update_topology(void) -{ - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - INFO("Gathering DRAM information\n"); - - if (tm->cfg_src == MV_DDR_CFG_SPD) { - /* configure MPPs to enable i2c */ - mpp_config(); - - /* initialize i2c */ - i2c_init((void *)MVEBU_CP0_I2C_BASE); - - /* select SPD memory page 0 to access DRAM configuration */ - i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); - - /* read data from spd */ - i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, - sizeof(tm->spd_data.all_bytes)); - } -} diff --git a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0/board/marvell_plat_config.c deleted file mode 100644 index 7901dd2..0000000 --- a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -/* - * If bootrom is currently at BLE there's no need to include the memory - * maps structure at this point - */ -#include -#ifndef IMAGE_BLE - -/***************************************************************************** - * AMB Configuration - ***************************************************************************** - */ -struct addr_map_win amb_memory_map[] = { - /* CP1 SPI1 CS0 Direct Mode access */ - {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, -}; - -int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - *win = amb_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(amb_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * IO WIN Configuration - ***************************************************************************** - */ -struct addr_map_win io_win_memory_map[] = { - /* CP1 (MCI0) internal regs */ - {0x00000000f4000000, 0x2000000, MCI_0_TID}, -#ifndef IMAGE_BLE - /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ - {0x00000000f9000000, 0x2000000, MCI_0_TID}, - /* PCIe1 on CP1*/ - {0x00000000fb000000, 0x1000000, MCI_0_TID}, - /* PCIe2 on CP1*/ - {0x00000000fc000000, 0x1000000, MCI_0_TID}, - /* MCI 0 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, - /* MCI 1 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, -#endif -}; - -uint32_t marvell_get_io_win_gcr_target(int ap_index) -{ - return PIDI_TID; -} - -int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = io_win_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(io_win_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * IOB Configuration - ***************************************************************************** - */ -struct addr_map_win iob_memory_map_cp0[] = { - /* CP0 */ - /* PEX1_X1 window */ - {0x00000000f7000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000f8000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000f6000000, 0x1000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x100000000, PEX0_TID}, -}; - -struct addr_map_win iob_memory_map_cp1[] = { - /* CP1 */ - /* SPI1_CS0 (RUNIT) window */ - {0x00000000f9000000, 0x1000000, RUNIT_TID}, - /* PEX1_X1 window */ - {0x00000000fb000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000fc000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000fa000000, 0x1000000, PEX0_TID} -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - switch (base) { - case MVEBU_CP_REGS_BASE(0): - *win = iob_memory_map_cp0; - *size = ARRAY_SIZE(iob_memory_map_cp0); - return 0; - case MVEBU_CP_REGS_BASE(1): - *win = iob_memory_map_cp1; - *size = ARRAY_SIZE(iob_memory_map_cp1); - return 0; - default: - *size = 0; - *win = 0; - return 1; - } -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ - {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ - {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ -#endif -}; - -uint32_t marvell_get_ccu_gcr_target(int ap) -{ - return DRAM_0_TID; -} - -int marvell_get_ccu_memory_map(int ap, struct addr_map_win **win, - uint32_t *size) -{ - *win = ccu_memory_map; - *size = ARRAY_SIZE(ccu_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * SoC PM configuration - ***************************************************************************** - */ -/* CP GPIO should be used and the GPIOs should be within same GPIO register */ -struct power_off_method pm_cfg = { - .type = PMIC_GPIO, - .cfg.gpio.pin_count = 1, - .cfg.gpio.info = {{0, 35} }, - .cfg.gpio.step_count = 7, - .cfg.gpio.seq = {1, 0, 1, 0, 1, 0, 1}, - .cfg.gpio.delay_ms = 10, -}; - -void *plat_marvell_get_pm_cfg(void) -{ - /* Return the PM configurations */ - return &pm_cfg; -} - -/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ -#else -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -#if PLAT_RECOVERY_IMAGE_ENABLE -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/a8k/a80x0/board/phy-porting-layer.h deleted file mode 100644 index abd85b5..0000000 --- a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PHY_PORTING_LAYER_H -#define PHY_PORTING_LAYER_H - -#define MAX_LANE_NR 6 - -static const struct xfi_params - xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { - /* AP0 */ - { - /* CP 0 */ - { - { 0 }, /* Comphy0 */ - { 0 }, /* Comphy1 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, - .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, - .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, - .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, - .valid = 0x1 }, /* Comphy2 */ - { 0 }, /* Comphy3 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, - .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, - .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, - .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, - .valid = 0x1 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - - /* CP 1 */ - { - { 0 }, /* Comphy0 */ - { 0 }, /* Comphy1 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, - .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, - .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, - .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, - .valid = 0x1 }, /* Comphy2 */ - { 0 }, /* Comphy3 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, - .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, - .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, - .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, - .valid = 0x1 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - }, -}; - -static const struct sata_params - sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { - /* AP0 */ - { - /* CP 0 */ - { - { 0 }, /* Comphy0 */ - { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, - .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, - .g1_emph_en = 0x1, .g2_emph_en = 0x1, - .g3_emph_en = 0x1, - .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, - .g3_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, - .g3_tx_emph_en = 0x0, - .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, - .g3_tx_emph = 0x1, - .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, - .g3_ffe_cap_sel = 0xf, - .align90 = 0x61, - .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, - .g3_rx_selmuff = 0x3, - .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, - .g3_rx_selmufi = 0x3, - .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, - .g3_rx_selmupf = 0x2, - .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, - .g3_rx_selmupi = 0x2, - .valid = 0x1 - }, /* Comphy1 */ - { 0 }, /* Comphy2 */ - { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, - .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, - .g1_emph_en = 0x1, .g2_emph_en = 0x1, - .g3_emph_en = 0x1, - .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, - .g3_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, - .g3_tx_emph_en = 0x0, - .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, - .g3_tx_emph = 0x1, - .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, - .g3_ffe_cap_sel = 0xf, - .align90 = 0x61, - .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, - .g3_rx_selmuff = 0x3, - .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, - .g3_rx_selmufi = 0x3, - .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, - .g3_rx_selmupf = 0x2, - .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, - .g3_rx_selmupi = 0x2, - .valid = 0x1 - }, /* Comphy3 */ - { 0 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - - /* CP 1 */ - { - { 0 }, /* Comphy0 */ - { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, - .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, - .g1_emph_en = 0x1, .g2_emph_en = 0x1, - .g3_emph_en = 0x1, - .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, - .g3_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, - .g3_tx_emph_en = 0x0, - .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, - .g3_tx_emph = 0x1, - .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, - .g3_ffe_cap_sel = 0xf, - .align90 = 0x61, - .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, - .g3_rx_selmuff = 0x3, - .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, - .g3_rx_selmufi = 0x3, - .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, - .g3_rx_selmupf = 0x2, - .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, - .g3_rx_selmupi = 0x2, - .valid = 0x1 - }, /* Comphy1 */ - { 0 }, /* Comphy2 */ - { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, - .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, - .g1_emph_en = 0x1, .g2_emph_en = 0x1, - .g3_emph_en = 0x1, - .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, - .g3_tx_amp_adj = 0x1, - .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, - .g3_tx_emph_en = 0x0, - .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, - .g3_tx_emph = 0x1, - .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, - .g3_ffe_cap_sel = 0xf, - .align90 = 0x61, - .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, - .g3_rx_selmuff = 0x3, - .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, - .g3_rx_selmufi = 0x3, - .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, - .g3_rx_selmupf = 0x2, - .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, - .g3_rx_selmupi = 0x2, - .valid = 0x1 - }, /* Comphy3 */ - { 0 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - - }, - }, -}; -#endif /* PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/a8k/a80x0/mvebu_def.h b/plat/marvell/a8k/a80x0/mvebu_def.h deleted file mode 100644 index 3fa119a..0000000 --- a/plat/marvell/a8k/a80x0/mvebu_def.h +++ /dev/null @@ -1,17 +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 - -#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */ -#define I2C_SPD_ADDR 0x53 /* Access SPD data */ -#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a80x0/platform.mk b/plat/marvell/a8k/a80x0/platform.mk deleted file mode 100644 index 00d24b2..0000000 --- a/plat/marvell/a8k/a80x0/platform.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 2 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk -PLAT_INCLUDES += -Iplat/marvell/a8k/a80x0/board diff --git a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c deleted file mode 100644 index 2580852..0000000 --- a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include -#include -#include - -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 -#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 - -#define MVEBU_MPP_CTRL_MASK 0xf - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { - /* Board with 1CS 8Gb x4 devices of Micron 2400T */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0} }, - /* TODO: double check if the speed bin is 2400T */ - SPEED_BIN_DDR_2400T, /* speed_bin */ - MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ - MV_DDR_DIE_CAP_8GBIT, /* die capacity */ - MV_DDR_FREQ_SAR, /* frequency */ - 0, 0, /* cas_l, cas_wl */ - MV_DDR_TEMP_LOW} }, /* temperature */ - MV_DDR_64BIT_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_SPD, /* ddr configuration data source */ - { {0} }, /* raw spd data */ - {0}, /* timing parameters */ - { /* electrical configuration */ - { /* memory electrical configuration */ - MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ - { - MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ - MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ - }, - { - MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ - MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ - }, - MV_DDR_DIC_RZQ_DIV7 /* dic */ - }, - { /* phy electrical configuration */ - MV_DDR_OHM_30, /* data_drv_p */ - MV_DDR_OHM_30, /* data_drv_n */ - MV_DDR_OHM_30, /* ctrl_drv_p */ - MV_DDR_OHM_30, /* ctrl_drv_n */ - { - MV_DDR_OHM_60, /* odt_p 1cs */ - MV_DDR_OHM_120 /* odt_p 2cs */ - }, - { - MV_DDR_OHM_60, /* odt_n 1cs */ - MV_DDR_OHM_120 /* odt_n 2cs */ - }, - }, - { /* mac electrical configuration */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ - MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ - MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} - -static void mpp_config(void) -{ - uint32_t val; - uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4); - - /* configure CP0 MPP 37 and 38 to i2c */ - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); -} - -/* - * This function may modify the default DRAM parameters - * based on information received from SPD or bootloader - * configuration located on non volatile storage - */ -void plat_marvell_dram_update_topology(void) -{ - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - INFO("Gathering DRAM information\n"); - - if (tm->cfg_src == MV_DDR_CFG_SPD) { - /* configure MPPs to enable i2c */ - mpp_config(); - /* initialize the i2c */ - i2c_init((void *)MVEBU_CP0_I2C_BASE); - /* select SPD memory page 0 to access DRAM configuration */ - i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); - /* read data from spd */ - i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, - sizeof(tm->spd_data.all_bytes)); - } -} diff --git a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c deleted file mode 100644 index fa4e144..0000000 --- a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -/* - * If bootrom is currently at BLE there's no need to include the memory - * maps structure at this point - */ -#include -#ifndef IMAGE_BLE - -/***************************************************************************** - * GPIO Configuration - ***************************************************************************** - */ -#define MPP_CONTROL_REGISTER 0xf2440018 -#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000 -#define GPIO_DATA_OUT1_REGISTER 0xf2440140 -#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144 -#define GPIO52_MASK 0x100000 - -/* Reset PCIe via GPIO number 52 */ -int marvell_gpio_config(void) -{ - uint32_t reg; - - reg = mmio_read_32(MPP_CONTROL_REGISTER); - reg |= MPP_CONTROL_MPP_SEL_52_MASK; - mmio_write_32(MPP_CONTROL_REGISTER, reg); - - reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER); - reg |= GPIO52_MASK; - mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg); - - reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER); - reg &= ~GPIO52_MASK; - mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg); - udelay(100); - - return 0; -} - -/***************************************************************************** - * AMB Configuration - ***************************************************************************** - */ -struct addr_map_win amb_memory_map[] = { - /* CP1 SPI1 CS0 Direct Mode access */ - {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, -}; - -int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - *win = amb_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(amb_memory_map); - - return 0; -} -#endif - -/***************************************************************************** - * IO WIN Configuration - ***************************************************************************** - */ -struct addr_map_win io_win_memory_map[] = { - /* CP1 (MCI0) internal regs */ - {0x00000000f4000000, 0x2000000, MCI_0_TID}, -#ifndef IMAGE_BLE - /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ - {0x00000000f9000000, 0x2000000, MCI_0_TID}, - /* PCIe1 on CP1*/ - {0x00000000fb000000, 0x1000000, MCI_0_TID}, - /* PCIe2 on CP1*/ - {0x00000000fc000000, 0x1000000, MCI_0_TID}, - /* MCI 0 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, - /* MCI 1 indirect window */ - {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, -#endif -}; - -uint32_t marvell_get_io_win_gcr_target(int ap_index) -{ - return PIDI_TID; -} - -int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = io_win_memory_map; - if (*win == NULL) - *size = 0; - else - *size = ARRAY_SIZE(io_win_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * IOB Configuration - ***************************************************************************** - */ -struct addr_map_win iob_memory_map_cp0[] = { - /* CP0 */ - /* PEX1_X1 window */ - {0x00000000f7000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000f8000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000f6000000, 0x1000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x100000000, PEX0_TID}, -}; - -struct addr_map_win iob_memory_map_cp1[] = { - /* CP1 */ - /* SPI1_CS0 (RUNIT) window */ - {0x00000000f9000000, 0x1000000, RUNIT_TID}, - /* PEX1_X1 window */ - {0x00000000fb000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000fc000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000fa000000, 0x1000000, PEX0_TID} -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - switch (base) { - case MVEBU_CP_REGS_BASE(0): - *win = iob_memory_map_cp0; - *size = ARRAY_SIZE(iob_memory_map_cp0); - return 0; - case MVEBU_CP_REGS_BASE(1): - *win = iob_memory_map_cp1; - *size = ARRAY_SIZE(iob_memory_map_cp1); - return 0; - default: - *size = 0; - *win = 0; - return 1; - } -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ - {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ - {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ -#endif -}; - -uint32_t marvell_get_ccu_gcr_target(int ap) -{ - return DRAM_0_TID; -} - -int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, - uint32_t *size) -{ - *win = ccu_memory_map; - *size = ARRAY_SIZE(ccu_memory_map); - - return 0; -} - -/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ - -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -void *plat_marvell_get_skip_image_data(void) -{ - /* No recovery button on A8k-MCBIN board */ - return NULL; -} diff --git a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h deleted file mode 100644 index 3fa119a..0000000 --- a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h +++ /dev/null @@ -1,17 +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 - -#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */ -#define I2C_SPD_ADDR 0x53 /* Access SPD data */ -#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a80x0_mcbin/platform.mk b/plat/marvell/a8k/a80x0_mcbin/platform.mk deleted file mode 100644 index 3749c37..0000000 --- a/plat/marvell/a8k/a80x0_mcbin/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 2 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk deleted file mode 100644 index 1ff28f8..0000000 --- a/plat/marvell/a8k/common/a8k_common.mk +++ /dev/null @@ -1,130 +0,0 @@ -# -# Copyright (C) 2016 - 2020 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -include tools/marvell/doimage/doimage.mk - -PLAT_FAMILY := a8k -PLAT_FAMILY_BASE := plat/marvell/$(PLAT_FAMILY) -PLAT_INCLUDE_BASE := include/plat/marvell/$(PLAT_FAMILY) -PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common -MARVELL_DRV_BASE := drivers/marvell -MARVELL_COMMON_BASE := plat/marvell/common - -MARVELL_SVC_TEST := 0 -$(eval $(call add_define,MARVELL_SVC_TEST)) - -ERRATA_A72_859971 := 1 - -# Enable MSS support for a8k family -MSS_SUPPORT := 1 - -# Disable EL3 cache for power management -BL31_CACHE_DISABLE := 0 -$(eval $(call add_define,BL31_CACHE_DISABLE)) - -$(eval $(call add_define,PCI_EP_SUPPORT)) -$(eval $(call assert_boolean,PCI_EP_SUPPORT)) - -AP_NUM := 1 -$(eval $(call add_define,AP_NUM)) - -DOIMAGEPATH ?= tools/marvell/doimage -DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage - -ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin -DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) - -# Check whether to build system_power.c for the platform -ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") -SYSTEM_POWER_SUPPORT = 1 -else -SYSTEM_POWER_SUPPORT = 0 -endif - -# This define specifies DDR type for BLE -$(eval $(call add_define,CONFIG_DDR4)) - -MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \ - drivers/ti/uart/aarch64/16550_console.S - -BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c - -BLE_SOURCES := drivers/mentor/i2c/mi2cv.c \ - $(PLAT_COMMON_BASE)/plat_ble_setup.c \ - $(MARVELL_MOCHI_DRV) \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(MARVELL_DRV_BASE)/ap807_clocks_init.c \ - $(MARVELL_DRV_BASE)/thermal.c \ - $(PLAT_COMMON_BASE)/plat_thermal.c \ - $(BLE_PORTING_SOURCES) \ - $(MARVELL_DRV_BASE)/ccu.c \ - $(MARVELL_DRV_BASE)/io_win.c - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a72.S - -MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ - $(MARVELL_DRV_BASE)/iob.c \ - $(MARVELL_DRV_BASE)/mci.c \ - $(MARVELL_DRV_BASE)/amb_adec.c \ - $(MARVELL_DRV_BASE)/ccu.c \ - $(MARVELL_DRV_BASE)/cache_llc.c \ - $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ - $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -ifeq ($(SYSTEM_POWER_SUPPORT),1) -BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c -endif - -BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(PLAT_COMMON_BASE)/plat_bl31_setup.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv2.c \ - $(MARVELL_COMMON_BASE)/mrvl_sip_svc.c \ - $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ - $(BL31_PORTING_SOURCES) \ - $(MARVELL_DRV) \ - $(MARVELL_MOCHI_DRV) \ - $(MARVELL_GIC_SOURCES) - -# Add trace functionality for PM -BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c - -# Force builds with BL2 image on a80x0 platforms -ifndef SCP_BL2 - $(error "Error: SCP_BL2 image is mandatory for a8k family") -endif - -# MSS (SCP) build -include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk - -# BLE (ROM context execution code, AKA binary extension) -BLE_PATH ?= $(PLAT_COMMON_BASE)/ble - -include ${BLE_PATH}/ble.mk -$(eval $(call MAKE_BL,e)) - -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} - diff --git a/plat/marvell/a8k/common/aarch64/a8k_common.c b/plat/marvell/a8k/common/aarch64/a8k_common.c deleted file mode 100644 index 7c2bf31..0000000 --- a/plat/marvell/a8k/common/aarch64/a8k_common.c +++ /dev/null @@ -1,64 +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_BLE -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/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/a8k/common/aarch64/plat_arch_config.c deleted file mode 100644 index 06dc841..0000000 --- a/plat/marvell/a8k/common/aarch64/plat_arch_config.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) -#define MVEBU_IO_AFFINITY (0xF00) - - -static void plat_enable_affinity(void) -{ - int cluster_id; - int affinity; - - /* set CPU Affinity */ - cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT; - affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id)); - mmio_write_32(CCU_HTC_ASET, affinity); - - /* set barier */ - isb(); -} - -void marvell_psci_arch_init(int die_index) -{ -#if LLC_ENABLE - /* check if LLC is in exclusive mode - * as L2 is configured to UniqueClean eviction - * (in a8k reset handler) - */ - if (llc_is_exclusive(0) == 0) - ERROR("LLC should be configured to exclusice mode\n"); -#endif - - /* Enable Affinity */ - plat_enable_affinity(); -} diff --git a/plat/marvell/a8k/common/aarch64/plat_helpers.S b/plat/marvell/a8k/common/aarch64/plat_helpers.S deleted file mode 100644 index fadc4c2..0000000 --- a/plat/marvell/a8k/common/aarch64/plat_helpers.S +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - .globl plat_reset_handler - - /* ----------------------------------------------------- - * 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 a cold and warm boot - * For a cold boot, return 0. - * For a warm boot, read the mailbox and return the address it contains. - * - * --------------------------------------------------------------------- - */ -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, MVEBU_MAILBOX_MAGIC_NUM - cmp x1, x2 - beq warm_boot /* If compare failed, return 0, i.e. cold boot */ - mov x0, #0 - ret -warm_boot: - mov_imm x1, MBOX_IDX_SEC_ADDR /* Get the jump address */ - subs x1, x1, #1 - mov x2, #(MBOX_IDX_SEC_ADDR * 8) - lsl x3, x2, x1 - add x0, x0, x3 - 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 - - /* ----------------------------------------------------- - * void plat_reset_handler (void); - * - * Platform specific configuration right after cpu is - * is our of reset. - * - * The plat_reset_handler can clobber x0 - x18, x30. - * ----------------------------------------------------- - */ -func plat_reset_handler - /* - * Note: the configurations below should be done before MMU, - * I Cache and L2are enabled. - * The reset handler is executed right after reset - * and before Caches are enabled. - */ - - /* Enable L1/L2 ECC and Parity */ - mrs x5, s3_1_c11_c0_2 /* L2 Ctrl */ - orr x5, x5, #(1 << 21) /* Enable L1/L2 cache ECC & Parity */ - msr s3_1_c11_c0_2, x5 /* L2 Ctrl */ - -#if LLC_ENABLE - /* - * Enable L2 UniqueClean evictions - * Note: this configuration assumes that LLC is configured - * in exclusive mode. - * Later on in the code this assumption will be validated - */ - mrs x5, s3_1_c15_c0_0 /* L2 Ctrl */ - orr x5, x5, #(1 << 14) /* Enable UniqueClean evictions with data */ - msr s3_1_c15_c0_0, x5 /* L2 Ctrl */ -#endif - - /* Instruction Barrier to allow msr command completion */ - isb - - ret -endfunc plat_reset_handler diff --git a/plat/marvell/a8k/common/ble/ble.ld.S b/plat/marvell/a8k/common/ble/ble.ld.S deleted file mode 100644 index d7a0592..0000000 --- a/plat/marvell/a8k/common/ble/ble.ld.S +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) -OUTPUT_ARCH(PLATFORM_LINKER_ARCH) -ENTRY(ble_main) - -MEMORY { - RAM (rwx): ORIGIN = BLE_BASE, LENGTH = BLE_LIMIT - BLE_BASE -} - -SECTIONS -{ - . = BLE_BASE; - - ro . : { - __RO_START__ = .; - *ble_main.o(.entry*) - *(.text*) - *(.rodata*) - __RO_END_UNALIGNED__ = .; - __RO_END__ = .; - } >RAM - - /* - * Define a linker symbol to mark start of the RW memory area for this - * image. - */ - __RW_START__ = . ; - - .data . : { - __DATA_START__ = .; - *(.data*) - __DATA_END__ = .; - } >RAM - - stacks . (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - - .bss : { - __BSS_START__ = .; - *(.bss*) - __BSS_END__ = .; - } >RAM - - /* - * Extend the BLE binary to the maximum size allocated for it in platform - * definition files and prevent overlapping between BLE BSS section and - * additional extensions that can follow the BLE in flash image preamble. - * This situation happens for instance when secure extension is added to - * the image preamble. - */ - .fill LOADADDR(.bss) + SIZEOF(.bss) : { - FILL(0xDEADC0DE); - . = ORIGIN(RAM) + LENGTH(RAM) - 1; - BYTE(0x00) - } >RAM - - /* - * Define a linker symbol to mark end of the RW memory area for this - * image. - */ - __RW_END__ = .; - __BLE_END__ = .; - - __BSS_SIZE__ = SIZEOF(.bss); -} diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk deleted file mode 100644 index b6a9cd2..0000000 --- a/plat/marvell/a8k/common/ble/ble.mk +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -MV_DDR_PATH ?= drivers/marvell/mv_ddr - -MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a -LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a -BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) -PLAT_MARVELL = plat/marvell - -BLE_SOURCES += $(BLE_PATH)/ble_main.c \ - $(BLE_PATH)/ble_mem.S \ - drivers/delay_timer/delay_timer.c \ - $(PLAT_MARVELL)/common/aarch64/marvell_helpers.S \ - $(PLAT_MARVELL)/common/plat_delay_timer.c \ - $(PLAT_MARVELL)/common/marvell_console.c - -PLAT_INCLUDES += -I$(MV_DDR_PATH) \ - -I$(CURDIR)/include \ - -I$(CURDIR)/include/arch/aarch64 \ - -I$(CURDIR)/include/lib/libc \ - -I$(CURDIR)/include/lib/libc/aarch64 \ - -I$(CURDIR)/drivers/marvell - -BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S - -FORCE: - -$(MV_DDR_LIB): FORCE - @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c deleted file mode 100644 index 5b3acec..0000000 --- a/plat/marvell/a8k/common/ble/ble_main.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#define BR_FLAG_SILENT 0x1 -#define SKIP_IMAGE_CODE 0xDEADB002 - -void mailbox_clean(void) -{ - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); -} - -int exec_ble_main(int bootrom_flags) -{ - int skip = 0; - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* - * In some situations, like boot from UART, bootrom will - * request to avoid printing to console. in that case don't - * initialize the console and prints will be ignored - */ - if ((bootrom_flags & BR_FLAG_SILENT) == 0) - marvell_console_boot_init(); - - NOTICE("Starting binary extension\n"); - - /* initialize time (for delay functionality) */ - plat_delay_timer_init(); - - ble_plat_setup(&skip); - - /* if there's skip image request, bootrom will load from the image - * saved on the next address of the flash - */ - if (skip) - return SKIP_IMAGE_CODE; - - /* - * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC - * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. - * If the above is true, this is the recovery from suspend to RAM state. - * In such case the mailbox should remain intact, since it stores the - * warm boot jump address to be used by the TF-A in BL31. - * Othervise the mailbox should be cleaned from a garbage data. - */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { - NOTICE("Cold boot\n"); - mailbox_clean(); - } else { - void (*bootrom_exit)(void) = - (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; - - INFO("Recovery...\n"); - /* - * If this is recovery from suspend, two things has to be done: - * 1. Define the DRAM region as executable memory for preparing - * jump to TF-A - * 2. Instead of returning control to the BootROM, invalidate - * and flush caches, and continue execution at address stored - * in the mailbox. - * This should be done until the BootROM have a native support - * for the system restore flow. - */ - marvell_ble_prepare_exit(); - bootrom_exit(); - } - - return 0; -} - -/* NOTE: don't notify this function, all code must be added to exec_ble_main - * in order to keep the end of ble_main as a fixed address. - */ -int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) -{ - volatile int ret; - - ret = exec_ble_main(bootrom_flags); - return ret; -} diff --git a/plat/marvell/a8k/common/ble/ble_mem.S b/plat/marvell/a8k/common/ble/ble_mem.S deleted file mode 100644 index a48d546..0000000 --- a/plat/marvell/a8k/common/ble/ble_mem.S +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - -#define PTE_NON_EXEC_OFF 54 /* XN - eXecute Never bit offset - see VMSAv8-64 */ - - .globl marvell_ble_prepare_exit - -func marvell_ble_prepare_exit - /* - * Read the page table base and set the first page to be executable. - * This is required for jumping to DRAM for further execution. - */ - mrs x0, ttbr0_el3 - ldr x1, [x0] - mov x2, #1 - bic x1, x1, x2, lsl #PTE_NON_EXEC_OFF - str x1, [x0] - tlbi alle3 - dsb sy - isb - ret -endfunc marvell_ble_prepare_exit diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/a8k/common/include/a8k_plat_def.h deleted file mode 100644 index de80315..0000000 --- a/plat/marvell/a8k/common/include/a8k_plat_def.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A8K_PLAT_DEF_H -#define A8K_PLAT_DEF_H - -#include - -#define MVEBU_PRIMARY_CPU 0x0 -#define MVEBU_AP0 0x0 - -/* APN806 revision ID */ -#define MVEBU_CSS_GWD_CTRL_IIDR2_REG (MVEBU_REGS_BASE + 0x610FCC) -#define GWD_IIDR2_REV_ID_OFFSET 12 -#define GWD_IIDR2_REV_ID_MASK 0xF -#define GWD_IIDR2_CHIP_ID_OFFSET 20 -#define GWD_IIDR2_CHIP_ID_MASK (0xFFFu << GWD_IIDR2_CHIP_ID_OFFSET) - -#define CHIP_ID_AP806 0x806 -#define CHIP_ID_AP807 0x807 - -#define COUNTER_FREQUENCY 25000000 - -#define MVEBU_REGS_BASE 0xF0000000 -#define MVEBU_REGS_BASE_MASK 0xF0000000 -#define MVEBU_REGS_BASE_AP(ap) MVEBU_REGS_BASE -#define MVEBU_AP_IO_BASE(ap) 0xF2000000 -#define MVEBU_CP_OFFSET 0x2000000 -#define MVEBU_CP_REGS_BASE(cp_index) (MVEBU_AP_IO_BASE(0) + \ - (cp_index) * MVEBU_CP_OFFSET) -#define MVEBU_RFU_BASE (MVEBU_REGS_BASE + 0x6F0000) -#define MVEBU_IO_WIN_BASE(ap_index) (MVEBU_RFU_BASE) -#define MVEBU_IO_WIN_GCR_OFFSET (0x70) -#define MVEBU_IO_WIN_MAX_WINS (7) - -/* Misc SoC configurations Base */ -#define MVEBU_MISC_SOC_BASE (MVEBU_REGS_BASE + 0x6F4300) - -#define MVEBU_CCU_BASE(ap_index) (MVEBU_REGS_BASE + 0x4000) -#define MVEBU_CCU_MAX_WINS (8) - -#define MVEBU_LLC_BASE(ap_index) (MVEBU_REGS_BASE + 0x8000) -#define MVEBU_DRAM_MAC_BASE (MVEBU_REGS_BASE + 0x20000) -#define MVEBU_DRAM_PHY_BASE (MVEBU_REGS_BASE + 0x20000) -#define MVEBU_SMMU_BASE (MVEBU_REGS_BASE + 0x100000) -#define MVEBU_CP_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440000 + ((n) << 2)) -#define MVEBU_PM_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440000 + ((n / 8) << 2)) -#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \ - (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440100 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \ - (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440104 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440110 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2)) -#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040) -#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10) -#define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000) -#define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000) -#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084) - -#define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ - 0x20080 + ((win) * 0x8)) -#define MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ - 0x20084 + ((win) * 0x8)) - -/* MCI indirect access definitions */ -#define MCI_MAX_UNIT_ID 2 -/* SoC RFU / IHBx4 Control */ -#define MCIX4_REG_START_ADDRESS_REG(unit_id) (MVEBU_RFU_BASE + \ - 0x4218 + (unit_id * 0x20)) -#define MCI_REMAP_OFF_SHIFT 8 - -#define MVEBU_MCI_REG_BASE_REMAP(index) (0xFD000000 + \ - ((index) * 0x1000000)) - -#define MVEBU_PCIE_X4_MAC_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x600000) -#define MVEBU_COMPHY_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x441000) -#define MVEBU_HPIPE_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x120000) -#define MVEBU_CP_DFX_OFFSET (0x400200) - -/***************************************************************************** - * MVEBU memory map related constants - ***************************************************************************** - */ -/* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE MVEBU_REGS_BASE -#define DEVICE0_SIZE 0x10000000 - -/***************************************************************************** - * GIC-400 & interrupt handling related constants - ***************************************************************************** - */ -/* Base MVEBU compatible GIC memory map */ -#define MVEBU_GICD_BASE 0x210000 -#define MVEBU_GICC_BASE 0x220000 - - -/***************************************************************************** - * AXI Configuration - ***************************************************************************** - */ -#define MVEBU_AXI_ATTR_ARCACHE_OFFSET 4 -#define MVEBU_AXI_ATTR_ARCACHE_MASK (0xF << \ - MVEBU_AXI_ATTR_ARCACHE_OFFSET) -#define MVEBU_AXI_ATTR_ARDOMAIN_OFFSET 12 -#define MVEBU_AXI_ATTR_ARDOMAIN_MASK (0x3 << \ - MVEBU_AXI_ATTR_ARDOMAIN_OFFSET) -#define MVEBU_AXI_ATTR_AWCACHE_OFFSET 20 -#define MVEBU_AXI_ATTR_AWCACHE_MASK (0xF << \ - MVEBU_AXI_ATTR_AWCACHE_OFFSET) -#define MVEBU_AXI_ATTR_AWDOMAIN_OFFSET 28 -#define MVEBU_AXI_ATTR_AWDOMAIN_MASK (0x3 << \ - MVEBU_AXI_ATTR_AWDOMAIN_OFFSET) - -/* SATA MBUS to AXI configuration */ -#define MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET 1 -#define MVEBU_SATA_M2A_AXI_ARCACHE_MASK (0xF << \ - MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET) -#define MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET 5 -#define MVEBU_SATA_M2A_AXI_AWCACHE_MASK (0xF << \ - MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET) - -/* ARM cache attributes */ -#define CACHE_ATTR_BUFFERABLE 0x1 -#define CACHE_ATTR_CACHEABLE 0x2 -#define CACHE_ATTR_READ_ALLOC 0x4 -#define CACHE_ATTR_WRITE_ALLOC 0x8 -/* Domain */ -#define DOMAIN_NON_SHAREABLE 0x0 -#define DOMAIN_INNER_SHAREABLE 0x1 -#define DOMAIN_OUTER_SHAREABLE 0x2 -#define DOMAIN_SYSTEM_SHAREABLE 0x3 - -/************************************************************************ - * Required platform porting definitions common to all - * Management Compute SubSystems (MSS) - ************************************************************************ - */ -/* - * Load address of SCP_BL2 - * SCP_BL2 is loaded to the same place as BL31. - * Once SCP_BL2 is transferred to the SCP, - * it is discarded and BL31 is loaded over the top. - */ -#ifdef SCP_IMAGE -#define SCP_BL2_BASE BL31_BASE -#define SCP_BL2_SIZE BL31_LIMIT -#endif - -#ifndef __ASSEMBLER__ -enum ap806_sar_target_dev { - SAR_PIDI_MCIX2 = 0x0, - SAR_MCIX4 = 0x1, - SAR_SPI = 0x2, - SAR_SD = 0x3, - SAR_PIDI_MCIX2_BD = 0x4, /* BootRom disabled */ - SAR_MCIX4_DB = 0x5, /* BootRom disabled */ - SAR_SPI_DB = 0x6, /* BootRom disabled */ - SAR_EMMC = 0x7 -}; - -enum io_win_target_ids { - MCI_0_TID = 0x0, - MCI_1_TID = 0x1, - MCI_2_TID = 0x2, - PIDI_TID = 0x3, - SPI_TID = 0x4, - STM_TID = 0x5, - BOOTROM_TID = 0x6, - IO_WIN_MAX_TID -}; - -enum ccu_target_ids { - IO_0_TID = 0x00, - DRAM_0_TID = 0x03, - IO_1_TID = 0x0F, - CFG_REG_TID = 0x10, - RAR_TID = 0x20, - SRAM_TID = 0x40, - DRAM_1_TID = 0xC0, - CCU_MAX_TID, - INVALID_TID = 0xFF -}; -#endif /* __ASSEMBLER__ */ - -#endif /* A8K_PLAT_DEF_H */ diff --git a/plat/marvell/a8k/common/include/ddr_info.h b/plat/marvell/a8k/common/include/ddr_info.h deleted file mode 100644 index e19036a..0000000 --- a/plat/marvell/a8k/common/include/ddr_info.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#define DRAM_MAX_IFACE 1 -#define DRAM_CH0_MMAP_LOW_OFFSET 0x20200 diff --git a/plat/marvell/a8k/common/include/mentor_i2c_plat.h b/plat/marvell/a8k/common/include/mentor_i2c_plat.h deleted file mode 100644 index e03c448..0000000 --- a/plat/marvell/a8k/common/include/mentor_i2c_plat.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -/* This driver provides I2C support for Marvell A8K and compatible SoCs */ - -#ifndef MENTOR_I2C_PLAT_H -#define MENTOR_I2C_PLAT_H - -#define CONFIG_SYS_TCLK 250000000 -#define CONFIG_SYS_I2C_SPEED 100000 -#define CONFIG_SYS_I2C_SLAVE 0x0 - -#define I2C_CAN_UNSTUCK - -struct mentor_i2c_regs { - uint32_t slave_address; - uint32_t data; - uint32_t control; - union { - uint32_t status; /* when reading */ - uint32_t baudrate; /* when writing */ - }; - uint32_t xtnd_slave_addr; - uint32_t reserved[2]; - uint32_t soft_reset; - uint8_t reserved2[0xa0 - 0x20]; - uint32_t unstuck; -}; - -#endif /* MENTOR_I2C_PLAT_H */ diff --git a/plat/marvell/a8k/common/include/plat_macros.S b/plat/marvell/a8k/common/include/plat_macros.S deleted file mode 100644 index 8faccf0..0000000 --- a/plat/marvell/a8k/common/include/plat_macros.S +++ /dev/null @@ -1,20 +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 - -/* - * Required platform porting macros - * (Provided by included headers) - */ -.macro plat_crash_print_regs -.endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/a8k/common/include/platform_def.h b/plat/marvell/a8k/common/include/platform_def.h deleted file mode 100644 index ec1c903..0000000 --- a/plat/marvell/a8k/common/include/platform_def.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2018 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 - -#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_SRAM_BASE 0xFFE1C048 -#define PLAT_MARVELL_SRAM_END 0xFFE78000 - -#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_NORTHB_COUNT 1 - -#define PLAT_MARVELL_CLUSTER_COUNT U(2) -#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) - -#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ - PLAT_MARVELL_CLUSTER_CORE_COUNT) - -/* 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_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), \ - INTR_PROP_DESC(MARVELL_IRQ_PIC0, 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 - -/* - * 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 + 0x512000) -#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 200000000 - -#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 - -/* Recovery image enable */ -#define PLAT_RECOVERY_IMAGE_ENABLE 0 - -/* 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 (note the lower memory space - * is reserved for BLE data) - */ -#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_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/a8k/common/mss/mss_a8k.mk b/plat/marvell/a8k/common/mss/mss_a8k.mk deleted file mode 100644 index efd03c5..0000000 --- a/plat/marvell/a8k/common/mss/mss_a8k.mk +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PLAT_MARVELL := plat/marvell -A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss - -BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ - $(MARVELL_MOCHI_DRV) - -BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c - -PLAT_INCLUDES += -I$(A8K_MSS_SOURCE) - -ifneq (${SCP_BL2},) -# This define is used to inidcate the SCP image is present -$(eval $(call add_define,SCP_IMAGE)) -endif diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c deleted file mode 100644 index 09b8446..0000000 --- a/plat/marvell/a8k/common/mss/mss_bl2_setup.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include /* timer functionality */ - -#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) -#define MSS_AEBR_MASK 0xFFF -#define MSS_AIBR_MASK 0xFFF - -#define MSS_EXTERNAL_SPACE 0x50000000 -#define MSS_EXTERNAL_ACCESS_BIT 28 -#define MSS_EXTERNAL_ADDR_MASK 0xfffffff -#define MSS_INTERNAL_ACCESS_BIT 28 - -struct addr_map_win ccu_mem_map[] = { - {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID} -}; - -/* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors, - * the access to cp0 and cp1 need to be provided. More precisely it is - * required to: - * - get the information about device id which is stored in CP0 registers - * (to distinguish between cases where we have cp0 and cp1 or standalone cp0) - * - get the access to cp which is needed for loading fw for cp0/cp1 - * coprocessors - * This function configures ccu windows accordingly. - * - * Note: there is no need to restore previous ccu configuration, since in next - * phase (BL31) the init_ccu will be called (via apn806_init/ - * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten. - */ -static int bl2_plat_mmap_init(void) -{ - int cfg_num, win_id, cfg_idx; - - cfg_num = ARRAY_SIZE(ccu_mem_map); - - /* CCU window-0 should not be counted - it's already used */ - if (cfg_num > (MVEBU_CCU_MAX_WINS - 1)) { - ERROR("BL2: %s: trying to open too many windows\n", __func__); - return -1; - } - - /* Enable required CCU windows - * 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++) { - /* Enable required CCU windows */ - ccu_win_check(&ccu_mem_map[cfg_idx]); - ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); - } - - /* Set the default target id to PIDI */ - mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); - - /* 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)); - - return 0; -} - -/***************************************************************************** - * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. - * Return 0 on success, -1 otherwise. - ***************************************************************************** - */ -int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) -{ - int ret; - - INFO("BL2: Initiating SCP_BL2 transfer to SCP\n"); - - /* initialize time (for delay functionality) */ - plat_delay_timer_init(); - - ret = bl2_plat_mmap_init(); - if (ret != 0) - return ret; - - ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base, - scp_bl2_image_info->image_size); - - if (ret == 0) - INFO("BL2: SCP_BL2 transferred to SCP\n"); - else - ERROR("BL2: SCP_BL2 transfer failure\n"); - - return ret; -} - -uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx) -{ - return MVEBU_CP_REGS_BASE(cp_idx) + 0x280000; -} - -uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx) -{ - return MVEBU_REGS_BASE + 0x580000; -} - -uint32_t bl2_plat_get_cp_count(int ap_idx) -{ - uint32_t revision = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - /* A8040: two CPs. - * A7040: one CP. - */ - if (revision == MVEBU_80X0_DEV_ID || - revision == MVEBU_80X0_CP115_DEV_ID) - return 2; - else - return 1; -} - -uint32_t bl2_plat_get_ap_count(void) -{ - /* A8040 and A7040 have only one AP */ - return 1; -} - -void bl2_plat_configure_mss_windows(uintptr_t mss_regs) -{ - /* set AXI External and Internal Address Bus extension */ - mmio_write_32(MSS_AEBR(mss_regs), - ((0x0 >> MSS_EXTERNAL_ACCESS_BIT) & MSS_AEBR_MASK)); - mmio_write_32(MSS_AIBR(mss_regs), - ((mss_regs >> MSS_INTERNAL_ACCESS_BIT) & MSS_AIBR_MASK)); -} diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/a8k/common/mss/mss_pm_ipc.c deleted file mode 100644 index a070583..0000000 --- a/plat/marvell/a8k/common/mss/mss_pm_ipc.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include - -#include - -/* - * SISR is 32 bit interrupt register representing 32 interrupts - * - * +======+=============+=============+ - * + Bits + 31 + 30 - 00 + - * +======+=============+=============+ - * + Desc + MSS Msg Int + Reserved + - * +======+=============+=============+ - */ -#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0) -#define MSS_SISTR (MVEBU_REGS_BASE + 0x5800D8) - -#define MSS_MSG_INT_MASK (0x80000000) -#define MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) -#define MSS_TRIGGER_TIMEOUT (2000) - -/***************************************************************************** - * mss_pm_ipc_msg_send - * - * DESCRIPTION: create and transmit IPC message - ***************************************************************************** - */ -int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, - const psci_power_state_t *target_state) -{ - /* Transmit IPC message */ -#ifndef DISABLE_CLUSTER_LEVEL - mv_pm_ipc_msg_tx(channel_id, msg_id, - (unsigned int)target_state->pwr_domain_state[ - MPIDR_AFFLVL1]); -#else - mv_pm_ipc_msg_tx(channel_id, msg_id, 0); -#endif - - return 0; -} - -/***************************************************************************** - * mss_pm_ipc_msg_trigger - * - * DESCRIPTION: Trigger IPC message interrupt to MSS - ***************************************************************************** - */ -int mss_pm_ipc_msg_trigger(void) -{ - unsigned int timeout; - unsigned int t_end; - unsigned int t_start = mmio_read_32(MSS_TIMER_BASE); - - mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK); - - do { - /* wait while SCP process incoming interrupt */ - if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK) - break; - - /* check timeout */ - t_end = mmio_read_32(MSS_TIMER_BASE); - - timeout = ((t_start > t_end) ? - (t_start - t_end) : (t_end - t_start)); - if (timeout > MSS_TRIGGER_TIMEOUT) { - ERROR("PM MSG Trigger Timeout\n"); - break; - } - - } while (1); - - return 0; -} diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/a8k/common/mss/mss_pm_ipc.h deleted file mode 100644 index 1dfa9fa..0000000 --- a/plat/marvell/a8k/common/mss/mss_pm_ipc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_PM_IPC_H -#define MSS_PM_IPC_H - -#include - -/* Currently MSS does not support Cluster level Power Down */ -#define DISABLE_CLUSTER_LEVEL - - -/***************************************************************************** - * mss_pm_ipc_msg_send - * - * DESCRIPTION: create and transmit IPC message - ***************************************************************************** - */ -int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, - const psci_power_state_t *target_state); - -/***************************************************************************** - * mss_pm_ipc_msg_trigger - * - * DESCRIPTION: Trigger IPC message interrupt to MSS - ***************************************************************************** - */ -int mss_pm_ipc_msg_trigger(void); - - -#endif /* MSS_PM_IPC_H */ diff --git a/plat/marvell/a8k/common/plat_bl1_setup.c b/plat/marvell/a8k/common/plat_bl1_setup.c deleted file mode 100644 index f9521c8..0000000 --- a/plat/marvell/a8k/common/plat_bl1_setup.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -void marvell_bl1_setup_mpps(void) -{ - /* Enable UART MPPs. - ** In a normal system, this is done by Bootrom. - */ - mmio_write_32(MVEBU_AP_MPP_REGS(1), 0x3000); - mmio_write_32(MVEBU_AP_MPP_REGS(2), 0x3000); -} diff --git a/plat/marvell/a8k/common/plat_bl31_setup.c b/plat/marvell/a8k/common/plat_bl31_setup.c deleted file mode 100644 index 98b3966..0000000 --- a/plat/marvell/a8k/common/plat_bl31_setup.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* In Armada-8k family AP806/AP807, CP0 connected to PIDI - * and CP1 connected to IHB via MCI #0 - */ -#define MVEBU_MCI0 0 - -static _Bool pm_fw_running; - -/* Set a weak stub for platforms that don't need to configure GPIO */ -#pragma weak marvell_gpio_config -int marvell_gpio_config(void) -{ - return 0; -} - -static void marvell_bl31_mpp_init(int cp) -{ - uint32_t reg; - - /* need to do for CP#0 only */ - if (cp) - return; - - - /* - * Enable CP0 I2C MPPs (MPP: 37-38) - * U-Boot rely on proper MPP settings for I2C EEPROM usage - * (only for CP0) - */ - reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4)); - mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); -} - -void marvell_bl31_mss_init(void) -{ - struct mss_pm_ctrl_block *mss_pm_crtl = - (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; - - /* Check that the image was loaded successfully */ - if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) { - NOTICE("MSS PM is not supported in this build\n"); - return; - } - - /* If we got here it means that the PM firmware is running */ - pm_fw_running = 1; - - INFO("MSS IPC init\n"); - - if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) - mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); -} - -_Bool is_pm_fw_running(void) -{ - return pm_fw_running; -} - -/* For TrusTzone we treat the "target" field of addr_map_win - * struct as attribute - */ -static const struct addr_map_win tz_map[] = { - {PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT} -}; - -/* Configure MC TrustZone regions */ -static void marvell_bl31_security_setup(void) -{ - int tz_nr, win_id; - - tz_nr = ARRAY_SIZE(tz_map); - - for (win_id = 0; win_id < tz_nr; win_id++) - tz_enable_win(MVEBU_AP0, tz_map, win_id); -} - -/* This function overruns the same function in marvell_bl31_setup.c */ -void bl31_plat_arch_setup(void) -{ - int cp; - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* initialize the timer for mdelay/udelay functionality */ - plat_delay_timer_init(); - - /* configure apn806 */ - ap_init(); - - /* In marvell_bl31_plat_arch_setup, el3 mmu is configured. - * el3 mmu configuration MUST be called after apn806_init, if not, - * this will cause an hang in init_io_win - * (after setting the IO windows GCR values). - */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) - marvell_bl31_plat_arch_setup(); - - for (cp = 0; cp < CP_COUNT; cp++) { - /* configure cp110 for CP0*/ - if (cp == 1) - mci_initialize(MVEBU_MCI0); - - /* initialize MCI & CP1 */ - cp110_init(MVEBU_CP_REGS_BASE(cp), - STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); - - /* Should be called only after setting IOB windows */ - marvell_bl31_mpp_init(cp); - } - - /* initialize IPC between MSS and ATF */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) - marvell_bl31_mss_init(); - - /* Configure GPIO */ - marvell_gpio_config(); - - marvell_bl31_security_setup(); -} diff --git a/plat/marvell/a8k/common/plat_ble_setup.c b/plat/marvell/a8k/common/plat_ble_setup.c deleted file mode 100644 index 7f9e242..0000000 --- a/plat/marvell/a8k/common/plat_ble_setup.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Register for skip image use */ -#define SCRATCH_PAD_REG2 0xF06F00A8 -#define SCRATCH_PAD_SKIP_VAL 0x01 -#define NUM_OF_GPIO_PER_REG 32 - -#define MMAP_SAVE_AND_CONFIG 0 -#define MMAP_RESTORE_SAVED 1 - -/* SAR clock settings */ -#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) -#define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ - ((r) << 2)) - -#define SAR_CLOCK_FREQ_MODE_OFFSET (0) -#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET) -#define SAR_PIDI_LOW_SPEED_OFFSET (20) -#define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET) -#define SAR_PIDI_LOW_SPEED_SHIFT (15) -#define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT) - -#define FREQ_MODE_AP_SAR_REG_NUM (0) -#define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \ - SAR_CLOCK_FREQ_MODE_OFFSET) - -#define AVS_I2C_EEPROM_ADDR 0x57 /* EEPROM */ -#define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130) -#define AVS_ENABLE_OFFSET (0) -#define AVS_SOFT_RESET_OFFSET (2) -#define AVS_TARGET_DELTA_OFFSET (21) - -#ifndef MVEBU_SOC_AP807 - /* AP806 SVC bits */ - #define AVS_LOW_VDD_LIMIT_OFFSET (4) - #define AVS_HIGH_VDD_LIMIT_OFFSET (12) - #define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET) - #define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET) -#else - /* AP807 SVC bits */ - #define AVS_LOW_VDD_LIMIT_OFFSET (3) - #define AVS_HIGH_VDD_LIMIT_OFFSET (13) - #define AVS_VDD_LOW_LIMIT_MASK (0x3FF << AVS_LOW_VDD_LIMIT_OFFSET) - #define AVS_VDD_HIGH_LIMIT_MASK (0x3FF << AVS_HIGH_VDD_LIMIT_OFFSET) -#endif - -/* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */ -#define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ - (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \ - (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD limit is 1.0V for all A80x0 devices */ -#define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ - (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \ - (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD limit is 0.82V for all A3900 devices - * AVS offsets are not the same as in A70x0 - */ -#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ - (0x2c2 << 13) | \ - (0x2c2 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD is 0.88V for 2GHz clock */ -#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ - (0x2f5 << 13) | \ - (0x2f5 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) - -#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) -#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 -#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) - - -/* - * - Identification information in the LD-0 eFuse: - * DRO: LD0[74:65] - Not used by the SW - * Revision: LD0[78:75] - Not used by the SW - * Bin: LD0[80:79] - Not used by the SW - * SW Revision: LD0[115:113] - * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 - * resulting in 2 CPUs active only (7020) - */ -#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) -/* Bits [94:63] - 32 data bits total */ -#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) -/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ -#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) -/* Bits [220:189] - 32 data bits total */ -#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) -/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ -#define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ -#define EFUSE_AP_LD0_DRO_MASK 0x3FF -#define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ -#define EFUSE_AP_LD0_REVID_MASK 0xF -#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ -#define EFUSE_AP_LD0_BIN_MASK 0x3 -#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ -#define EFUSE_AP_LD0_SWREV_MASK 0x7 - -#ifndef MVEBU_SOC_AP807 - /* AP806 AVS work points in the LD0 eFuse - * SVC1 work point: LD0[88:81] - * SVC2 work point: LD0[96:89] - * SVC3 work point: LD0[104:97] - * SVC4 work point: LD0[112:105] - */ - #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */ - #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ - #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ - #define EFUSE_AP_LD0_WP_MASK 0xFF -#else - /* AP807 AVS work points in the LD0 eFuse - * SVC1 work point: LD0[91:81] - * SVC2 work point: LD0[102:92] - * SVC3 work point: LD0[113:103] - */ - #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ - #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ - #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ - #define EFUSE_AP_LD0_WP_MASK 0x3FF -#endif - -#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ - -#define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4 - -#if MARVELL_SVC_TEST -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_I2C_FUNC 2 -#define MVEBU_MPP_CTRL_MASK 0xf -#endif - -/* Return the AP revision of the chip */ -static unsigned int ble_get_ap_type(void) -{ - unsigned int chip_rev_id; - - chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG); - chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >> - GWD_IIDR2_CHIP_ID_OFFSET); - - return chip_rev_id; -} - -/****************************************************************************** - * The routine allows to save the CCU and IO windows configuration during DRAM - * setup and restore them afterwards before exiting the BLE stage. - * Such window configuration is required since not all default settings coming - * from the HW and the BootROM allow access to peripherals connected to - * all available CPn components. - * For instance, when the boot device is located on CP0, the IO window to CP1 - * is not opened automatically by the HW and if the DRAM SPD is located on CP1 - * i2c channel, it cannot be read at BLE stage. - * Therefore the DRAM init procedure have to provide access to all available - * CPn peripherals during the BLE stage by setting the CCU IO window to all - * CPnph addresses and by enabling the IO windows accordingly. - * Additionally this function configures the CCU GCR to DRAM, which allows - * usage or more than 4GB DRAM as it configured by the default CCU DRAM window. - * - * IN: - * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it - * MMAP_RESTORE_SAVED - restore saved configuration - * OUT: - * NONE - **************************************************************************** - */ -static void ble_plat_mmap_config(int restore) -{ - if (restore == MMAP_RESTORE_SAVED) { - /* Restore all orig. settings that were modified by BLE stage */ - ccu_restore_win_all(MVEBU_AP0); - /* Restore CCU */ - iow_restore_win_all(MVEBU_AP0); - return; - } - - /* Store original values */ - ccu_save_win_all(MVEBU_AP0); - /* Save CCU */ - iow_save_win_all(MVEBU_AP0); - - init_ccu(MVEBU_AP0); - /* The configuration saved, now all the changes can be done */ - init_io_win(MVEBU_AP0); -} - -/**************************************************************************** - * Setup Adaptive Voltage Switching - this is required for some platforms - **************************************************************************** - */ -#if !MARVELL_SVC_TEST -static void ble_plat_avs_config(void) -{ - uint32_t freq_mode, device_id; - uint32_t avs_val = 0; - - freq_mode = - SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - /* Check which SoC is running and act accordingly */ - if (ble_get_ap_type() == CHIP_ID_AP807) { - /* Increase CPU voltage for higher CPU clock */ - if (freq_mode == CPU_2000_DDR_1200_RCLK_1200) - avs_val = AVS_A3900_HIGH_CLK_VALUE; - else - avs_val = AVS_A3900_CLK_VALUE; - } else { - /* Check which SoC is running and act accordingly */ - device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - switch (device_id) { - case MVEBU_80X0_DEV_ID: - case MVEBU_80X0_CP115_DEV_ID: - /* Always fix the default AVS value on A80x0 */ - avs_val = AVS_A8K_CLK_VALUE; - break; - case MVEBU_70X0_DEV_ID: - case MVEBU_70X0_CP115_DEV_ID: - /* Fix AVS for CPU clocks lower than 1600MHz on A70x0 */ - if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) && - (freq_mode < CPU_DDR_RCLK_INVALID)) - avs_val = AVS_A7K_LOW_CLK_VALUE; - break; - default: - ERROR("Unsupported Device ID 0x%x\n", device_id); - return; - } - } - - if (avs_val) { - VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val); - mmio_write_32(AVS_EN_CTRL_REG, avs_val); - } -} -#endif -/****************************************************************************** - * Update or override current AVS work point value using data stored in EEPROM - * This is only required by QA/validation flows and activated by - * MARVELL_SVC_TEST flag. - * - * The function is expected to be called twice. - * - * First time with AVS value of 0 for testing if the EEPROM requests completely - * override the AVS value and bypass the eFuse test - * - * Second time - with non-zero AVS value obtained from eFuses as an input. - * In this case the EEPROM may contain AVS correction value (either positive - * or negative) that is added to the input AVS value and returned back for - * further processing. - ****************************************************************************** - */ -static uint32_t avs_update_from_eeprom(uint32_t avs_workpoint) -{ - uint32_t new_wp = avs_workpoint; -#if MARVELL_SVC_TEST - /* --------------------------------------------------------------------- - * EEPROM | Data description (avs_step) - * address | - * --------------------------------------------------------------------- - * 0x120 | AVS workpoint correction value - * | if not 0 and not 0xff, correct the AVS taken from eFuse - * | by the number of steps indicated by bit[6:0] - * | bit[7] defines correction direction. - * | If bit[7]=1, add the value from bit[6:0] to AVS workpoint, - * | othervise substruct this value from AVS workpoint. - * --------------------------------------------------------------------- - * 0x121 | AVS workpoint override value - * | Override the AVS workpoint with the value stored in this - * | byte. When running on AP806, the AVS workpoint is 7 bits - * | wide and override value is valid when bit[6:0] holds - * | value greater than zero and smaller than 0x33. - * | When running on AP807, the AVS workpoint is 10 bits wide. - * | Additional 2 MSB bits are supplied by EEPROM byte 0x122. - * | AVS override value is valid when byte @ 0x121 and bit[1:0] - * | of byte @ 0x122 combined have non-zero value. - * --------------------------------------------------------------------- - * 0x122 | Extended AVS workpoint override value - * | Valid only for AP807 platforms and must be less than 0x4 - * --------------------------------------------------------------------- - */ - static uint8_t avs_step[3] = {0}; - uintptr_t reg; - uint32_t val; - unsigned int ap_type = ble_get_ap_type(); - - /* Always happens on second call to this function */ - if (avs_workpoint != 0) { - /* Get correction steps from the EEPROM */ - if ((avs_step[0] != 0) && (avs_step[0] != 0xff)) { - NOTICE("AVS request to step %s by 0x%x from old 0x%x\n", - avs_step[0] & 0x80 ? "DOWN" : "UP", - avs_step[0] & 0x7f, new_wp); - if (avs_step[0] & 0x80) - new_wp -= avs_step[0] & 0x7f; - else - new_wp += avs_step[0] & 0x7f; - } - - return new_wp; - } - - /* AVS values are located in EEPROM - * at CP0 i2c bus #0, device 0x57 offset 0x120 - * The SDA and SCK pins of CP0 i2c-0: MPP[38:37], i2c function 0x2. - */ - reg = MVEBU_CP_MPP_REGS(0, 4); - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); - - /* Init CP0 i2c-0 */ - i2c_init((void *)(MVEBU_CP0_I2C_BASE)); - - /* Read EEPROM only once at the fist call! */ - i2c_read(AVS_I2C_EEPROM_ADDR, 0x120, 2, avs_step, 3); - NOTICE("== SVC test build ==\n"); - NOTICE("EEPROM holds values 0x%x, 0x%x and 0x%x\n", - avs_step[0], avs_step[1], avs_step[2]); - - /* Override the AVS value? */ - if ((ap_type != CHIP_ID_AP807) && (avs_step[1] < 0x33)) { - /* AP806 - AVS is 7 bits */ - new_wp = avs_step[1]; - - } else if (ap_type == CHIP_ID_AP807 && (avs_step[2] < 0x4)) { - /* AP807 - AVS is 10 bits */ - new_wp = avs_step[2]; - new_wp <<= 8; - new_wp |= avs_step[1]; - } - - if (new_wp == 0) - NOTICE("Ignore BAD AVS Override value in EEPROM!\n"); - else - NOTICE("Override AVS by EEPROM value 0x%x\n", new_wp); -#endif /* MARVELL_SVC_TEST */ - return new_wp; -} - -/**************************************************************************** - * SVC flow - v0.10 - * The feature is intended to configure AVS value according to eFuse values - * that are burned individually for each SoC during the test process. - * Primary AVS value is stored in HD efuse and processed on power on - * by the HW engine - * Secondary AVS value is located in LD efuse and contains 4 work points for - * various CPU frequencies. - * The Secondary AVS value is only taken into account if the SW Revision stored - * in the efuse is greater than 0 and the CPU is running in a certain speed. - **************************************************************************** - */ -static void ble_plat_svc_config(void) -{ - uint32_t reg_val, avs_workpoint, freq_pidi_mode; - uint64_t efuse; - uint32_t device_id, single_cluster; - uint16_t svc[4], perr[4], i, sw_ver; - unsigned int ap_type; - - /* Set access to LD0 */ - avs_workpoint = avs_update_from_eeprom(0); - if (avs_workpoint) - goto set_aws_wp; - - /* Set access to LD0 */ - reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); - reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; - mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); - - /* Obtain the value of LD0[125:63] */ - efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); - efuse <<= 32; - efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); - - /* SW Revision: - * Starting from SW revision 1 the SVC flow is supported. - * SW version 0 (efuse not programmed) should follow the - * regular AVS update flow. - */ - sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK; - if (sw_ver < 1) { - NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver); -#if MARVELL_SVC_TEST - NOTICE("SVC_TEST: AVS bypassed\n"); - -#else - ble_plat_avs_config(); -#endif - return; - } - - /* Frequency mode from SAR */ - freq_pidi_mode = SAR_CLOCK_FREQ_MODE( - mmio_read_32( - MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - - /* Decode all SVC work points */ - svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK; - svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK; - svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK; - - /* Fetch AP type to distinguish between AP806 and AP807 */ - ap_type = ble_get_ap_type(); - - if (ap_type != CHIP_ID_AP807) { - svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) - & EFUSE_AP_LD0_WP_MASK; - INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", - svc[0], svc[1], svc[2], svc[3]); - } else { - INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", - svc[0], svc[1], svc[2]); - } - - /* Validate parity of SVC workpoint values */ - for (i = 0; i < 4; i++) { - uint8_t parity, bit; - - perr[i] = 0; - - for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) - parity ^= (svc[i] >> bit) & 1; - - /* Starting from SW version 2, the parity check is mandatory */ - if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) - perr[i] = 1; /* register the error */ - } - - single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); - single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; - - device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - if (device_id == MVEBU_80X0_DEV_ID || - device_id == MVEBU_80X0_CP115_DEV_ID) { - /* A8040/A8020 */ - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1800_DDR_1200_RCLK_1200: - case CPU_1800_DDR_1050_RCLK_1050: - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - break; - case CPU_1600_DDR_1050_RCLK_1050: - case CPU_1600_DDR_900_RCLK_900_2: - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - break; - case CPU_1300_DDR_800_RCLK_800: - case CPU_1300_DDR_650_RCLK_650: - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; - break; - case CPU_2000_DDR_1200_RCLK_1200: - case CPU_2000_DDR_1050_RCLK_1050: - default: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - } - } else if (device_id == MVEBU_70X0_DEV_ID || - device_id == MVEBU_70X0_CP115_DEV_ID) { - /* A7040/A7020/A6040 */ - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - single_cluster == 0 ? "7040" : "7020", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1400_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - } else { - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - } - break; - case CPU_1200_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - } else { - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - } - break; - case CPU_800_DDR_800_RCLK_800: - case CPU_1000_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; - } else { - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - } - break; - case CPU_600_DDR_800_RCLK_800: - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; /* Same for 6040 and 7020 */ - break; - case CPU_1600_DDR_800_RCLK_800: /* 7020 only */ - default: - if (single_cluster) {/* 7020 */ - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - } else - avs_workpoint = 0; - break; - } - } else if (device_id == MVEBU_3900_DEV_ID) { - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - "3900", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1600_DDR_1200_RCLK_1200: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - case CPU_1300_DDR_800_RCLK_800: - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - break; - default: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - } - } else { - ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); - return; - } - - /* Set AVS control if needed */ - if (avs_workpoint == 0) { - ERROR("SVC: AVS work point not changed\n"); - return; - } - - /* Remove parity bit */ - if (ap_type != CHIP_ID_AP807) - avs_workpoint &= 0x7F; - - /* Update WP from EEPROM if needed */ - avs_workpoint = avs_update_from_eeprom(avs_workpoint); - -set_aws_wp: - reg_val = mmio_read_32(AVS_EN_CTRL_REG); - NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n", - (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET, - avs_workpoint); - reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK); - reg_val |= 0x1 << AVS_ENABLE_OFFSET; - reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET; - reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET; - mmio_write_32(AVS_EN_CTRL_REG, reg_val); - return; - -perror: - ERROR("Failed SVC WP[%d] parity check!\n", i); - ERROR("Ignoring the WP values\n"); -} - -#if PLAT_RECOVERY_IMAGE_ENABLE -static int ble_skip_image_i2c(struct skip_image *skip_im) -{ - ERROR("skipping image using i2c is not supported\n"); - /* not supported */ - return 0; -} - -static int ble_skip_image_other(struct skip_image *skip_im) -{ - ERROR("implementation missing for skip image request\n"); - /* not supported, make your own implementation */ - return 0; -} - -static int ble_skip_image_gpio(struct skip_image *skip_im) -{ - unsigned int val; - unsigned int mpp_address = 0; - unsigned int offset = 0; - - switch (skip_im->info.test.cp_ap) { - case(CP): - mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index, - skip_im->info.gpio.num); - if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG) - offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG; - else - offset = skip_im->info.gpio.num; - break; - case(AP): - mpp_address = MVEBU_AP_GPIO_DATA_IN; - offset = skip_im->info.gpio.num; - break; - } - - val = mmio_read_32(mpp_address); - val &= (1 << offset); - if ((!val && skip_im->info.gpio.button_state == HIGH) || - (val && skip_im->info.gpio.button_state == LOW)) { - mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL); - return 1; - } - - return 0; -} - -/* - * This function checks if there's a skip image request: - * return values: - * 1: (true) images request been made. - * 0: (false) no image request been made. - */ -static int ble_skip_current_image(void) -{ - struct skip_image *skip_im; - - /*fetching skip image info*/ - skip_im = (struct skip_image *)plat_marvell_get_skip_image_data(); - - if (skip_im == NULL) - return 0; - - /* check if skipping image request has already been made */ - if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL) - return 0; - - switch (skip_im->detection_method) { - case GPIO: - return ble_skip_image_gpio(skip_im); - case I2C: - return ble_skip_image_i2c(skip_im); - case USER_DEFINED: - return ble_skip_image_other(skip_im); - } - - return 0; -} -#endif - - -int ble_plat_setup(int *skip) -{ - int ret; - unsigned int freq_mode; - - /* Power down unused CPUs */ - plat_marvell_early_cpu_powerdown(); - - /* - * Save the current CCU configuration and make required changes: - * - Allow access to DRAM larger than 4GB - * - Open memory access to all CPn peripherals - */ - ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG); - -#if PLAT_RECOVERY_IMAGE_ENABLE - /* Check if there's a skip request to bootRom recovery Image */ - if (ble_skip_current_image()) { - /* close memory access to all CPn peripherals. */ - ble_plat_mmap_config(MMAP_RESTORE_SAVED); - *skip = 1; - return 0; - } -#endif - /* Do required CP-110 setups for BLE stage */ - cp110_ble_init(MVEBU_CP_REGS_BASE(0)); - - /* Setup AVS */ - ble_plat_svc_config(); - - /* read clk option from sampled-at-reset register */ - freq_mode = - SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - - /* work with PLL clock driver in AP807 */ - if (ble_get_ap_type() == CHIP_ID_AP807) - ap807_clocks_init(freq_mode); - - /* Do required AP setups for BLE stage */ - ap_ble_init(); - - /* Update DRAM topology (scan DIMM SPDs) */ - plat_marvell_dram_update_topology(); - - /* Kick it in */ - ret = dram_init(); - - /* Restore the original CCU configuration before exit from BLE */ - ble_plat_mmap_config(MMAP_RESTORE_SAVED); - - return ret; -} diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c deleted file mode 100644 index 96e95c2..0000000 --- a/plat/marvell/a8k/common/plat_pm.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MVEBU_PRIVATE_UID_REG 0x30 -#define MVEBU_RFU_GLOBL_SW_RST 0x84 -#define MVEBU_CCU_RVBAR(cpu) (MVEBU_REGS_BASE + 0x640 + (cpu * 4)) -#define MVEBU_CCU_CPU_UN_RESET(cpu) (MVEBU_REGS_BASE + 0x650 + (cpu * 4)) - -#define MPIDR_CPU_GET(mpidr) ((mpidr) & MPIDR_CPU_MASK) -#define MPIDR_CLUSTER_GET(mpidr) MPIDR_AFFLVL1_VAL((mpidr)) - -#define MVEBU_GPIO_MASK(index) (1 << (index % 32)) -#define MVEBU_MPP_MASK(index) (0xF << (4 * (index % 8))) -#define MVEBU_GPIO_VALUE(index, value) (value << (index % 32)) - -#define MVEBU_USER_CMD_0_REG (MVEBU_DRAM_MAC_BASE + 0x20) -#define MVEBU_USER_CMD_CH0_OFFSET 28 -#define MVEBU_USER_CMD_CH0_MASK (1 << MVEBU_USER_CMD_CH0_OFFSET) -#define MVEBU_USER_CMD_CH0_EN (1 << MVEBU_USER_CMD_CH0_OFFSET) -#define MVEBU_USER_CMD_CS_OFFSET 24 -#define MVEBU_USER_CMD_CS_MASK (0xF << MVEBU_USER_CMD_CS_OFFSET) -#define MVEBU_USER_CMD_CS_ALL (0xF << MVEBU_USER_CMD_CS_OFFSET) -#define MVEBU_USER_CMD_SR_OFFSET 6 -#define MVEBU_USER_CMD_SR_MASK (0x3 << MVEBU_USER_CMD_SR_OFFSET) -#define MVEBU_USER_CMD_SR_ENTER (0x1 << MVEBU_USER_CMD_SR_OFFSET) -#define MVEBU_MC_PWR_CTRL_REG (MVEBU_DRAM_MAC_BASE + 0x54) -#define MVEBU_MC_AC_ON_DLY_OFFSET 8 -#define MVEBU_MC_AC_ON_DLY_MASK (0xF << MVEBU_MC_AC_ON_DLY_OFFSET) -#define MVEBU_MC_AC_ON_DLY_DEF_VAR (8 << MVEBU_MC_AC_ON_DLY_OFFSET) -#define MVEBU_MC_AC_OFF_DLY_OFFSET 4 -#define MVEBU_MC_AC_OFF_DLY_MASK (0xF << MVEBU_MC_AC_OFF_DLY_OFFSET) -#define MVEBU_MC_AC_OFF_DLY_DEF_VAR (0xC << MVEBU_MC_AC_OFF_DLY_OFFSET) -#define MVEBU_MC_PHY_AUTO_OFF_OFFSET 0 -#define MVEBU_MC_PHY_AUTO_OFF_MASK (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) -#define MVEBU_MC_PHY_AUTO_OFF_EN (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) - -/* this lock synchronize AP multiple cores execution with MSS */ -DEFINE_BAKERY_LOCK(pm_sys_lock); - -/* Weak definitions may be overridden in specific board */ -#pragma weak plat_marvell_get_pm_cfg - -/* AP806 CPU power down /power up definitions */ -enum CPU_ID { - CPU0, - CPU1, - CPU2, - CPU3 -}; - -#define REG_WR_VALIDATE_TIMEOUT (2000) - -#define FEATURE_DISABLE_STATUS_REG \ - (MVEBU_REGS_BASE + 0x6F8230) -#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET 4 -#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK \ - (0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET) - -#ifdef MVEBU_SOC_AP807 - #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 1 - #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 0 -#else - #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 0 - #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 31 -#endif - -#define PWRC_CPUN_CR_REG(cpu_id) \ - (MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10)) -#define PWRC_CPUN_CR_PWR_DN_RQ_MASK \ - (0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET) -#define PWRC_CPUN_CR_ISO_ENABLE_OFFSET 16 -#define PWRC_CPUN_CR_ISO_ENABLE_MASK \ - (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET) -#define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK \ - (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET) - -#define CCU_B_PRCRN_REG(cpu_id) \ - (MVEBU_REGS_BASE + 0x1A50 + \ - ((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4)) -#define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET 0 -#define CCU_B_PRCRN_CPUPORESET_STATIC_MASK \ - (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET) - -/* power switch fingers */ -#define AP807_PWRC_LDO_CR0_REG \ - (MVEBU_REGS_BASE + 0x680000 + 0x100) -#define AP807_PWRC_LDO_CR0_OFFSET 16 -#define AP807_PWRC_LDO_CR0_MASK \ - (0xff << AP807_PWRC_LDO_CR0_OFFSET) -#define AP807_PWRC_LDO_CR0_VAL 0xfc - -/* - * Power down CPU: - * Used to reduce power consumption, and avoid SoC unnecessary temperature rise. - */ -static int plat_marvell_cpu_powerdown(int cpu_id) -{ - uint32_t reg_val; - int exit_loop = REG_WR_VALIDATE_TIMEOUT; - - INFO("Powering down CPU%d\n", cpu_id); - - /* 1. Isolation enable */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 2. Read and check Isolation enabled - verify bit set to 1 */ - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && - exit_loop > 0); - - /* 3. Switch off CPU power */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 4. Read and check Switch Off - verify bit set to 0 */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweroff_error; - - /* 5. De-Assert power ready */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 6. Assert CPU POR reset */ - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK; - mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); - - /* 7. Read and poll on Validate the CPU is out of reset */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - exit_loop--; - } while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweroff_error; - - INFO("Successfully powered down CPU%d\n", cpu_id); - - return 0; - -cpu_poweroff_error: - ERROR("ERROR: Can't power down CPU%d\n", cpu_id); - return -1; -} - -/* - * Power down CPUs 1-3 at early boot stage, - * to reduce power consumption and SoC temperature. - * This is triggered by BLE prior to DDR initialization. - * - * Note: - * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage, - * which is triggered by PSCI ops (pwr_domain_on). - */ -int plat_marvell_early_cpu_powerdown(void) -{ - uint32_t cpu_cluster_status = - mmio_read_32(FEATURE_DISABLE_STATUS_REG) & - FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK; - /* if cpu_cluster_status bit is set, - * that means we have only single cluster - */ - int cluster_count = cpu_cluster_status ? 1 : 2; - - INFO("Powering off unused CPUs\n"); - - /* CPU1 is in AP806 cluster-0, which always exists, so power it down */ - if (plat_marvell_cpu_powerdown(CPU1) == -1) - return -1; - - /* - * CPU2-3 are in AP806 2nd cluster (cluster-1), - * which doesn't exists in dual-core systems. - * so need to check if we have dual-core (single cluster) - * or quad-code (2 clusters) - */ - if (cluster_count == 2) { - /* CPU2-3 are part of 2nd cluster */ - if (plat_marvell_cpu_powerdown(CPU2) == -1) - return -1; - if (plat_marvell_cpu_powerdown(CPU3) == -1) - return -1; - } - - return 0; -} - -/* - * Power up CPU - part of Linux boot stage - */ -static int plat_marvell_cpu_powerup(u_register_t mpidr) -{ - uint32_t reg_val; - int cpu_id = MPIDR_CPU_GET(mpidr), - cluster = MPIDR_CLUSTER_GET(mpidr); - int exit_loop = REG_WR_VALIDATE_TIMEOUT; - - /* calculate absolute CPU ID */ - cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id; - - INFO("Powering on CPU%d\n", cpu_id); - -#ifdef MVEBU_SOC_AP807 - /* Activate 2 power switch fingers */ - reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG); - reg_val &= ~(AP807_PWRC_LDO_CR0_MASK); - reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET); - mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val); - udelay(100); -#endif - - /* 1. Switch CPU power ON */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 2. Wait for CPU on, up to 100 uSec: */ - udelay(100); - - /* 3. Assert power ready */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 4. Read & Validate power ready - * used in order to generate 16 Host CPU cycles - */ - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) && - exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweron_error; - - /* 5. Isolation disable */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 6. Read and check Isolation enabled - verify bit set to 1 */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && - exit_loop > 0); - - /* 7. De Assert CPU POR reset & Core reset */ - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET; - mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); - - /* 8. Read & Validate CPU POR reset */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) && - exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweron_error; - - INFO("Successfully powered on CPU%d\n", cpu_id); - - return 0; - -cpu_poweron_error: - ERROR("ERROR: Can't power up CPU%d\n", cpu_id); - return -1; -} - -static int plat_marvell_cpu_on(u_register_t mpidr) -{ - int cpu_id; - int cluster; - - /* Set barierr */ - dsbsy(); - - /* Get cpu number - use CPU ID */ - cpu_id = MPIDR_CPU_GET(mpidr); - - /* Get cluster number - use affinity level 1 */ - cluster = MPIDR_CLUSTER_GET(mpidr); - - /* Set CPU private UID */ - mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4); - - /* Set the cpu start address to BL1 entry point (align to 0x10000) */ - mmio_write_32(MVEBU_CCU_RVBAR(cpu_id), - PLAT_MARVELL_CPU_ENTRY_ADDR >> 16); - - /* Get the cpu out of reset */ - mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001); - - return 0; -} - -/***************************************************************************** - * A8K handler called to check the validity of the power state - * parameter. - ***************************************************************************** - */ -static int a8k_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - int pstate = psci_get_pstate_type(power_state); - int pwr_lvl = psci_get_pstate_pwrlvl(power_state); - int i; - - if (pwr_lvl > PLAT_MAX_PWR_LVL) - return PSCI_E_INVALID_PARAMS; - - /* Sanity check the requested state */ - if (pstate == PSTATE_TYPE_STANDBY) { - /* - * It's possible to enter standby only on power level 0 - * Ignore any other power level. - */ - if (pwr_lvl != MARVELL_PWR_LVL0) - return PSCI_E_INVALID_PARAMS; - - req_state->pwr_domain_state[MARVELL_PWR_LVL0] = - MARVELL_LOCAL_STATE_RET; - } else { - for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++) - req_state->pwr_domain_state[i] = - MARVELL_LOCAL_STATE_OFF; - } - - /* - * We expect the 'state id' to be zero. - */ - if (psci_get_pstate_id(power_state)) - return PSCI_E_INVALID_PARAMS; - - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A8K handler called when a CPU is about to enter standby. - ***************************************************************************** - */ -static void a8k_cpu_standby(plat_local_state_t cpu_state) -{ - if (!is_pm_fw_running()) { - ERROR("%s: needs to be implemented\n", __func__); - panic(); - } -} - -/***************************************************************************** - * A8K handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ***************************************************************************** - */ -static int a8k_pwr_domain_on(u_register_t mpidr) -{ - /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */ - plat_marvell_cpu_powerup(mpidr); - - if (is_pm_fw_running()) { - unsigned int target = - ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2)); - - /* - * pm system synchronization - used to synchronize - * multiple core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU ON IPC Message to MSS */ - mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_ON | target); - } else { - /* proprietary CPU ON exection flow */ - plat_marvell_cpu_on(mpidr); - } - - return 0; -} - -/***************************************************************************** - * A8K handler called to validate the entry point. - ***************************************************************************** - */ -static int a8k_validate_ns_entrypoint(uintptr_t entrypoint) -{ - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A8K 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. - ***************************************************************************** - */ -static void a8k_pwr_domain_off(const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - unsigned int idx = plat_my_core_pos(); - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - /* pm system synchronization - used to synchronize multiple - * core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU OFF IPC Message to MSS */ - mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_OFF); - } else { - INFO("%s: is not supported without SCP\n", __func__); - } -} - -/* Get PM config to power off the SoC */ -void *plat_marvell_get_pm_cfg(void) -{ - return NULL; -} - -/* - * This function should be called on restore from - * "suspend to RAM" state when the execution flow - * has to bypass BootROM image to RAM copy and speed up - * the system recovery - * - */ -static void plat_marvell_exit_bootrom(void) -{ - marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE); -} - -/* - * Prepare for the power off of the system via GPIO - */ -static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg, - register_t *gpio_addr, - register_t *gpio_data) -{ - unsigned int gpio; - unsigned int idx; - unsigned int shift; - unsigned int reg; - unsigned int addr; - gpio_info_t *info; - unsigned int tog_bits; - - assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) && - (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP)); - - /* Prepare GPIOs for PMIC */ - for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { - info = &pm_cfg->cfg.gpio.info[gpio]; - /* Set PMIC GPIO to output mode */ - reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN( - info->cp_index, info->gpio_index)); - mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN( - info->cp_index, info->gpio_index), - reg & ~MVEBU_GPIO_MASK(info->gpio_index)); - - /* Set the appropriate MPP to GPIO mode */ - reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index, - info->gpio_index)); - mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index, - info->gpio_index), - reg & ~MVEBU_MPP_MASK(info->gpio_index)); - } - - /* Wait for MPP & GPIO pre-configurations done */ - mdelay(pm_cfg->cfg.gpio.delay_ms); - - /* Toggle the GPIO values, and leave final step to be triggered - * after DDR self-refresh is enabled - */ - for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) { - tog_bits = pm_cfg->cfg.gpio.seq[idx]; - - /* The GPIOs must be within same GPIO register, - * thus could get the original value by first GPIO - */ - info = &pm_cfg->cfg.gpio.info[0]; - reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT( - info->cp_index, info->gpio_index)); - addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index); - - for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { - shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32; - if (GPIO_LOW == (tog_bits & (1 << gpio))) - reg &= ~(1 << shift); - else - reg |= (1 << shift); - } - - /* Set the GPIO register, for last step just store - * register address and values to system registers - */ - if (idx < pm_cfg->cfg.gpio.step_count - 1) { - mmio_write_32(MVEBU_CP_GPIO_DATA_OUT( - info->cp_index, info->gpio_index), reg); - mdelay(pm_cfg->cfg.gpio.delay_ms); - } else { - /* Save GPIO register and address values for - * finishing the power down operation later - */ - *gpio_addr = addr; - *gpio_data = reg; - } - } -} - -/* - * Prepare for the power off of the system - */ -static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg, - register_t *addr, register_t *data) -{ - switch (pm_cfg->type) { - case PMIC_GPIO: - plat_marvell_power_off_gpio(pm_cfg, addr, data); - break; - default: - break; - } -} - -/***************************************************************************** - * A8K handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - unsigned int idx; - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - idx = plat_my_core_pos(); - - /* pm system synchronization - used to synchronize multiple - * core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU Suspend IPC Message to MSS */ - mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND); - } else { - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - INFO("Suspending to RAM\n"); - - marvell_console_runtime_end(); - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE; - mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom; - -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + - MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), - 2 * sizeof(uintptr_t)); -#endif - /* Flush and disable LLC before going off-power */ - llc_disable(0); - - isb(); - /* - * Do not halt here! - * The function must return for allowing the caller function - * psci_power_up_finish() to do the proper context saving and - * to release the CPU lock. - */ - } -} - -/***************************************************************************** - * A8K 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. - ***************************************************************************** - */ -static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); - - if (is_pm_fw_running()) { - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH); - } -} - -/***************************************************************************** - * A8K 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. - ***************************************************************************** - */ -static void a8k_pwr_domain_suspend_finish( - const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - gicv2_cpuif_enable(); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH); - } else { - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* Only primary CPU requres platform init */ - if (!plat_my_core_pos()) { - /* Initialize the console to provide - * early debug support - */ - marvell_console_runtime_init(); - - bl31_plat_arch_setup(); - marvell_bl31_platform_setup(); - /* - * Remove suspend to RAM marker from the mailbox - * for treating a regular reset as a cold boot - */ - mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0; - mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0; -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + - MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), - 2 * sizeof(uintptr_t)); -#endif - } - } -} - -/***************************************************************************** - * 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. - ***************************************************************************** - */ -static void a8k_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; -} - -static void -__dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) -{ - struct power_off_method *pm_cfg; - unsigned int srcmd; - unsigned int sdram_reg; - register_t gpio_data = 0, gpio_addr = 0; - - if (is_pm_fw_running()) { - psci_power_down_wfi(); - panic(); - } - - pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg(); - - /* Prepare for power off */ - plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data); - - /* First step to enable DDR self-refresh - * to keep the data during suspend - */ - mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1); - - /* Save DDR self-refresh second step register - * and value to be issued later - */ - sdram_reg = MVEBU_USER_CMD_0_REG; - srcmd = mmio_read_32(sdram_reg); - srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK | - MVEBU_USER_CMD_SR_MASK); - srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL | - MVEBU_USER_CMD_SR_ENTER); - - /* - * Wait for DRAM is done using registers access only. - * At this stage any access to DRAM (procedure call) will - * release it from the self-refresh mode - */ - __asm__ volatile ( - /* Align to a cache line */ - " .balign 64\n\t" - - /* Enter self refresh */ - " str %[srcmd], [%[sdram_reg]]\n\t" - - /* - * Wait 100 cycles for DDR to enter self refresh, by - * doing 50 times two instructions. - */ - " mov x1, #50\n\t" - "1: subs x1, x1, #1\n\t" - " bne 1b\n\t" - - /* Issue the command to trigger the SoC power off */ - " str %[gpio_data], [%[gpio_addr]]\n\t" - - /* Trap the processor */ - " b .\n\t" - : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg), - [gpio_addr] "r" (gpio_addr), [gpio_data] "r" (gpio_data) - : "x1"); - - panic(); -} - -/***************************************************************************** - * A8K handlers to shutdown/reboot the system - ***************************************************************************** - */ - -/* Set a weak stub for platforms that don't configure system power off */ -#pragma weak system_power_off -int system_power_off(void) -{ - return 0; -} - -static void __dead2 a8k_system_off(void) -{ - /* Call the platform specific system power off function */ - system_power_off(); - - /* board doesn't have a system off implementation */ - ERROR("%s: needs to be implemented\n", __func__); - panic(); -} - -void plat_marvell_system_reset(void) -{ - mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0); -} - -static void __dead2 a8k_system_reset(void) -{ - plat_marvell_system_reset(); - - /* we 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 = a8k_cpu_standby, - .pwr_domain_on = a8k_pwr_domain_on, - .pwr_domain_off = a8k_pwr_domain_off, - .pwr_domain_suspend = a8k_pwr_domain_suspend, - .pwr_domain_on_finish = a8k_pwr_domain_on_finish, - .get_sys_suspend_power_state = a8k_get_sys_suspend_power_state, - .pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish, - .pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi, - .system_off = a8k_system_off, - .system_reset = a8k_system_reset, - .validate_power_state = a8k_validate_power_state, - .validate_ns_entrypoint = a8k_validate_ns_entrypoint -}; diff --git a/plat/marvell/a8k/common/plat_pm_trace.c b/plat/marvell/a8k/common/plat_pm_trace.c deleted file mode 100644 index f589ff3..0000000 --- a/plat/marvell/a8k/common/plat_pm_trace.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -#ifdef PM_TRACE_ENABLE - -/* core trace APIs */ -core_trace_func funcTbl[PLATFORM_CORE_COUNT] = { - pm_core_0_trace, - pm_core_1_trace, - pm_core_2_trace, - pm_core_3_trace}; - -/***************************************************************************** - * pm_core0_trace - * pm_core1_trace - * pm_core2_trace - * pm_core_3trace - * - * This functions set trace info into core cyclic trace queue in MSS SRAM - * memory space - ***************************************************************************** - */ -void pm_core_0_trace(unsigned int trace) -{ - unsigned int current_position_core_0 = - mmio_read_32(AP_MSS_ATF_CORE_0_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_0_INFO_BASE + - (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_0_INFO_TRACE + - (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_0_CTRL_BASE, - ((current_position_core_0 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_1_trace(unsigned int trace) -{ - unsigned int current_position_core_1 = - mmio_read_32(AP_MSS_ATF_CORE_1_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_1_INFO_BASE + - (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_1_INFO_TRACE + - (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_1_CTRL_BASE, - ((current_position_core_1 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_2_trace(unsigned int trace) -{ - unsigned int current_position_core_2 = - mmio_read_32(AP_MSS_ATF_CORE_2_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_2_INFO_BASE + - (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_2_INFO_TRACE + - (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_2_CTRL_BASE, - ((current_position_core_2 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_3_trace(unsigned int trace) -{ - unsigned int current_position_core_3 = - mmio_read_32(AP_MSS_ATF_CORE_3_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_3_INFO_BASE + - (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_3_INFO_TRACE + - (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_3_CTRL_BASE, - ((current_position_core_3 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} -#endif /* PM_TRACE_ENABLE */ diff --git a/plat/marvell/a8k/common/plat_thermal.c b/plat/marvell/a8k/common/plat_thermal.c deleted file mode 100644 index a2fc0d0..0000000 --- a/plat/marvell/a8k/common/plat_thermal.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include - -#define THERMAL_TIMEOUT 1200 - -#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET 0 -#define THERMAL_SEN_CTRL_LSB_STRT_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET) -#define THERMAL_SEN_CTRL_LSB_RST_OFFSET 1 -#define THERMAL_SEN_CTRL_LSB_RST_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET) -#define THERMAL_SEN_CTRL_LSB_EN_OFFSET 2 -#define THERMAL_SEN_CTRL_LSB_EN_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET) - -#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET 16 -#define THERMAL_SEN_CTRL_STATS_VALID_MASK \ - (0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET) -#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET 0 -#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK \ - (0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET) - -#define THERMAL_SEN_OUTPUT_MSB 512 -#define THERMAL_SEN_OUTPUT_COMP 1024 - -struct tsen_regs { - uint32_t ext_tsen_ctrl_lsb; - uint32_t ext_tsen_ctrl_msb; - uint32_t ext_tsen_status; -}; - -static int ext_tsen_probe(struct tsen_config *tsen_cfg) -{ - uint32_t reg, timeout = 0; - struct tsen_regs *base; - - if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) { - ERROR("initial thermal sensor configuration is missing\n"); - return -1; - } - base = (struct tsen_regs *)tsen_cfg->regs_base; - - INFO("initializing thermal sensor\n"); - - /* initialize thermal sensor hardware reset once */ - reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb); - reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */ - reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */ - reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */ - mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg); - - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 && - timeout < THERMAL_TIMEOUT) { - udelay(100); - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - timeout++; - } - - if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) { - ERROR("thermal sensor is not ready\n"); - return -1; - } - - tsen_cfg->tsen_ready = 1; - - VERBOSE("thermal sensor was initialized\n"); - - return 0; -} - -static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp) -{ - uint32_t reg; - struct tsen_regs *base; - - if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) { - ERROR("thermal sensor was not initialized\n"); - return -1; - } - base = (struct tsen_regs *)tsen_cfg->regs_base; - - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >> - THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET); - - /* - * TSEN output format is signed as a 2s complement number - * ranging from-512 to +511. when MSB is set, need to - * calculate the complement number - */ - if (reg >= THERMAL_SEN_OUTPUT_MSB) - reg -= THERMAL_SEN_OUTPUT_COMP; - - if (tsen_cfg->tsen_divisor == 0) { - ERROR("thermal sensor divisor cannot be zero\n"); - return -1; - } - - *temp = ((tsen_cfg->tsen_gain * ((int)reg)) + - tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor; - - return 0; -} - -static struct tsen_config tsen_cfg = { - .tsen_offset = 153400, - .tsen_gain = 425, - .tsen_divisor = 1000, - .tsen_ready = 0, - .regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE, - .ptr_tsen_probe = ext_tsen_probe, - .ptr_tsen_read = ext_tsen_read -}; - -struct tsen_config *marvell_thermal_config_get(void) -{ - return &tsen_cfg; -} diff --git a/plat/marvell/armada/a3700/a3700/board/pm_src.c b/plat/marvell/armada/a3700/a3700/board/pm_src.c new file mode 100644 index 0000000..d6eca5d --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/a3700/mvebu_def.h b/plat/marvell/armada/a3700/a3700/mvebu_def.h new file mode 100644 index 0000000..dad1085 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c new file mode 100644 index 0000000..6862a86 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/a3700/platform.mk b/plat/marvell/armada/a3700/a3700/platform.mk new file mode 100644 index 0000000..bd9464a --- /dev/null +++ b/plat/marvell/armada/a3700/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/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 new file mode 100644 index 0000000..36865a8 --- /dev/null +++ b/plat/marvell/armada/a3700/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 := 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 new file mode 100644 index 0000000..dd46beb --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/a3700_sip_svc.c b/plat/marvell/armada/a3700/common/a3700_sip_svc.c new file mode 100644 index 0000000..e8ac5fc --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/aarch64/a3700_common.c b/plat/marvell/armada/a3700/common/aarch64/a3700_common.c new file mode 100644 index 0000000..6351285 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S new file mode 100644 index 0000000..90d76f0 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/dram_win.c b/plat/marvell/armada/a3700/common/dram_win.c new file mode 100644 index 0000000..694f6d4 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/a3700_plat_def.h b/plat/marvell/armada/a3700/common/include/a3700_plat_def.h new file mode 100644 index 0000000..c7f40ad --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/a3700_pm.h b/plat/marvell/armada/a3700/common/include/a3700_pm.h new file mode 100644 index 0000000..cc6cf43 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/ddr_info.h b/plat/marvell/armada/a3700/common/include/ddr_info.h new file mode 100644 index 0000000..254f78c --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/dram_win.h b/plat/marvell/armada/a3700/common/include/dram_win.h new file mode 100644 index 0000000..26a0137 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/io_addr_dec.h b/plat/marvell/armada/a3700/common/include/io_addr_dec.h new file mode 100644 index 0000000..42ef30b --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/plat_macros.S b/plat/marvell/armada/a3700/common/include/plat_macros.S new file mode 100644 index 0000000..f689b4f --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/include/platform_def.h b/plat/marvell/armada/a3700/common/include/platform_def.h new file mode 100644 index 0000000..e6660d4 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/platform_def.h @@ -0,0 +1,232 @@ +/* + * 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 new file mode 100644 index 0000000..b27633c --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/marvell_plat_config.c b/plat/marvell/armada/a3700/common/marvell_plat_config.c new file mode 100644 index 0000000..3bf3d96 --- /dev/null +++ b/plat/marvell/armada/a3700/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/a3700/common/plat_pm.c b/plat/marvell/armada/a3700/common/plat_pm.c new file mode 100644 index 0000000..f8ce6fe --- /dev/null +++ b/plat/marvell/armada/a3700/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/dram_port.c b/plat/marvell/armada/a8k/a70x0/board/dram_port.c new file mode 100644 index 0000000..4fca7e3 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/board/dram_port.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +/* + * This function may modify the default DRAM parameters + * based on information received from SPD or bootloader + * configuration located on non volatile storage + */ +void plat_marvell_dram_update_topology(void) +{ +} + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { +/* FIXME: MISL board 2CS 4Gb x8 devices of micron - 2133P */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0} }, + SPEED_BIN_DDR_2133P, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_4GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} diff --git a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c new file mode 100644 index 0000000..d126f55 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP0 SPI1 CS0 Direct Mode access */ + {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, +}; + +int marvell_get_amb_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base) +{ + *win = amb_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(amb_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * IO_WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { +#ifndef IMAGE_BLE + /* MCI 0 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, + /* MCI 1 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, +#endif +}; + +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + return PIDI_TID; +} + +int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = io_win_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(io_win_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * IOB Configuration + ***************************************************************************** + */ +struct addr_map_win iob_memory_map[] = { + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + {0x00000000c0000000, 0x30000000, PEX2_TID}, + {0x0000000800000000, 0x100000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = iob_memory_map; + *size = ARRAY_SIZE(iob_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { /* IO window */ +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ +#endif +}; + +uint32_t marvell_get_ccu_gcr_target(int ap) +{ + return DRAM_0_TID; +} + +int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +#ifdef IMAGE_BLE +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a70x0/mvebu_def.h b/plat/marvell/armada/a8k/a70x0/mvebu_def.h new file mode 100644 index 0000000..72bca12 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/mvebu_def.h @@ -0,0 +1,15 @@ +/* + * 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 + +#define CP_COUNT 1 /* A70x0 has single CP0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a70x0/platform.mk b/plat/marvell/armada/a8k/a70x0/platform.mk new file mode 100644 index 0000000..a77e349 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 1 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c new file mode 100644 index 0000000..aecf6c5 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +/* + * This function may modify the default DRAM parameters + * based on information received from SPD or bootloader + * configuration located on non volatile storage + */ +void plat_marvell_dram_update_topology(void) +{ +} + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { +/* FIXME: MISL board 2CS 8Gb x8 devices of micron - 2133P */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0} }, + SPEED_BIN_DDR_2400T, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_8GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} 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 new file mode 100644 index 0000000..f8a1c40 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win *amb_memory_map; + +int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = amb_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(amb_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * IO WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { +#ifndef IMAGE_BLE + /* MCI 0 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, + /* MCI 1 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, +#endif +}; + +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + return PIDI_TID; +} + +int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = io_win_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(io_win_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * IOB Configuration + ***************************************************************************** + */ +struct addr_map_win iob_memory_map[] = { + /* PEX0_X4 window */ + {0x00000000f6000000, 0x6000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x200000000, PEX0_TID}, +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = iob_memory_map; + *size = ARRAY_SIZE(iob_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */ +#endif +}; + +uint32_t marvell_get_ccu_gcr_target(int ap) +{ + return DRAM_0_TID; +} + +int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +#ifdef IMAGE_BLE + +struct pci_hw_cfg *plat_get_pcie_hw_data(void) +{ + return NULL; +} + +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h new file mode 100644 index 0000000..cedf323 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h @@ -0,0 +1,31 @@ +/* + * 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 + +#define CP_COUNT 1 /* A70x0 has single CP0 */ + +/*********************************************************************** + * Required platform porting definitions common to all + * Management Compute SubSystems (MSS) + *********************************************************************** + */ +/* + * Load address of SCP_BL2 + * SCP_BL2 is loaded to the same place as BL31. + * Once SCP_BL2 is transferred to the SCP, + * it is discarded and BL31 is loaded over the top. + */ +#ifdef SCP_IMAGE +#define SCP_BL2_BASE BL31_BASE +#endif + + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/platform.mk b/plat/marvell/armada/a8k/a70x0_amc/platform.mk new file mode 100644 index 0000000..a77e349 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 1 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c new file mode 100644 index 0000000..02f4ffb --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0) +#define MVEBU_AP_MPP_CTRL4_OFFS 16 +#define MVEBU_AP_MPP_CTRL5_OFFS 20 +#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3 +#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3 + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { + /* MISL board with 1CS 8Gb x4 devices of Micron 2400T */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + /* TODO: double check if the speed bin is 2400T */ + SPEED_BIN_DDR_2400T, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_8GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_SPD, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +static void mpp_config(void) +{ + uintptr_t reg; + uint32_t val; + + reg = MVEBU_CP_MPP_REGS(0, 4); + /* configure CP0 MPP 37 and 38 to i2c */ + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << + MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << + MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); +} + +/* + * This function may modify the default DRAM parameters + * based on information received from SPD or bootloader + * configuration located on non volatile storage + */ +void plat_marvell_dram_update_topology(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + + /* initialize i2c */ + i2c_init((void *)MVEBU_CP0_I2C_BASE); + + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} diff --git a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c new file mode 100644 index 0000000..7901dd2 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP1 SPI1 CS0 Direct Mode access */ + {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, +}; + +int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = amb_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(amb_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * IO WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { + /* CP1 (MCI0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, +#ifndef IMAGE_BLE + /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x2000000, MCI_0_TID}, + /* PCIe1 on CP1*/ + {0x00000000fb000000, 0x1000000, MCI_0_TID}, + /* PCIe2 on CP1*/ + {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* MCI 0 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, + /* MCI 1 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, +#endif +}; + +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + return PIDI_TID; +} + +int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = io_win_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(io_win_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * IOB Configuration + ***************************************************************************** + */ +struct addr_map_win iob_memory_map_cp0[] = { + /* CP0 */ + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x100000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + /* CP1 */ + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, + /* PEX1_X1 window */ + {0x00000000fb000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000fc000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000fa000000, 0x1000000, PEX0_TID} +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ +#endif +}; + +uint32_t marvell_get_ccu_gcr_target(int ap) +{ + return DRAM_0_TID; +} + +int marvell_get_ccu_memory_map(int ap, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * SoC PM configuration + ***************************************************************************** + */ +/* CP GPIO should be used and the GPIOs should be within same GPIO register */ +struct power_off_method pm_cfg = { + .type = PMIC_GPIO, + .cfg.gpio.pin_count = 1, + .cfg.gpio.info = {{0, 35} }, + .cfg.gpio.step_count = 7, + .cfg.gpio.seq = {1, 0, 1, 0, 1, 0, 1}, + .cfg.gpio.delay_ms = 10, +}; + +void *plat_marvell_get_pm_cfg(void) +{ + /* Return the PM configurations */ + return &pm_cfg; +} + +/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ +#else +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h new file mode 100644 index 0000000..abd85b5 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PHY_PORTING_LAYER_H +#define PHY_PORTING_LAYER_H + +#define MAX_LANE_NR 6 + +static const struct xfi_params + xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 */ + { 0 }, /* Comphy1 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, + .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, + .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, + .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, + .valid = 0x1 }, /* Comphy2 */ + { 0 }, /* Comphy3 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, + .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, + .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, + .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, + .valid = 0x1 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + + /* CP 1 */ + { + { 0 }, /* Comphy0 */ + { 0 }, /* Comphy1 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, + .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, + .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, + .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, + .valid = 0x1 }, /* Comphy2 */ + { 0 }, /* Comphy3 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .g1_amp = 0x1c, .g1_emph = 0xe, + .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x1, .g1_tx_emph = 0x0, + .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, + .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, + .valid = 0x1 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + }, +}; + +static const struct sata_params + sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, + .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, + .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, + .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, + .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, + .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, + .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, + .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, + .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, + .g3_rx_selmupi = 0x2, + .valid = 0x1 + }, /* Comphy1 */ + { 0 }, /* Comphy2 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, + .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, + .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, + .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, + .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, + .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, + .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, + .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, + .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, + .g3_rx_selmupi = 0x2, + .valid = 0x1 + }, /* Comphy3 */ + { 0 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + + /* CP 1 */ + { + { 0 }, /* Comphy0 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, + .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, + .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, + .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, + .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, + .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, + .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, + .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, + .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, + .g3_rx_selmupi = 0x2, + .valid = 0x1 + }, /* Comphy1 */ + { 0 }, /* Comphy2 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, + .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, + .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, + .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, + .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, + .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, + .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, + .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, + .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, + .g3_rx_selmupi = 0x2, + .valid = 0x1 + }, /* Comphy3 */ + { 0 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + + }, + }, +}; +#endif /* PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/armada/a8k/a80x0/mvebu_def.h b/plat/marvell/armada/a8k/a80x0/mvebu_def.h new file mode 100644 index 0000000..3fa119a --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/mvebu_def.h @@ -0,0 +1,17 @@ +/* + * 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 + +#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */ +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a80x0/platform.mk b/plat/marvell/armada/a8k/a80x0/platform.mk new file mode 100644 index 0000000..56c4117 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/platform.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 2 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk +PLAT_INCLUDES += -Iplat/marvell/armada/a8k/a80x0/board diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c new file mode 100644 index 0000000..2580852 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { + /* Board with 1CS 8Gb x4 devices of Micron 2400T */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + /* TODO: double check if the speed bin is 2400T */ + SPEED_BIN_DDR_2400T, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_8GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_64BIT_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_SPD, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +static void mpp_config(void) +{ + uint32_t val; + uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4); + + /* configure CP0 MPP 37 and 38 to i2c */ + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); +} + +/* + * This function may modify the default DRAM parameters + * based on information received from SPD or bootloader + * configuration located on non volatile storage + */ +void plat_marvell_dram_update_topology(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + /* initialize the i2c */ + i2c_init((void *)MVEBU_CP0_I2C_BASE); + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} 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 new file mode 100644 index 0000000..fa4e144 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * GPIO Configuration + ***************************************************************************** + */ +#define MPP_CONTROL_REGISTER 0xf2440018 +#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000 +#define GPIO_DATA_OUT1_REGISTER 0xf2440140 +#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144 +#define GPIO52_MASK 0x100000 + +/* Reset PCIe via GPIO number 52 */ +int marvell_gpio_config(void) +{ + uint32_t reg; + + reg = mmio_read_32(MPP_CONTROL_REGISTER); + reg |= MPP_CONTROL_MPP_SEL_52_MASK; + mmio_write_32(MPP_CONTROL_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER); + reg |= GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER); + reg &= ~GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg); + udelay(100); + + return 0; +} + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP1 SPI1 CS0 Direct Mode access */ + {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, +}; + +int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = amb_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(amb_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * IO WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { + /* CP1 (MCI0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, +#ifndef IMAGE_BLE + /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x2000000, MCI_0_TID}, + /* PCIe1 on CP1*/ + {0x00000000fb000000, 0x1000000, MCI_0_TID}, + /* PCIe2 on CP1*/ + {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* MCI 0 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, + /* MCI 1 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, +#endif +}; + +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + return PIDI_TID; +} + +int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = io_win_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(io_win_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * IOB Configuration + ***************************************************************************** + */ +struct addr_map_win iob_memory_map_cp0[] = { + /* CP0 */ + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x100000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + /* CP1 */ + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, + /* PEX1_X1 window */ + {0x00000000fb000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000fc000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000fa000000, 0x1000000, PEX0_TID} +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ +#endif +}; + +uint32_t marvell_get_ccu_gcr_target(int ap) +{ + return DRAM_0_TID; +} + +int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ + +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +void *plat_marvell_get_skip_image_data(void) +{ + /* No recovery button on A8k-MCBIN board */ + return NULL; +} diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h new file mode 100644 index 0000000..3fa119a --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h @@ -0,0 +1,17 @@ +/* + * 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 + +#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */ +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk new file mode 100644 index 0000000..d962b3d --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 2 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk new file mode 100644 index 0000000..471bc82 --- /dev/null +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -0,0 +1,130 @@ +# +# Copyright (C) 2016 - 2020 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +include tools/marvell/doimage/doimage.mk + +PLAT_FAMILY := a8k +PLAT_FAMILY_BASE := plat/marvell/armada/$(PLAT_FAMILY) +PLAT_INCLUDE_BASE := include/plat/marvell/armada/$(PLAT_FAMILY) +PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common +MARVELL_DRV_BASE := drivers/marvell +MARVELL_COMMON_BASE := plat/marvell/armada/common + +MARVELL_SVC_TEST := 0 +$(eval $(call add_define,MARVELL_SVC_TEST)) + +ERRATA_A72_859971 := 1 + +# Enable MSS support for a8k family +MSS_SUPPORT := 1 + +# Disable EL3 cache for power management +BL31_CACHE_DISABLE := 0 +$(eval $(call add_define,BL31_CACHE_DISABLE)) + +$(eval $(call add_define,PCI_EP_SUPPORT)) +$(eval $(call assert_boolean,PCI_EP_SUPPORT)) + +AP_NUM := 1 +$(eval $(call add_define,AP_NUM)) + +DOIMAGEPATH ?= tools/marvell/doimage +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin +DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) + +# Check whether to build system_power.c for the platform +ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") +SYSTEM_POWER_SUPPORT = 1 +else +SYSTEM_POWER_SUPPORT = 0 +endif + +# This define specifies DDR type for BLE +$(eval $(call add_define,CONFIG_DDR4)) + +MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \ + drivers/ti/uart/aarch64/16550_console.S + +BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \ + $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c + +BLE_SOURCES := drivers/mentor/i2c/mi2cv.c \ + $(PLAT_COMMON_BASE)/plat_ble_setup.c \ + $(MARVELL_MOCHI_DRV) \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(MARVELL_DRV_BASE)/ap807_clocks_init.c \ + $(MARVELL_DRV_BASE)/thermal.c \ + $(PLAT_COMMON_BASE)/plat_thermal.c \ + $(BLE_PORTING_SOURCES) \ + $(MARVELL_DRV_BASE)/ccu.c \ + $(MARVELL_DRV_BASE)/io_win.c + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a72.S + +MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ + $(MARVELL_DRV_BASE)/iob.c \ + $(MARVELL_DRV_BASE)/mci.c \ + $(MARVELL_DRV_BASE)/amb_adec.c \ + $(MARVELL_DRV_BASE)/ccu.c \ + $(MARVELL_DRV_BASE)/cache_llc.c \ + $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ + $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +ifeq ($(SYSTEM_POWER_SUPPORT),1) +BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c +endif + +BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(PLAT_COMMON_BASE)/plat_bl31_setup.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv2.c \ + $(MARVELL_COMMON_BASE)/mrvl_sip_svc.c \ + $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ + $(BL31_PORTING_SOURCES) \ + $(MARVELL_DRV) \ + $(MARVELL_MOCHI_DRV) \ + $(MARVELL_GIC_SOURCES) + +# Add trace functionality for PM +BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c + +# Force builds with BL2 image on a80x0 platforms +ifndef SCP_BL2 + $(error "Error: SCP_BL2 image is mandatory for a8k family") +endif + +# MSS (SCP) build +include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk + +# BLE (ROM context execution code, AKA binary extension) +BLE_PATH ?= $(PLAT_COMMON_BASE)/ble + +include ${BLE_PATH}/ble.mk +$(eval $(call MAKE_BL,e)) + +mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin + $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) + $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) + ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} + diff --git a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c new file mode 100644 index 0000000..7c2bf31 --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c @@ -0,0 +1,64 @@ +/* + * 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_BLE +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/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c new file mode 100644 index 0000000..06dc841 --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) +#define MVEBU_IO_AFFINITY (0xF00) + + +static void plat_enable_affinity(void) +{ + int cluster_id; + int affinity; + + /* set CPU Affinity */ + cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT; + affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id)); + mmio_write_32(CCU_HTC_ASET, affinity); + + /* set barier */ + isb(); +} + +void marvell_psci_arch_init(int die_index) +{ +#if LLC_ENABLE + /* check if LLC is in exclusive mode + * as L2 is configured to UniqueClean eviction + * (in a8k reset handler) + */ + if (llc_is_exclusive(0) == 0) + ERROR("LLC should be configured to exclusice mode\n"); +#endif + + /* Enable Affinity */ + plat_enable_affinity(); +} diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S new file mode 100644 index 0000000..fadc4c2 --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl plat_reset_handler + + /* ----------------------------------------------------- + * 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 a cold and warm boot + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * + * --------------------------------------------------------------------- + */ +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, MVEBU_MAILBOX_MAGIC_NUM + cmp x1, x2 + beq warm_boot /* If compare failed, return 0, i.e. cold boot */ + mov x0, #0 + ret +warm_boot: + mov_imm x1, MBOX_IDX_SEC_ADDR /* Get the jump address */ + subs x1, x1, #1 + mov x2, #(MBOX_IDX_SEC_ADDR * 8) + lsl x3, x2, x1 + add x0, x0, x3 + 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 + + /* ----------------------------------------------------- + * void plat_reset_handler (void); + * + * Platform specific configuration right after cpu is + * is our of reset. + * + * The plat_reset_handler can clobber x0 - x18, x30. + * ----------------------------------------------------- + */ +func plat_reset_handler + /* + * Note: the configurations below should be done before MMU, + * I Cache and L2are enabled. + * The reset handler is executed right after reset + * and before Caches are enabled. + */ + + /* Enable L1/L2 ECC and Parity */ + mrs x5, s3_1_c11_c0_2 /* L2 Ctrl */ + orr x5, x5, #(1 << 21) /* Enable L1/L2 cache ECC & Parity */ + msr s3_1_c11_c0_2, x5 /* L2 Ctrl */ + +#if LLC_ENABLE + /* + * Enable L2 UniqueClean evictions + * Note: this configuration assumes that LLC is configured + * in exclusive mode. + * Later on in the code this assumption will be validated + */ + mrs x5, s3_1_c15_c0_0 /* L2 Ctrl */ + orr x5, x5, #(1 << 14) /* Enable UniqueClean evictions with data */ + msr s3_1_c15_c0_0, x5 /* L2 Ctrl */ +#endif + + /* Instruction Barrier to allow msr command completion */ + isb + + ret +endfunc plat_reset_handler diff --git a/plat/marvell/armada/a8k/common/ble/ble.ld.S b/plat/marvell/armada/a8k/common/ble/ble.ld.S new file mode 100644 index 0000000..d7a0592 --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble.ld.S @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) +ENTRY(ble_main) + +MEMORY { + RAM (rwx): ORIGIN = BLE_BASE, LENGTH = BLE_LIMIT - BLE_BASE +} + +SECTIONS +{ + . = BLE_BASE; + + ro . : { + __RO_START__ = .; + *ble_main.o(.entry*) + *(.text*) + *(.rodata*) + __RO_END_UNALIGNED__ = .; + __RO_END__ = .; + } >RAM + + /* + * Define a linker symbol to mark start of the RW memory area for this + * image. + */ + __RW_START__ = . ; + + .data . : { + __DATA_START__ = .; + *(.data*) + __DATA_END__ = .; + } >RAM + + stacks . (NOLOAD) : { + __STACKS_START__ = .; + *(tzfw_normal_stacks) + __STACKS_END__ = .; + } >RAM + + .bss : { + __BSS_START__ = .; + *(.bss*) + __BSS_END__ = .; + } >RAM + + /* + * Extend the BLE binary to the maximum size allocated for it in platform + * definition files and prevent overlapping between BLE BSS section and + * additional extensions that can follow the BLE in flash image preamble. + * This situation happens for instance when secure extension is added to + * the image preamble. + */ + .fill LOADADDR(.bss) + SIZEOF(.bss) : { + FILL(0xDEADC0DE); + . = ORIGIN(RAM) + LENGTH(RAM) - 1; + BYTE(0x00) + } >RAM + + /* + * Define a linker symbol to mark end of the RW memory area for this + * image. + */ + __RW_END__ = .; + __BLE_END__ = .; + + __BSS_SIZE__ = SIZEOF(.bss); +} diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk new file mode 100644 index 0000000..82ac098 --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +MV_DDR_PATH ?= drivers/marvell/mv_ddr + +MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a +LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a +BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) +PLAT_MARVELL = plat/marvell/armada + +BLE_SOURCES += $(BLE_PATH)/ble_main.c \ + $(BLE_PATH)/ble_mem.S \ + drivers/delay_timer/delay_timer.c \ + $(PLAT_MARVELL)/common/aarch64/marvell_helpers.S \ + $(PLAT_MARVELL)/common/plat_delay_timer.c \ + $(PLAT_MARVELL)/common/marvell_console.c + +PLAT_INCLUDES += -I$(MV_DDR_PATH) \ + -I$(CURDIR)/include \ + -I$(CURDIR)/include/arch/aarch64 \ + -I$(CURDIR)/include/lib/libc \ + -I$(CURDIR)/include/lib/libc/aarch64 \ + -I$(CURDIR)/drivers/marvell + +BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S + +FORCE: + +$(MV_DDR_LIB): FORCE + @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble diff --git a/plat/marvell/armada/a8k/common/ble/ble_main.c b/plat/marvell/armada/a8k/common/ble/ble_main.c new file mode 100644 index 0000000..5b3acec --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble_main.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#define BR_FLAG_SILENT 0x1 +#define SKIP_IMAGE_CODE 0xDEADB002 + +void mailbox_clean(void) +{ + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); +} + +int exec_ble_main(int bootrom_flags) +{ + int skip = 0; + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* + * In some situations, like boot from UART, bootrom will + * request to avoid printing to console. in that case don't + * initialize the console and prints will be ignored + */ + if ((bootrom_flags & BR_FLAG_SILENT) == 0) + marvell_console_boot_init(); + + NOTICE("Starting binary extension\n"); + + /* initialize time (for delay functionality) */ + plat_delay_timer_init(); + + ble_plat_setup(&skip); + + /* if there's skip image request, bootrom will load from the image + * saved on the next address of the flash + */ + if (skip) + return SKIP_IMAGE_CODE; + + /* + * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC + * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. + * If the above is true, this is the recovery from suspend to RAM state. + * In such case the mailbox should remain intact, since it stores the + * warm boot jump address to be used by the TF-A in BL31. + * Othervise the mailbox should be cleaned from a garbage data. + */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { + NOTICE("Cold boot\n"); + mailbox_clean(); + } else { + void (*bootrom_exit)(void) = + (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; + + INFO("Recovery...\n"); + /* + * If this is recovery from suspend, two things has to be done: + * 1. Define the DRAM region as executable memory for preparing + * jump to TF-A + * 2. Instead of returning control to the BootROM, invalidate + * and flush caches, and continue execution at address stored + * in the mailbox. + * This should be done until the BootROM have a native support + * for the system restore flow. + */ + marvell_ble_prepare_exit(); + bootrom_exit(); + } + + return 0; +} + +/* NOTE: don't notify this function, all code must be added to exec_ble_main + * in order to keep the end of ble_main as a fixed address. + */ +int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) +{ + volatile int ret; + + ret = exec_ble_main(bootrom_flags); + return ret; +} diff --git a/plat/marvell/armada/a8k/common/ble/ble_mem.S b/plat/marvell/armada/a8k/common/ble/ble_mem.S new file mode 100644 index 0000000..a48d546 --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble_mem.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#define PTE_NON_EXEC_OFF 54 /* XN - eXecute Never bit offset - see VMSAv8-64 */ + + .globl marvell_ble_prepare_exit + +func marvell_ble_prepare_exit + /* + * Read the page table base and set the first page to be executable. + * This is required for jumping to DRAM for further execution. + */ + mrs x0, ttbr0_el3 + ldr x1, [x0] + mov x2, #1 + bic x1, x1, x2, lsl #PTE_NON_EXEC_OFF + str x1, [x0] + tlbi alle3 + dsb sy + isb + ret +endfunc marvell_ble_prepare_exit diff --git a/plat/marvell/armada/a8k/common/include/a8k_plat_def.h b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h new file mode 100644 index 0000000..de80315 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A8K_PLAT_DEF_H +#define A8K_PLAT_DEF_H + +#include + +#define MVEBU_PRIMARY_CPU 0x0 +#define MVEBU_AP0 0x0 + +/* APN806 revision ID */ +#define MVEBU_CSS_GWD_CTRL_IIDR2_REG (MVEBU_REGS_BASE + 0x610FCC) +#define GWD_IIDR2_REV_ID_OFFSET 12 +#define GWD_IIDR2_REV_ID_MASK 0xF +#define GWD_IIDR2_CHIP_ID_OFFSET 20 +#define GWD_IIDR2_CHIP_ID_MASK (0xFFFu << GWD_IIDR2_CHIP_ID_OFFSET) + +#define CHIP_ID_AP806 0x806 +#define CHIP_ID_AP807 0x807 + +#define COUNTER_FREQUENCY 25000000 + +#define MVEBU_REGS_BASE 0xF0000000 +#define MVEBU_REGS_BASE_MASK 0xF0000000 +#define MVEBU_REGS_BASE_AP(ap) MVEBU_REGS_BASE +#define MVEBU_AP_IO_BASE(ap) 0xF2000000 +#define MVEBU_CP_OFFSET 0x2000000 +#define MVEBU_CP_REGS_BASE(cp_index) (MVEBU_AP_IO_BASE(0) + \ + (cp_index) * MVEBU_CP_OFFSET) +#define MVEBU_RFU_BASE (MVEBU_REGS_BASE + 0x6F0000) +#define MVEBU_IO_WIN_BASE(ap_index) (MVEBU_RFU_BASE) +#define MVEBU_IO_WIN_GCR_OFFSET (0x70) +#define MVEBU_IO_WIN_MAX_WINS (7) + +/* Misc SoC configurations Base */ +#define MVEBU_MISC_SOC_BASE (MVEBU_REGS_BASE + 0x6F4300) + +#define MVEBU_CCU_BASE(ap_index) (MVEBU_REGS_BASE + 0x4000) +#define MVEBU_CCU_MAX_WINS (8) + +#define MVEBU_LLC_BASE(ap_index) (MVEBU_REGS_BASE + 0x8000) +#define MVEBU_DRAM_MAC_BASE (MVEBU_REGS_BASE + 0x20000) +#define MVEBU_DRAM_PHY_BASE (MVEBU_REGS_BASE + 0x20000) +#define MVEBU_SMMU_BASE (MVEBU_REGS_BASE + 0x100000) +#define MVEBU_CP_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440000 + ((n) << 2)) +#define MVEBU_PM_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440000 + ((n / 8) << 2)) +#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \ + (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440100 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \ + (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440104 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440110 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2)) +#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040) +#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10) +#define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000) +#define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000) +#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084) + +#define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ + 0x20080 + ((win) * 0x8)) +#define MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ + 0x20084 + ((win) * 0x8)) + +/* MCI indirect access definitions */ +#define MCI_MAX_UNIT_ID 2 +/* SoC RFU / IHBx4 Control */ +#define MCIX4_REG_START_ADDRESS_REG(unit_id) (MVEBU_RFU_BASE + \ + 0x4218 + (unit_id * 0x20)) +#define MCI_REMAP_OFF_SHIFT 8 + +#define MVEBU_MCI_REG_BASE_REMAP(index) (0xFD000000 + \ + ((index) * 0x1000000)) + +#define MVEBU_PCIE_X4_MAC_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x600000) +#define MVEBU_COMPHY_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x441000) +#define MVEBU_HPIPE_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x120000) +#define MVEBU_CP_DFX_OFFSET (0x400200) + +/***************************************************************************** + * MVEBU memory map related constants + ***************************************************************************** + */ +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE MVEBU_REGS_BASE +#define DEVICE0_SIZE 0x10000000 + +/***************************************************************************** + * GIC-400 & interrupt handling related constants + ***************************************************************************** + */ +/* Base MVEBU compatible GIC memory map */ +#define MVEBU_GICD_BASE 0x210000 +#define MVEBU_GICC_BASE 0x220000 + + +/***************************************************************************** + * AXI Configuration + ***************************************************************************** + */ +#define MVEBU_AXI_ATTR_ARCACHE_OFFSET 4 +#define MVEBU_AXI_ATTR_ARCACHE_MASK (0xF << \ + MVEBU_AXI_ATTR_ARCACHE_OFFSET) +#define MVEBU_AXI_ATTR_ARDOMAIN_OFFSET 12 +#define MVEBU_AXI_ATTR_ARDOMAIN_MASK (0x3 << \ + MVEBU_AXI_ATTR_ARDOMAIN_OFFSET) +#define MVEBU_AXI_ATTR_AWCACHE_OFFSET 20 +#define MVEBU_AXI_ATTR_AWCACHE_MASK (0xF << \ + MVEBU_AXI_ATTR_AWCACHE_OFFSET) +#define MVEBU_AXI_ATTR_AWDOMAIN_OFFSET 28 +#define MVEBU_AXI_ATTR_AWDOMAIN_MASK (0x3 << \ + MVEBU_AXI_ATTR_AWDOMAIN_OFFSET) + +/* SATA MBUS to AXI configuration */ +#define MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET 1 +#define MVEBU_SATA_M2A_AXI_ARCACHE_MASK (0xF << \ + MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET) +#define MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET 5 +#define MVEBU_SATA_M2A_AXI_AWCACHE_MASK (0xF << \ + MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET) + +/* ARM cache attributes */ +#define CACHE_ATTR_BUFFERABLE 0x1 +#define CACHE_ATTR_CACHEABLE 0x2 +#define CACHE_ATTR_READ_ALLOC 0x4 +#define CACHE_ATTR_WRITE_ALLOC 0x8 +/* Domain */ +#define DOMAIN_NON_SHAREABLE 0x0 +#define DOMAIN_INNER_SHAREABLE 0x1 +#define DOMAIN_OUTER_SHAREABLE 0x2 +#define DOMAIN_SYSTEM_SHAREABLE 0x3 + +/************************************************************************ + * Required platform porting definitions common to all + * Management Compute SubSystems (MSS) + ************************************************************************ + */ +/* + * Load address of SCP_BL2 + * SCP_BL2 is loaded to the same place as BL31. + * Once SCP_BL2 is transferred to the SCP, + * it is discarded and BL31 is loaded over the top. + */ +#ifdef SCP_IMAGE +#define SCP_BL2_BASE BL31_BASE +#define SCP_BL2_SIZE BL31_LIMIT +#endif + +#ifndef __ASSEMBLER__ +enum ap806_sar_target_dev { + SAR_PIDI_MCIX2 = 0x0, + SAR_MCIX4 = 0x1, + SAR_SPI = 0x2, + SAR_SD = 0x3, + SAR_PIDI_MCIX2_BD = 0x4, /* BootRom disabled */ + SAR_MCIX4_DB = 0x5, /* BootRom disabled */ + SAR_SPI_DB = 0x6, /* BootRom disabled */ + SAR_EMMC = 0x7 +}; + +enum io_win_target_ids { + MCI_0_TID = 0x0, + MCI_1_TID = 0x1, + MCI_2_TID = 0x2, + PIDI_TID = 0x3, + SPI_TID = 0x4, + STM_TID = 0x5, + BOOTROM_TID = 0x6, + IO_WIN_MAX_TID +}; + +enum ccu_target_ids { + IO_0_TID = 0x00, + DRAM_0_TID = 0x03, + IO_1_TID = 0x0F, + CFG_REG_TID = 0x10, + RAR_TID = 0x20, + SRAM_TID = 0x40, + DRAM_1_TID = 0xC0, + CCU_MAX_TID, + INVALID_TID = 0xFF +}; +#endif /* __ASSEMBLER__ */ + +#endif /* A8K_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/include/ddr_info.h b/plat/marvell/armada/a8k/common/include/ddr_info.h new file mode 100644 index 0000000..e19036a --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/ddr_info.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#define DRAM_MAX_IFACE 1 +#define DRAM_CH0_MMAP_LOW_OFFSET 0x20200 diff --git a/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h new file mode 100644 index 0000000..e03c448 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +/* This driver provides I2C support for Marvell A8K and compatible SoCs */ + +#ifndef MENTOR_I2C_PLAT_H +#define MENTOR_I2C_PLAT_H + +#define CONFIG_SYS_TCLK 250000000 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x0 + +#define I2C_CAN_UNSTUCK + +struct mentor_i2c_regs { + uint32_t slave_address; + uint32_t data; + uint32_t control; + union { + uint32_t status; /* when reading */ + uint32_t baudrate; /* when writing */ + }; + uint32_t xtnd_slave_addr; + uint32_t reserved[2]; + uint32_t soft_reset; + uint8_t reserved2[0xa0 - 0x20]; + uint32_t unstuck; +}; + +#endif /* MENTOR_I2C_PLAT_H */ diff --git a/plat/marvell/armada/a8k/common/include/plat_macros.S b/plat/marvell/armada/a8k/common/include/plat_macros.S new file mode 100644 index 0000000..8faccf0 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/plat_macros.S @@ -0,0 +1,20 @@ +/* + * 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 + +/* + * Required platform porting macros + * (Provided by included headers) + */ +.macro plat_crash_print_regs +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h new file mode 100644 index 0000000..ec1c903 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2018 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 + +#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_SRAM_BASE 0xFFE1C048 +#define PLAT_MARVELL_SRAM_END 0xFFE78000 + +#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_NORTHB_COUNT 1 + +#define PLAT_MARVELL_CLUSTER_COUNT U(2) +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) + +#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ + PLAT_MARVELL_CLUSTER_CORE_COUNT) + +/* 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_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), \ + INTR_PROP_DESC(MARVELL_IRQ_PIC0, 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 + +/* + * 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 + 0x512000) +#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 200000000 + +#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 + +/* Recovery image enable */ +#define PLAT_RECOVERY_IMAGE_ENABLE 0 + +/* 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 (note the lower memory space + * is reserved for BLE data) + */ +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_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_a8k.mk b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk new file mode 100644 index 0000000..d8d4921 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk @@ -0,0 +1,21 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PLAT_MARVELL := plat/marvell/armada +A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss + +BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ + $(MARVELL_MOCHI_DRV) + +BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c + +PLAT_INCLUDES += -I$(A8K_MSS_SOURCE) + +ifneq (${SCP_BL2},) +# This define is used to inidcate the SCP image is present +$(eval $(call add_define,SCP_IMAGE)) +endif diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c new file mode 100644 index 0000000..09b8446 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include /* timer functionality */ + +#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) +#define MSS_AEBR_MASK 0xFFF +#define MSS_AIBR_MASK 0xFFF + +#define MSS_EXTERNAL_SPACE 0x50000000 +#define MSS_EXTERNAL_ACCESS_BIT 28 +#define MSS_EXTERNAL_ADDR_MASK 0xfffffff +#define MSS_INTERNAL_ACCESS_BIT 28 + +struct addr_map_win ccu_mem_map[] = { + {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID} +}; + +/* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors, + * the access to cp0 and cp1 need to be provided. More precisely it is + * required to: + * - get the information about device id which is stored in CP0 registers + * (to distinguish between cases where we have cp0 and cp1 or standalone cp0) + * - get the access to cp which is needed for loading fw for cp0/cp1 + * coprocessors + * This function configures ccu windows accordingly. + * + * Note: there is no need to restore previous ccu configuration, since in next + * phase (BL31) the init_ccu will be called (via apn806_init/ + * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten. + */ +static int bl2_plat_mmap_init(void) +{ + int cfg_num, win_id, cfg_idx; + + cfg_num = ARRAY_SIZE(ccu_mem_map); + + /* CCU window-0 should not be counted - it's already used */ + if (cfg_num > (MVEBU_CCU_MAX_WINS - 1)) { + ERROR("BL2: %s: trying to open too many windows\n", __func__); + return -1; + } + + /* Enable required CCU windows + * 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++) { + /* Enable required CCU windows */ + ccu_win_check(&ccu_mem_map[cfg_idx]); + ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); + } + + /* Set the default target id to PIDI */ + mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); + + /* 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)); + + return 0; +} + +/***************************************************************************** + * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. + * Return 0 on success, -1 otherwise. + ***************************************************************************** + */ +int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + int ret; + + INFO("BL2: Initiating SCP_BL2 transfer to SCP\n"); + + /* initialize time (for delay functionality) */ + plat_delay_timer_init(); + + ret = bl2_plat_mmap_init(); + if (ret != 0) + return ret; + + ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base, + scp_bl2_image_info->image_size); + + if (ret == 0) + INFO("BL2: SCP_BL2 transferred to SCP\n"); + else + ERROR("BL2: SCP_BL2 transfer failure\n"); + + return ret; +} + +uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx) +{ + return MVEBU_CP_REGS_BASE(cp_idx) + 0x280000; +} + +uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx) +{ + return MVEBU_REGS_BASE + 0x580000; +} + +uint32_t bl2_plat_get_cp_count(int ap_idx) +{ + uint32_t revision = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + /* A8040: two CPs. + * A7040: one CP. + */ + if (revision == MVEBU_80X0_DEV_ID || + revision == MVEBU_80X0_CP115_DEV_ID) + return 2; + else + return 1; +} + +uint32_t bl2_plat_get_ap_count(void) +{ + /* A8040 and A7040 have only one AP */ + return 1; +} + +void bl2_plat_configure_mss_windows(uintptr_t mss_regs) +{ + /* set AXI External and Internal Address Bus extension */ + mmio_write_32(MSS_AEBR(mss_regs), + ((0x0 >> MSS_EXTERNAL_ACCESS_BIT) & MSS_AEBR_MASK)); + mmio_write_32(MSS_AIBR(mss_regs), + ((mss_regs >> MSS_INTERNAL_ACCESS_BIT) & MSS_AIBR_MASK)); +} diff --git a/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c new file mode 100644 index 0000000..a070583 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include + +#include + +/* + * SISR is 32 bit interrupt register representing 32 interrupts + * + * +======+=============+=============+ + * + Bits + 31 + 30 - 00 + + * +======+=============+=============+ + * + Desc + MSS Msg Int + Reserved + + * +======+=============+=============+ + */ +#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0) +#define MSS_SISTR (MVEBU_REGS_BASE + 0x5800D8) + +#define MSS_MSG_INT_MASK (0x80000000) +#define MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) +#define MSS_TRIGGER_TIMEOUT (2000) + +/***************************************************************************** + * mss_pm_ipc_msg_send + * + * DESCRIPTION: create and transmit IPC message + ***************************************************************************** + */ +int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, + const psci_power_state_t *target_state) +{ + /* Transmit IPC message */ +#ifndef DISABLE_CLUSTER_LEVEL + mv_pm_ipc_msg_tx(channel_id, msg_id, + (unsigned int)target_state->pwr_domain_state[ + MPIDR_AFFLVL1]); +#else + mv_pm_ipc_msg_tx(channel_id, msg_id, 0); +#endif + + return 0; +} + +/***************************************************************************** + * mss_pm_ipc_msg_trigger + * + * DESCRIPTION: Trigger IPC message interrupt to MSS + ***************************************************************************** + */ +int mss_pm_ipc_msg_trigger(void) +{ + unsigned int timeout; + unsigned int t_end; + unsigned int t_start = mmio_read_32(MSS_TIMER_BASE); + + mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK); + + do { + /* wait while SCP process incoming interrupt */ + if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK) + break; + + /* check timeout */ + t_end = mmio_read_32(MSS_TIMER_BASE); + + timeout = ((t_start > t_end) ? + (t_start - t_end) : (t_end - t_start)); + if (timeout > MSS_TRIGGER_TIMEOUT) { + ERROR("PM MSG Trigger Timeout\n"); + break; + } + + } while (1); + + return 0; +} diff --git a/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h new file mode 100644 index 0000000..1dfa9fa --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_PM_IPC_H +#define MSS_PM_IPC_H + +#include + +/* Currently MSS does not support Cluster level Power Down */ +#define DISABLE_CLUSTER_LEVEL + + +/***************************************************************************** + * mss_pm_ipc_msg_send + * + * DESCRIPTION: create and transmit IPC message + ***************************************************************************** + */ +int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, + const psci_power_state_t *target_state); + +/***************************************************************************** + * mss_pm_ipc_msg_trigger + * + * DESCRIPTION: Trigger IPC message interrupt to MSS + ***************************************************************************** + */ +int mss_pm_ipc_msg_trigger(void); + + +#endif /* MSS_PM_IPC_H */ diff --git a/plat/marvell/armada/a8k/common/plat_bl1_setup.c b/plat/marvell/armada/a8k/common/plat_bl1_setup.c new file mode 100644 index 0000000..f9521c8 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_bl1_setup.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +void marvell_bl1_setup_mpps(void) +{ + /* Enable UART MPPs. + ** In a normal system, this is done by Bootrom. + */ + mmio_write_32(MVEBU_AP_MPP_REGS(1), 0x3000); + mmio_write_32(MVEBU_AP_MPP_REGS(2), 0x3000); +} diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c new file mode 100644 index 0000000..98b3966 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* In Armada-8k family AP806/AP807, CP0 connected to PIDI + * and CP1 connected to IHB via MCI #0 + */ +#define MVEBU_MCI0 0 + +static _Bool pm_fw_running; + +/* Set a weak stub for platforms that don't need to configure GPIO */ +#pragma weak marvell_gpio_config +int marvell_gpio_config(void) +{ + return 0; +} + +static void marvell_bl31_mpp_init(int cp) +{ + uint32_t reg; + + /* need to do for CP#0 only */ + if (cp) + return; + + + /* + * Enable CP0 I2C MPPs (MPP: 37-38) + * U-Boot rely on proper MPP settings for I2C EEPROM usage + * (only for CP0) + */ + reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4)); + mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); +} + +void marvell_bl31_mss_init(void) +{ + struct mss_pm_ctrl_block *mss_pm_crtl = + (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; + + /* Check that the image was loaded successfully */ + if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) { + NOTICE("MSS PM is not supported in this build\n"); + return; + } + + /* If we got here it means that the PM firmware is running */ + pm_fw_running = 1; + + INFO("MSS IPC init\n"); + + if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) + mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); +} + +_Bool is_pm_fw_running(void) +{ + return pm_fw_running; +} + +/* For TrusTzone we treat the "target" field of addr_map_win + * struct as attribute + */ +static const struct addr_map_win tz_map[] = { + {PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT} +}; + +/* Configure MC TrustZone regions */ +static void marvell_bl31_security_setup(void) +{ + int tz_nr, win_id; + + tz_nr = ARRAY_SIZE(tz_map); + + for (win_id = 0; win_id < tz_nr; win_id++) + tz_enable_win(MVEBU_AP0, tz_map, win_id); +} + +/* This function overruns the same function in marvell_bl31_setup.c */ +void bl31_plat_arch_setup(void) +{ + int cp; + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* initialize the timer for mdelay/udelay functionality */ + plat_delay_timer_init(); + + /* configure apn806 */ + ap_init(); + + /* In marvell_bl31_plat_arch_setup, el3 mmu is configured. + * el3 mmu configuration MUST be called after apn806_init, if not, + * this will cause an hang in init_io_win + * (after setting the IO windows GCR values). + */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) + marvell_bl31_plat_arch_setup(); + + for (cp = 0; cp < CP_COUNT; cp++) { + /* configure cp110 for CP0*/ + if (cp == 1) + mci_initialize(MVEBU_MCI0); + + /* initialize MCI & CP1 */ + cp110_init(MVEBU_CP_REGS_BASE(cp), + STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); + + /* Should be called only after setting IOB windows */ + marvell_bl31_mpp_init(cp); + } + + /* initialize IPC between MSS and ATF */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) + marvell_bl31_mss_init(); + + /* Configure GPIO */ + marvell_gpio_config(); + + marvell_bl31_security_setup(); +} diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c new file mode 100644 index 0000000..7f9e242 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -0,0 +1,735 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Register for skip image use */ +#define SCRATCH_PAD_REG2 0xF06F00A8 +#define SCRATCH_PAD_SKIP_VAL 0x01 +#define NUM_OF_GPIO_PER_REG 32 + +#define MMAP_SAVE_AND_CONFIG 0 +#define MMAP_RESTORE_SAVED 1 + +/* SAR clock settings */ +#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) +#define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ + ((r) << 2)) + +#define SAR_CLOCK_FREQ_MODE_OFFSET (0) +#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET) +#define SAR_PIDI_LOW_SPEED_OFFSET (20) +#define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET) +#define SAR_PIDI_LOW_SPEED_SHIFT (15) +#define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT) + +#define FREQ_MODE_AP_SAR_REG_NUM (0) +#define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \ + SAR_CLOCK_FREQ_MODE_OFFSET) + +#define AVS_I2C_EEPROM_ADDR 0x57 /* EEPROM */ +#define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130) +#define AVS_ENABLE_OFFSET (0) +#define AVS_SOFT_RESET_OFFSET (2) +#define AVS_TARGET_DELTA_OFFSET (21) + +#ifndef MVEBU_SOC_AP807 + /* AP806 SVC bits */ + #define AVS_LOW_VDD_LIMIT_OFFSET (4) + #define AVS_HIGH_VDD_LIMIT_OFFSET (12) + #define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET) + #define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET) +#else + /* AP807 SVC bits */ + #define AVS_LOW_VDD_LIMIT_OFFSET (3) + #define AVS_HIGH_VDD_LIMIT_OFFSET (13) + #define AVS_VDD_LOW_LIMIT_MASK (0x3FF << AVS_LOW_VDD_LIMIT_OFFSET) + #define AVS_VDD_HIGH_LIMIT_MASK (0x3FF << AVS_HIGH_VDD_LIMIT_OFFSET) +#endif + +/* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */ +#define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ + (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \ + (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD limit is 1.0V for all A80x0 devices */ +#define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ + (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \ + (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD limit is 0.82V for all A3900 devices + * AVS offsets are not the same as in A70x0 + */ +#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ + (0x2c2 << 13) | \ + (0x2c2 << 3) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD is 0.88V for 2GHz clock */ +#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ + (0x2f5 << 13) | \ + (0x2f5 << 3) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) + +#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) +#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 +#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) + + +/* + * - Identification information in the LD-0 eFuse: + * DRO: LD0[74:65] - Not used by the SW + * Revision: LD0[78:75] - Not used by the SW + * Bin: LD0[80:79] - Not used by the SW + * SW Revision: LD0[115:113] + * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 + * resulting in 2 CPUs active only (7020) + */ +#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) +/* Bits [94:63] - 32 data bits total */ +#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) +/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ +#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) +/* Bits [220:189] - 32 data bits total */ +#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) +/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ +#define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ +#define EFUSE_AP_LD0_DRO_MASK 0x3FF +#define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ +#define EFUSE_AP_LD0_REVID_MASK 0xF +#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ +#define EFUSE_AP_LD0_BIN_MASK 0x3 +#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ +#define EFUSE_AP_LD0_SWREV_MASK 0x7 + +#ifndef MVEBU_SOC_AP807 + /* AP806 AVS work points in the LD0 eFuse + * SVC1 work point: LD0[88:81] + * SVC2 work point: LD0[96:89] + * SVC3 work point: LD0[104:97] + * SVC4 work point: LD0[112:105] + */ + #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */ + #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ + #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ + #define EFUSE_AP_LD0_WP_MASK 0xFF +#else + /* AP807 AVS work points in the LD0 eFuse + * SVC1 work point: LD0[91:81] + * SVC2 work point: LD0[102:92] + * SVC3 work point: LD0[113:103] + */ + #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ + #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ + #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ + #define EFUSE_AP_LD0_WP_MASK 0x3FF +#endif + +#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ + +#define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4 + +#if MARVELL_SVC_TEST +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_I2C_FUNC 2 +#define MVEBU_MPP_CTRL_MASK 0xf +#endif + +/* Return the AP revision of the chip */ +static unsigned int ble_get_ap_type(void) +{ + unsigned int chip_rev_id; + + chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG); + chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >> + GWD_IIDR2_CHIP_ID_OFFSET); + + return chip_rev_id; +} + +/****************************************************************************** + * The routine allows to save the CCU and IO windows configuration during DRAM + * setup and restore them afterwards before exiting the BLE stage. + * Such window configuration is required since not all default settings coming + * from the HW and the BootROM allow access to peripherals connected to + * all available CPn components. + * For instance, when the boot device is located on CP0, the IO window to CP1 + * is not opened automatically by the HW and if the DRAM SPD is located on CP1 + * i2c channel, it cannot be read at BLE stage. + * Therefore the DRAM init procedure have to provide access to all available + * CPn peripherals during the BLE stage by setting the CCU IO window to all + * CPnph addresses and by enabling the IO windows accordingly. + * Additionally this function configures the CCU GCR to DRAM, which allows + * usage or more than 4GB DRAM as it configured by the default CCU DRAM window. + * + * IN: + * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it + * MMAP_RESTORE_SAVED - restore saved configuration + * OUT: + * NONE + **************************************************************************** + */ +static void ble_plat_mmap_config(int restore) +{ + if (restore == MMAP_RESTORE_SAVED) { + /* Restore all orig. settings that were modified by BLE stage */ + ccu_restore_win_all(MVEBU_AP0); + /* Restore CCU */ + iow_restore_win_all(MVEBU_AP0); + return; + } + + /* Store original values */ + ccu_save_win_all(MVEBU_AP0); + /* Save CCU */ + iow_save_win_all(MVEBU_AP0); + + init_ccu(MVEBU_AP0); + /* The configuration saved, now all the changes can be done */ + init_io_win(MVEBU_AP0); +} + +/**************************************************************************** + * Setup Adaptive Voltage Switching - this is required for some platforms + **************************************************************************** + */ +#if !MARVELL_SVC_TEST +static void ble_plat_avs_config(void) +{ + uint32_t freq_mode, device_id; + uint32_t avs_val = 0; + + freq_mode = + SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + /* Check which SoC is running and act accordingly */ + if (ble_get_ap_type() == CHIP_ID_AP807) { + /* Increase CPU voltage for higher CPU clock */ + if (freq_mode == CPU_2000_DDR_1200_RCLK_1200) + avs_val = AVS_A3900_HIGH_CLK_VALUE; + else + avs_val = AVS_A3900_CLK_VALUE; + } else { + /* Check which SoC is running and act accordingly */ + device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + switch (device_id) { + case MVEBU_80X0_DEV_ID: + case MVEBU_80X0_CP115_DEV_ID: + /* Always fix the default AVS value on A80x0 */ + avs_val = AVS_A8K_CLK_VALUE; + break; + case MVEBU_70X0_DEV_ID: + case MVEBU_70X0_CP115_DEV_ID: + /* Fix AVS for CPU clocks lower than 1600MHz on A70x0 */ + if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) && + (freq_mode < CPU_DDR_RCLK_INVALID)) + avs_val = AVS_A7K_LOW_CLK_VALUE; + break; + default: + ERROR("Unsupported Device ID 0x%x\n", device_id); + return; + } + } + + if (avs_val) { + VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val); + mmio_write_32(AVS_EN_CTRL_REG, avs_val); + } +} +#endif +/****************************************************************************** + * Update or override current AVS work point value using data stored in EEPROM + * This is only required by QA/validation flows and activated by + * MARVELL_SVC_TEST flag. + * + * The function is expected to be called twice. + * + * First time with AVS value of 0 for testing if the EEPROM requests completely + * override the AVS value and bypass the eFuse test + * + * Second time - with non-zero AVS value obtained from eFuses as an input. + * In this case the EEPROM may contain AVS correction value (either positive + * or negative) that is added to the input AVS value and returned back for + * further processing. + ****************************************************************************** + */ +static uint32_t avs_update_from_eeprom(uint32_t avs_workpoint) +{ + uint32_t new_wp = avs_workpoint; +#if MARVELL_SVC_TEST + /* --------------------------------------------------------------------- + * EEPROM | Data description (avs_step) + * address | + * --------------------------------------------------------------------- + * 0x120 | AVS workpoint correction value + * | if not 0 and not 0xff, correct the AVS taken from eFuse + * | by the number of steps indicated by bit[6:0] + * | bit[7] defines correction direction. + * | If bit[7]=1, add the value from bit[6:0] to AVS workpoint, + * | othervise substruct this value from AVS workpoint. + * --------------------------------------------------------------------- + * 0x121 | AVS workpoint override value + * | Override the AVS workpoint with the value stored in this + * | byte. When running on AP806, the AVS workpoint is 7 bits + * | wide and override value is valid when bit[6:0] holds + * | value greater than zero and smaller than 0x33. + * | When running on AP807, the AVS workpoint is 10 bits wide. + * | Additional 2 MSB bits are supplied by EEPROM byte 0x122. + * | AVS override value is valid when byte @ 0x121 and bit[1:0] + * | of byte @ 0x122 combined have non-zero value. + * --------------------------------------------------------------------- + * 0x122 | Extended AVS workpoint override value + * | Valid only for AP807 platforms and must be less than 0x4 + * --------------------------------------------------------------------- + */ + static uint8_t avs_step[3] = {0}; + uintptr_t reg; + uint32_t val; + unsigned int ap_type = ble_get_ap_type(); + + /* Always happens on second call to this function */ + if (avs_workpoint != 0) { + /* Get correction steps from the EEPROM */ + if ((avs_step[0] != 0) && (avs_step[0] != 0xff)) { + NOTICE("AVS request to step %s by 0x%x from old 0x%x\n", + avs_step[0] & 0x80 ? "DOWN" : "UP", + avs_step[0] & 0x7f, new_wp); + if (avs_step[0] & 0x80) + new_wp -= avs_step[0] & 0x7f; + else + new_wp += avs_step[0] & 0x7f; + } + + return new_wp; + } + + /* AVS values are located in EEPROM + * at CP0 i2c bus #0, device 0x57 offset 0x120 + * The SDA and SCK pins of CP0 i2c-0: MPP[38:37], i2c function 0x2. + */ + reg = MVEBU_CP_MPP_REGS(0, 4); + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); + + /* Init CP0 i2c-0 */ + i2c_init((void *)(MVEBU_CP0_I2C_BASE)); + + /* Read EEPROM only once at the fist call! */ + i2c_read(AVS_I2C_EEPROM_ADDR, 0x120, 2, avs_step, 3); + NOTICE("== SVC test build ==\n"); + NOTICE("EEPROM holds values 0x%x, 0x%x and 0x%x\n", + avs_step[0], avs_step[1], avs_step[2]); + + /* Override the AVS value? */ + if ((ap_type != CHIP_ID_AP807) && (avs_step[1] < 0x33)) { + /* AP806 - AVS is 7 bits */ + new_wp = avs_step[1]; + + } else if (ap_type == CHIP_ID_AP807 && (avs_step[2] < 0x4)) { + /* AP807 - AVS is 10 bits */ + new_wp = avs_step[2]; + new_wp <<= 8; + new_wp |= avs_step[1]; + } + + if (new_wp == 0) + NOTICE("Ignore BAD AVS Override value in EEPROM!\n"); + else + NOTICE("Override AVS by EEPROM value 0x%x\n", new_wp); +#endif /* MARVELL_SVC_TEST */ + return new_wp; +} + +/**************************************************************************** + * SVC flow - v0.10 + * The feature is intended to configure AVS value according to eFuse values + * that are burned individually for each SoC during the test process. + * Primary AVS value is stored in HD efuse and processed on power on + * by the HW engine + * Secondary AVS value is located in LD efuse and contains 4 work points for + * various CPU frequencies. + * The Secondary AVS value is only taken into account if the SW Revision stored + * in the efuse is greater than 0 and the CPU is running in a certain speed. + **************************************************************************** + */ +static void ble_plat_svc_config(void) +{ + uint32_t reg_val, avs_workpoint, freq_pidi_mode; + uint64_t efuse; + uint32_t device_id, single_cluster; + uint16_t svc[4], perr[4], i, sw_ver; + unsigned int ap_type; + + /* Set access to LD0 */ + avs_workpoint = avs_update_from_eeprom(0); + if (avs_workpoint) + goto set_aws_wp; + + /* Set access to LD0 */ + reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); + reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; + mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); + + /* Obtain the value of LD0[125:63] */ + efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); + efuse <<= 32; + efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); + + /* SW Revision: + * Starting from SW revision 1 the SVC flow is supported. + * SW version 0 (efuse not programmed) should follow the + * regular AVS update flow. + */ + sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK; + if (sw_ver < 1) { + NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver); +#if MARVELL_SVC_TEST + NOTICE("SVC_TEST: AVS bypassed\n"); + +#else + ble_plat_avs_config(); +#endif + return; + } + + /* Frequency mode from SAR */ + freq_pidi_mode = SAR_CLOCK_FREQ_MODE( + mmio_read_32( + MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + + /* Decode all SVC work points */ + svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK; + svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK; + svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK; + + /* Fetch AP type to distinguish between AP806 and AP807 */ + ap_type = ble_get_ap_type(); + + if (ap_type != CHIP_ID_AP807) { + svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) + & EFUSE_AP_LD0_WP_MASK; + INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", + svc[0], svc[1], svc[2], svc[3]); + } else { + INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", + svc[0], svc[1], svc[2]); + } + + /* Validate parity of SVC workpoint values */ + for (i = 0; i < 4; i++) { + uint8_t parity, bit; + + perr[i] = 0; + + for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) + parity ^= (svc[i] >> bit) & 1; + + /* Starting from SW version 2, the parity check is mandatory */ + if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) + perr[i] = 1; /* register the error */ + } + + single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); + single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; + + device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + if (device_id == MVEBU_80X0_DEV_ID || + device_id == MVEBU_80X0_CP115_DEV_ID) { + /* A8040/A8020 */ + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1800_DDR_1200_RCLK_1200: + case CPU_1800_DDR_1050_RCLK_1050: + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + break; + case CPU_1600_DDR_1050_RCLK_1050: + case CPU_1600_DDR_900_RCLK_900_2: + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + break; + case CPU_1300_DDR_800_RCLK_800: + case CPU_1300_DDR_650_RCLK_650: + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; + break; + case CPU_2000_DDR_1200_RCLK_1200: + case CPU_2000_DDR_1050_RCLK_1050: + default: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + } + } else if (device_id == MVEBU_70X0_DEV_ID || + device_id == MVEBU_70X0_CP115_DEV_ID) { + /* A7040/A7020/A6040 */ + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + single_cluster == 0 ? "7040" : "7020", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1400_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + } else { + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + } + break; + case CPU_1200_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + } else { + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + } + break; + case CPU_800_DDR_800_RCLK_800: + case CPU_1000_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; + } else { + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + } + break; + case CPU_600_DDR_800_RCLK_800: + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; /* Same for 6040 and 7020 */ + break; + case CPU_1600_DDR_800_RCLK_800: /* 7020 only */ + default: + if (single_cluster) {/* 7020 */ + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + } else + avs_workpoint = 0; + break; + } + } else if (device_id == MVEBU_3900_DEV_ID) { + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + "3900", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1600_DDR_1200_RCLK_1200: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + case CPU_1300_DDR_800_RCLK_800: + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + break; + default: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + } + } else { + ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); + return; + } + + /* Set AVS control if needed */ + if (avs_workpoint == 0) { + ERROR("SVC: AVS work point not changed\n"); + return; + } + + /* Remove parity bit */ + if (ap_type != CHIP_ID_AP807) + avs_workpoint &= 0x7F; + + /* Update WP from EEPROM if needed */ + avs_workpoint = avs_update_from_eeprom(avs_workpoint); + +set_aws_wp: + reg_val = mmio_read_32(AVS_EN_CTRL_REG); + NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n", + (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET, + avs_workpoint); + reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK); + reg_val |= 0x1 << AVS_ENABLE_OFFSET; + reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET; + reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET; + mmio_write_32(AVS_EN_CTRL_REG, reg_val); + return; + +perror: + ERROR("Failed SVC WP[%d] parity check!\n", i); + ERROR("Ignoring the WP values\n"); +} + +#if PLAT_RECOVERY_IMAGE_ENABLE +static int ble_skip_image_i2c(struct skip_image *skip_im) +{ + ERROR("skipping image using i2c is not supported\n"); + /* not supported */ + return 0; +} + +static int ble_skip_image_other(struct skip_image *skip_im) +{ + ERROR("implementation missing for skip image request\n"); + /* not supported, make your own implementation */ + return 0; +} + +static int ble_skip_image_gpio(struct skip_image *skip_im) +{ + unsigned int val; + unsigned int mpp_address = 0; + unsigned int offset = 0; + + switch (skip_im->info.test.cp_ap) { + case(CP): + mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index, + skip_im->info.gpio.num); + if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG) + offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG; + else + offset = skip_im->info.gpio.num; + break; + case(AP): + mpp_address = MVEBU_AP_GPIO_DATA_IN; + offset = skip_im->info.gpio.num; + break; + } + + val = mmio_read_32(mpp_address); + val &= (1 << offset); + if ((!val && skip_im->info.gpio.button_state == HIGH) || + (val && skip_im->info.gpio.button_state == LOW)) { + mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL); + return 1; + } + + return 0; +} + +/* + * This function checks if there's a skip image request: + * return values: + * 1: (true) images request been made. + * 0: (false) no image request been made. + */ +static int ble_skip_current_image(void) +{ + struct skip_image *skip_im; + + /*fetching skip image info*/ + skip_im = (struct skip_image *)plat_marvell_get_skip_image_data(); + + if (skip_im == NULL) + return 0; + + /* check if skipping image request has already been made */ + if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL) + return 0; + + switch (skip_im->detection_method) { + case GPIO: + return ble_skip_image_gpio(skip_im); + case I2C: + return ble_skip_image_i2c(skip_im); + case USER_DEFINED: + return ble_skip_image_other(skip_im); + } + + return 0; +} +#endif + + +int ble_plat_setup(int *skip) +{ + int ret; + unsigned int freq_mode; + + /* Power down unused CPUs */ + plat_marvell_early_cpu_powerdown(); + + /* + * Save the current CCU configuration and make required changes: + * - Allow access to DRAM larger than 4GB + * - Open memory access to all CPn peripherals + */ + ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG); + +#if PLAT_RECOVERY_IMAGE_ENABLE + /* Check if there's a skip request to bootRom recovery Image */ + if (ble_skip_current_image()) { + /* close memory access to all CPn peripherals. */ + ble_plat_mmap_config(MMAP_RESTORE_SAVED); + *skip = 1; + return 0; + } +#endif + /* Do required CP-110 setups for BLE stage */ + cp110_ble_init(MVEBU_CP_REGS_BASE(0)); + + /* Setup AVS */ + ble_plat_svc_config(); + + /* read clk option from sampled-at-reset register */ + freq_mode = + SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + + /* work with PLL clock driver in AP807 */ + if (ble_get_ap_type() == CHIP_ID_AP807) + ap807_clocks_init(freq_mode); + + /* Do required AP setups for BLE stage */ + ap_ble_init(); + + /* Update DRAM topology (scan DIMM SPDs) */ + plat_marvell_dram_update_topology(); + + /* Kick it in */ + ret = dram_init(); + + /* Restore the original CCU configuration before exit from BLE */ + ble_plat_mmap_config(MMAP_RESTORE_SAVED); + + return ret; +} diff --git a/plat/marvell/armada/a8k/common/plat_pm.c b/plat/marvell/armada/a8k/common/plat_pm.c new file mode 100644 index 0000000..96e95c2 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_pm.c @@ -0,0 +1,844 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MVEBU_PRIVATE_UID_REG 0x30 +#define MVEBU_RFU_GLOBL_SW_RST 0x84 +#define MVEBU_CCU_RVBAR(cpu) (MVEBU_REGS_BASE + 0x640 + (cpu * 4)) +#define MVEBU_CCU_CPU_UN_RESET(cpu) (MVEBU_REGS_BASE + 0x650 + (cpu * 4)) + +#define MPIDR_CPU_GET(mpidr) ((mpidr) & MPIDR_CPU_MASK) +#define MPIDR_CLUSTER_GET(mpidr) MPIDR_AFFLVL1_VAL((mpidr)) + +#define MVEBU_GPIO_MASK(index) (1 << (index % 32)) +#define MVEBU_MPP_MASK(index) (0xF << (4 * (index % 8))) +#define MVEBU_GPIO_VALUE(index, value) (value << (index % 32)) + +#define MVEBU_USER_CMD_0_REG (MVEBU_DRAM_MAC_BASE + 0x20) +#define MVEBU_USER_CMD_CH0_OFFSET 28 +#define MVEBU_USER_CMD_CH0_MASK (1 << MVEBU_USER_CMD_CH0_OFFSET) +#define MVEBU_USER_CMD_CH0_EN (1 << MVEBU_USER_CMD_CH0_OFFSET) +#define MVEBU_USER_CMD_CS_OFFSET 24 +#define MVEBU_USER_CMD_CS_MASK (0xF << MVEBU_USER_CMD_CS_OFFSET) +#define MVEBU_USER_CMD_CS_ALL (0xF << MVEBU_USER_CMD_CS_OFFSET) +#define MVEBU_USER_CMD_SR_OFFSET 6 +#define MVEBU_USER_CMD_SR_MASK (0x3 << MVEBU_USER_CMD_SR_OFFSET) +#define MVEBU_USER_CMD_SR_ENTER (0x1 << MVEBU_USER_CMD_SR_OFFSET) +#define MVEBU_MC_PWR_CTRL_REG (MVEBU_DRAM_MAC_BASE + 0x54) +#define MVEBU_MC_AC_ON_DLY_OFFSET 8 +#define MVEBU_MC_AC_ON_DLY_MASK (0xF << MVEBU_MC_AC_ON_DLY_OFFSET) +#define MVEBU_MC_AC_ON_DLY_DEF_VAR (8 << MVEBU_MC_AC_ON_DLY_OFFSET) +#define MVEBU_MC_AC_OFF_DLY_OFFSET 4 +#define MVEBU_MC_AC_OFF_DLY_MASK (0xF << MVEBU_MC_AC_OFF_DLY_OFFSET) +#define MVEBU_MC_AC_OFF_DLY_DEF_VAR (0xC << MVEBU_MC_AC_OFF_DLY_OFFSET) +#define MVEBU_MC_PHY_AUTO_OFF_OFFSET 0 +#define MVEBU_MC_PHY_AUTO_OFF_MASK (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) +#define MVEBU_MC_PHY_AUTO_OFF_EN (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) + +/* this lock synchronize AP multiple cores execution with MSS */ +DEFINE_BAKERY_LOCK(pm_sys_lock); + +/* Weak definitions may be overridden in specific board */ +#pragma weak plat_marvell_get_pm_cfg + +/* AP806 CPU power down /power up definitions */ +enum CPU_ID { + CPU0, + CPU1, + CPU2, + CPU3 +}; + +#define REG_WR_VALIDATE_TIMEOUT (2000) + +#define FEATURE_DISABLE_STATUS_REG \ + (MVEBU_REGS_BASE + 0x6F8230) +#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET 4 +#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK \ + (0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET) + +#ifdef MVEBU_SOC_AP807 + #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 1 + #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 0 +#else + #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 0 + #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 31 +#endif + +#define PWRC_CPUN_CR_REG(cpu_id) \ + (MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10)) +#define PWRC_CPUN_CR_PWR_DN_RQ_MASK \ + (0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET) +#define PWRC_CPUN_CR_ISO_ENABLE_OFFSET 16 +#define PWRC_CPUN_CR_ISO_ENABLE_MASK \ + (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET) +#define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK \ + (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET) + +#define CCU_B_PRCRN_REG(cpu_id) \ + (MVEBU_REGS_BASE + 0x1A50 + \ + ((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4)) +#define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET 0 +#define CCU_B_PRCRN_CPUPORESET_STATIC_MASK \ + (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET) + +/* power switch fingers */ +#define AP807_PWRC_LDO_CR0_REG \ + (MVEBU_REGS_BASE + 0x680000 + 0x100) +#define AP807_PWRC_LDO_CR0_OFFSET 16 +#define AP807_PWRC_LDO_CR0_MASK \ + (0xff << AP807_PWRC_LDO_CR0_OFFSET) +#define AP807_PWRC_LDO_CR0_VAL 0xfc + +/* + * Power down CPU: + * Used to reduce power consumption, and avoid SoC unnecessary temperature rise. + */ +static int plat_marvell_cpu_powerdown(int cpu_id) +{ + uint32_t reg_val; + int exit_loop = REG_WR_VALIDATE_TIMEOUT; + + INFO("Powering down CPU%d\n", cpu_id); + + /* 1. Isolation enable */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 2. Read and check Isolation enabled - verify bit set to 1 */ + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && + exit_loop > 0); + + /* 3. Switch off CPU power */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 4. Read and check Switch Off - verify bit set to 0 */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweroff_error; + + /* 5. De-Assert power ready */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 6. Assert CPU POR reset */ + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK; + mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); + + /* 7. Read and poll on Validate the CPU is out of reset */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + exit_loop--; + } while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweroff_error; + + INFO("Successfully powered down CPU%d\n", cpu_id); + + return 0; + +cpu_poweroff_error: + ERROR("ERROR: Can't power down CPU%d\n", cpu_id); + return -1; +} + +/* + * Power down CPUs 1-3 at early boot stage, + * to reduce power consumption and SoC temperature. + * This is triggered by BLE prior to DDR initialization. + * + * Note: + * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage, + * which is triggered by PSCI ops (pwr_domain_on). + */ +int plat_marvell_early_cpu_powerdown(void) +{ + uint32_t cpu_cluster_status = + mmio_read_32(FEATURE_DISABLE_STATUS_REG) & + FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK; + /* if cpu_cluster_status bit is set, + * that means we have only single cluster + */ + int cluster_count = cpu_cluster_status ? 1 : 2; + + INFO("Powering off unused CPUs\n"); + + /* CPU1 is in AP806 cluster-0, which always exists, so power it down */ + if (plat_marvell_cpu_powerdown(CPU1) == -1) + return -1; + + /* + * CPU2-3 are in AP806 2nd cluster (cluster-1), + * which doesn't exists in dual-core systems. + * so need to check if we have dual-core (single cluster) + * or quad-code (2 clusters) + */ + if (cluster_count == 2) { + /* CPU2-3 are part of 2nd cluster */ + if (plat_marvell_cpu_powerdown(CPU2) == -1) + return -1; + if (plat_marvell_cpu_powerdown(CPU3) == -1) + return -1; + } + + return 0; +} + +/* + * Power up CPU - part of Linux boot stage + */ +static int plat_marvell_cpu_powerup(u_register_t mpidr) +{ + uint32_t reg_val; + int cpu_id = MPIDR_CPU_GET(mpidr), + cluster = MPIDR_CLUSTER_GET(mpidr); + int exit_loop = REG_WR_VALIDATE_TIMEOUT; + + /* calculate absolute CPU ID */ + cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id; + + INFO("Powering on CPU%d\n", cpu_id); + +#ifdef MVEBU_SOC_AP807 + /* Activate 2 power switch fingers */ + reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG); + reg_val &= ~(AP807_PWRC_LDO_CR0_MASK); + reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET); + mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val); + udelay(100); +#endif + + /* 1. Switch CPU power ON */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 2. Wait for CPU on, up to 100 uSec: */ + udelay(100); + + /* 3. Assert power ready */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 4. Read & Validate power ready + * used in order to generate 16 Host CPU cycles + */ + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) && + exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweron_error; + + /* 5. Isolation disable */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 6. Read and check Isolation enabled - verify bit set to 1 */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && + exit_loop > 0); + + /* 7. De Assert CPU POR reset & Core reset */ + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET; + mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); + + /* 8. Read & Validate CPU POR reset */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) && + exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweron_error; + + INFO("Successfully powered on CPU%d\n", cpu_id); + + return 0; + +cpu_poweron_error: + ERROR("ERROR: Can't power up CPU%d\n", cpu_id); + return -1; +} + +static int plat_marvell_cpu_on(u_register_t mpidr) +{ + int cpu_id; + int cluster; + + /* Set barierr */ + dsbsy(); + + /* Get cpu number - use CPU ID */ + cpu_id = MPIDR_CPU_GET(mpidr); + + /* Get cluster number - use affinity level 1 */ + cluster = MPIDR_CLUSTER_GET(mpidr); + + /* Set CPU private UID */ + mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4); + + /* Set the cpu start address to BL1 entry point (align to 0x10000) */ + mmio_write_32(MVEBU_CCU_RVBAR(cpu_id), + PLAT_MARVELL_CPU_ENTRY_ADDR >> 16); + + /* Get the cpu out of reset */ + mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001); + + return 0; +} + +/***************************************************************************** + * A8K handler called to check the validity of the power state + * parameter. + ***************************************************************************** + */ +static int a8k_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + int pstate = psci_get_pstate_type(power_state); + int pwr_lvl = psci_get_pstate_pwrlvl(power_state); + int i; + + if (pwr_lvl > PLAT_MAX_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + + /* Sanity check the requested state */ + if (pstate == PSTATE_TYPE_STANDBY) { + /* + * It's possible to enter standby only on power level 0 + * Ignore any other power level. + */ + if (pwr_lvl != MARVELL_PWR_LVL0) + return PSCI_E_INVALID_PARAMS; + + req_state->pwr_domain_state[MARVELL_PWR_LVL0] = + MARVELL_LOCAL_STATE_RET; + } else { + for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++) + req_state->pwr_domain_state[i] = + MARVELL_LOCAL_STATE_OFF; + } + + /* + * We expect the 'state id' to be zero. + */ + if (psci_get_pstate_id(power_state)) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A8K handler called when a CPU is about to enter standby. + ***************************************************************************** + */ +static void a8k_cpu_standby(plat_local_state_t cpu_state) +{ + if (!is_pm_fw_running()) { + ERROR("%s: needs to be implemented\n", __func__); + panic(); + } +} + +/***************************************************************************** + * A8K handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ***************************************************************************** + */ +static int a8k_pwr_domain_on(u_register_t mpidr) +{ + /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */ + plat_marvell_cpu_powerup(mpidr); + + if (is_pm_fw_running()) { + unsigned int target = + ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2)); + + /* + * pm system synchronization - used to synchronize + * multiple core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU ON IPC Message to MSS */ + mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_ON | target); + } else { + /* proprietary CPU ON exection flow */ + plat_marvell_cpu_on(mpidr); + } + + return 0; +} + +/***************************************************************************** + * A8K handler called to validate the entry point. + ***************************************************************************** + */ +static int a8k_validate_ns_entrypoint(uintptr_t entrypoint) +{ + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A8K 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. + ***************************************************************************** + */ +static void a8k_pwr_domain_off(const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + unsigned int idx = plat_my_core_pos(); + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + /* pm system synchronization - used to synchronize multiple + * core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU OFF IPC Message to MSS */ + mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_OFF); + } else { + INFO("%s: is not supported without SCP\n", __func__); + } +} + +/* Get PM config to power off the SoC */ +void *plat_marvell_get_pm_cfg(void) +{ + return NULL; +} + +/* + * This function should be called on restore from + * "suspend to RAM" state when the execution flow + * has to bypass BootROM image to RAM copy and speed up + * the system recovery + * + */ +static void plat_marvell_exit_bootrom(void) +{ + marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE); +} + +/* + * Prepare for the power off of the system via GPIO + */ +static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg, + register_t *gpio_addr, + register_t *gpio_data) +{ + unsigned int gpio; + unsigned int idx; + unsigned int shift; + unsigned int reg; + unsigned int addr; + gpio_info_t *info; + unsigned int tog_bits; + + assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) && + (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP)); + + /* Prepare GPIOs for PMIC */ + for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { + info = &pm_cfg->cfg.gpio.info[gpio]; + /* Set PMIC GPIO to output mode */ + reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN( + info->cp_index, info->gpio_index)); + mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN( + info->cp_index, info->gpio_index), + reg & ~MVEBU_GPIO_MASK(info->gpio_index)); + + /* Set the appropriate MPP to GPIO mode */ + reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index, + info->gpio_index)); + mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index, + info->gpio_index), + reg & ~MVEBU_MPP_MASK(info->gpio_index)); + } + + /* Wait for MPP & GPIO pre-configurations done */ + mdelay(pm_cfg->cfg.gpio.delay_ms); + + /* Toggle the GPIO values, and leave final step to be triggered + * after DDR self-refresh is enabled + */ + for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) { + tog_bits = pm_cfg->cfg.gpio.seq[idx]; + + /* The GPIOs must be within same GPIO register, + * thus could get the original value by first GPIO + */ + info = &pm_cfg->cfg.gpio.info[0]; + reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT( + info->cp_index, info->gpio_index)); + addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index); + + for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { + shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32; + if (GPIO_LOW == (tog_bits & (1 << gpio))) + reg &= ~(1 << shift); + else + reg |= (1 << shift); + } + + /* Set the GPIO register, for last step just store + * register address and values to system registers + */ + if (idx < pm_cfg->cfg.gpio.step_count - 1) { + mmio_write_32(MVEBU_CP_GPIO_DATA_OUT( + info->cp_index, info->gpio_index), reg); + mdelay(pm_cfg->cfg.gpio.delay_ms); + } else { + /* Save GPIO register and address values for + * finishing the power down operation later + */ + *gpio_addr = addr; + *gpio_data = reg; + } + } +} + +/* + * Prepare for the power off of the system + */ +static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg, + register_t *addr, register_t *data) +{ + switch (pm_cfg->type) { + case PMIC_GPIO: + plat_marvell_power_off_gpio(pm_cfg, addr, data); + break; + default: + break; + } +} + +/***************************************************************************** + * A8K handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + unsigned int idx; + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + idx = plat_my_core_pos(); + + /* pm system synchronization - used to synchronize multiple + * core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU Suspend IPC Message to MSS */ + mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND); + } else { + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + INFO("Suspending to RAM\n"); + + marvell_console_runtime_end(); + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE; + mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom; + +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + + MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), + 2 * sizeof(uintptr_t)); +#endif + /* Flush and disable LLC before going off-power */ + llc_disable(0); + + isb(); + /* + * Do not halt here! + * The function must return for allowing the caller function + * psci_power_up_finish() to do the proper context saving and + * to release the CPU lock. + */ + } +} + +/***************************************************************************** + * A8K 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. + ***************************************************************************** + */ +static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + if (is_pm_fw_running()) { + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH); + } +} + +/***************************************************************************** + * A8K 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. + ***************************************************************************** + */ +static void a8k_pwr_domain_suspend_finish( + const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + gicv2_cpuif_enable(); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH); + } else { + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* Only primary CPU requres platform init */ + if (!plat_my_core_pos()) { + /* Initialize the console to provide + * early debug support + */ + marvell_console_runtime_init(); + + bl31_plat_arch_setup(); + marvell_bl31_platform_setup(); + /* + * Remove suspend to RAM marker from the mailbox + * for treating a regular reset as a cold boot + */ + mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0; + mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0; +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + + MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), + 2 * sizeof(uintptr_t)); +#endif + } + } +} + +/***************************************************************************** + * 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. + ***************************************************************************** + */ +static void a8k_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; +} + +static void +__dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ + struct power_off_method *pm_cfg; + unsigned int srcmd; + unsigned int sdram_reg; + register_t gpio_data = 0, gpio_addr = 0; + + if (is_pm_fw_running()) { + psci_power_down_wfi(); + panic(); + } + + pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg(); + + /* Prepare for power off */ + plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data); + + /* First step to enable DDR self-refresh + * to keep the data during suspend + */ + mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1); + + /* Save DDR self-refresh second step register + * and value to be issued later + */ + sdram_reg = MVEBU_USER_CMD_0_REG; + srcmd = mmio_read_32(sdram_reg); + srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK | + MVEBU_USER_CMD_SR_MASK); + srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL | + MVEBU_USER_CMD_SR_ENTER); + + /* + * Wait for DRAM is done using registers access only. + * At this stage any access to DRAM (procedure call) will + * release it from the self-refresh mode + */ + __asm__ volatile ( + /* Align to a cache line */ + " .balign 64\n\t" + + /* Enter self refresh */ + " str %[srcmd], [%[sdram_reg]]\n\t" + + /* + * Wait 100 cycles for DDR to enter self refresh, by + * doing 50 times two instructions. + */ + " mov x1, #50\n\t" + "1: subs x1, x1, #1\n\t" + " bne 1b\n\t" + + /* Issue the command to trigger the SoC power off */ + " str %[gpio_data], [%[gpio_addr]]\n\t" + + /* Trap the processor */ + " b .\n\t" + : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg), + [gpio_addr] "r" (gpio_addr), [gpio_data] "r" (gpio_data) + : "x1"); + + panic(); +} + +/***************************************************************************** + * A8K handlers to shutdown/reboot the system + ***************************************************************************** + */ + +/* Set a weak stub for platforms that don't configure system power off */ +#pragma weak system_power_off +int system_power_off(void) +{ + return 0; +} + +static void __dead2 a8k_system_off(void) +{ + /* Call the platform specific system power off function */ + system_power_off(); + + /* board doesn't have a system off implementation */ + ERROR("%s: needs to be implemented\n", __func__); + panic(); +} + +void plat_marvell_system_reset(void) +{ + mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0); +} + +static void __dead2 a8k_system_reset(void) +{ + plat_marvell_system_reset(); + + /* we 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 = a8k_cpu_standby, + .pwr_domain_on = a8k_pwr_domain_on, + .pwr_domain_off = a8k_pwr_domain_off, + .pwr_domain_suspend = a8k_pwr_domain_suspend, + .pwr_domain_on_finish = a8k_pwr_domain_on_finish, + .get_sys_suspend_power_state = a8k_get_sys_suspend_power_state, + .pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi, + .system_off = a8k_system_off, + .system_reset = a8k_system_reset, + .validate_power_state = a8k_validate_power_state, + .validate_ns_entrypoint = a8k_validate_ns_entrypoint +}; diff --git a/plat/marvell/armada/a8k/common/plat_pm_trace.c b/plat/marvell/armada/a8k/common/plat_pm_trace.c new file mode 100644 index 0000000..f589ff3 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_pm_trace.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +#ifdef PM_TRACE_ENABLE + +/* core trace APIs */ +core_trace_func funcTbl[PLATFORM_CORE_COUNT] = { + pm_core_0_trace, + pm_core_1_trace, + pm_core_2_trace, + pm_core_3_trace}; + +/***************************************************************************** + * pm_core0_trace + * pm_core1_trace + * pm_core2_trace + * pm_core_3trace + * + * This functions set trace info into core cyclic trace queue in MSS SRAM + * memory space + ***************************************************************************** + */ +void pm_core_0_trace(unsigned int trace) +{ + unsigned int current_position_core_0 = + mmio_read_32(AP_MSS_ATF_CORE_0_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_0_INFO_BASE + + (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_0_INFO_TRACE + + (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_0_CTRL_BASE, + ((current_position_core_0 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_1_trace(unsigned int trace) +{ + unsigned int current_position_core_1 = + mmio_read_32(AP_MSS_ATF_CORE_1_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_1_INFO_BASE + + (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_1_INFO_TRACE + + (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_1_CTRL_BASE, + ((current_position_core_1 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_2_trace(unsigned int trace) +{ + unsigned int current_position_core_2 = + mmio_read_32(AP_MSS_ATF_CORE_2_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_2_INFO_BASE + + (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_2_INFO_TRACE + + (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_2_CTRL_BASE, + ((current_position_core_2 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_3_trace(unsigned int trace) +{ + unsigned int current_position_core_3 = + mmio_read_32(AP_MSS_ATF_CORE_3_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_3_INFO_BASE + + (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_3_INFO_TRACE + + (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_3_CTRL_BASE, + ((current_position_core_3 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} +#endif /* PM_TRACE_ENABLE */ diff --git a/plat/marvell/armada/a8k/common/plat_thermal.c b/plat/marvell/armada/a8k/common/plat_thermal.c new file mode 100644 index 0000000..a2fc0d0 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_thermal.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include + +#define THERMAL_TIMEOUT 1200 + +#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET 0 +#define THERMAL_SEN_CTRL_LSB_STRT_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET) +#define THERMAL_SEN_CTRL_LSB_RST_OFFSET 1 +#define THERMAL_SEN_CTRL_LSB_RST_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET) +#define THERMAL_SEN_CTRL_LSB_EN_OFFSET 2 +#define THERMAL_SEN_CTRL_LSB_EN_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET) + +#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET 16 +#define THERMAL_SEN_CTRL_STATS_VALID_MASK \ + (0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET) +#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET 0 +#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK \ + (0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET) + +#define THERMAL_SEN_OUTPUT_MSB 512 +#define THERMAL_SEN_OUTPUT_COMP 1024 + +struct tsen_regs { + uint32_t ext_tsen_ctrl_lsb; + uint32_t ext_tsen_ctrl_msb; + uint32_t ext_tsen_status; +}; + +static int ext_tsen_probe(struct tsen_config *tsen_cfg) +{ + uint32_t reg, timeout = 0; + struct tsen_regs *base; + + if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) { + ERROR("initial thermal sensor configuration is missing\n"); + return -1; + } + base = (struct tsen_regs *)tsen_cfg->regs_base; + + INFO("initializing thermal sensor\n"); + + /* initialize thermal sensor hardware reset once */ + reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb); + reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */ + reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */ + reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */ + mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg); + + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 && + timeout < THERMAL_TIMEOUT) { + udelay(100); + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + timeout++; + } + + if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) { + ERROR("thermal sensor is not ready\n"); + return -1; + } + + tsen_cfg->tsen_ready = 1; + + VERBOSE("thermal sensor was initialized\n"); + + return 0; +} + +static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp) +{ + uint32_t reg; + struct tsen_regs *base; + + if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) { + ERROR("thermal sensor was not initialized\n"); + return -1; + } + base = (struct tsen_regs *)tsen_cfg->regs_base; + + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >> + THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET); + + /* + * TSEN output format is signed as a 2s complement number + * ranging from-512 to +511. when MSB is set, need to + * calculate the complement number + */ + if (reg >= THERMAL_SEN_OUTPUT_MSB) + reg -= THERMAL_SEN_OUTPUT_COMP; + + if (tsen_cfg->tsen_divisor == 0) { + ERROR("thermal sensor divisor cannot be zero\n"); + return -1; + } + + *temp = ((tsen_cfg->tsen_gain * ((int)reg)) + + tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor; + + return 0; +} + +static struct tsen_config tsen_cfg = { + .tsen_offset = 153400, + .tsen_gain = 425, + .tsen_divisor = 1000, + .tsen_ready = 0, + .regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE, + .ptr_tsen_probe = ext_tsen_probe, + .ptr_tsen_read = ext_tsen_read +}; + +struct tsen_config *marvell_thermal_config_get(void) +{ + return &tsen_cfg; +} diff --git a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c new file mode 100644 index 0000000..6a8e11c --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { +#ifdef SCP_BL2_BASE + /* Fill SCP_BL2 related information if it exists */ + { + .image_id = SCP_BL2_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, 0), + .image_info.image_base = SCP_BL2_BASE, + .image_info.image_max_size = SCP_BL2_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif /* SCP_BL2_BASE */ + +#ifdef EL3_PAYLOAD_BASE + /* Fill EL3 payload related information (BL31 is EL3 payload)*/ + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = EL3_PAYLOAD_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + +#else /* EL3_PAYLOAD_BASE */ + + /* Fill BL31 related information */ + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = BL31_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), +#if DEBUG + .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL, +#endif + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), + .image_info.image_base = BL31_BASE, + .image_info.image_max_size = BL31_LIMIT - BL31_BASE, + +# ifdef BL32_BASE + .next_handoff_image_id = BL32_IMAGE_ID, +# else + .next_handoff_image_id = BL33_IMAGE_ID, +# endif + }, + +# ifdef BL32_BASE + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, SECURE | EXECUTABLE), + .ep_info.pc = BL32_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, +# endif /* BL32_BASE */ + + /* Fill BL33 related information */ + { + .image_id = BL33_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE), +# ifdef PRELOADED_BL33_BASE + .ep_info.pc = PRELOADED_BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), +# else + .ep_info.pc = MARVELL_DRAM_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = MARVELL_DRAM_BASE, + .image_info.image_max_size = MARVELL_DRAM_SIZE, +# endif /* PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +#endif /* EL3_PAYLOAD_BASE */ +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/marvell/armada/common/aarch64/marvell_common.c b/plat/marvell/armada/common/aarch64/marvell_common.c new file mode 100644 index 0000000..21a62d4 --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_common.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_get_ns_image_entrypoint +#pragma weak plat_marvell_get_mmap + +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - Code section; + * - Read-only data section; + * - Coherent memory region, if applicable. + */ +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 + ) +{ + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *) total_base, (void *) (total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, + MT_MEMORY | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *) code_start, (void *) code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, + MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *) rodata_start, (void *) rodata_limit); + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, + MT_RO_DATA | MT_SECURE); + +#if USE_COHERENT_MEM + /* Re-map the coherent memory region */ + VERBOSE("Coherent region: %p - %p\n", + (void *) coh_start, (void *) coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); +#endif + + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_marvell_get_mmap()); + + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} + +unsigned long plat_get_ns_image_entrypoint(void) +{ + return PLAT_MARVELL_NS_IMAGE_OFFSET; +} + +/***************************************************************************** + * Gets SPSR for BL32 entry + ***************************************************************************** + */ +uint32_t marvell_get_spsr_for_bl32_entry(void) +{ + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + return 0; +} + +/***************************************************************************** + * Gets SPSR for BL33 entry + ***************************************************************************** + */ +uint32_t marvell_get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +/***************************************************************************** + * Returns ARM platform specific memory map regions. + ***************************************************************************** + */ +const mmap_region_t *plat_marvell_get_mmap(void) +{ + return plat_marvell_mmap; +} + diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S new file mode 100644 index 0000000..6f625b9 --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#ifndef PLAT_a3700 +#include +#include +#endif +#include +#include + + .weak plat_marvell_calc_core_pos + .weak plat_my_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl platform_mem_init + .globl disable_mmu_dcache + .globl invalidate_tlb_all + .globl platform_unmap_sram + .globl disable_sram + .globl disable_icache + .globl invalidate_icache_all + .globl marvell_exit_bootrom + .globl ca72_l2_enable_unique_clean + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_marvell_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_marvell_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_marvell_calc_core_pos(uint64_t mpidr) + * Helper function to calculate the core position. + * With this function: CorePos = (ClusterId * 2) + + * CoreId + * ----------------------------------------------------- + */ +func plat_marvell_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #7 + ret +endfunc plat_marvell_calc_core_pos + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0, x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE + mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ + mov_imm x2, MARVELL_CONSOLE_BAUDRATE +#ifdef PLAT_a3700 + b console_a3700_core_init +#else + b console_16550_core_init +#endif +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE +#ifdef PLAT_a3700 + + b console_a3700_core_putc +#else + b console_16550_core_putc +#endif +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush() + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : r0 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE +#ifdef PLAT_a3700 + b console_a3700_core_flush +#else + b console_16550_core_flush +#endif +endfunc plat_crash_console_flush + + /* --------------------------------------------------------------------- + * We don't need to carry out any memory initialization on ARM + * platforms. The Secure RAM is accessible straight away. + * --------------------------------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init + + /* ----------------------------------------------------- + * Disable icache, dcache, and MMU + * ----------------------------------------------------- + */ +func disable_mmu_dcache + mrs x0, sctlr_el3 + bic x0, x0, 0x1 /* M bit - MMU */ + bic x0, x0, 0x4 /* C bit - Dcache L1 & L2 */ + msr sctlr_el3, x0 + isb + b mmu_off +mmu_off: + ret +endfunc disable_mmu_dcache + + /* ----------------------------------------------------- + * Disable all TLB entries + * ----------------------------------------------------- + */ +func invalidate_tlb_all + tlbi alle3 + dsb sy + isb + ret +endfunc invalidate_tlb_all + + /* ----------------------------------------------------- + * Disable the i cache + * ----------------------------------------------------- + */ +func disable_icache + mrs x0, sctlr_el3 + bic x0, x0, 0x1000 /* I bit - Icache L1 & L2 */ + msr sctlr_el3, x0 + isb + ret +endfunc disable_icache + + /* ----------------------------------------------------- + * Disable all of the i caches + * ----------------------------------------------------- + */ +func invalidate_icache_all + ic ialluis + isb sy + ret +endfunc invalidate_icache_all + + /* ----------------------------------------------------- + * Clear the SRAM enabling bit to unmap SRAM + * ----------------------------------------------------- + */ +func platform_unmap_sram + ldr x0, =CCU_SRAM_WIN_CR + str wzr, [x0] + ret +endfunc platform_unmap_sram + + /* ----------------------------------------------------- + * Disable the SRAM + * ----------------------------------------------------- + */ +func disable_sram + /* Disable the line lockings. They must be disabled expictly + * or the OS will have problems using the cache */ + ldr x1, =MASTER_LLC_TC0_LOCK + str wzr, [x1] + + /* Invalidate all ways */ + ldr w1, =LLC_WAY_MASK + ldr x0, =MASTER_L2X0_INV_WAY + str w1, [x0] + + /* Finally disable LLC */ + ldr x0, =MASTER_LLC_CTRL + str wzr, [x0] + + ret +endfunc disable_sram + + /* ----------------------------------------------------- + * Operation when exit bootROM: + * Disable the MMU + * Disable and invalidate the dcache + * Unmap and disable the SRAM + * Disable and invalidate the icache + * ----------------------------------------------------- + */ +func marvell_exit_bootrom + /* Save the system restore address */ + mov x28, x0 + + /* Close the caches and MMU */ + bl disable_mmu_dcache + + /* + * There is nothing important in the caches now, + * so invalidate them instead of cleaning. + */ + adr x0, __RW_START__ + adr x1, __RW_END__ + sub x1, x1, x0 + bl inv_dcache_range + bl invalidate_tlb_all + + /* + * Clean the memory mapping of SRAM + * the DDR mapping will remain to enable boot image to execute + */ + bl platform_unmap_sram + + /* Disable the SRAM */ + bl disable_sram + + /* Disable and invalidate icache */ + bl disable_icache + bl invalidate_icache_all + + mov x0, x28 + br x0 +endfunc marvell_exit_bootrom + + /* + * Enable L2 UniqueClean evictions with data + */ +func ca72_l2_enable_unique_clean + + mrs x0, CORTEX_A72_L2ACTLR_EL1 + orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN + msr CORTEX_A72_L2ACTLR_EL1, x0 + + ret +endfunc ca72_l2_enable_unique_clean diff --git a/plat/marvell/armada/common/marvell_bl1_setup.c b/plat/marvell/armada/common/marvell_bl1_setup.c new file mode 100644 index 0000000..7b7cef3 --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl1_setup.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* Weak definitions may be overridden in specific Marvell standard platform */ +#pragma weak bl1_early_platform_setup +#pragma weak bl1_plat_arch_setup +#pragma weak bl1_platform_setup +#pragma weak bl1_plat_sec_mem_layout + +/* Data structure which holds the extents of the RAM for BL1*/ +static meminfo_t bl1_ram_layout; + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_ram_layout; +} + +/* + * BL1 specific platform actions shared between Marvell standard platforms. + */ +void marvell_bl1_early_platform_setup(void) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + + /* Allow BL1 to see the whole Trusted RAM */ + bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE; + bl1_ram_layout.total_size = MARVELL_BL_RAM_SIZE; +} + +void bl1_early_platform_setup(void) +{ + marvell_bl1_early_platform_setup(); +} + +/* + * Perform the very early platform specific architecture setup shared between + * MARVELL standard platforms. This only does basic initialization. Later + * architectural setup (bl1_arch_setup()) does not do anything platform + * specific. + */ +void marvell_bl1_plat_arch_setup(void) +{ + marvell_setup_page_tables(bl1_ram_layout.total_base, + bl1_ram_layout.total_size, + BL1_RO_BASE, + BL1_RO_LIMIT, + BL1_RO_DATA_BASE, + BL1_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el3(0); +} + +void bl1_plat_arch_setup(void) +{ + marvell_bl1_plat_arch_setup(); +} + +/* + * Perform the platform specific architecture setup shared between + * MARVELL standard platforms. + */ +void marvell_bl1_platform_setup(void) +{ + /* Initialise the IO layer and register platform IO devices */ + plat_marvell_io_setup(); +} + +void bl1_platform_setup(void) +{ + marvell_bl1_platform_setup(); +} + +void bl1_plat_prepare_exit(entry_point_info_t *ep_info) +{ +#ifdef EL3_PAYLOAD_BASE + /* + * Program the EL3 payload's entry point address into the CPUs mailbox + * in order to release secondary CPUs from their holding pen and make + * them jump there. + */ + marvell_program_trusted_mailbox(ep_info->pc); + dsbsy(); + sev(); +#endif +} diff --git a/plat/marvell/armada/common/marvell_bl2_setup.c b/plat/marvell/armada/common/marvell_bl2_setup.c new file mode 100644 index 0000000..3c1c391 --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl2_setup.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +/* Weak definitions may be overridden in specific MARVELL standard platform */ +#pragma weak bl2_early_platform_setup2 +#pragma weak bl2_platform_setup +#pragma weak bl2_plat_arch_setup +#pragma weak bl2_plat_sec_mem_layout + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +/***************************************************************************** + * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted SRAM. + * Copy it to a safe location before its reclaimed by later BL2 functionality. + ***************************************************************************** + */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout = *mem_layout; + + /* Initialise the IO layer and register platform IO devices */ + plat_marvell_io_setup(); +} + + +void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct meminfo *mem_layout = (struct meminfo *)arg1; + + marvell_bl2_early_platform_setup(mem_layout); +} + +void bl2_platform_setup(void) +{ + /* Nothing to do */ +} + +/***************************************************************************** + * Perform the very early platform specific architectural setup here. At the + * moment this is only initializes the mmu in a quick and dirty way. + ***************************************************************************** + */ +void marvell_bl2_plat_arch_setup(void) +{ + marvell_setup_page_tables(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el1(0); +} + +void bl2_plat_arch_setup(void) +{ + marvell_bl2_plat_arch_setup(); +} + +int marvell_bl2_handle_post_image_load(unsigned int image_id) +{ + int err = 0; + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + + assert(bl_mem_params); + + switch (image_id) { + + case BL33_IMAGE_ID: + /* BL33 expects to receive the primary CPU MPID (through r0) */ + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl33_entry(); + break; +#ifdef SCP_BL2_BASE + case SCP_BL2_IMAGE_ID: + /* The subsequent handling of SCP_BL2 is platform specific */ + err = bl2_plat_handle_scp_bl2(&bl_mem_params->image_info); + if (err) { + WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); + } + break; +#endif + default: + /* Do nothing in default case */ + break; + } + + return err; + +} + +/******************************************************************************* + * This function can be used by the platforms to update/use image + * information for given `image_id`. + ******************************************************************************/ +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return marvell_bl2_handle_post_image_load(image_id); +} + diff --git a/plat/marvell/armada/common/marvell_bl31_setup.c b/plat/marvell/armada/common/marvell_bl31_setup.c new file mode 100644 index 0000000..26ba906 --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl31_setup.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#ifdef USE_CCI +#include +#endif +#include +#include + +#include +#include +#include + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak bl31_early_platform_setup2 +#pragma weak bl31_platform_setup +#pragma weak bl31_plat_arch_setup +#pragma weak bl31_plat_get_next_image_ep_info +#pragma weak plat_get_syscnt_freq2 + +/***************************************************************************** + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ***************************************************************************** + */ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + assert(sec_state_is_valid(type)); + next_image_info = (type == NON_SECURE) + ? &bl33_image_ep_info : &bl32_image_ep_info; + + return next_image_info; +} + +/***************************************************************************** + * Perform any BL31 early platform setup common to ARM standard platforms. + * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 + * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be + * done before the MMU is initialized so that the memory layout can be used + * while creating page tables. BL2 has flushed this information to memory, so + * we are guaranteed to pick up good data. + ***************************************************************************** + */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + +#if RESET_TO_BL31 + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + +#ifdef BL32_BASE + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry(); +#endif /* BL32_BASE */ + + /* Populate entry point information for BL33 */ + SET_PARAM_HEAD(&bl33_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#else + /* + * In debug builds, we pass a special value in 'plat_params_from_bl2' + * to verify platform parameters from BL2 to BL31. + * In release builds, it's not used. + */ + assert(((unsigned long long)plat_params_from_bl2) == + MARVELL_BL31_PLAT_PARAM_VAL); + + /* + * Check params passed from BL2 should not be NULL, + */ + bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 and BL32 (if present), entry point information. + * They are stored in Secure RAM, in BL2's address space. + */ + while (bl_params != NULL) { + if (bl_params->image_id == BL32_IMAGE_ID) + bl32_image_ep_info = *bl_params->ep_info; + + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; + + bl_params = bl_params->next_params_info; + } +#endif +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) + +{ + marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2, + (void *)arg3); + +#ifdef USE_CCI + /* + * Initialize CCI for this cluster during cold boot. + * 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(); +#endif +} + +/***************************************************************************** + * Perform any BL31 platform setup common to ARM standard platforms + ***************************************************************************** + */ +void marvell_bl31_platform_setup(void) +{ + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_marvell_gic_driver_init(); + plat_marvell_gic_init(); + + /* For Armada-8k-plus family, the SoC includes more than + * a single AP die, but the default die that boots is AP #0. + * For other families there is only one die (#0). + * Initialize psci arch from die 0 + */ + marvell_psci_arch_init(0); +} + +/***************************************************************************** + * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM + * standard platforms + ***************************************************************************** + */ +void marvell_bl31_plat_runtime_setup(void) +{ + console_switch_state(CONSOLE_FLAG_RUNTIME); + + /* Initialize the runtime console */ + marvell_console_runtime_init(); +} + +void bl31_platform_setup(void) +{ + marvell_bl31_platform_setup(); +} + +void bl31_plat_runtime_setup(void) +{ + marvell_bl31_plat_runtime_setup(); +} + +/***************************************************************************** + * Perform the very early platform specific architectural setup shared between + * ARM standard platforms. This only does basic initialization. Later + * architectural setup (bl31_arch_setup()) does not do anything platform + * specific. + ***************************************************************************** + */ +void marvell_bl31_plat_arch_setup(void) +{ + marvell_setup_page_tables(BL31_BASE, + BL31_END - BL31_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + +#if BL31_CACHE_DISABLE + enable_mmu_el3(DISABLE_DCACHE); + INFO("Cache is disabled in BL3\n"); +#else + enable_mmu_el3(0); +#endif +} + +void bl31_plat_arch_setup(void) +{ + marvell_bl31_plat_arch_setup(); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return PLAT_REF_CLK_IN_HZ; +} diff --git a/plat/marvell/armada/common/marvell_cci.c b/plat/marvell/armada/common/marvell_cci.c new file mode 100644 index 0000000..80351ae --- /dev/null +++ b/plat/marvell/armada/common/marvell_cci.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +static const int cci_map[] = { + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX +}; + +/**************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way ARM CCI driver is initialised and used. + **************************************************************************** + */ +#pragma weak plat_marvell_interconnect_init +#pragma weak plat_marvell_interconnect_enter_coherency +#pragma weak plat_marvell_interconnect_exit_coherency + + +/**************************************************************************** + * Helper function to initialize ARM CCI driver. + **************************************************************************** + */ +void plat_marvell_interconnect_init(void) +{ + cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); +} + +/**************************************************************************** + * Helper function to place current master into coherency + **************************************************************************** + */ +void plat_marvell_interconnect_enter_coherency(void) +{ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} + +/**************************************************************************** + * Helper function to remove current master from coherency + **************************************************************************** + */ +void plat_marvell_interconnect_exit_coherency(void) +{ + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk new file mode 100644 index 0000000..f5f0c41 --- /dev/null +++ b/plat/marvell/armada/common/marvell_common.mk @@ -0,0 +1,72 @@ +# 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 + +include plat/marvell/version.mk +include plat/marvell/marvell.mk + +VERSION_STRING +=(Marvell-${SUBVERSION}) + +SEPARATE_CODE_AND_RODATA := 1 + +# flag to switch from PLL to ARO +ARO_ENABLE := 0 +$(eval $(call add_define,ARO_ENABLE)) +# Enable/Disable LLC +LLC_ENABLE := 1 +$(eval $(call add_define,LLC_ENABLE)) + +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_INCLUDES += -I$(MARVELL_PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_PLAT_INCLUDE_BASE)/common/aarch64 + + +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S \ + $(MARVELL_COMMON_BASE)/marvell_console.c + +BL1_SOURCES += drivers/delay_timer/delay_timer.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + $(MARVELL_PLAT_BASE)/common/marvell_bl1_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ + $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c + +ifdef EL3_PAYLOAD_BASE +# Need the arm_program_trusted_mailbox() function to release secondary CPUs from +# their holding pen +endif + +BL2_SOURCES += drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + common/desc_image_load.c \ + $(MARVELL_PLAT_BASE)/common/marvell_bl2_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \ + $(MARVELL_PLAT_BASE)/common/marvell_image_load.c + + +BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_pm.c \ + $(MARVELL_PLAT_BASE)/common/marvell_topology.c \ + plat/common/plat_psci_common.c \ + $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c \ + drivers/delay_timer/delay_timer.c + +# PSCI functionality +$(eval $(call add_define,CONFIG_ARM64)) + +# MSS (SCP) build +ifeq (${MSS_SUPPORT}, 1) +include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk +endif + +fip: mrvl_flash diff --git a/plat/marvell/armada/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c new file mode 100644 index 0000000..1716661 --- /dev/null +++ b/plat/marvell/armada/common/marvell_console.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include + +#include +#include + +#include + +#ifdef PLAT_a3700 +#include +#define console_marvell_register console_a3700_register +#else +#include +#define console_marvell_register console_16550_register +#endif + +static console_t marvell_boot_console; +static console_t marvell_runtime_console; + +/******************************************************************************* + * Functions that set up the console + ******************************************************************************/ + +/* Initialize the console to provide early debug support */ +void marvell_console_boot_init(void) +{ + int rc = + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_boot_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT); +} + +void marvell_console_boot_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_boot_console); +} + +/* Initialize the runtime console */ +void marvell_console_runtime_init(void) +{ + int rc = + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_runtime_console); + if (rc == 0) + panic(); + + console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME); +} + +void marvell_console_runtime_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_runtime_console); +} diff --git a/plat/marvell/armada/common/marvell_ddr_info.c b/plat/marvell/armada/common/marvell_ddr_info.c new file mode 100644 index 0000000..7340996 --- /dev/null +++ b/plat/marvell/armada/common/marvell_ddr_info.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include + +#define DRAM_CH0_MMAP_LOW_REG(iface, cs, base) \ + (base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8) +#define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base) \ + (DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4) +#define DRAM_CS_VALID_ENABLED_MASK 0x1 +#define DRAM_AREA_LENGTH_OFFS 16 +#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS) +#define DRAM_START_ADDRESS_L_OFFS 23 +#define DRAM_START_ADDRESS_L_MASK \ + (0x1ff << DRAM_START_ADDRESS_L_OFFS) +#define DRAM_START_ADDR_HTOL_OFFS 32 + +#define DRAM_MAX_CS_NUM 2 + +#define DRAM_CS_ENABLED(iface, cs, base) \ + (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ + DRAM_CS_VALID_ENABLED_MASK) +#define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \ + (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ + DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS + +/* Mapping between DDR area length and real DDR size is specific and looks like + * bellow: + * 0 => 384 MB + * 1 => 768 MB + * 2 => 1536 MB + * 3 => 3 GB + * 4 => 6 GB + * + * 7 => 8 MB + * 8 => 16 MB + * 9 => 32 MB + * 10 => 64 MB + * 11 => 128 MB + * 12 => 256 MB + * 13 => 512 MB + * 14 => 1 GB + * 15 => 2 GB + * 16 => 4 GB + * 17 => 8 GB + * 18 => 16 GB + * 19 => 32 GB + * 20 => 64 GB + * 21 => 128 GB + * 22 => 256 GB + * 23 => 512 GB + * 24 => 1 TB + * 25 => 2 TB + * 26 => 4 TB + * + * to calculate real size we need to use two different formulas: + * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD) + * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN) + * using mentioned formulas we cover whole mapping between "Area length" value + * and real size (see above mapping). + */ +#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26)) +#define GET_DRAM_REGION_SIZE_EVEN(C) ((uint64_t)1 << ((C) + 16)) +#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4) +#define GET_DRAM_REGION_SIZE_ODD(C) ((uint64_t)0x18000000 << (C)) + + +uint64_t mvebu_get_dram_size(uint64_t ap_base_addr) +{ + uint64_t mem_size = 0; + uint8_t region_code; + uint8_t cs, iface; + + for (iface = 0; iface < DRAM_MAX_IFACE; iface++) { + for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) { + + /* Exit loop on first disabled DRAM CS */ + if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr)) + break; + + /* Decode area length for current CS + * from register value + */ + region_code = + GET_DRAM_REGION_SIZE_CODE(iface, cs, + ap_base_addr); + + if (DRAM_REGION_SIZE_EVEN(region_code)) { + mem_size += + GET_DRAM_REGION_SIZE_EVEN(region_code); + } else if (DRAM_REGION_SIZE_ODD(region_code)) { + mem_size += + GET_DRAM_REGION_SIZE_ODD(region_code); + } else { + WARN("%s: Invalid mem region (0x%x) CS#%d\n", + __func__, region_code, cs); + return 0; + } + } + } + + return mem_size; +} diff --git a/plat/marvell/armada/common/marvell_gicv2.c b/plat/marvell/armada/common/marvell_gicv2.c new file mode 100644 index 0000000..2505c9f --- /dev/null +++ b/plat/marvell/armada/common/marvell_gicv2.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* + * The following functions are defined as weak to allow a platform to override + * the way the GICv2 driver is initialised and used. + */ +#pragma weak plat_marvell_gic_driver_init +#pragma weak plat_marvell_gic_init + +#define A7K8K_PIC_CAUSE_REG 0xf03f0100 +#define A7K8K_PIC0_MASK_REG 0xf03f0108 + +#define A7K8K_PIC_PMUOF_IRQ_MASK (1 << 17) + +#define A7K8K_PIC_MAX_IRQS 32 +#define A7K8K_PIC_MAX_IRQ_MASK ((1UL << A7K8K_PIC_MAX_IRQS) - 1) + +#define A7K8K_ODMIN_SET_REG 0xf0300040 +#define A7K8K_ODMI_PMU_IRQ(idx) ((2 + idx) << 12) + +#define A7K8K_ODMI_PMU_GIC_IRQ(idx) (130 + idx) + +static DEFINE_BAKERY_LOCK(a7k8k_irq_lock); + +/* + * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 + * interrupts. + */ +static const interrupt_prop_t marvell_interrupt_props[] = { + PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0) +}; + +static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; + +/* + * Ideally `marvell_gic_data` structure definition should be a `const` but it is + * kept as modifiable for overwriting with different GICD and GICC base when + * running on FVP with VE memory map. + */ +static gicv2_driver_data_t marvell_gic_data = { + .gicd_base = PLAT_MARVELL_GICD_BASE, + .gicc_base = PLAT_MARVELL_GICC_BASE, + .interrupt_props = marvell_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), + .target_masks = target_mask_array, + .target_masks_num = ARRAY_SIZE(target_mask_array), +}; + +/* + * ARM common helper to initialize the GICv2 only driver. + */ +void plat_marvell_gic_driver_init(void) +{ + gicv2_driver_init(&marvell_gic_data); +} + +static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + unsigned int idx = plat_my_core_pos(); + uint32_t irq; + + bakery_lock_get(&a7k8k_irq_lock); + + /* Acknowledge IRQ */ + irq = plat_ic_acknowledge_interrupt(); + + plat_ic_end_of_interrupt(irq); + + if (irq != MARVELL_IRQ_PIC0) { + bakery_lock_release(&a7k8k_irq_lock); + return 0; + } + + /* Acknowledge PMU overflow IRQ in PIC0 */ + mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); + + /* Trigger ODMI Frame IRQ */ + mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); + + bakery_lock_release(&a7k8k_irq_lock); + + return 0; +} + +void mvebu_pmu_interrupt_enable(void) +{ + unsigned int idx; + uint32_t flags; + int32_t rc; + + /* Reset PIC */ + mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); + /* Unmask PMU overflow IRQ in PIC0 */ + mmio_clrbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); + + /* Configure ODMI Frame IRQs as edge triggered */ + for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) + gicv2_interrupt_set_cfg(A7K8K_ODMI_PMU_GIC_IRQ(idx), + GIC_INTR_CFG_EDGE); + + /* + * Register IRQ handler as INTR_TYPE_S_EL1 as its the only valid type + * for GICv2 in ARM-TF. + */ + flags = 0U; + set_interrupt_rm_flag((flags), (NON_SECURE)); + rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, + a7k8k_pmu_interrupt_handler, + flags); + if (rc != 0) + panic(); +} + +void mvebu_pmu_interrupt_disable(void) +{ + /* Reset PIC */ + mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); + /* Mask PMU overflow IRQ in PIC0 */ + mmio_setbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); +} + +void plat_marvell_gic_init(void) +{ + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_set_pe_target_mask(plat_my_core_pos()); + gicv2_cpuif_enable(); +} diff --git a/plat/marvell/armada/common/marvell_gicv3.c b/plat/marvell/armada/common/marvell_gicv3.c new file mode 100644 index 0000000..0bd5545 --- /dev/null +++ b/plat/marvell/armada/common/marvell_gicv3.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include + +#include +#include + +/****************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way the GICv3 driver is initialised and used. + ****************************************************************************** + */ +#pragma weak plat_marvell_gic_driver_init +#pragma weak plat_marvell_gic_init +#pragma weak plat_marvell_gic_cpuif_enable +#pragma weak plat_marvell_gic_cpuif_disable +#pragma weak plat_marvell_gic_pcpu_init + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static const interrupt_prop_t marvell_interrupt_props[] = { + PLAT_MARVELL_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_MARVELL_G0_IRQ_PROPS(INTR_GROUP0) +}; + +/* + * We save and restore the GICv3 context on system suspend. Allocate the + * data in the designated EL3 Secure carve-out memory + */ +static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + +/* + * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register + * to core position. + * + * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity + * values read from GICR_TYPER don't have an MT field. To reuse the same + * translation used for CPUs, we insert MT bit read from the PE's MPIDR into + * that read from GICR_TYPER. + * + * Assumptions: + * + * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; + * - No CPUs implemented in the system use affinity level 3. + */ +static unsigned int marvell_gicv3_mpidr_hash(u_register_t mpidr) +{ + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + return plat_marvell_calc_core_pos(mpidr); +} + +const gicv3_driver_data_t marvell_gic_data = { + .gicd_base = PLAT_MARVELL_GICD_BASE, + .gicr_base = PLAT_MARVELL_GICR_BASE, + .interrupt_props = marvell_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = marvell_gicv3_mpidr_hash +}; + +void plat_marvell_gic_driver_init(void) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ +#if IMAGE_BL31 + gicv3_driver_init(&marvell_gic_data); +#endif +} + +/****************************************************************************** + * Marvell common helper to initialize the GIC. Only invoked by BL31 + ****************************************************************************** + */ +void plat_marvell_gic_init(void) +{ + /* Initialize GIC-600 Multi Chip feature, + * only if the maximum number of north bridges + * is more than 1 - otherwise no need for multi + * chip feature initialization + */ +#if (PLAT_MARVELL_NORTHB_COUNT > 1) + if (gic600_multi_chip_init()) + ERROR("GIC-600 Multi Chip initialization failed\n"); +#endif + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to enable the GIC CPU interface + ****************************************************************************** + */ +void plat_marvell_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to disable the GIC CPU interface + ****************************************************************************** + */ +void plat_marvell_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to init. the per-cpu redistributor interface in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to save SPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_save(void) +{ + + /* + * If an ITS is available, save its context before + * the Redistributor using: + * gicv3_its_save_disable(gits_base, &its_ctx[i]) + * Additionally, an implementation-defined sequence may + * be required to save the whole ITS state. + */ + + /* + * Save the GIC Redistributors and ITS contexts before the + * Distributor context. As we only handle SYSTEM SUSPEND API, + * we only need to save the context of the CPU that is issuing + * the SYSTEM SUSPEND call, i.e. the current CPU. + */ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + + /* Save the GIC Distributor context */ + gicv3_distif_save(&dist_ctx); + + /* + * From here, all the components of the GIC can be safely powered down + * as long as there is an alternate way to handle wakeup interrupt + * sources. + */ +} + +/****************************************************************************** + * Marvell common helper to restore SPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_restore(void) +{ + /* Restore the GIC Distributor context */ + gicv3_distif_init_restore(&dist_ctx); + + /* + * Restore the GIC Redistributor and ITS contexts after the + * Distributor context. As we only handle SYSTEM SUSPEND API, + * we only need to restore the context of the CPU that issued + * the SYSTEM SUSPEND call. + */ + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); + + /* + * If an ITS is available, restore its context after + * the Redistributor using: + * gicv3_its_restore(gits_base, &its_ctx[i]) + * An implementation-defined sequence may be required to + * restore the whole ITS state. The ITS must also be + * re-enabled after this sequence has been executed. + */ +} + +/****************************************************************************** + * Marvell common helper to save per-cpu PPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_pcpu_save(void) +{ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); +} + +/****************************************************************************** + * Marvell common helper to restore per-cpu PPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_pcpu_restore(void) +{ + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); +} diff --git a/plat/marvell/armada/common/marvell_image_load.c b/plat/marvell/armada/common/marvell_image_load.c new file mode 100644 index 0000000..be16b08 --- /dev/null +++ b/plat/marvell/armada/common/marvell_image_load.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/marvell/armada/common/marvell_io_storage.c b/plat/marvell/armada/common/marvell_io_storage.c new file mode 100644 index 0000000..065f956 --- /dev/null +++ b/plat/marvell/armada/common/marvell_io_storage.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = PLAT_MARVELL_FIP_BASE, + .length = PLAT_MARVELL_FIP_MAX_SIZE +}; + +static const io_uuid_spec_t bl2_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t scp_bl2_uuid_spec = { + .uuid = UUID_SCP_FIRMWARE_SCP_BL2, +}; + +static const io_uuid_spec_t bl31_uuid_spec = { + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, +}; +static const io_uuid_spec_t bl32_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32, +}; +static const io_uuid_spec_t bl33_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +/* By default, Marvell platforms load images from the FIP */ +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl2_uuid_spec, + open_fip + }, + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&scp_bl2_uuid_spec, + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl31_uuid_spec, + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_uuid_spec, + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl33_uuid_spec, + open_fip + }, +}; + + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_marvell_io_setup +#pragma weak plat_marvell_get_alt_image_source + + +static int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + + +static int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} + + +void marvell_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_marvell_io_setup(void) +{ + marvell_io_setup(); +} + +int plat_marvell_get_alt_image_source( + unsigned int image_id __attribute__((unused)), + uintptr_t *dev_handle __attribute__((unused)), + uintptr_t *image_spec __attribute__((unused))) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_marvell_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} + +/* + * See if a Firmware Image Package is available, + * by checking if TOC is valid or not. + */ +int marvell_io_is_toc_valid(void) +{ + int result; + + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + + return result == 0; +} diff --git a/plat/marvell/armada/common/marvell_pm.c b/plat/marvell/armada/common/marvell_pm.c new file mode 100644 index 0000000..3c675b2 --- /dev/null +++ b/plat/marvell/armada/common/marvell_pm.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include + +/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */ +extern const plat_psci_ops_t plat_arm_psci_pm_ops; + +/***************************************************************************** + * Private function to program the mailbox for a cpu before it is released + * from reset. This function assumes that the mail box base is within + * the MARVELL_SHARED_RAM region + ***************************************************************************** + */ +void marvell_program_mailbox(uintptr_t address) +{ + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* + * Ensure that the PLAT_MARVELL_MAILBOX_BASE is within + * MARVELL_SHARED_RAM region. + */ + assert((PLAT_MARVELL_MAILBOX_BASE >= MARVELL_SHARED_RAM_BASE) && + ((PLAT_MARVELL_MAILBOX_BASE + sizeof(*mailbox)) <= + (MARVELL_SHARED_RAM_BASE + MARVELL_SHARED_RAM_SIZE))); + + mailbox[MBOX_IDX_MAGIC] = MVEBU_MAILBOX_MAGIC_NUM; + mailbox[MBOX_IDX_SEC_ADDR] = address; + + /* 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 + + 8 * MBOX_IDX_MAGIC, + 2 * sizeof(uint64_t)); +#endif +} + +/***************************************************************************** + * The ARM Standard platform definition of platform porting API + * `plat_setup_psci_ops`. + ***************************************************************************** + */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_arm_psci_pm_ops; + + /* Setup mailbox with entry point. */ + marvell_program_mailbox(sec_entrypoint); + return 0; +} diff --git a/plat/marvell/armada/common/marvell_topology.c b/plat/marvell/armada/common/marvell_topology.c new file mode 100644 index 0000000..a40ff6f --- /dev/null +++ b/plat/marvell/armada/common/marvell_topology.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* The power domain tree descriptor */ +unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1]; + +/***************************************************************************** + * This function dynamically constructs the topology according to + * PLAT_MARVELL_CLUSTER_COUNT and returns it. + ***************************************************************************** + */ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + /* + * The power domain tree does not have a single system level power + * domain i.e. a single root node. The first entry in the power domain + * descriptor specifies the number of power domains at the highest power + * level. + * For Marvell Platform this is the number of cluster power domains. + */ + marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT; + + for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++) + marvell_power_domain_tree_desc[i + 1] = + PLAT_MARVELL_CLUSTER_CORE_COUNT; + + return marvell_power_domain_tree_desc; +} + +/***************************************************************************** + * This function validates an MPIDR by checking whether it falls within the + * acceptable bounds. An error code (-1) is returned if an incorrect mpidr + * is passed. + ***************************************************************************** + */ +int marvell_check_mpidr(u_register_t mpidr) +{ + unsigned int nb_id, cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK | + MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) + return -1; + + /* Get north bridge ID */ + nb_id = MPIDR_AFFLVL3_VAL(mpidr); + cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + + if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT) + return -1; + + if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT) + return -1; + + if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT) + return -1; + + return 0; +} + +/***************************************************************************** + * This function implements a part of the critical interface between the PSCI + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ***************************************************************************** + */ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + if (marvell_check_mpidr(mpidr) == -1) + return -1; + + return plat_marvell_calc_core_pos(mpidr); +} diff --git a/plat/marvell/armada/common/mrvl_sip_svc.c b/plat/marvell/armada/common/mrvl_sip_svc.c new file mode 100644 index 0000000..0291024 --- /dev/null +++ b/plat/marvell/armada/common/mrvl_sip_svc.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "comphy/phy-comphy-cp110.h" +#include + +/* #define DEBUG_COMPHY */ +#ifdef DEBUG_COMPHY +#define debug(format...) NOTICE(format) +#else +#define debug(format, arg...) +#endif + +/* 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 +#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004 +#define MV_SIP_COMPHY_DIG_RESET 0x82000005 + +/* Miscellaneous FID's' */ +#define MV_SIP_DRAM_SIZE 0x82000010 +#define MV_SIP_LLC_ENABLE 0x82000011 +#define MV_SIP_PMU_IRQ_ENABLE 0x82000012 +#define MV_SIP_PMU_IRQ_DISABLE 0x82000013 + +#define MAX_LANE_NR 6 +#define MVEBU_COMPHY_OFFSET 0x441000 +#define MVEBU_CP_BASE_MASK (~0xffffff) + +/* 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_DIG_RESET) + +_Bool is_cp_range_valid(u_register_t *addr) +{ + int cp_nr; + + *addr &= MVEBU_CP_BASE_MASK; + for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) { + if (*addr == MVEBU_CP_REGS_BASE(cp_nr)) + return true; + } + + return false; +} + +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; + int i; + + debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", + __func__, smc_fid, x1, x2, x3); + + if (is_comphy_fid(smc_fid)) { + /* validate address passed via x1 */ + if (!is_cp_range_valid(&x1)) { + ERROR("%s: Wrong smc (0x%x) address: %lx\n", + __func__, smc_fid, x1); + SMC_RET1(handle, SMC_UNK); + } + + x1 += MVEBU_COMPHY_OFFSET; + + if (x2 >= 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_base, x2: comphy_index, x3: comphy_mode */ + ret = mvebu_cp110_comphy_power_on(x1, x2, x3); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_POWER_OFF: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_power_off(x1, x2, x3); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_PLL_LOCK: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_is_pll_locked(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_XFI_TRAIN: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_xfi_rx_training(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_DIG_RESET: + /* x1: comphy_base, x2: comphy_index, x3: mode, x4: command */ + ret = mvebu_cp110_comphy_digital_reset(x1, x2, x3, x4); + SMC_RET1(handle, ret); + + /* Miscellaneous FID's' */ + case MV_SIP_DRAM_SIZE: + ret = mvebu_get_dram_size(MVEBU_REGS_BASE); + SMC_RET1(handle, ret); + case MV_SIP_LLC_ENABLE: + for (i = 0; i < ap_get_count(); i++) + llc_runtime_enable(i); + + SMC_RET1(handle, 0); +#ifdef MVEBU_PMU_IRQ_WA + case MV_SIP_PMU_IRQ_ENABLE: + mvebu_pmu_interrupt_enable(); + SMC_RET1(handle, 0); + case MV_SIP_PMU_IRQ_DISABLE: + mvebu_pmu_interrupt_disable(); + SMC_RET1(handle, 0); +#endif + + 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/common/mss/mss_common.mk b/plat/marvell/armada/common/mss/mss_common.mk new file mode 100644 index 0000000..050d88d --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_common.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + + +PLAT_MARVELL := plat/marvell/armada +MSS_SOURCE := $(PLAT_MARVELL)/common/mss + +BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \ + $(PLAT_MARVELL)/common/plat_delay_timer.c \ + drivers/delay_timer/delay_timer.c \ + $(MARVELL_DRV) \ + $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c + +PLAT_INCLUDES += -I$(MSS_SOURCE) diff --git a/plat/marvell/armada/common/mss/mss_ipc_drv.c b/plat/marvell/armada/common/mss/mss_ipc_drv.c new file mode 100644 index 0000000..70ccfa5 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_ipc_drv.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include +#include + +#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK + +#define IPC_CH_NUM_OF_MSG (16) +#define IPC_CH_MSG_IDX (-1) + +unsigned long mv_pm_ipc_msg_base; +unsigned int mv_pm_ipc_queue_size; + +unsigned int msg_sync; +int msg_index = IPC_CH_MSG_IDX; + +/****************************************************************************** + * mss_pm_ipc_init + * + * DESCRIPTION: Initialize PM IPC infrastructure + ****************************************************************************** + */ +int mv_pm_ipc_init(unsigned long ipc_control_addr) +{ + struct mss_pm_ipc_ctrl *ipc_control = + (struct mss_pm_ipc_ctrl *)ipc_control_addr; + + /* Initialize PM IPC control block */ + mv_pm_ipc_msg_base = ipc_control->msg_base_address | + IPC_MSG_BASE_MASK; + mv_pm_ipc_queue_size = ipc_control->queue_size; + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_queue_addr_get + * + * DESCRIPTION: Returns the IPC queue address + ****************************************************************************** + */ +unsigned int mv_pm_ipc_queue_addr_get(void) +{ + unsigned int addr; + + inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + msg_index = msg_index + 1; + if (msg_index >= IPC_CH_NUM_OF_MSG) + msg_index = 0; + + addr = (unsigned int)(mv_pm_ipc_msg_base + + (msg_index * mv_pm_ipc_queue_size)); + + flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + + return addr; +} + +/****************************************************************************** + * mv_pm_ipc_msg_rx + * + * DESCRIPTION: Retrieve message from IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC); + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_msg_tx + * + * DESCRIPTION: Send message via IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, + unsigned int cluster_power_state) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + /* Validate the entry for message placed by the host is free */ + if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) { + inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + msg_sync = msg_sync + 1; + flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + + mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync); + mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id); + mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id); + mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, + cluster_power_state); + mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY); + + } else { + ERROR("%s: FAILED\n", __func__); + } + + return 0; +} diff --git a/plat/marvell/armada/common/mss/mss_ipc_drv.h b/plat/marvell/armada/common/mss/mss_ipc_drv.h new file mode 100644 index 0000000..bcb4b2d --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_ipc_drv.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_IPC_DRV_H +#define MSS_IPC_DRV_H + +#include + +#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */ +/* Increament for each version */ +#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001) +#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \ + MV_PM_FW_IPC_VERSION_SEQ) + +#define IPC_MSG_STATE_LOC (0x0) +#define IPC_MSG_SYNC_ID_LOC (0x4) +#define IPC_MSG_ID_LOC (0x8) +#define IPC_MSG_RET_CH_ID_LOC (0xC) +#define IPC_MSG_CPU_ID_LOC (0x10) +#define IPC_MSG_CLUSTER_ID_LOC (0x14) +#define IPC_MSG_SYSTEM_ID_LOC (0x18) +#define IPC_MSG_POWER_STATE_LOC (0x1C) +#define IPC_MSG_REPLY_LOC (0x20) +#define IPC_MSG_RESERVED_LOC (0x24) + +/* IPC initialization state */ +enum mss_pm_ipc_init_state { + IPC_UN_INITIALIZED = 1, + IPC_INITIALIZED = 2 +}; + +/* IPC queue direction */ +enum mss_pm_ipc_init_msg_dir { + IPC_MSG_TX = 0, + IPC_MSG_RX = 1 +}; + +/* IPC message state */ +enum mss_pm_ipc_msg_state { + IPC_MSG_FREE = 1, + IPC_MSG_OCCUPY = 2 + +}; + +/* IPC control block */ +struct mss_pm_ipc_ctrl { + unsigned int ctrl_base_address; + unsigned int msg_base_address; + unsigned int num_of_channels; + unsigned int channel_size; + unsigned int queue_size; +}; + +/* IPC message types */ +enum mss_pm_msg_id { + PM_IPC_MSG_CPU_SUSPEND = 1, + PM_IPC_MSG_CPU_OFF = 2, + PM_IPC_MSG_CPU_ON = 3, + PM_IPC_MSG_SYSTEM_RESET = 4, + PM_IPC_MSG_SYSTEM_SUSPEND = 5, + PM_IPC_MAX_MSG +}; + +struct mss_pm_ipc_msg { + unsigned int msg_sync_id; /* + * Sync number, validate message + * reply corresponding to message + * received + */ + unsigned int msg_id; /* Message Id */ + unsigned int ret_channel_id; /* IPC channel reply */ + unsigned int cpu_id; /* CPU Id */ + unsigned int cluster_id; /* Cluster Id */ + unsigned int system_id; /* System Id */ + unsigned int power_state; + unsigned int msg_reply; /* Message reply */ +}; + +/* IPC queue */ +struct mss_pm_ipc_queue { + unsigned int state; + struct mss_pm_ipc_msg msg; +}; + +/* IPC channel */ +struct mss_pm_ipc_ch { + struct mss_pm_ipc_queue *tx_queue; + struct mss_pm_ipc_queue *rx_queue; +}; + +/***************************************************************************** + * mv_pm_ipc_init + * + * DESCRIPTION: Initialize PM IPC infrastructure + ***************************************************************************** + */ +int mv_pm_ipc_init(unsigned long ipc_control_addr); + +/***************************************************************************** + * mv_pm_ipc_msg_rx + * + * DESCRIPTION: Retrieve message from IPC channel + ***************************************************************************** + */ +int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg); + +/***************************************************************************** + * mv_pm_ipc_msg_tx + * + * DESCRIPTION: Send message via IPC channel + ***************************************************************************** + */ +int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, + unsigned int cluster_power_state); + +#endif /* MSS_IPC_DRV_H */ diff --git a/plat/marvell/armada/common/mss/mss_mem.h b/plat/marvell/armada/common/mss/mss_mem.h new file mode 100644 index 0000000..5d68ac7 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_mem.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_MEM_H +#define MSS_MEM_H + +/* MSS SRAM Memory base */ +#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000) + +enum mss_pm_ctrl_handshake { + MSS_UN_INITIALIZED = 0, + MSS_COMPATIBILITY_ERROR = 1, + MSS_ACKNOWLEDGMENT = 2, + HOST_ACKNOWLEDGMENT = 3 +}; + +enum mss_pm_ctrl_rtos_env { + MSS_MULTI_PROCESS_ENV = 0, + MSS_SINGLE_PROCESS_ENV = 1, + MSS_MAX_PROCESS_ENV +}; + +struct mss_pm_ctrl_block { + /* This field is used to synchronize the Host + * and MSS initialization sequence + * Valid Values + * 0 - Un-Initialized + * 1 - Compatibility Error + * 2 - MSS Acknowledgment + * 3 - Host Acknowledgment + */ + unsigned int handshake; + + /* + * This field include Host IPC version. Once received by the MSS + * It will be compared to MSS IPC version and set MSS Acknowledge to + * "compatibility error" in case there is no match + */ + unsigned int ipc_version; + unsigned int ipc_base_address; + unsigned int ipc_state; + + /* Following fields defines firmware core architecture */ + unsigned int num_of_cores; + unsigned int num_of_clusters; + unsigned int num_of_cores_per_cluster; + + /* Following fields define pm trace debug base address */ + unsigned int pm_trace_ctrl_base_address; + unsigned int pm_trace_info_base_address; + unsigned int pm_trace_info_core_size; + + unsigned int ctrl_blk_size; +}; + +#endif /* MSS_MEM_H */ diff --git a/plat/marvell/armada/common/mss/mss_scp_bl2_format.h b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h new file mode 100644 index 0000000..7150f0a --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_SCP_BL2_FORMAT_H +#define MSS_SCP_BL2_FORMAT_H + +#define MAX_NR_OF_FILES 8 +#define FILE_MAGIC 0xddd01ff +#define HEADER_VERSION 0x1 + +#define MSS_IDRAM_SIZE 0x10000 /* 64KB */ +#define MG_SRAM_SIZE 0x20000 /* 128KB */ + +/* Types definitions */ +typedef struct file_header { + /* Magic specific for concatenated file (used for validation) */ + uint32_t magic; + uint32_t nr_of_imgs; /* Number of images concatenated */ +} file_header_t; + +/* Types definitions */ +enum cm3_t { + MSS_AP, + MSS_CP0, + MSS_CP1, + MSS_CP2, + MSS_CP3, + MG_CP0, + MG_CP1, + MG_CP2, +}; + +typedef struct img_header { + uint32_t type; /* CM3 type, can be one of cm3_t */ + uint32_t length; /* Image length */ + uint32_t version; /* For sanity checks and future + * extended functionality + */ +} img_header_t; + +#endif /* MSS_SCP_BL2_FORMAT_H */ diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.c b/plat/marvell/armada/common/mss/mss_scp_bootloader.c new file mode 100644 index 0000000..4473d81 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MSS_DMA_SRCBR(base) (base + 0xC0) +#define MSS_DMA_DSTBR(base) (base + 0xC4) +#define MSS_DMA_CTRLR(base) (base + 0xC8) +#define MSS_M3_RSTCR(base) (base + 0xFC) + +#define MSS_DMA_CTRLR_SIZE_OFFSET (0) +#define MSS_DMA_CTRLR_REQ_OFFSET (15) +#define MSS_DMA_CTRLR_REQ_SET (1) +#define MSS_DMA_CTRLR_ACK_OFFSET (12) +#define MSS_DMA_CTRLR_ACK_MASK (0x1) +#define MSS_DMA_CTRLR_ACK_READY (1) +#define MSS_M3_RSTCR_RST_OFFSET (0) +#define MSS_M3_RSTCR_RST_OFF (1) + +#define MSS_DMA_TIMEOUT 1000 +#define MSS_EXTERNAL_SPACE 0x50000000 +#define MSS_EXTERNAL_ADDR_MASK 0xfffffff + +#define DMA_SIZE 128 + +#define MSS_HANDSHAKE_TIMEOUT 50 + +#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) + +static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) +{ + int timeout = MSS_HANDSHAKE_TIMEOUT; + + /* Wait for SCP to signal it's ready */ + while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) && + (timeout-- > 0)) + mdelay(1); + + if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) + return -1; + + mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT; + + return 0; +} + +static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) +{ + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* + * Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + +static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) +{ + uint32_t i, loop_num, timeout; + + /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */ + if (size > MSS_IDRAM_SIZE) { + ERROR("image is too big to fit into MSS CM3 memory\n"); + return 1; + } + + NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n", + src_addr, size, mss_regs); + /* load image to MSS RAM using DMA */ + loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1); + + for (i = 0; i < loop_num; i++) { + /* write destination and source addresses */ + mmio_write_32(MSS_DMA_SRCBR(mss_regs), + MSS_EXTERNAL_SPACE | + ((src_addr & MSS_EXTERNAL_ADDR_MASK) + + (i * DMA_SIZE))); + mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE)); + + dsb(); /* make sure DMA data is ready before triggering it */ + + /* set the DMA control register */ + mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET + << MSS_DMA_CTRLR_REQ_OFFSET) | + (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET))); + + /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ + timeout = MSS_DMA_TIMEOUT; + while (timeout) { + if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> + MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK) + == MSS_DMA_CTRLR_ACK_READY) { + break; + } + + udelay(50); + timeout--; + } + + if (timeout == 0) { + ERROR("\nDMA failed to load MSS image\n"); + return 1; + } + } + + bl2_plat_configure_mss_windows(mss_regs); + + /* Release M3 from reset */ + mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF << + MSS_M3_RSTCR_RST_OFFSET)); + + NOTICE("Done\n"); + + return 0; +} + +/* Load image to MSS AP and do PM related initialization + * Note that this routine is different than other CM3 loading routines, because + * firmware for AP is dedicated for PM and therefore some additional PM + * initialization is required + */ +static int mss_ap_load_image(uintptr_t single_img, + uint32_t image_size, uint32_t ap_idx) +{ + volatile struct mss_pm_ctrl_block *mss_pm_crtl; + int ret; + + /* TODO: add PM Control Info from platform */ + mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; + mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION; + mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT; + mss_pm_crtl->num_of_cores_per_cluster = + PLAT_MARVELL_CLUSTER_CORE_COUNT; + mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT * + PLAT_MARVELL_CLUSTER_CORE_COUNT; + mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE; + mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE; + mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE; + VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE); + VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n", + mss_pm_crtl->ipc_version); + VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n", + mss_pm_crtl->num_of_cores); + VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n", + mss_pm_crtl->num_of_clusters); + VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n", + mss_pm_crtl->num_of_cores_per_cluster); + VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n", + mss_pm_crtl->pm_trace_ctrl_base_address); + VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n", + mss_pm_crtl->pm_trace_info_base_address); + VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n", + mss_pm_crtl->pm_trace_info_core_size); + + /* TODO: add checksum to image */ + VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); + + ret = mss_image_load(single_img, image_size, + bl2_plat_get_ap_mss_regs(ap_idx)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + + /* check that the image was loaded successfully */ + ret = mss_check_image_ready(mss_pm_crtl); + if (ret != 0) + NOTICE("SCP Image doesn't contain PM firmware\n"); + + return 0; +} + +/* Load CM3 image (single_img) to CM3 pointed by cm3_type */ +static int load_img_to_cm3(enum cm3_t cm3_type, + uintptr_t single_img, uint32_t image_size) +{ + int ret, ap_idx, cp_index; + uint32_t ap_count = bl2_plat_get_ap_count(); + + switch (cm3_type) { + case MSS_AP: + for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { + NOTICE("Load image to AP%d MSS\n", ap_idx); + ret = mss_ap_load_image(single_img, image_size, ap_idx); + if (ret != 0) + return ret; + } + break; + case MSS_CP0: + case MSS_CP1: + case MSS_CP2: + case MSS_CP3: + /* MSS_AP = 0 + * MSS_CP1 = 1 + * . + * . + * MSS_CP3 = 4 + * Actual CP index is MSS_CPX - 1 + */ + cp_index = cm3_type - 1; + for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { + /* Check if we should load this image + * according to number of CPs + */ + if (bl2_plat_get_cp_count(ap_idx) <= cp_index) { + NOTICE("Skipping MSS CP%d related image\n", + cp_index); + break; + } + + NOTICE("Load image to CP%d MSS AP%d\n", + cp_index, ap_idx); + ret = mss_image_load(single_img, image_size, + bl2_plat_get_cp_mss_regs( + ap_idx, cp_index)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + } + break; + case MG_CP0: + case MG_CP1: + case MG_CP2: + cp_index = cm3_type - MG_CP0; + if (bl2_plat_get_cp_count(0) <= cp_index) { + NOTICE("Skipping MG CP%d related image\n", + cp_index); + break; + } + NOTICE("Load image to CP%d MG\n", cp_index); + ret = mg_image_load(single_img, image_size, + MG_CM3_SRAM_BASE(cp_index)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + break; + default: + ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); + break; + } + + return 0; +} + +/* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was + * required to provide a method for loading firmware to all of the service CPUs. + * To achieve that, the scp_bl2 image in fact is file containing up to 5 + * concatenated firmwares and this routine splits concatenated image into single + * images dedicated for appropriate service CPU and then load them. + */ +static int split_and_load_bl2_image(void *image) +{ + file_header_t *file_hdr; + img_header_t *img_hdr; + uintptr_t single_img; + int i; + + file_hdr = (file_header_t *)image; + + if (file_hdr->magic != FILE_MAGIC) { + ERROR("SCP_BL2 wrong img format\n"); + return -1; + } + + if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { + ERROR("SCP_BL2 concatenated image contains too many images\n"); + return -1; + } + + img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t)); + single_img = (uintptr_t)image + sizeof(file_header_t) + + sizeof(img_header_t) * file_hdr->nr_of_imgs; + + NOTICE("SCP_BL2 contains %d concatenated images\n", + file_hdr->nr_of_imgs); + for (i = 0; i < file_hdr->nr_of_imgs; i++) { + + /* Before loading make sanity check on header */ + if (img_hdr->version != HEADER_VERSION) { + ERROR("Wrong header, img corrupted exiting\n"); + return -1; + } + + load_img_to_cm3(img_hdr->type, single_img, img_hdr->length); + + /* Prepare offsets for next run */ + single_img += img_hdr->length; + img_hdr++; + } + + return 0; +} + +int scp_bootloader_transfer(void *image, unsigned int image_size) +{ +#ifdef SCP_BL2_BASE + assert((uintptr_t) image == SCP_BL2_BASE); +#endif + + VERBOSE("Concatenated img size %d\n", image_size); + + if (image_size == 0) { + ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n", + image_size); + return -1; + } + + if (split_and_load_bl2_image(image)) + return -1; + + return 0; +} diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.h b/plat/marvell/armada/common/mss/mss_scp_bootloader.h new file mode 100644 index 0000000..4950d24 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_SCP_BOOTLOADER_H +#define MSS_SCP_BOOTLOADER_H + +int scp_bootloader_transfer(void *image, unsigned int image_size); +uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx); +uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx); +uint32_t bl2_plat_get_cp_count(int ap_idx); +uint32_t bl2_plat_get_ap_count(void); +void bl2_plat_configure_mss_windows(uintptr_t mss_regs); +int bl2_plat_mss_check_image_ready(void); + +#endif /* MSS_SCP_BOOTLOADER_H */ diff --git a/plat/marvell/armada/common/plat_delay_timer.c b/plat/marvell/armada/common/plat_delay_timer.c new file mode 100644 index 0000000..2539752 --- /dev/null +++ b/plat/marvell/armada/common/plat_delay_timer.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#define SYS_COUNTER_FREQ_IN_MHZ (COUNTER_FREQUENCY/1000000) + +static uint32_t plat_get_timer_value(void) +{ + /* + * Generic delay timer implementation expects the timer to be a down + * counter. We apply bitwise NOT operator to the tick values returned + * by read_cntpct_el0() to simulate the down counter. + */ + return (uint32_t)(~read_cntpct_el0()); +} + +static const timer_ops_t plat_timer_ops = { + .get_timer_value = plat_get_timer_value, + .clk_mult = 1, + .clk_div = SYS_COUNTER_FREQ_IN_MHZ +}; + +void plat_delay_timer_init(void) +{ + timer_init(&plat_timer_ops); +} diff --git a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c deleted file mode 100644 index 6a8e11c..0000000 --- a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -/******************************************************************************* - * Following descriptor provides BL image/ep information that gets used - * by BL2 to load the images and also subset of this information is - * passed to next BL image. The image loading sequence is managed by - * populating the images in required loading order. The image execution - * sequence is managed by populating the `next_handoff_image_id` with - * the next executable image id. - ******************************************************************************/ -static bl_mem_params_node_t bl2_mem_params_descs[] = { -#ifdef SCP_BL2_BASE - /* Fill SCP_BL2 related information if it exists */ - { - .image_id = SCP_BL2_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, - VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE), - - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = SCP_BL2_BASE, - .image_info.image_max_size = SCP_BL2_SIZE, - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, -#endif /* SCP_BL2_BASE */ - -#ifdef EL3_PAYLOAD_BASE - /* Fill EL3 payload related information (BL31 is EL3 payload)*/ - { - .image_id = BL31_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, - VERSION_2, entry_point_info_t, - SECURE | EXECUTABLE | EP_FIRST_EXE), - .ep_info.pc = EL3_PAYLOAD_BASE, - .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS), - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, - IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING), - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, - -#else /* EL3_PAYLOAD_BASE */ - - /* Fill BL31 related information */ - { - .image_id = BL31_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, - VERSION_2, entry_point_info_t, - SECURE | EXECUTABLE | EP_FIRST_EXE), - .ep_info.pc = BL31_BASE, - .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS), -#if DEBUG - .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL, -#endif - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), - .image_info.image_base = BL31_BASE, - .image_info.image_max_size = BL31_LIMIT - BL31_BASE, - -# ifdef BL32_BASE - .next_handoff_image_id = BL32_IMAGE_ID, -# else - .next_handoff_image_id = BL33_IMAGE_ID, -# endif - }, - -# ifdef BL32_BASE - /* Fill BL32 related information */ - { - .image_id = BL32_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, - VERSION_2, entry_point_info_t, SECURE | EXECUTABLE), - .ep_info.pc = BL32_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, 0), - .image_info.image_base = BL32_BASE, - .image_info.image_max_size = BL32_LIMIT - BL32_BASE, - - .next_handoff_image_id = BL33_IMAGE_ID, - }, -# endif /* BL32_BASE */ - - /* Fill BL33 related information */ - { - .image_id = BL33_IMAGE_ID, - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, - VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE), -# ifdef PRELOADED_BL33_BASE - .ep_info.pc = PRELOADED_BL33_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), -# else - .ep_info.pc = MARVELL_DRAM_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, 0), - .image_info.image_base = MARVELL_DRAM_BASE, - .image_info.image_max_size = MARVELL_DRAM_SIZE, -# endif /* PRELOADED_BL33_BASE */ - - .next_handoff_image_id = INVALID_IMAGE_ID, - } -#endif /* EL3_PAYLOAD_BASE */ -}; - -REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/marvell/common/aarch64/marvell_common.c b/plat/marvell/common/aarch64/marvell_common.c deleted file mode 100644 index 21a62d4..0000000 --- a/plat/marvell/common/aarch64/marvell_common.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak plat_get_ns_image_entrypoint -#pragma weak plat_marvell_get_mmap - -/* - * Set up the page tables for the generic and platform-specific memory regions. - * The extents of the generic memory regions are specified by the function - * arguments and consist of: - * - Trusted SRAM seen by the BL image; - * - Code section; - * - Read-only data section; - * - Coherent memory region, if applicable. - */ -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 - ) -{ - /* - * Map the Trusted SRAM with appropriate memory attributes. - * Subsequent mappings will adjust the attributes for specific regions. - */ - VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", - (void *) total_base, (void *) (total_base + total_size)); - mmap_add_region(total_base, total_base, - total_size, - MT_MEMORY | MT_RW | MT_SECURE); - - /* Re-map the code section */ - VERBOSE("Code region: %p - %p\n", - (void *) code_start, (void *) code_limit); - mmap_add_region(code_start, code_start, - code_limit - code_start, - MT_CODE | MT_SECURE); - - /* Re-map the read-only data section */ - VERBOSE("Read-only data region: %p - %p\n", - (void *) rodata_start, (void *) rodata_limit); - mmap_add_region(rodata_start, rodata_start, - rodata_limit - rodata_start, - MT_RO_DATA | MT_SECURE); - -#if USE_COHERENT_MEM - /* Re-map the coherent memory region */ - VERBOSE("Coherent region: %p - %p\n", - (void *) coh_start, (void *) coh_limit); - mmap_add_region(coh_start, coh_start, - coh_limit - coh_start, - MT_DEVICE | MT_RW | MT_SECURE); -#endif - - /* Now (re-)map the platform-specific memory regions */ - mmap_add(plat_marvell_get_mmap()); - - /* Create the page tables to reflect the above mappings */ - init_xlat_tables(); -} - -unsigned long plat_get_ns_image_entrypoint(void) -{ - return PLAT_MARVELL_NS_IMAGE_OFFSET; -} - -/***************************************************************************** - * Gets SPSR for BL32 entry - ***************************************************************************** - */ -uint32_t marvell_get_spsr_for_bl32_entry(void) -{ - /* - * The Secure Payload Dispatcher service is responsible for - * setting the SPSR prior to entry into the BL32 image. - */ - return 0; -} - -/***************************************************************************** - * Gets SPSR for BL33 entry - ***************************************************************************** - */ -uint32_t marvell_get_spsr_for_bl33_entry(void) -{ - unsigned long el_status; - unsigned int mode; - uint32_t spsr; - - /* Figure out what mode we enter the non-secure world in */ - el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; - el_status &= ID_AA64PFR0_ELX_MASK; - - mode = (el_status) ? MODE_EL2 : MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); - return spsr; -} - -/***************************************************************************** - * Returns ARM platform specific memory map regions. - ***************************************************************************** - */ -const mmap_region_t *plat_marvell_get_mmap(void) -{ - return plat_marvell_mmap; -} - diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S deleted file mode 100644 index 6f625b9..0000000 --- a/plat/marvell/common/aarch64/marvell_helpers.S +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#ifndef PLAT_a3700 -#include -#include -#endif -#include -#include - - .weak plat_marvell_calc_core_pos - .weak plat_my_core_pos - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush - .globl platform_mem_init - .globl disable_mmu_dcache - .globl invalidate_tlb_all - .globl platform_unmap_sram - .globl disable_sram - .globl disable_icache - .globl invalidate_icache_all - .globl marvell_exit_bootrom - .globl ca72_l2_enable_unique_clean - - /* ----------------------------------------------------- - * unsigned int plat_my_core_pos(void) - * This function uses the plat_marvell_calc_core_pos() - * definition to get the index of the calling CPU. - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_marvell_calc_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_marvell_calc_core_pos(uint64_t mpidr) - * Helper function to calculate the core position. - * With this function: CorePos = (ClusterId * 2) + - * CoreId - * ----------------------------------------------------- - */ -func plat_marvell_calc_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #7 - ret -endfunc plat_marvell_calc_core_pos - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0, x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE - mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ - mov_imm x2, MARVELL_CONSOLE_BAUDRATE -#ifdef PLAT_a3700 - b console_a3700_core_init -#else - b console_16550_core_init -#endif -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE -#ifdef PLAT_a3700 - - b console_a3700_core_putc -#else - b console_16550_core_putc -#endif -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : r0 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE -#ifdef PLAT_a3700 - b console_a3700_core_flush -#else - b console_16550_core_flush -#endif -endfunc plat_crash_console_flush - - /* --------------------------------------------------------------------- - * We don't need to carry out any memory initialization on ARM - * platforms. The Secure RAM is accessible straight away. - * --------------------------------------------------------------------- - */ -func platform_mem_init - ret -endfunc platform_mem_init - - /* ----------------------------------------------------- - * Disable icache, dcache, and MMU - * ----------------------------------------------------- - */ -func disable_mmu_dcache - mrs x0, sctlr_el3 - bic x0, x0, 0x1 /* M bit - MMU */ - bic x0, x0, 0x4 /* C bit - Dcache L1 & L2 */ - msr sctlr_el3, x0 - isb - b mmu_off -mmu_off: - ret -endfunc disable_mmu_dcache - - /* ----------------------------------------------------- - * Disable all TLB entries - * ----------------------------------------------------- - */ -func invalidate_tlb_all - tlbi alle3 - dsb sy - isb - ret -endfunc invalidate_tlb_all - - /* ----------------------------------------------------- - * Disable the i cache - * ----------------------------------------------------- - */ -func disable_icache - mrs x0, sctlr_el3 - bic x0, x0, 0x1000 /* I bit - Icache L1 & L2 */ - msr sctlr_el3, x0 - isb - ret -endfunc disable_icache - - /* ----------------------------------------------------- - * Disable all of the i caches - * ----------------------------------------------------- - */ -func invalidate_icache_all - ic ialluis - isb sy - ret -endfunc invalidate_icache_all - - /* ----------------------------------------------------- - * Clear the SRAM enabling bit to unmap SRAM - * ----------------------------------------------------- - */ -func platform_unmap_sram - ldr x0, =CCU_SRAM_WIN_CR - str wzr, [x0] - ret -endfunc platform_unmap_sram - - /* ----------------------------------------------------- - * Disable the SRAM - * ----------------------------------------------------- - */ -func disable_sram - /* Disable the line lockings. They must be disabled expictly - * or the OS will have problems using the cache */ - ldr x1, =MASTER_LLC_TC0_LOCK - str wzr, [x1] - - /* Invalidate all ways */ - ldr w1, =LLC_WAY_MASK - ldr x0, =MASTER_L2X0_INV_WAY - str w1, [x0] - - /* Finally disable LLC */ - ldr x0, =MASTER_LLC_CTRL - str wzr, [x0] - - ret -endfunc disable_sram - - /* ----------------------------------------------------- - * Operation when exit bootROM: - * Disable the MMU - * Disable and invalidate the dcache - * Unmap and disable the SRAM - * Disable and invalidate the icache - * ----------------------------------------------------- - */ -func marvell_exit_bootrom - /* Save the system restore address */ - mov x28, x0 - - /* Close the caches and MMU */ - bl disable_mmu_dcache - - /* - * There is nothing important in the caches now, - * so invalidate them instead of cleaning. - */ - adr x0, __RW_START__ - adr x1, __RW_END__ - sub x1, x1, x0 - bl inv_dcache_range - bl invalidate_tlb_all - - /* - * Clean the memory mapping of SRAM - * the DDR mapping will remain to enable boot image to execute - */ - bl platform_unmap_sram - - /* Disable the SRAM */ - bl disable_sram - - /* Disable and invalidate icache */ - bl disable_icache - bl invalidate_icache_all - - mov x0, x28 - br x0 -endfunc marvell_exit_bootrom - - /* - * Enable L2 UniqueClean evictions with data - */ -func ca72_l2_enable_unique_clean - - mrs x0, CORTEX_A72_L2ACTLR_EL1 - orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN - msr CORTEX_A72_L2ACTLR_EL1, x0 - - ret -endfunc ca72_l2_enable_unique_clean diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c deleted file mode 100644 index 7b7cef3..0000000 --- a/plat/marvell/common/marvell_bl1_setup.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -/* Weak definitions may be overridden in specific Marvell standard platform */ -#pragma weak bl1_early_platform_setup -#pragma weak bl1_plat_arch_setup -#pragma weak bl1_platform_setup -#pragma weak bl1_plat_sec_mem_layout - -/* Data structure which holds the extents of the RAM for BL1*/ -static meminfo_t bl1_ram_layout; - -meminfo_t *bl1_plat_sec_mem_layout(void) -{ - return &bl1_ram_layout; -} - -/* - * BL1 specific platform actions shared between Marvell standard platforms. - */ -void marvell_bl1_early_platform_setup(void) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - - /* Allow BL1 to see the whole Trusted RAM */ - bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE; - bl1_ram_layout.total_size = MARVELL_BL_RAM_SIZE; -} - -void bl1_early_platform_setup(void) -{ - marvell_bl1_early_platform_setup(); -} - -/* - * Perform the very early platform specific architecture setup shared between - * MARVELL standard platforms. This only does basic initialization. Later - * architectural setup (bl1_arch_setup()) does not do anything platform - * specific. - */ -void marvell_bl1_plat_arch_setup(void) -{ - marvell_setup_page_tables(bl1_ram_layout.total_base, - bl1_ram_layout.total_size, - BL1_RO_BASE, - BL1_RO_LIMIT, - BL1_RO_DATA_BASE, - BL1_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - enable_mmu_el3(0); -} - -void bl1_plat_arch_setup(void) -{ - marvell_bl1_plat_arch_setup(); -} - -/* - * Perform the platform specific architecture setup shared between - * MARVELL standard platforms. - */ -void marvell_bl1_platform_setup(void) -{ - /* Initialise the IO layer and register platform IO devices */ - plat_marvell_io_setup(); -} - -void bl1_platform_setup(void) -{ - marvell_bl1_platform_setup(); -} - -void bl1_plat_prepare_exit(entry_point_info_t *ep_info) -{ -#ifdef EL3_PAYLOAD_BASE - /* - * Program the EL3 payload's entry point address into the CPUs mailbox - * in order to release secondary CPUs from their holding pen and make - * them jump there. - */ - marvell_program_trusted_mailbox(ep_info->pc); - dsbsy(); - sev(); -#endif -} diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c deleted file mode 100644 index 3c1c391..0000000 --- a/plat/marvell/common/marvell_bl2_setup.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Data structure which holds the extents of the trusted SRAM for BL2 */ -static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); - -/* Weak definitions may be overridden in specific MARVELL standard platform */ -#pragma weak bl2_early_platform_setup2 -#pragma weak bl2_platform_setup -#pragma weak bl2_plat_arch_setup -#pragma weak bl2_plat_sec_mem_layout - -meminfo_t *bl2_plat_sec_mem_layout(void) -{ - return &bl2_tzram_layout; -} - -/***************************************************************************** - * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 - * in x0. This memory layout is sitting at the base of the free trusted SRAM. - * Copy it to a safe location before its reclaimed by later BL2 functionality. - ***************************************************************************** - */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - - /* Setup the BL2 memory layout */ - bl2_tzram_layout = *mem_layout; - - /* Initialise the IO layer and register platform IO devices */ - plat_marvell_io_setup(); -} - - -void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - struct meminfo *mem_layout = (struct meminfo *)arg1; - - marvell_bl2_early_platform_setup(mem_layout); -} - -void bl2_platform_setup(void) -{ - /* Nothing to do */ -} - -/***************************************************************************** - * Perform the very early platform specific architectural setup here. At the - * moment this is only initializes the mmu in a quick and dirty way. - ***************************************************************************** - */ -void marvell_bl2_plat_arch_setup(void) -{ - marvell_setup_page_tables(bl2_tzram_layout.total_base, - bl2_tzram_layout.total_size, - BL_CODE_BASE, - BL_CODE_END, - BL_RO_DATA_BASE, - BL_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - enable_mmu_el1(0); -} - -void bl2_plat_arch_setup(void) -{ - marvell_bl2_plat_arch_setup(); -} - -int marvell_bl2_handle_post_image_load(unsigned int image_id) -{ - int err = 0; - bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); - - assert(bl_mem_params); - - switch (image_id) { - - case BL33_IMAGE_ID: - /* BL33 expects to receive the primary CPU MPID (through r0) */ - bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); - bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl33_entry(); - break; -#ifdef SCP_BL2_BASE - case SCP_BL2_IMAGE_ID: - /* The subsequent handling of SCP_BL2 is platform specific */ - err = bl2_plat_handle_scp_bl2(&bl_mem_params->image_info); - if (err) { - WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); - } - break; -#endif - default: - /* Do nothing in default case */ - break; - } - - return err; - -} - -/******************************************************************************* - * This function can be used by the platforms to update/use image - * information for given `image_id`. - ******************************************************************************/ -int bl2_plat_handle_post_image_load(unsigned int image_id) -{ - return marvell_bl2_handle_post_image_load(image_id); -} - diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c deleted file mode 100644 index 26ba906..0000000 --- a/plat/marvell/common/marvell_bl31_setup.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#ifdef USE_CCI -#include -#endif -#include -#include - -#include -#include -#include - -/* - * Placeholder variables for copying the arguments that have been passed to - * BL31 from BL2. - */ -static entry_point_info_t bl32_image_ep_info; -static entry_point_info_t bl33_image_ep_info; - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak bl31_early_platform_setup2 -#pragma weak bl31_platform_setup -#pragma weak bl31_plat_arch_setup -#pragma weak bl31_plat_get_next_image_ep_info -#pragma weak plat_get_syscnt_freq2 - -/***************************************************************************** - * Return a pointer to the 'entry_point_info' structure of the next image for - * the security state specified. BL33 corresponds to the non-secure image type - * while BL32 corresponds to the secure image type. A NULL pointer is returned - * if the image does not exist. - ***************************************************************************** - */ -entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) -{ - entry_point_info_t *next_image_info; - - assert(sec_state_is_valid(type)); - next_image_info = (type == NON_SECURE) - ? &bl33_image_ep_info : &bl32_image_ep_info; - - return next_image_info; -} - -/***************************************************************************** - * Perform any BL31 early platform setup common to ARM standard platforms. - * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 - * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be - * done before the MMU is initialized so that the memory layout can be used - * while creating page tables. BL2 has flushed this information to memory, so - * we are guaranteed to pick up good data. - ***************************************************************************** - */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - -#if RESET_TO_BL31 - /* There are no parameters from BL2 if BL31 is a reset vector */ - assert(from_bl2 == NULL); - assert(plat_params_from_bl2 == NULL); - -#ifdef BL32_BASE - /* Populate entry point information for BL32 */ - SET_PARAM_HEAD(&bl32_image_ep_info, - PARAM_EP, - VERSION_1, - 0); - SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); - bl32_image_ep_info.pc = BL32_BASE; - bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry(); -#endif /* BL32_BASE */ - - /* Populate entry point information for BL33 */ - SET_PARAM_HEAD(&bl33_image_ep_info, - PARAM_EP, - VERSION_1, - 0); - /* - * Tell BL31 where the non-trusted software image - * is located and the entry state information - */ - bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); - bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry(); - SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); - -#else - /* - * In debug builds, we pass a special value in 'plat_params_from_bl2' - * to verify platform parameters from BL2 to BL31. - * In release builds, it's not used. - */ - assert(((unsigned long long)plat_params_from_bl2) == - MARVELL_BL31_PLAT_PARAM_VAL); - - /* - * Check params passed from BL2 should not be NULL, - */ - bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; - assert(params_from_bl2 != NULL); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); - - bl_params_node_t *bl_params = params_from_bl2->head; - - /* - * Copy BL33 and BL32 (if present), entry point information. - * They are stored in Secure RAM, in BL2's address space. - */ - while (bl_params != NULL) { - if (bl_params->image_id == BL32_IMAGE_ID) - bl32_image_ep_info = *bl_params->ep_info; - - if (bl_params->image_id == BL33_IMAGE_ID) - bl33_image_ep_info = *bl_params->ep_info; - - bl_params = bl_params->next_params_info; - } -#endif -} - -void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) - -{ - marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2, - (void *)arg3); - -#ifdef USE_CCI - /* - * Initialize CCI for this cluster during cold boot. - * 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(); -#endif -} - -/***************************************************************************** - * Perform any BL31 platform setup common to ARM standard platforms - ***************************************************************************** - */ -void marvell_bl31_platform_setup(void) -{ - /* Initialize the GIC driver, cpu and distributor interfaces */ - plat_marvell_gic_driver_init(); - plat_marvell_gic_init(); - - /* For Armada-8k-plus family, the SoC includes more than - * a single AP die, but the default die that boots is AP #0. - * For other families there is only one die (#0). - * Initialize psci arch from die 0 - */ - marvell_psci_arch_init(0); -} - -/***************************************************************************** - * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM - * standard platforms - ***************************************************************************** - */ -void marvell_bl31_plat_runtime_setup(void) -{ - console_switch_state(CONSOLE_FLAG_RUNTIME); - - /* Initialize the runtime console */ - marvell_console_runtime_init(); -} - -void bl31_platform_setup(void) -{ - marvell_bl31_platform_setup(); -} - -void bl31_plat_runtime_setup(void) -{ - marvell_bl31_plat_runtime_setup(); -} - -/***************************************************************************** - * Perform the very early platform specific architectural setup shared between - * ARM standard platforms. This only does basic initialization. Later - * architectural setup (bl31_arch_setup()) does not do anything platform - * specific. - ***************************************************************************** - */ -void marvell_bl31_plat_arch_setup(void) -{ - marvell_setup_page_tables(BL31_BASE, - BL31_END - BL31_BASE, - BL_CODE_BASE, - BL_CODE_END, - BL_RO_DATA_BASE, - BL_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - -#if BL31_CACHE_DISABLE - enable_mmu_el3(DISABLE_DCACHE); - INFO("Cache is disabled in BL3\n"); -#else - enable_mmu_el3(0); -#endif -} - -void bl31_plat_arch_setup(void) -{ - marvell_bl31_plat_arch_setup(); -} - -unsigned int plat_get_syscnt_freq2(void) -{ - return PLAT_REF_CLK_IN_HZ; -} diff --git a/plat/marvell/common/marvell_cci.c b/plat/marvell/common/marvell_cci.c deleted file mode 100644 index 80351ae..0000000 --- a/plat/marvell/common/marvell_cci.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -static const int cci_map[] = { - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX, - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX -}; - -/**************************************************************************** - * The following functions are defined as weak to allow a platform to override - * the way ARM CCI driver is initialised and used. - **************************************************************************** - */ -#pragma weak plat_marvell_interconnect_init -#pragma weak plat_marvell_interconnect_enter_coherency -#pragma weak plat_marvell_interconnect_exit_coherency - - -/**************************************************************************** - * Helper function to initialize ARM CCI driver. - **************************************************************************** - */ -void plat_marvell_interconnect_init(void) -{ - cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); -} - -/**************************************************************************** - * Helper function to place current master into coherency - **************************************************************************** - */ -void plat_marvell_interconnect_enter_coherency(void) -{ - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -} - -/**************************************************************************** - * Helper function to remove current master from coherency - **************************************************************************** - */ -void plat_marvell_interconnect_exit_coherency(void) -{ - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -} diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk deleted file mode 100644 index f41d7a4..0000000 --- a/plat/marvell/common/marvell_common.mk +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -MARVELL_PLAT_BASE := plat/marvell -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell - -include $(MARVELL_PLAT_BASE)/version.mk -include $(MARVELL_PLAT_BASE)/marvell.mk - -VERSION_STRING +=(Marvell-${SUBVERSION}) - -SEPARATE_CODE_AND_RODATA := 1 - -# flag to switch from PLL to ARO -ARO_ENABLE := 0 -$(eval $(call add_define,ARO_ENABLE)) -# Enable/Disable LLC -LLC_ENABLE := 1 -$(eval $(call add_define,LLC_ENABLE)) - -include lib/xlat_tables_v2/xlat_tables.mk - -PLAT_INCLUDES += -I$(MARVELL_PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_PLAT_INCLUDE_BASE)/common/aarch64 - - -PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S \ - $(MARVELL_COMMON_BASE)/marvell_console.c - -BL1_SOURCES += drivers/delay_timer/delay_timer.c \ - drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - drivers/io/io_storage.c \ - $(MARVELL_PLAT_BASE)/common/marvell_bl1_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ - $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c - -ifdef EL3_PAYLOAD_BASE -# Need the arm_program_trusted_mailbox() function to release secondary CPUs from -# their holding pen -endif - -BL2_SOURCES += drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - drivers/io/io_storage.c \ - common/desc_image_load.c \ - $(MARVELL_PLAT_BASE)/common/marvell_bl2_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \ - $(MARVELL_PLAT_BASE)/common/marvell_image_load.c - - -BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_pm.c \ - $(MARVELL_PLAT_BASE)/common/marvell_topology.c \ - plat/common/plat_psci_common.c \ - $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c \ - drivers/delay_timer/delay_timer.c - -# PSCI functionality -$(eval $(call add_define,CONFIG_ARM64)) - -# MSS (SCP) build -ifeq (${MSS_SUPPORT}, 1) -include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk -endif - -fip: mrvl_flash diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c deleted file mode 100644 index 1716661..0000000 --- a/plat/marvell/common/marvell_console.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include - -#include - -#include -#include - -#include - -#ifdef PLAT_a3700 -#include -#define console_marvell_register console_a3700_register -#else -#include -#define console_marvell_register console_16550_register -#endif - -static console_t marvell_boot_console; -static console_t marvell_runtime_console; - -/******************************************************************************* - * Functions that set up the console - ******************************************************************************/ - -/* Initialize the console to provide early debug support */ -void marvell_console_boot_init(void) -{ - int rc = - console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_boot_console); - if (rc == 0) { - /* - * The crash console doesn't use the multi console API, it uses - * the core console functions directly. It is safe to call panic - * and let it print debug information. - */ - panic(); - } - - console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT); -} - -void marvell_console_boot_end(void) -{ - (void)console_flush(); - - (void)console_unregister(&marvell_boot_console); -} - -/* Initialize the runtime console */ -void marvell_console_runtime_init(void) -{ - int rc = - console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_runtime_console); - if (rc == 0) - panic(); - - console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME); -} - -void marvell_console_runtime_end(void) -{ - (void)console_flush(); - - (void)console_unregister(&marvell_runtime_console); -} diff --git a/plat/marvell/common/marvell_ddr_info.c b/plat/marvell/common/marvell_ddr_info.c deleted file mode 100644 index 7340996..0000000 --- a/plat/marvell/common/marvell_ddr_info.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include - -#define DRAM_CH0_MMAP_LOW_REG(iface, cs, base) \ - (base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8) -#define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base) \ - (DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4) -#define DRAM_CS_VALID_ENABLED_MASK 0x1 -#define DRAM_AREA_LENGTH_OFFS 16 -#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS) -#define DRAM_START_ADDRESS_L_OFFS 23 -#define DRAM_START_ADDRESS_L_MASK \ - (0x1ff << DRAM_START_ADDRESS_L_OFFS) -#define DRAM_START_ADDR_HTOL_OFFS 32 - -#define DRAM_MAX_CS_NUM 2 - -#define DRAM_CS_ENABLED(iface, cs, base) \ - (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ - DRAM_CS_VALID_ENABLED_MASK) -#define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \ - (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ - DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS - -/* Mapping between DDR area length and real DDR size is specific and looks like - * bellow: - * 0 => 384 MB - * 1 => 768 MB - * 2 => 1536 MB - * 3 => 3 GB - * 4 => 6 GB - * - * 7 => 8 MB - * 8 => 16 MB - * 9 => 32 MB - * 10 => 64 MB - * 11 => 128 MB - * 12 => 256 MB - * 13 => 512 MB - * 14 => 1 GB - * 15 => 2 GB - * 16 => 4 GB - * 17 => 8 GB - * 18 => 16 GB - * 19 => 32 GB - * 20 => 64 GB - * 21 => 128 GB - * 22 => 256 GB - * 23 => 512 GB - * 24 => 1 TB - * 25 => 2 TB - * 26 => 4 TB - * - * to calculate real size we need to use two different formulas: - * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD) - * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN) - * using mentioned formulas we cover whole mapping between "Area length" value - * and real size (see above mapping). - */ -#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26)) -#define GET_DRAM_REGION_SIZE_EVEN(C) ((uint64_t)1 << ((C) + 16)) -#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4) -#define GET_DRAM_REGION_SIZE_ODD(C) ((uint64_t)0x18000000 << (C)) - - -uint64_t mvebu_get_dram_size(uint64_t ap_base_addr) -{ - uint64_t mem_size = 0; - uint8_t region_code; - uint8_t cs, iface; - - for (iface = 0; iface < DRAM_MAX_IFACE; iface++) { - for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) { - - /* Exit loop on first disabled DRAM CS */ - if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr)) - break; - - /* Decode area length for current CS - * from register value - */ - region_code = - GET_DRAM_REGION_SIZE_CODE(iface, cs, - ap_base_addr); - - if (DRAM_REGION_SIZE_EVEN(region_code)) { - mem_size += - GET_DRAM_REGION_SIZE_EVEN(region_code); - } else if (DRAM_REGION_SIZE_ODD(region_code)) { - mem_size += - GET_DRAM_REGION_SIZE_ODD(region_code); - } else { - WARN("%s: Invalid mem region (0x%x) CS#%d\n", - __func__, region_code, cs); - return 0; - } - } - } - - return mem_size; -} diff --git a/plat/marvell/common/marvell_gicv2.c b/plat/marvell/common/marvell_gicv2.c deleted file mode 100644 index 2505c9f..0000000 --- a/plat/marvell/common/marvell_gicv2.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -/* - * The following functions are defined as weak to allow a platform to override - * the way the GICv2 driver is initialised and used. - */ -#pragma weak plat_marvell_gic_driver_init -#pragma weak plat_marvell_gic_init - -#define A7K8K_PIC_CAUSE_REG 0xf03f0100 -#define A7K8K_PIC0_MASK_REG 0xf03f0108 - -#define A7K8K_PIC_PMUOF_IRQ_MASK (1 << 17) - -#define A7K8K_PIC_MAX_IRQS 32 -#define A7K8K_PIC_MAX_IRQ_MASK ((1UL << A7K8K_PIC_MAX_IRQS) - 1) - -#define A7K8K_ODMIN_SET_REG 0xf0300040 -#define A7K8K_ODMI_PMU_IRQ(idx) ((2 + idx) << 12) - -#define A7K8K_ODMI_PMU_GIC_IRQ(idx) (130 + idx) - -static DEFINE_BAKERY_LOCK(a7k8k_irq_lock); - -/* - * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 - * interrupts. - */ -static const interrupt_prop_t marvell_interrupt_props[] = { - PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), - PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0) -}; - -static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; - -/* - * Ideally `marvell_gic_data` structure definition should be a `const` but it is - * kept as modifiable for overwriting with different GICD and GICC base when - * running on FVP with VE memory map. - */ -static gicv2_driver_data_t marvell_gic_data = { - .gicd_base = PLAT_MARVELL_GICD_BASE, - .gicc_base = PLAT_MARVELL_GICC_BASE, - .interrupt_props = marvell_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), - .target_masks = target_mask_array, - .target_masks_num = ARRAY_SIZE(target_mask_array), -}; - -/* - * ARM common helper to initialize the GICv2 only driver. - */ -void plat_marvell_gic_driver_init(void) -{ - gicv2_driver_init(&marvell_gic_data); -} - -static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, - uint32_t flags, - void *handle, - void *cookie) -{ - unsigned int idx = plat_my_core_pos(); - uint32_t irq; - - bakery_lock_get(&a7k8k_irq_lock); - - /* Acknowledge IRQ */ - irq = plat_ic_acknowledge_interrupt(); - - plat_ic_end_of_interrupt(irq); - - if (irq != MARVELL_IRQ_PIC0) { - bakery_lock_release(&a7k8k_irq_lock); - return 0; - } - - /* Acknowledge PMU overflow IRQ in PIC0 */ - mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); - - /* Trigger ODMI Frame IRQ */ - mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); - - bakery_lock_release(&a7k8k_irq_lock); - - return 0; -} - -void mvebu_pmu_interrupt_enable(void) -{ - unsigned int idx; - uint32_t flags; - int32_t rc; - - /* Reset PIC */ - mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); - /* Unmask PMU overflow IRQ in PIC0 */ - mmio_clrbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); - - /* Configure ODMI Frame IRQs as edge triggered */ - for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) - gicv2_interrupt_set_cfg(A7K8K_ODMI_PMU_GIC_IRQ(idx), - GIC_INTR_CFG_EDGE); - - /* - * Register IRQ handler as INTR_TYPE_S_EL1 as its the only valid type - * for GICv2 in ARM-TF. - */ - flags = 0U; - set_interrupt_rm_flag((flags), (NON_SECURE)); - rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, - a7k8k_pmu_interrupt_handler, - flags); - if (rc != 0) - panic(); -} - -void mvebu_pmu_interrupt_disable(void) -{ - /* Reset PIC */ - mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); - /* Mask PMU overflow IRQ in PIC0 */ - mmio_setbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); -} - -void plat_marvell_gic_init(void) -{ - gicv2_distif_init(); - gicv2_pcpu_distif_init(); - gicv2_set_pe_target_mask(plat_my_core_pos()); - gicv2_cpuif_enable(); -} diff --git a/plat/marvell/common/marvell_gicv3.c b/plat/marvell/common/marvell_gicv3.c deleted file mode 100644 index 0bd5545..0000000 --- a/plat/marvell/common/marvell_gicv3.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include - -#include -#include - -/****************************************************************************** - * The following functions are defined as weak to allow a platform to override - * the way the GICv3 driver is initialised and used. - ****************************************************************************** - */ -#pragma weak plat_marvell_gic_driver_init -#pragma weak plat_marvell_gic_init -#pragma weak plat_marvell_gic_cpuif_enable -#pragma weak plat_marvell_gic_cpuif_disable -#pragma weak plat_marvell_gic_pcpu_init - -/* The GICv3 driver only needs to be initialized in EL3 */ -static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; - -static const interrupt_prop_t marvell_interrupt_props[] = { - PLAT_MARVELL_G1S_IRQ_PROPS(INTR_GROUP1S), - PLAT_MARVELL_G0_IRQ_PROPS(INTR_GROUP0) -}; - -/* - * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory - */ -static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); - -/* - * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register - * to core position. - * - * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity - * values read from GICR_TYPER don't have an MT field. To reuse the same - * translation used for CPUs, we insert MT bit read from the PE's MPIDR into - * that read from GICR_TYPER. - * - * Assumptions: - * - * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; - * - No CPUs implemented in the system use affinity level 3. - */ -static unsigned int marvell_gicv3_mpidr_hash(u_register_t mpidr) -{ - mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); - return plat_marvell_calc_core_pos(mpidr); -} - -const gicv3_driver_data_t marvell_gic_data = { - .gicd_base = PLAT_MARVELL_GICD_BASE, - .gicr_base = PLAT_MARVELL_GICR_BASE, - .interrupt_props = marvell_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), - .rdistif_num = PLATFORM_CORE_COUNT, - .rdistif_base_addrs = rdistif_base_addrs, - .mpidr_to_core_pos = marvell_gicv3_mpidr_hash -}; - -void plat_marvell_gic_driver_init(void) -{ - /* - * The GICv3 driver is initialized in EL3 and does not need - * to be initialized again in SEL1. This is because the S-EL1 - * can use GIC system registers to manage interrupts and does - * not need GIC interface base addresses to be configured. - */ -#if IMAGE_BL31 - gicv3_driver_init(&marvell_gic_data); -#endif -} - -/****************************************************************************** - * Marvell common helper to initialize the GIC. Only invoked by BL31 - ****************************************************************************** - */ -void plat_marvell_gic_init(void) -{ - /* Initialize GIC-600 Multi Chip feature, - * only if the maximum number of north bridges - * is more than 1 - otherwise no need for multi - * chip feature initialization - */ -#if (PLAT_MARVELL_NORTHB_COUNT > 1) - if (gic600_multi_chip_init()) - ERROR("GIC-600 Multi Chip initialization failed\n"); -#endif - gicv3_distif_init(); - gicv3_rdistif_init(plat_my_core_pos()); - gicv3_cpuif_enable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to enable the GIC CPU interface - ****************************************************************************** - */ -void plat_marvell_gic_cpuif_enable(void) -{ - gicv3_cpuif_enable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to disable the GIC CPU interface - ****************************************************************************** - */ -void plat_marvell_gic_cpuif_disable(void) -{ - gicv3_cpuif_disable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to init. the per-cpu redistributor interface in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_pcpu_init(void) -{ - gicv3_rdistif_init(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to save SPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_save(void) -{ - - /* - * If an ITS is available, save its context before - * the Redistributor using: - * gicv3_its_save_disable(gits_base, &its_ctx[i]) - * Additionally, an implementation-defined sequence may - * be required to save the whole ITS state. - */ - - /* - * Save the GIC Redistributors and ITS contexts before the - * Distributor context. As we only handle SYSTEM SUSPEND API, - * we only need to save the context of the CPU that is issuing - * the SYSTEM SUSPEND call, i.e. the current CPU. - */ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); - - /* Save the GIC Distributor context */ - gicv3_distif_save(&dist_ctx); - - /* - * From here, all the components of the GIC can be safely powered down - * as long as there is an alternate way to handle wakeup interrupt - * sources. - */ -} - -/****************************************************************************** - * Marvell common helper to restore SPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_restore(void) -{ - /* Restore the GIC Distributor context */ - gicv3_distif_init_restore(&dist_ctx); - - /* - * Restore the GIC Redistributor and ITS contexts after the - * Distributor context. As we only handle SYSTEM SUSPEND API, - * we only need to restore the context of the CPU that issued - * the SYSTEM SUSPEND call. - */ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); - - /* - * If an ITS is available, restore its context after - * the Redistributor using: - * gicv3_its_restore(gits_base, &its_ctx[i]) - * An implementation-defined sequence may be required to - * restore the whole ITS state. The ITS must also be - * re-enabled after this sequence has been executed. - */ -} - -/****************************************************************************** - * Marvell common helper to save per-cpu PPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_pcpu_save(void) -{ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); -} - -/****************************************************************************** - * Marvell common helper to restore per-cpu PPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_pcpu_restore(void) -{ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); -} diff --git a/plat/marvell/common/marvell_image_load.c b/plat/marvell/common/marvell_image_load.c deleted file mode 100644 index be16b08..0000000 --- a/plat/marvell/common/marvell_image_load.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -/******************************************************************************* - * This function flushes the data structures so that they are visible - * in memory for the next BL image. - ******************************************************************************/ -void plat_flush_next_bl_params(void) -{ - flush_bl_params_desc(); -} - -/******************************************************************************* - * This function returns the list of loadable images. - ******************************************************************************/ -bl_load_info_t *plat_get_bl_image_load_info(void) -{ - return get_bl_load_info_from_mem_params_desc(); -} - -/******************************************************************************* - * This function returns the list of executable images. - ******************************************************************************/ -bl_params_t *plat_get_next_bl_params(void) -{ - return get_next_bl_params_from_mem_params_desc(); -} diff --git a/plat/marvell/common/marvell_io_storage.c b/plat/marvell/common/marvell_io_storage.c deleted file mode 100644 index 065f956..0000000 --- a/plat/marvell/common/marvell_io_storage.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* IO devices */ -static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; -static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = PLAT_MARVELL_FIP_BASE, - .length = PLAT_MARVELL_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t scp_bl2_uuid_spec = { - .uuid = UUID_SCP_FIRMWARE_SCP_BL2, -}; - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, Marvell platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [SCP_BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_bl2_uuid_spec, - open_fip - }, - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - open_fip - }, - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, -}; - - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak plat_marvell_io_setup -#pragma weak plat_marvell_get_alt_image_source - - -static int open_fip(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - /* See if a Firmware Image Package is available */ - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { - result = io_open(fip_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using FIP\n"); - io_close(local_image_handle); - } - } - return result; -} - - -static int open_memmap(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(memmap_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using Memmap\n"); - io_close(local_image_handle); - } - } - return result; -} - - -void marvell_io_setup(void) -{ - int io_result; - - io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); - - io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); - - /* Open connections to devices and cache the handles */ - io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - assert(io_result == 0); - - io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; -} - -void plat_marvell_io_setup(void) -{ - marvell_io_setup(); -} - -int plat_marvell_get_alt_image_source( - unsigned int image_id __attribute__((unused)), - uintptr_t *dev_handle __attribute__((unused)), - uintptr_t *image_spec __attribute__((unused))) -{ - /* By default do not try an alternative */ - return -ENOENT; -} - -/* - * Return an IO device handle and specification which can be used to access - * an image. Use this to enforce platform load policy - */ -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - if (result == 0) { - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - } else { - VERBOSE("Trying alternative IO\n"); - result = plat_marvell_get_alt_image_source(image_id, dev_handle, - image_spec); - } - - return result; -} - -/* - * See if a Firmware Image Package is available, - * by checking if TOC is valid or not. - */ -int marvell_io_is_toc_valid(void) -{ - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return result == 0; -} diff --git a/plat/marvell/common/marvell_pm.c b/plat/marvell/common/marvell_pm.c deleted file mode 100644 index 3c675b2..0000000 --- a/plat/marvell/common/marvell_pm.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include - -/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */ -extern const plat_psci_ops_t plat_arm_psci_pm_ops; - -/***************************************************************************** - * Private function to program the mailbox for a cpu before it is released - * from reset. This function assumes that the mail box base is within - * the MARVELL_SHARED_RAM region - ***************************************************************************** - */ -void marvell_program_mailbox(uintptr_t address) -{ - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* - * Ensure that the PLAT_MARVELL_MAILBOX_BASE is within - * MARVELL_SHARED_RAM region. - */ - assert((PLAT_MARVELL_MAILBOX_BASE >= MARVELL_SHARED_RAM_BASE) && - ((PLAT_MARVELL_MAILBOX_BASE + sizeof(*mailbox)) <= - (MARVELL_SHARED_RAM_BASE + MARVELL_SHARED_RAM_SIZE))); - - mailbox[MBOX_IDX_MAGIC] = MVEBU_MAILBOX_MAGIC_NUM; - mailbox[MBOX_IDX_SEC_ADDR] = address; - - /* 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 + - 8 * MBOX_IDX_MAGIC, - 2 * sizeof(uint64_t)); -#endif -} - -/***************************************************************************** - * The ARM Standard platform definition of platform porting API - * `plat_setup_psci_ops`. - ***************************************************************************** - */ -int plat_setup_psci_ops(uintptr_t sec_entrypoint, - const plat_psci_ops_t **psci_ops) -{ - *psci_ops = &plat_arm_psci_pm_ops; - - /* Setup mailbox with entry point. */ - marvell_program_mailbox(sec_entrypoint); - return 0; -} diff --git a/plat/marvell/common/marvell_topology.c b/plat/marvell/common/marvell_topology.c deleted file mode 100644 index a40ff6f..0000000 --- a/plat/marvell/common/marvell_topology.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -/* The power domain tree descriptor */ -unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1]; - -/***************************************************************************** - * This function dynamically constructs the topology according to - * PLAT_MARVELL_CLUSTER_COUNT and returns it. - ***************************************************************************** - */ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - int i; - - /* - * The power domain tree does not have a single system level power - * domain i.e. a single root node. The first entry in the power domain - * descriptor specifies the number of power domains at the highest power - * level. - * For Marvell Platform this is the number of cluster power domains. - */ - marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT; - - for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++) - marvell_power_domain_tree_desc[i + 1] = - PLAT_MARVELL_CLUSTER_CORE_COUNT; - - return marvell_power_domain_tree_desc; -} - -/***************************************************************************** - * This function validates an MPIDR by checking whether it falls within the - * acceptable bounds. An error code (-1) is returned if an incorrect mpidr - * is passed. - ***************************************************************************** - */ -int marvell_check_mpidr(u_register_t mpidr) -{ - unsigned int nb_id, cluster_id, cpu_id; - - mpidr &= MPIDR_AFFINITY_MASK; - - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK | - MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) - return -1; - - /* Get north bridge ID */ - nb_id = MPIDR_AFFLVL3_VAL(mpidr); - cluster_id = MPIDR_AFFLVL1_VAL(mpidr); - cpu_id = MPIDR_AFFLVL0_VAL(mpidr); - - if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT) - return -1; - - if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT) - return -1; - - if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT) - return -1; - - return 0; -} - -/***************************************************************************** - * This function implements a part of the critical interface between the PSCI - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ***************************************************************************** - */ -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - if (marvell_check_mpidr(mpidr) == -1) - return -1; - - return plat_marvell_calc_core_pos(mpidr); -} diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c deleted file mode 100644 index 0291024..0000000 --- a/plat/marvell/common/mrvl_sip_svc.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "comphy/phy-comphy-cp110.h" -#include - -/* #define DEBUG_COMPHY */ -#ifdef DEBUG_COMPHY -#define debug(format...) NOTICE(format) -#else -#define debug(format, arg...) -#endif - -/* 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 -#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004 -#define MV_SIP_COMPHY_DIG_RESET 0x82000005 - -/* Miscellaneous FID's' */ -#define MV_SIP_DRAM_SIZE 0x82000010 -#define MV_SIP_LLC_ENABLE 0x82000011 -#define MV_SIP_PMU_IRQ_ENABLE 0x82000012 -#define MV_SIP_PMU_IRQ_DISABLE 0x82000013 - -#define MAX_LANE_NR 6 -#define MVEBU_COMPHY_OFFSET 0x441000 -#define MVEBU_CP_BASE_MASK (~0xffffff) - -/* 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_DIG_RESET) - -_Bool is_cp_range_valid(u_register_t *addr) -{ - int cp_nr; - - *addr &= MVEBU_CP_BASE_MASK; - for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) { - if (*addr == MVEBU_CP_REGS_BASE(cp_nr)) - return true; - } - - return false; -} - -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; - int i; - - debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", - __func__, smc_fid, x1, x2, x3); - - if (is_comphy_fid(smc_fid)) { - /* validate address passed via x1 */ - if (!is_cp_range_valid(&x1)) { - ERROR("%s: Wrong smc (0x%x) address: %lx\n", - __func__, smc_fid, x1); - SMC_RET1(handle, SMC_UNK); - } - - x1 += MVEBU_COMPHY_OFFSET; - - if (x2 >= 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_base, x2: comphy_index, x3: comphy_mode */ - ret = mvebu_cp110_comphy_power_on(x1, x2, x3); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_POWER_OFF: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_power_off(x1, x2, x3); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_PLL_LOCK: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_is_pll_locked(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_XFI_TRAIN: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_xfi_rx_training(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_DIG_RESET: - /* x1: comphy_base, x2: comphy_index, x3: mode, x4: command */ - ret = mvebu_cp110_comphy_digital_reset(x1, x2, x3, x4); - SMC_RET1(handle, ret); - - /* Miscellaneous FID's' */ - case MV_SIP_DRAM_SIZE: - ret = mvebu_get_dram_size(MVEBU_REGS_BASE); - SMC_RET1(handle, ret); - case MV_SIP_LLC_ENABLE: - for (i = 0; i < ap_get_count(); i++) - llc_runtime_enable(i); - - SMC_RET1(handle, 0); -#ifdef MVEBU_PMU_IRQ_WA - case MV_SIP_PMU_IRQ_ENABLE: - mvebu_pmu_interrupt_enable(); - SMC_RET1(handle, 0); - case MV_SIP_PMU_IRQ_DISABLE: - mvebu_pmu_interrupt_disable(); - SMC_RET1(handle, 0); -#endif - - 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/common/mss/mss_common.mk b/plat/marvell/common/mss/mss_common.mk deleted file mode 100644 index 898b6dc..0000000 --- a/plat/marvell/common/mss/mss_common.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - - -PLAT_MARVELL := plat/marvell -MSS_SOURCE := $(PLAT_MARVELL)/common/mss - -BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \ - $(PLAT_MARVELL)/common/plat_delay_timer.c \ - drivers/delay_timer/delay_timer.c \ - $(MARVELL_DRV) \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c - -PLAT_INCLUDES += -I$(MSS_SOURCE) diff --git a/plat/marvell/common/mss/mss_ipc_drv.c b/plat/marvell/common/mss/mss_ipc_drv.c deleted file mode 100644 index 70ccfa5..0000000 --- a/plat/marvell/common/mss/mss_ipc_drv.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include -#include - -#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK - -#define IPC_CH_NUM_OF_MSG (16) -#define IPC_CH_MSG_IDX (-1) - -unsigned long mv_pm_ipc_msg_base; -unsigned int mv_pm_ipc_queue_size; - -unsigned int msg_sync; -int msg_index = IPC_CH_MSG_IDX; - -/****************************************************************************** - * mss_pm_ipc_init - * - * DESCRIPTION: Initialize PM IPC infrastructure - ****************************************************************************** - */ -int mv_pm_ipc_init(unsigned long ipc_control_addr) -{ - struct mss_pm_ipc_ctrl *ipc_control = - (struct mss_pm_ipc_ctrl *)ipc_control_addr; - - /* Initialize PM IPC control block */ - mv_pm_ipc_msg_base = ipc_control->msg_base_address | - IPC_MSG_BASE_MASK; - mv_pm_ipc_queue_size = ipc_control->queue_size; - - return 0; -} - -/****************************************************************************** - * mv_pm_ipc_queue_addr_get - * - * DESCRIPTION: Returns the IPC queue address - ****************************************************************************** - */ -unsigned int mv_pm_ipc_queue_addr_get(void) -{ - unsigned int addr; - - inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); - msg_index = msg_index + 1; - if (msg_index >= IPC_CH_NUM_OF_MSG) - msg_index = 0; - - addr = (unsigned int)(mv_pm_ipc_msg_base + - (msg_index * mv_pm_ipc_queue_size)); - - flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); - - return addr; -} - -/****************************************************************************** - * mv_pm_ipc_msg_rx - * - * DESCRIPTION: Retrieve message from IPC channel - ****************************************************************************** - */ -int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg) -{ - unsigned int addr = mv_pm_ipc_queue_addr_get(); - - msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC); - - return 0; -} - -/****************************************************************************** - * mv_pm_ipc_msg_tx - * - * DESCRIPTION: Send message via IPC channel - ****************************************************************************** - */ -int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, - unsigned int cluster_power_state) -{ - unsigned int addr = mv_pm_ipc_queue_addr_get(); - - /* Validate the entry for message placed by the host is free */ - if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) { - inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); - msg_sync = msg_sync + 1; - flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); - - mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync); - mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id); - mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id); - mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, - cluster_power_state); - mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY); - - } else { - ERROR("%s: FAILED\n", __func__); - } - - return 0; -} diff --git a/plat/marvell/common/mss/mss_ipc_drv.h b/plat/marvell/common/mss/mss_ipc_drv.h deleted file mode 100644 index bcb4b2d..0000000 --- a/plat/marvell/common/mss/mss_ipc_drv.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_IPC_DRV_H -#define MSS_IPC_DRV_H - -#include - -#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */ -/* Increament for each version */ -#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001) -#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \ - MV_PM_FW_IPC_VERSION_SEQ) - -#define IPC_MSG_STATE_LOC (0x0) -#define IPC_MSG_SYNC_ID_LOC (0x4) -#define IPC_MSG_ID_LOC (0x8) -#define IPC_MSG_RET_CH_ID_LOC (0xC) -#define IPC_MSG_CPU_ID_LOC (0x10) -#define IPC_MSG_CLUSTER_ID_LOC (0x14) -#define IPC_MSG_SYSTEM_ID_LOC (0x18) -#define IPC_MSG_POWER_STATE_LOC (0x1C) -#define IPC_MSG_REPLY_LOC (0x20) -#define IPC_MSG_RESERVED_LOC (0x24) - -/* IPC initialization state */ -enum mss_pm_ipc_init_state { - IPC_UN_INITIALIZED = 1, - IPC_INITIALIZED = 2 -}; - -/* IPC queue direction */ -enum mss_pm_ipc_init_msg_dir { - IPC_MSG_TX = 0, - IPC_MSG_RX = 1 -}; - -/* IPC message state */ -enum mss_pm_ipc_msg_state { - IPC_MSG_FREE = 1, - IPC_MSG_OCCUPY = 2 - -}; - -/* IPC control block */ -struct mss_pm_ipc_ctrl { - unsigned int ctrl_base_address; - unsigned int msg_base_address; - unsigned int num_of_channels; - unsigned int channel_size; - unsigned int queue_size; -}; - -/* IPC message types */ -enum mss_pm_msg_id { - PM_IPC_MSG_CPU_SUSPEND = 1, - PM_IPC_MSG_CPU_OFF = 2, - PM_IPC_MSG_CPU_ON = 3, - PM_IPC_MSG_SYSTEM_RESET = 4, - PM_IPC_MSG_SYSTEM_SUSPEND = 5, - PM_IPC_MAX_MSG -}; - -struct mss_pm_ipc_msg { - unsigned int msg_sync_id; /* - * Sync number, validate message - * reply corresponding to message - * received - */ - unsigned int msg_id; /* Message Id */ - unsigned int ret_channel_id; /* IPC channel reply */ - unsigned int cpu_id; /* CPU Id */ - unsigned int cluster_id; /* Cluster Id */ - unsigned int system_id; /* System Id */ - unsigned int power_state; - unsigned int msg_reply; /* Message reply */ -}; - -/* IPC queue */ -struct mss_pm_ipc_queue { - unsigned int state; - struct mss_pm_ipc_msg msg; -}; - -/* IPC channel */ -struct mss_pm_ipc_ch { - struct mss_pm_ipc_queue *tx_queue; - struct mss_pm_ipc_queue *rx_queue; -}; - -/***************************************************************************** - * mv_pm_ipc_init - * - * DESCRIPTION: Initialize PM IPC infrastructure - ***************************************************************************** - */ -int mv_pm_ipc_init(unsigned long ipc_control_addr); - -/***************************************************************************** - * mv_pm_ipc_msg_rx - * - * DESCRIPTION: Retrieve message from IPC channel - ***************************************************************************** - */ -int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg); - -/***************************************************************************** - * mv_pm_ipc_msg_tx - * - * DESCRIPTION: Send message via IPC channel - ***************************************************************************** - */ -int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, - unsigned int cluster_power_state); - -#endif /* MSS_IPC_DRV_H */ diff --git a/plat/marvell/common/mss/mss_mem.h b/plat/marvell/common/mss/mss_mem.h deleted file mode 100644 index 5d68ac7..0000000 --- a/plat/marvell/common/mss/mss_mem.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_MEM_H -#define MSS_MEM_H - -/* MSS SRAM Memory base */ -#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000) - -enum mss_pm_ctrl_handshake { - MSS_UN_INITIALIZED = 0, - MSS_COMPATIBILITY_ERROR = 1, - MSS_ACKNOWLEDGMENT = 2, - HOST_ACKNOWLEDGMENT = 3 -}; - -enum mss_pm_ctrl_rtos_env { - MSS_MULTI_PROCESS_ENV = 0, - MSS_SINGLE_PROCESS_ENV = 1, - MSS_MAX_PROCESS_ENV -}; - -struct mss_pm_ctrl_block { - /* This field is used to synchronize the Host - * and MSS initialization sequence - * Valid Values - * 0 - Un-Initialized - * 1 - Compatibility Error - * 2 - MSS Acknowledgment - * 3 - Host Acknowledgment - */ - unsigned int handshake; - - /* - * This field include Host IPC version. Once received by the MSS - * It will be compared to MSS IPC version and set MSS Acknowledge to - * "compatibility error" in case there is no match - */ - unsigned int ipc_version; - unsigned int ipc_base_address; - unsigned int ipc_state; - - /* Following fields defines firmware core architecture */ - unsigned int num_of_cores; - unsigned int num_of_clusters; - unsigned int num_of_cores_per_cluster; - - /* Following fields define pm trace debug base address */ - unsigned int pm_trace_ctrl_base_address; - unsigned int pm_trace_info_base_address; - unsigned int pm_trace_info_core_size; - - unsigned int ctrl_blk_size; -}; - -#endif /* MSS_MEM_H */ diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/common/mss/mss_scp_bl2_format.h deleted file mode 100644 index 7150f0a..0000000 --- a/plat/marvell/common/mss/mss_scp_bl2_format.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_SCP_BL2_FORMAT_H -#define MSS_SCP_BL2_FORMAT_H - -#define MAX_NR_OF_FILES 8 -#define FILE_MAGIC 0xddd01ff -#define HEADER_VERSION 0x1 - -#define MSS_IDRAM_SIZE 0x10000 /* 64KB */ -#define MG_SRAM_SIZE 0x20000 /* 128KB */ - -/* Types definitions */ -typedef struct file_header { - /* Magic specific for concatenated file (used for validation) */ - uint32_t magic; - uint32_t nr_of_imgs; /* Number of images concatenated */ -} file_header_t; - -/* Types definitions */ -enum cm3_t { - MSS_AP, - MSS_CP0, - MSS_CP1, - MSS_CP2, - MSS_CP3, - MG_CP0, - MG_CP1, - MG_CP2, -}; - -typedef struct img_header { - uint32_t type; /* CM3 type, can be one of cm3_t */ - uint32_t length; /* Image length */ - uint32_t version; /* For sanity checks and future - * extended functionality - */ -} img_header_t; - -#endif /* MSS_SCP_BL2_FORMAT_H */ diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c deleted file mode 100644 index 4473d81..0000000 --- a/plat/marvell/common/mss/mss_scp_bootloader.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MSS_DMA_SRCBR(base) (base + 0xC0) -#define MSS_DMA_DSTBR(base) (base + 0xC4) -#define MSS_DMA_CTRLR(base) (base + 0xC8) -#define MSS_M3_RSTCR(base) (base + 0xFC) - -#define MSS_DMA_CTRLR_SIZE_OFFSET (0) -#define MSS_DMA_CTRLR_REQ_OFFSET (15) -#define MSS_DMA_CTRLR_REQ_SET (1) -#define MSS_DMA_CTRLR_ACK_OFFSET (12) -#define MSS_DMA_CTRLR_ACK_MASK (0x1) -#define MSS_DMA_CTRLR_ACK_READY (1) -#define MSS_M3_RSTCR_RST_OFFSET (0) -#define MSS_M3_RSTCR_RST_OFF (1) - -#define MSS_DMA_TIMEOUT 1000 -#define MSS_EXTERNAL_SPACE 0x50000000 -#define MSS_EXTERNAL_ADDR_MASK 0xfffffff - -#define DMA_SIZE 128 - -#define MSS_HANDSHAKE_TIMEOUT 50 - -#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) - -static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) -{ - int timeout = MSS_HANDSHAKE_TIMEOUT; - - /* Wait for SCP to signal it's ready */ - while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) && - (timeout-- > 0)) - mdelay(1); - - if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) - return -1; - - mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT; - - return 0; -} - -static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) -{ - if (size > MG_SRAM_SIZE) { - ERROR("image is too big to fit into MG CM3 memory\n"); - return 1; - } - - NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", - src_addr, size, mg_regs); - - /* Copy image to MG CM3 SRAM */ - memcpy((void *)mg_regs, (void *)src_addr, size); - - /* - * Don't release MG CM3 from reset - it will be done by next step - * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which - * has enabeld 802.3. auto-neg) will be choosen. - */ - - return 0; -} - -static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) -{ - uint32_t i, loop_num, timeout; - - /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */ - if (size > MSS_IDRAM_SIZE) { - ERROR("image is too big to fit into MSS CM3 memory\n"); - return 1; - } - - NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n", - src_addr, size, mss_regs); - /* load image to MSS RAM using DMA */ - loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1); - - for (i = 0; i < loop_num; i++) { - /* write destination and source addresses */ - mmio_write_32(MSS_DMA_SRCBR(mss_regs), - MSS_EXTERNAL_SPACE | - ((src_addr & MSS_EXTERNAL_ADDR_MASK) + - (i * DMA_SIZE))); - mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE)); - - dsb(); /* make sure DMA data is ready before triggering it */ - - /* set the DMA control register */ - mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET - << MSS_DMA_CTRLR_REQ_OFFSET) | - (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET))); - - /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ - timeout = MSS_DMA_TIMEOUT; - while (timeout) { - if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> - MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK) - == MSS_DMA_CTRLR_ACK_READY) { - break; - } - - udelay(50); - timeout--; - } - - if (timeout == 0) { - ERROR("\nDMA failed to load MSS image\n"); - return 1; - } - } - - bl2_plat_configure_mss_windows(mss_regs); - - /* Release M3 from reset */ - mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF << - MSS_M3_RSTCR_RST_OFFSET)); - - NOTICE("Done\n"); - - return 0; -} - -/* Load image to MSS AP and do PM related initialization - * Note that this routine is different than other CM3 loading routines, because - * firmware for AP is dedicated for PM and therefore some additional PM - * initialization is required - */ -static int mss_ap_load_image(uintptr_t single_img, - uint32_t image_size, uint32_t ap_idx) -{ - volatile struct mss_pm_ctrl_block *mss_pm_crtl; - int ret; - - /* TODO: add PM Control Info from platform */ - mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; - mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION; - mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT; - mss_pm_crtl->num_of_cores_per_cluster = - PLAT_MARVELL_CLUSTER_CORE_COUNT; - mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT * - PLAT_MARVELL_CLUSTER_CORE_COUNT; - mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE; - mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE; - mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE; - VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE); - VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n", - mss_pm_crtl->ipc_version); - VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n", - mss_pm_crtl->num_of_cores); - VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n", - mss_pm_crtl->num_of_clusters); - VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n", - mss_pm_crtl->num_of_cores_per_cluster); - VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n", - mss_pm_crtl->pm_trace_ctrl_base_address); - VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n", - mss_pm_crtl->pm_trace_info_base_address); - VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n", - mss_pm_crtl->pm_trace_info_core_size); - - /* TODO: add checksum to image */ - VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); - - ret = mss_image_load(single_img, image_size, - bl2_plat_get_ap_mss_regs(ap_idx)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - - /* check that the image was loaded successfully */ - ret = mss_check_image_ready(mss_pm_crtl); - if (ret != 0) - NOTICE("SCP Image doesn't contain PM firmware\n"); - - return 0; -} - -/* Load CM3 image (single_img) to CM3 pointed by cm3_type */ -static int load_img_to_cm3(enum cm3_t cm3_type, - uintptr_t single_img, uint32_t image_size) -{ - int ret, ap_idx, cp_index; - uint32_t ap_count = bl2_plat_get_ap_count(); - - switch (cm3_type) { - case MSS_AP: - for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { - NOTICE("Load image to AP%d MSS\n", ap_idx); - ret = mss_ap_load_image(single_img, image_size, ap_idx); - if (ret != 0) - return ret; - } - break; - case MSS_CP0: - case MSS_CP1: - case MSS_CP2: - case MSS_CP3: - /* MSS_AP = 0 - * MSS_CP1 = 1 - * . - * . - * MSS_CP3 = 4 - * Actual CP index is MSS_CPX - 1 - */ - cp_index = cm3_type - 1; - for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { - /* Check if we should load this image - * according to number of CPs - */ - if (bl2_plat_get_cp_count(ap_idx) <= cp_index) { - NOTICE("Skipping MSS CP%d related image\n", - cp_index); - break; - } - - NOTICE("Load image to CP%d MSS AP%d\n", - cp_index, ap_idx); - ret = mss_image_load(single_img, image_size, - bl2_plat_get_cp_mss_regs( - ap_idx, cp_index)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - } - break; - case MG_CP0: - case MG_CP1: - case MG_CP2: - cp_index = cm3_type - MG_CP0; - if (bl2_plat_get_cp_count(0) <= cp_index) { - NOTICE("Skipping MG CP%d related image\n", - cp_index); - break; - } - NOTICE("Load image to CP%d MG\n", cp_index); - ret = mg_image_load(single_img, image_size, - MG_CM3_SRAM_BASE(cp_index)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - break; - default: - ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); - break; - } - - return 0; -} - -/* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was - * required to provide a method for loading firmware to all of the service CPUs. - * To achieve that, the scp_bl2 image in fact is file containing up to 5 - * concatenated firmwares and this routine splits concatenated image into single - * images dedicated for appropriate service CPU and then load them. - */ -static int split_and_load_bl2_image(void *image) -{ - file_header_t *file_hdr; - img_header_t *img_hdr; - uintptr_t single_img; - int i; - - file_hdr = (file_header_t *)image; - - if (file_hdr->magic != FILE_MAGIC) { - ERROR("SCP_BL2 wrong img format\n"); - return -1; - } - - if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { - ERROR("SCP_BL2 concatenated image contains too many images\n"); - return -1; - } - - img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t)); - single_img = (uintptr_t)image + sizeof(file_header_t) + - sizeof(img_header_t) * file_hdr->nr_of_imgs; - - NOTICE("SCP_BL2 contains %d concatenated images\n", - file_hdr->nr_of_imgs); - for (i = 0; i < file_hdr->nr_of_imgs; i++) { - - /* Before loading make sanity check on header */ - if (img_hdr->version != HEADER_VERSION) { - ERROR("Wrong header, img corrupted exiting\n"); - return -1; - } - - load_img_to_cm3(img_hdr->type, single_img, img_hdr->length); - - /* Prepare offsets for next run */ - single_img += img_hdr->length; - img_hdr++; - } - - return 0; -} - -int scp_bootloader_transfer(void *image, unsigned int image_size) -{ -#ifdef SCP_BL2_BASE - assert((uintptr_t) image == SCP_BL2_BASE); -#endif - - VERBOSE("Concatenated img size %d\n", image_size); - - if (image_size == 0) { - ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n", - image_size); - return -1; - } - - if (split_and_load_bl2_image(image)) - return -1; - - return 0; -} diff --git a/plat/marvell/common/mss/mss_scp_bootloader.h b/plat/marvell/common/mss/mss_scp_bootloader.h deleted file mode 100644 index 4950d24..0000000 --- a/plat/marvell/common/mss/mss_scp_bootloader.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_SCP_BOOTLOADER_H -#define MSS_SCP_BOOTLOADER_H - -int scp_bootloader_transfer(void *image, unsigned int image_size); -uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx); -uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx); -uint32_t bl2_plat_get_cp_count(int ap_idx); -uint32_t bl2_plat_get_ap_count(void); -void bl2_plat_configure_mss_windows(uintptr_t mss_regs); -int bl2_plat_mss_check_image_ready(void); - -#endif /* MSS_SCP_BOOTLOADER_H */ diff --git a/plat/marvell/common/plat_delay_timer.c b/plat/marvell/common/plat_delay_timer.c deleted file mode 100644 index 2539752..0000000 --- a/plat/marvell/common/plat_delay_timer.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 - -#define SYS_COUNTER_FREQ_IN_MHZ (COUNTER_FREQUENCY/1000000) - -static uint32_t plat_get_timer_value(void) -{ - /* - * Generic delay timer implementation expects the timer to be a down - * counter. We apply bitwise NOT operator to the tick values returned - * by read_cntpct_el0() to simulate the down counter. - */ - return (uint32_t)(~read_cntpct_el0()); -} - -static const timer_ops_t plat_timer_ops = { - .get_timer_value = plat_get_timer_value, - .clk_mult = 1, - .clk_div = SYS_COUNTER_FREQ_IN_MHZ -}; - -void plat_delay_timer_init(void) -{ - timer_init(&plat_timer_ops); -}