Merge pull request #1410 from Anson-Huang/master

Add NXP's i.MX8QX and i.MX8QM SoC support
This commit is contained in:
Dimitris Papastamos 2018-06-19 15:10:23 +01:00 committed by GitHub
commit d135ad7884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 7275 additions and 0 deletions

58
docs/plat/imx8.rst Normal file
View File

@ -0,0 +1,58 @@
Description
===========
The i.MX 8 series of applications processors is a feature- and
performance-scalable multi-core platform that includes single-,
dual-, and quad-core families based on the Arm® Cortex®
architecture—including combined Cortex-A72 + Cortex-A53,
Cortex-A35, and Cortex-M4 based solutions for advanced graphics,
imaging, machine vision, audio, voice, video, and safety-critical
applications.
The i.MX8QM is with 2 Cortex-A72 ARM core, 4 Cortex-A53 ARM core
and 1 Cortex-M4 system controller.
The i.MX8QX is with 4 Cortex-A35 ARM core and 1 Cortex-M4 system
controller.
The System Controller (SC) represents the evolution of centralized
control for system-level resources on i.MX8. The heart of the system
controller is a Cortex-M4 that executes system controller firmware.
Boot Sequence
=============
Bootrom --> BL31 --> BL33(u-boot) --> Linux kernel
How to build
============
Build Procedure
---------------
- Prepare AARCH64 toolchain.
- Build System Controller Firmware and u-boot firstly, and get binary images: scfw_tcm.bin and u-boot.bin
- Build TF-A
Build bl31:
.. code:: shell
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
Target_SoC should be "imx8qm" for i.MX8QM SoC.
Target_SoC should be "imx8qx" for i.MX8QX SoC.
Deploy TF-A Images
-----------------
TF-A binary(bl31.bin), scfw_tcm.bin and u-boot.bin are combined together
to generate a binary file called flash.bin, the imx-mkimage tool is used
to generate flash.bin, and flash.bin needs to be flashed into SD card
with certain offset for BOOT ROM. The system controller firmware,
u-boot and imx-mkimage will be upstreamed soon, this doc will be updated
once they are ready, and the link will be posted.
.. _i.MX8: https://www.nxp.com/products/processors-and-microcontrollers/applications-processors/i.mx-applications-processors/i.mx-8-processors/i.mx-8-family-arm-cortex-a53-cortex-a72-virtualization-vision-3d-graphics-4k-video:i.MX8

View File

@ -102,6 +102,16 @@ Files:
- docs/plat/ls1043a.rst
- plat/layerscape/\*
NXP i.MX 8 platform sub-maintainer
--------------------------------------
Anson Huang (Anson.Huang@nxp.com, `Anson-Huang`_)
Files:
- docs/plat/imx8.rst
- plat/imx/\*
Raspberry Pi 3 platform sub-maintainer
--------------------------------------

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <platform_def.h>
#include <cortex_a35.h>
.globl plat_is_my_cpu_primary
.globl plat_my_core_pos
.globl plat_calc_core_pos
.globl plat_reset_handler
.globl plat_get_my_entrypoint
.globl plat_secondary_cold_boot_setup
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl platform_mem_init
.globl imx_mailbox_init
/* --------------------------------------------------------------------
* Helper macro that reads the part number of the current CPU and jumps
* to the given label if it matches the CPU MIDR provided.
*
* Clobbers x0.
* --------------------------------------------------------------------
*/
.macro jump_if_cpu_midr _cpu_midr, _label
mrs x0, midr_el1
ubfx x0, x0, MIDR_PN_SHIFT, #12
cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
b.eq \_label
.endm
/* ----------------------------------------------
* The mailbox_base is used to distinguish warm/cold
* reset. The mailbox_base is in the data section, not
* in .bss, this allows function to start using this
* variable before the runtime memory is initialized.
* ----------------------------------------------
*/
.section .data.mailbox_base
.align 3
mailbox_base: .quad 0x0
/* ----------------------------------------------
* unsigned int plat_is_my_cpu_primary(void);
* This function checks if this is the primary CPU
* ----------------------------------------------
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CPU_MASK)
cmp x0, #PLAT_PRIMARY_CPU
cset x0, eq
ret
endfunc plat_is_my_cpu_primary
/* ----------------------------------------------
* unsigned int plat_my_core_pos(void)
* This Function uses the plat_calc_core_pos()
* to get the index of the calling CPU.
* ----------------------------------------------
*/
func plat_my_core_pos
mrs x0, mpidr_el1
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
add x0, x1, x0, LSR #6
ret
endfunc plat_my_core_pos
/*
* unsigned int plat_calc_core_pos(uint64_t mpidr)
* helper function to calculate the core position.
* With this function.
*/
func plat_calc_core_pos
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
add x0, x1, x0, LSR #6
ret
endfunc plat_calc_core_pos
/* ---------------------------------------------
* function to get the entrypoint.
* ---------------------------------------------
*/
func plat_get_my_entrypoint
adrp x1, mailbox_base
ldr x0, [x1, :lo12:mailbox_base]
ret
endfunc plat_get_my_entrypoint
func imx_mailbox_init
adrp x1, mailbox_base
str x0, [x1, :lo12:mailbox_base]
ret
endfunc imx_mailbox_init
func plat_secondary_cold_boot_setup
b .
endfunc plat_secondary_cold_boot_setup
func plat_crash_console_init
ret
endfunc plat_crash_console_init
func plat_crash_console_putc
ret
endfunc plat_crash_console_putc
func platform_mem_init
ret
endfunc platform_mem_init

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <platform.h>
const unsigned char imx_power_domain_tree_desc[] = {
PWR_DOMAIN_AT_MAX_LVL,
PLATFORM_CLUSTER_COUNT,
PLATFORM_CORE_COUNT,
};
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return imx_power_domain_tree_desc;
}
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
unsigned int cluster_id, cpu_id;
mpidr &= MPIDR_AFFINITY_MASK;
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
return -1;
cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
if (cluster_id > PLATFORM_CLUSTER_COUNT ||
cpu_id > PLATFORM_MAX_CPU_PER_CLUSTER)
return -1;
return (cpu_id + (cluster_id * 4));
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __IMX8_IOMUX_H__
#define __IMX8_IOMUX_H__
#define PADRING_IFMUX_EN_SHIFT 31
#define PADRING_IFMUX_EN_MASK (1 << PADRING_IFMUX_EN_SHIFT)
#define PADRING_GP_EN_SHIFT 30
#define PADRING_GP_EN_MASK (1 << PADRING_GP_EN_SHIFT)
#define PADRING_IFMUX_SHIFT 27
#define PADRING_IFMUX_MASK (0x7 << PADRING_IFMUX_SHIFT)
#define PADRING_CONFIG_SHIFT 25
#define PADRING_CONFIG_MASK (0x3 << PADRING_CONFIG_SHIFT)
#define PADRING_LPCONFIG_SHIFT 23
#define PADRING_LPCONFIG_MASK (0x3 << PADRING_LPCONFIG_SHIFT)
#define PADRING_PULL_SHIFT 5
#define PADRING_PULL_MASK (0x3 << PADRING_PULL_SHIFT)
#define PADRING_DSE_SHIFT 0
#define PADRING_DSE_MASK (0x7 << PADRING_DSE_SHIFT)
#endif /* __IMX8_IOMUX_H__ */

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __IMX_LPUART_H__
#define __IMX_LPUART_H__
#include <console.h>
#define VERID 0x0
#define PARAM 0x4
#define GLOBAL 0x8
#define PINCFG 0xC
#define BAUD 0x10
#define STAT 0x14
#define CTRL 0x18
#define DATA 0x1C
#define MATCH 0x20
#define MODIR 0x24
#define FIFO 0x28
#define WATER 0x2c
#define US1_TDRE (1 << 23)
#define US1_RDRF (1 << 21)
#define CTRL_TE (1 << 19)
#define CTRL_RE (1 << 18)
#define FIFO_TXFE 0x80
#define FIFO_RXFE 0x40
#define WATER_TXWATER_OFF 1
#define WATER_RXWATER_OFF 16
#define LPUART_CTRL_PT_MASK 0x1
#define LPUART_CTRL_PE_MASK 0x2
#define LPUART_CTRL_M_MASK 0x10
#define LPUART_BAUD_OSR_MASK (0x1F000000U)
#define LPUART_BAUD_OSR_SHIFT (24U)
#define LPUART_BAUD_OSR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_OSR_SHIFT)) & LPUART_BAUD_OSR_MASK)
#define LPUART_BAUD_SBR_MASK (0x1FFFU)
#define LPUART_BAUD_SBR_SHIFT (0U)
#define LPUART_BAUD_SBR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_SBR_SHIFT)) & LPUART_BAUD_SBR_MASK)
#define LPUART_BAUD_SBNS_MASK (0x2000U)
#define LPUART_BAUD_BOTHEDGE_MASK (0x20000U)
#define LPUART_BAUD_M10_MASK (0x20000000U)
#ifndef __ASSEMBLY__
#include <types.h>
typedef struct {
console_t console;
uintptr_t base;
} console_lpuart_t;
int console_lpuart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
console_lpuart_t *console);
#endif /*__ASSEMBLY__*/
#endif /* __IMX_LPUART_H__*/

View File

@ -0,0 +1,293 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file used to configure SoC pad list.
*/
#ifndef SC_PADS_H
#define SC_PADS_H
/* Includes */
/* Defines */
/*!
* @name Pad Definitions
*/
/*@{*/
#define SC_P_SIM0_CLK 0 /* DMA.SIM0.CLK, LSIO.GPIO0.IO00 */
#define SC_P_SIM0_RST 1 /* DMA.SIM0.RST, LSIO.GPIO0.IO01 */
#define SC_P_SIM0_IO 2 /* DMA.SIM0.IO, LSIO.GPIO0.IO02 */
#define SC_P_SIM0_PD 3 /* DMA.SIM0.PD, DMA.I2C3.SCL, LSIO.GPIO0.IO03 */
#define SC_P_SIM0_POWER_EN 4 /* DMA.SIM0.POWER_EN, DMA.I2C3.SDA, LSIO.GPIO0.IO04 */
#define SC_P_SIM0_GPIO0_00 5 /* DMA.SIM0.POWER_EN, LSIO.GPIO0.IO05 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_SIM 6 /* */
#define SC_P_M40_I2C0_SCL 7 /* M40.I2C0.SCL, M40.UART0.RX, M40.GPIO0.IO02, LSIO.GPIO0.IO06 */
#define SC_P_M40_I2C0_SDA 8 /* M40.I2C0.SDA, M40.UART0.TX, M40.GPIO0.IO03, LSIO.GPIO0.IO07 */
#define SC_P_M40_GPIO0_00 9 /* M40.GPIO0.IO00, M40.TPM0.CH0, DMA.UART4.RX, LSIO.GPIO0.IO08 */
#define SC_P_M40_GPIO0_01 10 /* M40.GPIO0.IO01, M40.TPM0.CH1, DMA.UART4.TX, LSIO.GPIO0.IO09 */
#define SC_P_M41_I2C0_SCL 11 /* M41.I2C0.SCL, M41.UART0.RX, M41.GPIO0.IO02, LSIO.GPIO0.IO10 */
#define SC_P_M41_I2C0_SDA 12 /* M41.I2C0.SDA, M41.UART0.TX, M41.GPIO0.IO03, LSIO.GPIO0.IO11 */
#define SC_P_M41_GPIO0_00 13 /* M41.GPIO0.IO00, M41.TPM0.CH0, DMA.UART3.RX, LSIO.GPIO0.IO12 */
#define SC_P_M41_GPIO0_01 14 /* M41.GPIO0.IO01, M41.TPM0.CH1, DMA.UART3.TX, LSIO.GPIO0.IO13 */
#define SC_P_GPT0_CLK 15 /* LSIO.GPT0.CLK, DMA.I2C1.SCL, LSIO.KPP0.COL4, LSIO.GPIO0.IO14 */
#define SC_P_GPT0_CAPTURE 16 /* LSIO.GPT0.CAPTURE, DMA.I2C1.SDA, LSIO.KPP0.COL5, LSIO.GPIO0.IO15 */
#define SC_P_GPT0_COMPARE 17 /* LSIO.GPT0.COMPARE, LSIO.PWM3.OUT, LSIO.KPP0.COL6, LSIO.GPIO0.IO16 */
#define SC_P_GPT1_CLK 18 /* LSIO.GPT1.CLK, DMA.I2C2.SCL, LSIO.KPP0.COL7, LSIO.GPIO0.IO17 */
#define SC_P_GPT1_CAPTURE 19 /* LSIO.GPT1.CAPTURE, DMA.I2C2.SDA, LSIO.KPP0.ROW4, LSIO.GPIO0.IO18 */
#define SC_P_GPT1_COMPARE 20 /* LSIO.GPT1.COMPARE, LSIO.PWM2.OUT, LSIO.KPP0.ROW5, LSIO.GPIO0.IO19 */
#define SC_P_UART0_RX 21 /* DMA.UART0.RX, SCU.UART0.RX, LSIO.GPIO0.IO20 */
#define SC_P_UART0_TX 22 /* DMA.UART0.TX, SCU.UART0.TX, LSIO.GPIO0.IO21 */
#define SC_P_UART0_RTS_B 23 /* DMA.UART0.RTS_B, LSIO.PWM0.OUT, DMA.UART2.RX, LSIO.GPIO0.IO22 */
#define SC_P_UART0_CTS_B 24 /* DMA.UART0.CTS_B, LSIO.PWM1.OUT, DMA.UART2.TX, LSIO.GPIO0.IO23 */
#define SC_P_UART1_TX 25 /* DMA.UART1.TX, DMA.SPI3.SCK, LSIO.GPIO0.IO24 */
#define SC_P_UART1_RX 26 /* DMA.UART1.RX, DMA.SPI3.SDO, LSIO.GPIO0.IO25 */
#define SC_P_UART1_RTS_B 27 /* DMA.UART1.RTS_B, DMA.SPI3.SDI, DMA.UART1.CTS_B, LSIO.GPIO0.IO26 */
#define SC_P_UART1_CTS_B 28 /* DMA.UART1.CTS_B, DMA.SPI3.CS0, DMA.UART1.RTS_B, LSIO.GPIO0.IO27 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 29 /* */
#define SC_P_SCU_PMIC_MEMC_ON 30 /* SCU.GPIO0.IOXX_PMIC_MEMC_ON */
#define SC_P_SCU_WDOG_OUT 31 /* SCU.WDOG0.WDOG_OUT */
#define SC_P_PMIC_I2C_SDA 32 /* SCU.PMIC_I2C.SDA */
#define SC_P_PMIC_I2C_SCL 33 /* SCU.PMIC_I2C.SCL */
#define SC_P_PMIC_EARLY_WARNING 34 /* SCU.PMIC_EARLY_WARNING */
#define SC_P_PMIC_INT_B 35 /* SCU.DSC.PMIC_INT_B */
#define SC_P_SCU_GPIO0_00 36 /* SCU.GPIO0.IO00, SCU.UART0.RX, LSIO.GPIO0.IO28 */
#define SC_P_SCU_GPIO0_01 37 /* SCU.GPIO0.IO01, SCU.UART0.TX, LSIO.GPIO0.IO29 */
#define SC_P_SCU_GPIO0_02 38 /* SCU.GPIO0.IO02, SCU.GPIO0.IOXX_PMIC_GPU0_ON, LSIO.GPIO0.IO30 */
#define SC_P_SCU_GPIO0_03 39 /* SCU.GPIO0.IO03, SCU.GPIO0.IOXX_PMIC_GPU1_ON, LSIO.GPIO0.IO31 */
#define SC_P_SCU_GPIO0_04 40 /* SCU.GPIO0.IO04, SCU.GPIO0.IOXX_PMIC_A72_ON, LSIO.GPIO1.IO00 */
#define SC_P_SCU_GPIO0_05 41 /* SCU.GPIO0.IO05, SCU.GPIO0.IOXX_PMIC_A53_ON, LSIO.GPIO1.IO01 */
#define SC_P_SCU_GPIO0_06 42 /* SCU.GPIO0.IO06, SCU.TPM0.CH0, LSIO.GPIO1.IO02 */
#define SC_P_SCU_GPIO0_07 43 /* SCU.GPIO0.IO07, SCU.TPM0.CH1, SCU.DSC.RTC_CLOCK_OUTPUT_32K, LSIO.GPIO1.IO03 */
#define SC_P_SCU_BOOT_MODE0 44 /* SCU.DSC.BOOT_MODE0 */
#define SC_P_SCU_BOOT_MODE1 45 /* SCU.DSC.BOOT_MODE1 */
#define SC_P_SCU_BOOT_MODE2 46 /* SCU.DSC.BOOT_MODE2 */
#define SC_P_SCU_BOOT_MODE3 47 /* SCU.DSC.BOOT_MODE3 */
#define SC_P_SCU_BOOT_MODE4 48 /* SCU.DSC.BOOT_MODE4, SCU.PMIC_I2C.SCL */
#define SC_P_SCU_BOOT_MODE5 49 /* SCU.DSC.BOOT_MODE5, SCU.PMIC_I2C.SDA */
#define SC_P_LVDS0_GPIO00 50 /* LVDS0.GPIO0.IO00, LVDS0.PWM0.OUT, LSIO.GPIO1.IO04 */
#define SC_P_LVDS0_GPIO01 51 /* LVDS0.GPIO0.IO01, LSIO.GPIO1.IO05 */
#define SC_P_LVDS0_I2C0_SCL 52 /* LVDS0.I2C0.SCL, LVDS0.GPIO0.IO02, LSIO.GPIO1.IO06 */
#define SC_P_LVDS0_I2C0_SDA 53 /* LVDS0.I2C0.SDA, LVDS0.GPIO0.IO03, LSIO.GPIO1.IO07 */
#define SC_P_LVDS0_I2C1_SCL 54 /* LVDS0.I2C1.SCL, DMA.UART2.TX, LSIO.GPIO1.IO08 */
#define SC_P_LVDS0_I2C1_SDA 55 /* LVDS0.I2C1.SDA, DMA.UART2.RX, LSIO.GPIO1.IO09 */
#define SC_P_LVDS1_GPIO00 56 /* LVDS1.GPIO0.IO00, LVDS1.PWM0.OUT, LSIO.GPIO1.IO10 */
#define SC_P_LVDS1_GPIO01 57 /* LVDS1.GPIO0.IO01, LSIO.GPIO1.IO11 */
#define SC_P_LVDS1_I2C0_SCL 58 /* LVDS1.I2C0.SCL, LVDS1.GPIO0.IO02, LSIO.GPIO1.IO12 */
#define SC_P_LVDS1_I2C0_SDA 59 /* LVDS1.I2C0.SDA, LVDS1.GPIO0.IO03, LSIO.GPIO1.IO13 */
#define SC_P_LVDS1_I2C1_SCL 60 /* LVDS1.I2C1.SCL, DMA.UART3.TX, LSIO.GPIO1.IO14 */
#define SC_P_LVDS1_I2C1_SDA 61 /* LVDS1.I2C1.SDA, DMA.UART3.RX, LSIO.GPIO1.IO15 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_LVDSGPIO 62 /* */
#define SC_P_MIPI_DSI0_I2C0_SCL 63 /* MIPI_DSI0.I2C0.SCL, LSIO.GPIO1.IO16 */
#define SC_P_MIPI_DSI0_I2C0_SDA 64 /* MIPI_DSI0.I2C0.SDA, LSIO.GPIO1.IO17 */
#define SC_P_MIPI_DSI0_GPIO0_00 65 /* MIPI_DSI0.GPIO0.IO00, MIPI_DSI0.PWM0.OUT, LSIO.GPIO1.IO18 */
#define SC_P_MIPI_DSI0_GPIO0_01 66 /* MIPI_DSI0.GPIO0.IO01, LSIO.GPIO1.IO19 */
#define SC_P_MIPI_DSI1_I2C0_SCL 67 /* MIPI_DSI1.I2C0.SCL, LSIO.GPIO1.IO20 */
#define SC_P_MIPI_DSI1_I2C0_SDA 68 /* MIPI_DSI1.I2C0.SDA, LSIO.GPIO1.IO21 */
#define SC_P_MIPI_DSI1_GPIO0_00 69 /* MIPI_DSI1.GPIO0.IO00, MIPI_DSI1.PWM0.OUT, LSIO.GPIO1.IO22 */
#define SC_P_MIPI_DSI1_GPIO0_01 70 /* MIPI_DSI1.GPIO0.IO01, LSIO.GPIO1.IO23 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 71 /* */
#define SC_P_MIPI_CSI0_MCLK_OUT 72 /* MIPI_CSI0.ACM.MCLK_OUT, LSIO.GPIO1.IO24 */
#define SC_P_MIPI_CSI0_I2C0_SCL 73 /* MIPI_CSI0.I2C0.SCL, LSIO.GPIO1.IO25 */
#define SC_P_MIPI_CSI0_I2C0_SDA 74 /* MIPI_CSI0.I2C0.SDA, LSIO.GPIO1.IO26 */
#define SC_P_MIPI_CSI0_GPIO0_00 75 /* MIPI_CSI0.GPIO0.IO00, DMA.I2C0.SCL, MIPI_CSI1.I2C0.SCL, LSIO.GPIO1.IO27 */
#define SC_P_MIPI_CSI0_GPIO0_01 76 /* MIPI_CSI0.GPIO0.IO01, DMA.I2C0.SDA, MIPI_CSI1.I2C0.SDA, LSIO.GPIO1.IO28 */
#define SC_P_MIPI_CSI1_MCLK_OUT 77 /* MIPI_CSI1.ACM.MCLK_OUT, LSIO.GPIO1.IO29 */
#define SC_P_MIPI_CSI1_GPIO0_00 78 /* MIPI_CSI1.GPIO0.IO00, DMA.UART4.RX, LSIO.GPIO1.IO30 */
#define SC_P_MIPI_CSI1_GPIO0_01 79 /* MIPI_CSI1.GPIO0.IO01, DMA.UART4.TX, LSIO.GPIO1.IO31 */
#define SC_P_MIPI_CSI1_I2C0_SCL 80 /* MIPI_CSI1.I2C0.SCL, LSIO.GPIO2.IO00 */
#define SC_P_MIPI_CSI1_I2C0_SDA 81 /* MIPI_CSI1.I2C0.SDA, LSIO.GPIO2.IO01 */
#define SC_P_HDMI_TX0_TS_SCL 82 /* HDMI_TX0.I2C0.SCL, DMA.I2C0.SCL, LSIO.GPIO2.IO02 */
#define SC_P_HDMI_TX0_TS_SDA 83 /* HDMI_TX0.I2C0.SDA, DMA.I2C0.SDA, LSIO.GPIO2.IO03 */
#define SC_P_COMP_CTL_GPIO_3V3_HDMIGPIO 84 /* */
#define SC_P_ESAI1_FSR 85 /* AUD.ESAI1.FSR, LSIO.GPIO2.IO04 */
#define SC_P_ESAI1_FST 86 /* AUD.ESAI1.FST, AUD.SPDIF0.EXT_CLK, LSIO.GPIO2.IO05 */
#define SC_P_ESAI1_SCKR 87 /* AUD.ESAI1.SCKR, LSIO.GPIO2.IO06 */
#define SC_P_ESAI1_SCKT 88 /* AUD.ESAI1.SCKT, AUD.SAI2.RXC, AUD.SPDIF0.EXT_CLK, LSIO.GPIO2.IO07 */
#define SC_P_ESAI1_TX0 89 /* AUD.ESAI1.TX0, AUD.SAI2.RXD, AUD.SPDIF0.RX, LSIO.GPIO2.IO08 */
#define SC_P_ESAI1_TX1 90 /* AUD.ESAI1.TX1, AUD.SAI2.RXFS, AUD.SPDIF0.TX, LSIO.GPIO2.IO09 */
#define SC_P_ESAI1_TX2_RX3 91 /* AUD.ESAI1.TX2_RX3, AUD.SPDIF0.RX, LSIO.GPIO2.IO10 */
#define SC_P_ESAI1_TX3_RX2 92 /* AUD.ESAI1.TX3_RX2, AUD.SPDIF0.TX, LSIO.GPIO2.IO11 */
#define SC_P_ESAI1_TX4_RX1 93 /* AUD.ESAI1.TX4_RX1, LSIO.GPIO2.IO12 */
#define SC_P_ESAI1_TX5_RX0 94 /* AUD.ESAI1.TX5_RX0, LSIO.GPIO2.IO13 */
#define SC_P_SPDIF0_RX 95 /* AUD.SPDIF0.RX, AUD.MQS.R, AUD.ACM.MCLK_IN1, LSIO.GPIO2.IO14 */
#define SC_P_SPDIF0_TX 96 /* AUD.SPDIF0.TX, AUD.MQS.L, AUD.ACM.MCLK_OUT1, LSIO.GPIO2.IO15 */
#define SC_P_SPDIF0_EXT_CLK 97 /* AUD.SPDIF0.EXT_CLK, DMA.DMA0.REQ_IN0, LSIO.GPIO2.IO16 */
#define SC_P_SPI3_SCK 98 /* DMA.SPI3.SCK, LSIO.GPIO2.IO17 */
#define SC_P_SPI3_SDO 99 /* DMA.SPI3.SDO, DMA.FTM.CH0, LSIO.GPIO2.IO18 */
#define SC_P_SPI3_SDI 100 /* DMA.SPI3.SDI, DMA.FTM.CH1, LSIO.GPIO2.IO19 */
#define SC_P_SPI3_CS0 101 /* DMA.SPI3.CS0, DMA.FTM.CH2, LSIO.GPIO2.IO20 */
#define SC_P_SPI3_CS1 102 /* DMA.SPI3.CS1, LSIO.GPIO2.IO21 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 103 /* */
#define SC_P_ESAI0_FSR 104 /* AUD.ESAI0.FSR, LSIO.GPIO2.IO22 */
#define SC_P_ESAI0_FST 105 /* AUD.ESAI0.FST, LSIO.GPIO2.IO23 */
#define SC_P_ESAI0_SCKR 106 /* AUD.ESAI0.SCKR, LSIO.GPIO2.IO24 */
#define SC_P_ESAI0_SCKT 107 /* AUD.ESAI0.SCKT, LSIO.GPIO2.IO25 */
#define SC_P_ESAI0_TX0 108 /* AUD.ESAI0.TX0, LSIO.GPIO2.IO26 */
#define SC_P_ESAI0_TX1 109 /* AUD.ESAI0.TX1, LSIO.GPIO2.IO27 */
#define SC_P_ESAI0_TX2_RX3 110 /* AUD.ESAI0.TX2_RX3, LSIO.GPIO2.IO28 */
#define SC_P_ESAI0_TX3_RX2 111 /* AUD.ESAI0.TX3_RX2, LSIO.GPIO2.IO29 */
#define SC_P_ESAI0_TX4_RX1 112 /* AUD.ESAI0.TX4_RX1, LSIO.GPIO2.IO30 */
#define SC_P_ESAI0_TX5_RX0 113 /* AUD.ESAI0.TX5_RX0, LSIO.GPIO2.IO31 */
#define SC_P_MCLK_IN0 114 /* AUD.ACM.MCLK_IN0, AUD.ESAI0.RX_HF_CLK, AUD.ESAI1.RX_HF_CLK, LSIO.GPIO3.IO00 */
#define SC_P_MCLK_OUT0 115 /* AUD.ACM.MCLK_OUT0, AUD.ESAI0.TX_HF_CLK, AUD.ESAI1.TX_HF_CLK, LSIO.GPIO3.IO01 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHC 116 /* */
#define SC_P_SPI0_SCK 117 /* DMA.SPI0.SCK, AUD.SAI0.RXC, LSIO.GPIO3.IO02 */
#define SC_P_SPI0_SDO 118 /* DMA.SPI0.SDO, AUD.SAI0.TXD, LSIO.GPIO3.IO03 */
#define SC_P_SPI0_SDI 119 /* DMA.SPI0.SDI, AUD.SAI0.RXD, LSIO.GPIO3.IO04 */
#define SC_P_SPI0_CS0 120 /* DMA.SPI0.CS0, AUD.SAI0.RXFS, LSIO.GPIO3.IO05 */
#define SC_P_SPI0_CS1 121 /* DMA.SPI0.CS1, AUD.SAI0.TXC, LSIO.GPIO3.IO06 */
#define SC_P_SPI2_SCK 122 /* DMA.SPI2.SCK, LSIO.GPIO3.IO07 */
#define SC_P_SPI2_SDO 123 /* DMA.SPI2.SDO, LSIO.GPIO3.IO08 */
#define SC_P_SPI2_SDI 124 /* DMA.SPI2.SDI, LSIO.GPIO3.IO09 */
#define SC_P_SPI2_CS0 125 /* DMA.SPI2.CS0, LSIO.GPIO3.IO10 */
#define SC_P_SPI2_CS1 126 /* DMA.SPI2.CS1, AUD.SAI0.TXFS, LSIO.GPIO3.IO11 */
#define SC_P_SAI1_RXC 127 /* AUD.SAI1.RXC, AUD.SAI0.TXD, LSIO.GPIO3.IO12 */
#define SC_P_SAI1_RXD 128 /* AUD.SAI1.RXD, AUD.SAI0.TXFS, LSIO.GPIO3.IO13 */
#define SC_P_SAI1_RXFS 129 /* AUD.SAI1.RXFS, AUD.SAI0.RXD, LSIO.GPIO3.IO14 */
#define SC_P_SAI1_TXC 130 /* AUD.SAI1.TXC, AUD.SAI0.TXC, LSIO.GPIO3.IO15 */
#define SC_P_SAI1_TXD 131 /* AUD.SAI1.TXD, AUD.SAI1.RXC, LSIO.GPIO3.IO16 */
#define SC_P_SAI1_TXFS 132 /* AUD.SAI1.TXFS, AUD.SAI1.RXFS, LSIO.GPIO3.IO17 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 133 /* */
#define SC_P_ADC_IN7 134 /* DMA.ADC1.IN3, DMA.SPI1.CS1, LSIO.KPP0.ROW3, LSIO.GPIO3.IO25 */
#define SC_P_ADC_IN6 135 /* DMA.ADC1.IN2, DMA.SPI1.CS0, LSIO.KPP0.ROW2, LSIO.GPIO3.IO24 */
#define SC_P_ADC_IN5 136 /* DMA.ADC1.IN1, DMA.SPI1.SDI, LSIO.KPP0.ROW1, LSIO.GPIO3.IO23 */
#define SC_P_ADC_IN4 137 /* DMA.ADC1.IN0, DMA.SPI1.SDO, LSIO.KPP0.ROW0, LSIO.GPIO3.IO22 */
#define SC_P_ADC_IN3 138 /* DMA.ADC0.IN3, DMA.SPI1.SCK, LSIO.KPP0.COL3, LSIO.GPIO3.IO21 */
#define SC_P_ADC_IN2 139 /* DMA.ADC0.IN2, LSIO.KPP0.COL2, LSIO.GPIO3.IO20 */
#define SC_P_ADC_IN1 140 /* DMA.ADC0.IN1, LSIO.KPP0.COL1, LSIO.GPIO3.IO19 */
#define SC_P_ADC_IN0 141 /* DMA.ADC0.IN0, LSIO.KPP0.COL0, LSIO.GPIO3.IO18 */
#define SC_P_MLB_SIG 142 /* CONN.MLB.SIG, AUD.SAI3.RXC, LSIO.GPIO3.IO26 */
#define SC_P_MLB_CLK 143 /* CONN.MLB.CLK, AUD.SAI3.RXFS, LSIO.GPIO3.IO27 */
#define SC_P_MLB_DATA 144 /* CONN.MLB.DATA, AUD.SAI3.RXD, LSIO.GPIO3.IO28 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLHT 145 /* */
#define SC_P_FLEXCAN0_RX 146 /* DMA.FLEXCAN0.RX, LSIO.GPIO3.IO29 */
#define SC_P_FLEXCAN0_TX 147 /* DMA.FLEXCAN0.TX, LSIO.GPIO3.IO30 */
#define SC_P_FLEXCAN1_RX 148 /* DMA.FLEXCAN1.RX, LSIO.GPIO3.IO31 */
#define SC_P_FLEXCAN1_TX 149 /* DMA.FLEXCAN1.TX, LSIO.GPIO4.IO00 */
#define SC_P_FLEXCAN2_RX 150 /* DMA.FLEXCAN2.RX, LSIO.GPIO4.IO01 */
#define SC_P_FLEXCAN2_TX 151 /* DMA.FLEXCAN2.TX, LSIO.GPIO4.IO02 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOTHR 152 /* */
#define SC_P_USB_SS3_TC0 153 /* DMA.I2C1.SCL, CONN.USB_OTG1.PWR, LSIO.GPIO4.IO03 */
#define SC_P_USB_SS3_TC1 154 /* DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO04 */
#define SC_P_USB_SS3_TC2 155 /* DMA.I2C1.SDA, CONN.USB_OTG1.OC, LSIO.GPIO4.IO05 */
#define SC_P_USB_SS3_TC3 156 /* DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO06 */
#define SC_P_COMP_CTL_GPIO_3V3_USB3IO 157 /* */
#define SC_P_USDHC1_RESET_B 158 /* CONN.USDHC1.RESET_B, LSIO.GPIO4.IO07 */
#define SC_P_USDHC1_VSELECT 159 /* CONN.USDHC1.VSELECT, LSIO.GPIO4.IO08 */
#define SC_P_USDHC2_RESET_B 160 /* CONN.USDHC2.RESET_B, LSIO.GPIO4.IO09 */
#define SC_P_USDHC2_VSELECT 161 /* CONN.USDHC2.VSELECT, LSIO.GPIO4.IO10 */
#define SC_P_USDHC2_WP 162 /* CONN.USDHC2.WP, LSIO.GPIO4.IO11 */
#define SC_P_USDHC2_CD_B 163 /* CONN.USDHC2.CD_B, LSIO.GPIO4.IO12 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 164 /* */
#define SC_P_ENET0_MDIO 165 /* CONN.ENET0.MDIO, DMA.I2C4.SDA, LSIO.GPIO4.IO13 */
#define SC_P_ENET0_MDC 166 /* CONN.ENET0.MDC, DMA.I2C4.SCL, LSIO.GPIO4.IO14 */
#define SC_P_ENET0_REFCLK_125M_25M 167 /* CONN.ENET0.REFCLK_125M_25M, CONN.ENET0.PPS, LSIO.GPIO4.IO15 */
#define SC_P_ENET1_REFCLK_125M_25M 168 /* CONN.ENET1.REFCLK_125M_25M, CONN.ENET1.PPS, LSIO.GPIO4.IO16 */
#define SC_P_ENET1_MDIO 169 /* CONN.ENET1.MDIO, DMA.I2C4.SDA, LSIO.GPIO4.IO17 */
#define SC_P_ENET1_MDC 170 /* CONN.ENET1.MDC, DMA.I2C4.SCL, LSIO.GPIO4.IO18 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 171 /* */
#define SC_P_QSPI1A_SS0_B 172 /* LSIO.QSPI1A.SS0_B, LSIO.GPIO4.IO19 */
#define SC_P_QSPI1A_SS1_B 173 /* LSIO.QSPI1A.SS1_B, LSIO.QSPI1A.SCLK2, LSIO.GPIO4.IO20 */
#define SC_P_QSPI1A_SCLK 174 /* LSIO.QSPI1A.SCLK, LSIO.GPIO4.IO21 */
#define SC_P_QSPI1A_DQS 175 /* LSIO.QSPI1A.DQS, LSIO.GPIO4.IO22 */
#define SC_P_QSPI1A_DATA3 176 /* LSIO.QSPI1A.DATA3, DMA.I2C1.SDA, CONN.USB_OTG1.OC, LSIO.GPIO4.IO23 */
#define SC_P_QSPI1A_DATA2 177 /* LSIO.QSPI1A.DATA2, DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO24 */
#define SC_P_QSPI1A_DATA1 178 /* LSIO.QSPI1A.DATA1, DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO25 */
#define SC_P_QSPI1A_DATA0 179 /* LSIO.QSPI1A.DATA0, LSIO.GPIO4.IO26 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI1 180 /* */
#define SC_P_QSPI0A_DATA0 181 /* LSIO.QSPI0A.DATA0 */
#define SC_P_QSPI0A_DATA1 182 /* LSIO.QSPI0A.DATA1 */
#define SC_P_QSPI0A_DATA2 183 /* LSIO.QSPI0A.DATA2 */
#define SC_P_QSPI0A_DATA3 184 /* LSIO.QSPI0A.DATA3 */
#define SC_P_QSPI0A_DQS 185 /* LSIO.QSPI0A.DQS */
#define SC_P_QSPI0A_SS0_B 186 /* LSIO.QSPI0A.SS0_B */
#define SC_P_QSPI0A_SS1_B 187 /* LSIO.QSPI0A.SS1_B, LSIO.QSPI0A.SCLK2 */
#define SC_P_QSPI0A_SCLK 188 /* LSIO.QSPI0A.SCLK */
#define SC_P_QSPI0B_SCLK 189 /* LSIO.QSPI0B.SCLK */
#define SC_P_QSPI0B_DATA0 190 /* LSIO.QSPI0B.DATA0 */
#define SC_P_QSPI0B_DATA1 191 /* LSIO.QSPI0B.DATA1 */
#define SC_P_QSPI0B_DATA2 192 /* LSIO.QSPI0B.DATA2 */
#define SC_P_QSPI0B_DATA3 193 /* LSIO.QSPI0B.DATA3 */
#define SC_P_QSPI0B_DQS 194 /* LSIO.QSPI0B.DQS */
#define SC_P_QSPI0B_SS0_B 195 /* LSIO.QSPI0B.SS0_B */
#define SC_P_QSPI0B_SS1_B 196 /* LSIO.QSPI0B.SS1_B, LSIO.QSPI0B.SCLK2 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0 197 /* */
#define SC_P_PCIE_CTRL0_CLKREQ_B 198 /* HSIO.PCIE0.CLKREQ_B, LSIO.GPIO4.IO27 */
#define SC_P_PCIE_CTRL0_WAKE_B 199 /* HSIO.PCIE0.WAKE_B, LSIO.GPIO4.IO28 */
#define SC_P_PCIE_CTRL0_PERST_B 200 /* HSIO.PCIE0.PERST_B, LSIO.GPIO4.IO29 */
#define SC_P_PCIE_CTRL1_CLKREQ_B 201 /* HSIO.PCIE1.CLKREQ_B, DMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO30 */
#define SC_P_PCIE_CTRL1_WAKE_B 202 /* HSIO.PCIE1.WAKE_B, DMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO31 */
#define SC_P_PCIE_CTRL1_PERST_B 203 /* HSIO.PCIE1.PERST_B, DMA.I2C1.SCL, CONN.USB_OTG1.PWR, LSIO.GPIO5.IO00 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 204 /* */
#define SC_P_USB_HSIC0_DATA 205 /* CONN.USB_HSIC0.DATA, DMA.I2C1.SDA, LSIO.GPIO5.IO01 */
#define SC_P_USB_HSIC0_STROBE 206 /* CONN.USB_HSIC0.STROBE, DMA.I2C1.SCL, LSIO.GPIO5.IO02 */
#define SC_P_CALIBRATION_0_HSIC 207 /* */
#define SC_P_CALIBRATION_1_HSIC 208 /* */
#define SC_P_EMMC0_CLK 209 /* CONN.EMMC0.CLK, CONN.NAND.READY_B */
#define SC_P_EMMC0_CMD 210 /* CONN.EMMC0.CMD, CONN.NAND.DQS, AUD.MQS.R, LSIO.GPIO5.IO03 */
#define SC_P_EMMC0_DATA0 211 /* CONN.EMMC0.DATA0, CONN.NAND.DATA00, LSIO.GPIO5.IO04 */
#define SC_P_EMMC0_DATA1 212 /* CONN.EMMC0.DATA1, CONN.NAND.DATA01, LSIO.GPIO5.IO05 */
#define SC_P_EMMC0_DATA2 213 /* CONN.EMMC0.DATA2, CONN.NAND.DATA02, LSIO.GPIO5.IO06 */
#define SC_P_EMMC0_DATA3 214 /* CONN.EMMC0.DATA3, CONN.NAND.DATA03, LSIO.GPIO5.IO07 */
#define SC_P_EMMC0_DATA4 215 /* CONN.EMMC0.DATA4, CONN.NAND.DATA04, LSIO.GPIO5.IO08 */
#define SC_P_EMMC0_DATA5 216 /* CONN.EMMC0.DATA5, CONN.NAND.DATA05, LSIO.GPIO5.IO09 */
#define SC_P_EMMC0_DATA6 217 /* CONN.EMMC0.DATA6, CONN.NAND.DATA06, LSIO.GPIO5.IO10 */
#define SC_P_EMMC0_DATA7 218 /* CONN.EMMC0.DATA7, CONN.NAND.DATA07, LSIO.GPIO5.IO11 */
#define SC_P_EMMC0_STROBE 219 /* CONN.EMMC0.STROBE, CONN.NAND.CLE, LSIO.GPIO5.IO12 */
#define SC_P_EMMC0_RESET_B 220 /* CONN.EMMC0.RESET_B, CONN.NAND.WP_B, CONN.USDHC1.VSELECT, LSIO.GPIO5.IO13 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX 221 /* */
#define SC_P_USDHC1_CLK 222 /* CONN.USDHC1.CLK, AUD.MQS.R */
#define SC_P_USDHC1_CMD 223 /* CONN.USDHC1.CMD, AUD.MQS.L, LSIO.GPIO5.IO14 */
#define SC_P_USDHC1_DATA0 224 /* CONN.USDHC1.DATA0, CONN.NAND.RE_N, LSIO.GPIO5.IO15 */
#define SC_P_USDHC1_DATA1 225 /* CONN.USDHC1.DATA1, CONN.NAND.RE_P, LSIO.GPIO5.IO16 */
#define SC_P_CTL_NAND_RE_P_N 226 /* */
#define SC_P_USDHC1_DATA2 227 /* CONN.USDHC1.DATA2, CONN.NAND.DQS_N, LSIO.GPIO5.IO17 */
#define SC_P_USDHC1_DATA3 228 /* CONN.USDHC1.DATA3, CONN.NAND.DQS_P, LSIO.GPIO5.IO18 */
#define SC_P_CTL_NAND_DQS_P_N 229 /* */
#define SC_P_USDHC1_DATA4 230 /* CONN.USDHC1.DATA4, CONN.NAND.CE0_B, AUD.MQS.R, LSIO.GPIO5.IO19 */
#define SC_P_USDHC1_DATA5 231 /* CONN.USDHC1.DATA5, CONN.NAND.RE_B, AUD.MQS.L, LSIO.GPIO5.IO20 */
#define SC_P_USDHC1_DATA6 232 /* CONN.USDHC1.DATA6, CONN.NAND.WE_B, CONN.USDHC1.WP, LSIO.GPIO5.IO21 */
#define SC_P_USDHC1_DATA7 233 /* CONN.USDHC1.DATA7, CONN.NAND.ALE, CONN.USDHC1.CD_B, LSIO.GPIO5.IO22 */
#define SC_P_USDHC1_STROBE 234 /* CONN.USDHC1.STROBE, CONN.NAND.CE1_B, CONN.USDHC1.RESET_B, LSIO.GPIO5.IO23 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL2 235 /* */
#define SC_P_USDHC2_CLK 236 /* CONN.USDHC2.CLK, AUD.MQS.R, LSIO.GPIO5.IO24 */
#define SC_P_USDHC2_CMD 237 /* CONN.USDHC2.CMD, AUD.MQS.L, LSIO.GPIO5.IO25 */
#define SC_P_USDHC2_DATA0 238 /* CONN.USDHC2.DATA0, DMA.UART4.RX, LSIO.GPIO5.IO26 */
#define SC_P_USDHC2_DATA1 239 /* CONN.USDHC2.DATA1, DMA.UART4.TX, LSIO.GPIO5.IO27 */
#define SC_P_USDHC2_DATA2 240 /* CONN.USDHC2.DATA2, DMA.UART4.CTS_B, LSIO.GPIO5.IO28 */
#define SC_P_USDHC2_DATA3 241 /* CONN.USDHC2.DATA3, DMA.UART4.RTS_B, LSIO.GPIO5.IO29 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 242 /* */
#define SC_P_ENET0_RGMII_TXC 243 /* CONN.ENET0.RGMII_TXC, CONN.ENET0.RCLK50M_OUT, CONN.ENET0.RCLK50M_IN, LSIO.GPIO5.IO30 */
#define SC_P_ENET0_RGMII_TX_CTL 244 /* CONN.ENET0.RGMII_TX_CTL, LSIO.GPIO5.IO31 */
#define SC_P_ENET0_RGMII_TXD0 245 /* CONN.ENET0.RGMII_TXD0, LSIO.GPIO6.IO00 */
#define SC_P_ENET0_RGMII_TXD1 246 /* CONN.ENET0.RGMII_TXD1, LSIO.GPIO6.IO01 */
#define SC_P_ENET0_RGMII_TXD2 247 /* CONN.ENET0.RGMII_TXD2, DMA.UART3.TX, VPU.TSI_S1.VID, LSIO.GPIO6.IO02 */
#define SC_P_ENET0_RGMII_TXD3 248 /* CONN.ENET0.RGMII_TXD3, DMA.UART3.RTS_B, VPU.TSI_S1.SYNC, LSIO.GPIO6.IO03 */
#define SC_P_ENET0_RGMII_RXC 249 /* CONN.ENET0.RGMII_RXC, DMA.UART3.CTS_B, VPU.TSI_S1.DATA, LSIO.GPIO6.IO04 */
#define SC_P_ENET0_RGMII_RX_CTL 250 /* CONN.ENET0.RGMII_RX_CTL, VPU.TSI_S0.VID, LSIO.GPIO6.IO05 */
#define SC_P_ENET0_RGMII_RXD0 251 /* CONN.ENET0.RGMII_RXD0, VPU.TSI_S0.SYNC, LSIO.GPIO6.IO06 */
#define SC_P_ENET0_RGMII_RXD1 252 /* CONN.ENET0.RGMII_RXD1, VPU.TSI_S0.DATA, LSIO.GPIO6.IO07 */
#define SC_P_ENET0_RGMII_RXD2 253 /* CONN.ENET0.RGMII_RXD2, CONN.ENET0.RMII_RX_ER, VPU.TSI_S0.CLK, LSIO.GPIO6.IO08 */
#define SC_P_ENET0_RGMII_RXD3 254 /* CONN.ENET0.RGMII_RXD3, DMA.UART3.RX, VPU.TSI_S1.CLK, LSIO.GPIO6.IO09 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB 255 /* */
#define SC_P_ENET1_RGMII_TXC 256 /* CONN.ENET1.RGMII_TXC, CONN.ENET1.RCLK50M_OUT, CONN.ENET1.RCLK50M_IN, LSIO.GPIO6.IO10 */
#define SC_P_ENET1_RGMII_TX_CTL 257 /* CONN.ENET1.RGMII_TX_CTL, LSIO.GPIO6.IO11 */
#define SC_P_ENET1_RGMII_TXD0 258 /* CONN.ENET1.RGMII_TXD0, LSIO.GPIO6.IO12 */
#define SC_P_ENET1_RGMII_TXD1 259 /* CONN.ENET1.RGMII_TXD1, LSIO.GPIO6.IO13 */
#define SC_P_ENET1_RGMII_TXD2 260 /* CONN.ENET1.RGMII_TXD2, DMA.UART3.TX, VPU.TSI_S1.VID, LSIO.GPIO6.IO14 */
#define SC_P_ENET1_RGMII_TXD3 261 /* CONN.ENET1.RGMII_TXD3, DMA.UART3.RTS_B, VPU.TSI_S1.SYNC, LSIO.GPIO6.IO15 */
#define SC_P_ENET1_RGMII_RXC 262 /* CONN.ENET1.RGMII_RXC, DMA.UART3.CTS_B, VPU.TSI_S1.DATA, LSIO.GPIO6.IO16 */
#define SC_P_ENET1_RGMII_RX_CTL 263 /* CONN.ENET1.RGMII_RX_CTL, VPU.TSI_S0.VID, LSIO.GPIO6.IO17 */
#define SC_P_ENET1_RGMII_RXD0 264 /* CONN.ENET1.RGMII_RXD0, VPU.TSI_S0.SYNC, LSIO.GPIO6.IO18 */
#define SC_P_ENET1_RGMII_RXD1 265 /* CONN.ENET1.RGMII_RXD1, VPU.TSI_S0.DATA, LSIO.GPIO6.IO19 */
#define SC_P_ENET1_RGMII_RXD2 266 /* CONN.ENET1.RGMII_RXD2, CONN.ENET1.RMII_RX_ER, VPU.TSI_S0.CLK, LSIO.GPIO6.IO20 */
#define SC_P_ENET1_RGMII_RXD3 267 /* CONN.ENET1.RGMII_RXD3, DMA.UART3.RX, VPU.TSI_S1.CLK, LSIO.GPIO6.IO21 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA 268 /* */
/*@}*/
#endif /* SC_PADS_H */

View File

@ -0,0 +1,198 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file used to configure SoC pad list.
*/
#ifndef SC_PADS_H
#define SC_PADS_H
/* Includes */
/* Defines */
/*!
* @name Pad Definitions
*/
/*@{*/
#define SC_P_PCIE_CTRL0_PERST_B 0 /* HSIO.PCIE0.PERST_B, LSIO.GPIO4.IO00 */
#define SC_P_PCIE_CTRL0_CLKREQ_B 1 /* HSIO.PCIE0.CLKREQ_B, LSIO.GPIO4.IO01 */
#define SC_P_PCIE_CTRL0_WAKE_B 2 /* HSIO.PCIE0.WAKE_B, LSIO.GPIO4.IO02 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_PCIESEP 3 /* */
#define SC_P_USB_SS3_TC0 4 /* ADMA.I2C1.SCL, CONN.USB_OTG1.PWR, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO03 */
#define SC_P_USB_SS3_TC1 5 /* ADMA.I2C1.SCL, CONN.USB_OTG2.PWR, LSIO.GPIO4.IO04 */
#define SC_P_USB_SS3_TC2 6 /* ADMA.I2C1.SDA, CONN.USB_OTG1.OC, CONN.USB_OTG2.OC, LSIO.GPIO4.IO05 */
#define SC_P_USB_SS3_TC3 7 /* ADMA.I2C1.SDA, CONN.USB_OTG2.OC, LSIO.GPIO4.IO06 */
#define SC_P_COMP_CTL_GPIO_3V3_USB3IO 8 /* */
#define SC_P_EMMC0_CLK 9 /* CONN.EMMC0.CLK, CONN.NAND.READY_B, LSIO.GPIO4.IO07 */
#define SC_P_EMMC0_CMD 10 /* CONN.EMMC0.CMD, CONN.NAND.DQS, LSIO.GPIO4.IO08 */
#define SC_P_EMMC0_DATA0 11 /* CONN.EMMC0.DATA0, CONN.NAND.DATA00, LSIO.GPIO4.IO09 */
#define SC_P_EMMC0_DATA1 12 /* CONN.EMMC0.DATA1, CONN.NAND.DATA01, LSIO.GPIO4.IO10 */
#define SC_P_EMMC0_DATA2 13 /* CONN.EMMC0.DATA2, CONN.NAND.DATA02, LSIO.GPIO4.IO11 */
#define SC_P_EMMC0_DATA3 14 /* CONN.EMMC0.DATA3, CONN.NAND.DATA03, LSIO.GPIO4.IO12 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX0 15 /* */
#define SC_P_EMMC0_DATA4 16 /* CONN.EMMC0.DATA4, CONN.NAND.DATA04, CONN.EMMC0.WP, LSIO.GPIO4.IO13 */
#define SC_P_EMMC0_DATA5 17 /* CONN.EMMC0.DATA5, CONN.NAND.DATA05, CONN.EMMC0.VSELECT, LSIO.GPIO4.IO14 */
#define SC_P_EMMC0_DATA6 18 /* CONN.EMMC0.DATA6, CONN.NAND.DATA06, CONN.MLB.CLK, LSIO.GPIO4.IO15 */
#define SC_P_EMMC0_DATA7 19 /* CONN.EMMC0.DATA7, CONN.NAND.DATA07, CONN.MLB.SIG, LSIO.GPIO4.IO16 */
#define SC_P_EMMC0_STROBE 20 /* CONN.EMMC0.STROBE, CONN.NAND.CLE, CONN.MLB.DATA, LSIO.GPIO4.IO17 */
#define SC_P_EMMC0_RESET_B 21 /* CONN.EMMC0.RESET_B, CONN.NAND.WP_B, LSIO.GPIO4.IO18 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_SD1FIX1 22 /* */
#define SC_P_USDHC1_RESET_B 23 /* CONN.USDHC1.RESET_B, CONN.NAND.RE_N, ADMA.SPI2.SCK, LSIO.GPIO4.IO19 */
#define SC_P_USDHC1_VSELECT 24 /* CONN.USDHC1.VSELECT, CONN.NAND.RE_P, ADMA.SPI2.SDO, CONN.NAND.RE_B, LSIO.GPIO4.IO20 */
#define SC_P_CTL_NAND_RE_P_N 25 /* */
#define SC_P_USDHC1_WP 26 /* CONN.USDHC1.WP, CONN.NAND.DQS_N, ADMA.SPI2.SDI, LSIO.GPIO4.IO21 */
#define SC_P_USDHC1_CD_B 27 /* CONN.USDHC1.CD_B, CONN.NAND.DQS_P, ADMA.SPI2.CS0, CONN.NAND.DQS, LSIO.GPIO4.IO22 */
#define SC_P_CTL_NAND_DQS_P_N 28 /* */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSELSEP 29 /* */
#define SC_P_USDHC1_CLK 30 /* CONN.USDHC1.CLK, ADMA.UART3.RX, LSIO.GPIO4.IO23 */
#define SC_P_USDHC1_CMD 31 /* CONN.USDHC1.CMD, CONN.NAND.CE0_B, ADMA.MQS.R, LSIO.GPIO4.IO24 */
#define SC_P_USDHC1_DATA0 32 /* CONN.USDHC1.DATA0, CONN.NAND.CE1_B, ADMA.MQS.L, LSIO.GPIO4.IO25 */
#define SC_P_USDHC1_DATA1 33 /* CONN.USDHC1.DATA1, CONN.NAND.RE_B, ADMA.UART3.TX, LSIO.GPIO4.IO26 */
#define SC_P_USDHC1_DATA2 34 /* CONN.USDHC1.DATA2, CONN.NAND.WE_B, ADMA.UART3.CTS_B, LSIO.GPIO4.IO27 */
#define SC_P_USDHC1_DATA3 35 /* CONN.USDHC1.DATA3, CONN.NAND.ALE, ADMA.UART3.RTS_B, LSIO.GPIO4.IO28 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_VSEL3 36 /* */
#define SC_P_ENET0_RGMII_TXC 37 /* CONN.ENET0.RGMII_TXC, CONN.ENET0.RCLK50M_OUT, CONN.ENET0.RCLK50M_IN, CONN.NAND.CE1_B, LSIO.GPIO4.IO29 */
#define SC_P_ENET0_RGMII_TX_CTL 38 /* CONN.ENET0.RGMII_TX_CTL, CONN.USDHC1.RESET_B, LSIO.GPIO4.IO30 */
#define SC_P_ENET0_RGMII_TXD0 39 /* CONN.ENET0.RGMII_TXD0, CONN.USDHC1.VSELECT, LSIO.GPIO4.IO31 */
#define SC_P_ENET0_RGMII_TXD1 40 /* CONN.ENET0.RGMII_TXD1, CONN.USDHC1.WP, LSIO.GPIO5.IO00 */
#define SC_P_ENET0_RGMII_TXD2 41 /* CONN.ENET0.RGMII_TXD2, CONN.MLB.CLK, CONN.NAND.CE0_B, CONN.USDHC1.CD_B, LSIO.GPIO5.IO01 */
#define SC_P_ENET0_RGMII_TXD3 42 /* CONN.ENET0.RGMII_TXD3, CONN.MLB.SIG, CONN.NAND.RE_B, LSIO.GPIO5.IO02 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0 43 /* */
#define SC_P_ENET0_RGMII_RXC 44 /* CONN.ENET0.RGMII_RXC, CONN.MLB.DATA, CONN.NAND.WE_B, CONN.USDHC1.CLK, LSIO.GPIO5.IO03 */
#define SC_P_ENET0_RGMII_RX_CTL 45 /* CONN.ENET0.RGMII_RX_CTL, CONN.USDHC1.CMD, LSIO.GPIO5.IO04 */
#define SC_P_ENET0_RGMII_RXD0 46 /* CONN.ENET0.RGMII_RXD0, CONN.USDHC1.DATA0, LSIO.GPIO5.IO05 */
#define SC_P_ENET0_RGMII_RXD1 47 /* CONN.ENET0.RGMII_RXD1, CONN.USDHC1.DATA1, LSIO.GPIO5.IO06 */
#define SC_P_ENET0_RGMII_RXD2 48 /* CONN.ENET0.RGMII_RXD2, CONN.ENET0.RMII_RX_ER, CONN.USDHC1.DATA2, LSIO.GPIO5.IO07 */
#define SC_P_ENET0_RGMII_RXD3 49 /* CONN.ENET0.RGMII_RXD3, CONN.NAND.ALE, CONN.USDHC1.DATA3, LSIO.GPIO5.IO08 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1 50 /* */
#define SC_P_ENET0_REFCLK_125M_25M 51 /* CONN.ENET0.REFCLK_125M_25M, CONN.ENET0.PPS, CONN.ENET1.PPS, LSIO.GPIO5.IO09 */
#define SC_P_ENET0_MDIO 52 /* CONN.ENET0.MDIO, ADMA.I2C3.SDA, CONN.ENET1.MDIO, LSIO.GPIO5.IO10 */
#define SC_P_ENET0_MDC 53 /* CONN.ENET0.MDC, ADMA.I2C3.SCL, CONN.ENET1.MDC, LSIO.GPIO5.IO11 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOCT 54 /* */
#define SC_P_ESAI0_FSR 55 /* ADMA.ESAI0.FSR, CONN.ENET1.RCLK50M_OUT, ADMA.LCDIF.D00, CONN.ENET1.RGMII_TXC, CONN.ENET1.RCLK50M_IN */
#define SC_P_ESAI0_FST 56 /* ADMA.ESAI0.FST, CONN.MLB.CLK, ADMA.LCDIF.D01, CONN.ENET1.RGMII_TXD2, LSIO.GPIO0.IO01 */
#define SC_P_ESAI0_SCKR 57 /* ADMA.ESAI0.SCKR, ADMA.LCDIF.D02, CONN.ENET1.RGMII_TX_CTL, LSIO.GPIO0.IO02 */
#define SC_P_ESAI0_SCKT 58 /* ADMA.ESAI0.SCKT, CONN.MLB.SIG, ADMA.LCDIF.D03, CONN.ENET1.RGMII_TXD3, LSIO.GPIO0.IO03 */
#define SC_P_ESAI0_TX0 59 /* ADMA.ESAI0.TX0, CONN.MLB.DATA, ADMA.LCDIF.D04, CONN.ENET1.RGMII_RXC, LSIO.GPIO0.IO04 */
#define SC_P_ESAI0_TX1 60 /* ADMA.ESAI0.TX1, ADMA.LCDIF.D05, CONN.ENET1.RGMII_RXD3, LSIO.GPIO0.IO05 */
#define SC_P_ESAI0_TX2_RX3 61 /* ADMA.ESAI0.TX2_RX3, CONN.ENET1.RMII_RX_ER, ADMA.LCDIF.D06, CONN.ENET1.RGMII_RXD2, LSIO.GPIO0.IO06 */
#define SC_P_ESAI0_TX3_RX2 62 /* ADMA.ESAI0.TX3_RX2, ADMA.LCDIF.D07, CONN.ENET1.RGMII_RXD1, LSIO.GPIO0.IO07 */
#define SC_P_ESAI0_TX4_RX1 63 /* ADMA.ESAI0.TX4_RX1, ADMA.LCDIF.D08, CONN.ENET1.RGMII_TXD0, LSIO.GPIO0.IO08 */
#define SC_P_ESAI0_TX5_RX0 64 /* ADMA.ESAI0.TX5_RX0, ADMA.LCDIF.D09, CONN.ENET1.RGMII_TXD1, LSIO.GPIO0.IO09 */
#define SC_P_SPDIF0_RX 65 /* ADMA.SPDIF0.RX, ADMA.MQS.R, ADMA.LCDIF.D10, CONN.ENET1.RGMII_RXD0, LSIO.GPIO0.IO10 */
#define SC_P_SPDIF0_TX 66 /* ADMA.SPDIF0.TX, ADMA.MQS.L, ADMA.LCDIF.D11, CONN.ENET1.RGMII_RX_CTL, LSIO.GPIO0.IO11 */
#define SC_P_SPDIF0_EXT_CLK 67 /* ADMA.SPDIF0.EXT_CLK, ADMA.LCDIF.D12, CONN.ENET1.REFCLK_125M_25M, LSIO.GPIO0.IO12 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB 68 /* */
#define SC_P_SPI3_SCK 69 /* ADMA.SPI3.SCK, ADMA.LCDIF.D13, LSIO.GPIO0.IO13 */
#define SC_P_SPI3_SDO 70 /* ADMA.SPI3.SDO, ADMA.LCDIF.D14, LSIO.GPIO0.IO14 */
#define SC_P_SPI3_SDI 71 /* ADMA.SPI3.SDI, ADMA.LCDIF.D15, LSIO.GPIO0.IO15 */
#define SC_P_SPI3_CS0 72 /* ADMA.SPI3.CS0, ADMA.ACM.MCLK_OUT1, ADMA.LCDIF.HSYNC, LSIO.GPIO0.IO16 */
#define SC_P_SPI3_CS1 73 /* ADMA.SPI3.CS1, ADMA.I2C3.SCL, ADMA.LCDIF.RESET, ADMA.SPI2.CS0, ADMA.LCDIF.D16 */
#define SC_P_MCLK_IN1 74 /* ADMA.ACM.MCLK_IN1, ADMA.I2C3.SDA, ADMA.LCDIF.EN, ADMA.SPI2.SCK, ADMA.LCDIF.D17 */
#define SC_P_MCLK_IN0 75 /* ADMA.ACM.MCLK_IN0, ADMA.ESAI0.RX_HF_CLK, ADMA.LCDIF.VSYNC, ADMA.SPI2.SDI, LSIO.GPIO0.IO19 */
#define SC_P_MCLK_OUT0 76 /* ADMA.ACM.MCLK_OUT0, ADMA.ESAI0.TX_HF_CLK, ADMA.LCDIF.CLK, ADMA.SPI2.SDO, LSIO.GPIO0.IO20 */
#define SC_P_UART1_TX 77 /* ADMA.UART1.TX, LSIO.PWM0.OUT, LSIO.GPT0.CAPTURE, LSIO.GPIO0.IO21 */
#define SC_P_UART1_RX 78 /* ADMA.UART1.RX, LSIO.PWM1.OUT, LSIO.GPT0.COMPARE, LSIO.GPT1.CLK, LSIO.GPIO0.IO22 */
#define SC_P_UART1_RTS_B 79 /* ADMA.UART1.RTS_B, LSIO.PWM2.OUT, ADMA.LCDIF.D16, LSIO.GPT1.CAPTURE, LSIO.GPT0.CLK */
#define SC_P_UART1_CTS_B 80 /* ADMA.UART1.CTS_B, LSIO.PWM3.OUT, ADMA.LCDIF.D17, LSIO.GPT1.COMPARE, LSIO.GPIO0.IO24 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHK 81 /* */
#define SC_P_SAI0_TXD 82 /* ADMA.SAI0.TXD, ADMA.SAI1.RXC, ADMA.SPI1.SDO, ADMA.LCDIF.D18, LSIO.GPIO0.IO25 */
#define SC_P_SAI0_TXC 83 /* ADMA.SAI0.TXC, ADMA.SAI1.TXD, ADMA.SPI1.SDI, ADMA.LCDIF.D19, LSIO.GPIO0.IO26 */
#define SC_P_SAI0_RXD 84 /* ADMA.SAI0.RXD, ADMA.SAI1.RXFS, ADMA.SPI1.CS0, ADMA.LCDIF.D20, LSIO.GPIO0.IO27 */
#define SC_P_SAI0_TXFS 85 /* ADMA.SAI0.TXFS, ADMA.SPI2.CS1, ADMA.SPI1.SCK, LSIO.GPIO0.IO28 */
#define SC_P_SAI1_RXD 86 /* ADMA.SAI1.RXD, ADMA.SAI0.RXFS, ADMA.SPI1.CS1, ADMA.LCDIF.D21, LSIO.GPIO0.IO29 */
#define SC_P_SAI1_RXC 87 /* ADMA.SAI1.RXC, ADMA.SAI1.TXC, ADMA.LCDIF.D22, LSIO.GPIO0.IO30 */
#define SC_P_SAI1_RXFS 88 /* ADMA.SAI1.RXFS, ADMA.SAI1.TXFS, ADMA.LCDIF.D23, LSIO.GPIO0.IO31 */
#define SC_P_SPI2_CS0 89 /* ADMA.SPI2.CS0, LSIO.GPIO1.IO00 */
#define SC_P_SPI2_SDO 90 /* ADMA.SPI2.SDO, LSIO.GPIO1.IO01 */
#define SC_P_SPI2_SDI 91 /* ADMA.SPI2.SDI, LSIO.GPIO1.IO02 */
#define SC_P_SPI2_SCK 92 /* ADMA.SPI2.SCK, LSIO.GPIO1.IO03 */
#define SC_P_SPI0_SCK 93 /* ADMA.SPI0.SCK, ADMA.SAI0.TXC, M40.I2C0.SCL, M40.GPIO0.IO00, LSIO.GPIO1.IO04 */
#define SC_P_SPI0_SDI 94 /* ADMA.SPI0.SDI, ADMA.SAI0.TXD, M40.TPM0.CH0, M40.GPIO0.IO02, LSIO.GPIO1.IO05 */
#define SC_P_SPI0_SDO 95 /* ADMA.SPI0.SDO, ADMA.SAI0.TXFS, M40.I2C0.SDA, M40.GPIO0.IO01, LSIO.GPIO1.IO06 */
#define SC_P_SPI0_CS1 96 /* ADMA.SPI0.CS1, ADMA.SAI0.RXC, ADMA.SAI1.TXD, ADMA.LCD_PWM0.OUT, LSIO.GPIO1.IO07 */
#define SC_P_SPI0_CS0 97 /* ADMA.SPI0.CS0, ADMA.SAI0.RXD, M40.TPM0.CH1, M40.GPIO0.IO03, LSIO.GPIO1.IO08 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHT 98 /* */
#define SC_P_ADC_IN1 99 /* ADMA.ADC.IN1, M40.I2C0.SDA, M40.GPIO0.IO01, LSIO.GPIO1.IO09 */
#define SC_P_ADC_IN0 100 /* ADMA.ADC.IN0, M40.I2C0.SCL, M40.GPIO0.IO00, LSIO.GPIO1.IO10 */
#define SC_P_ADC_IN3 101 /* ADMA.ADC.IN3, M40.UART0.TX, M40.GPIO0.IO03, ADMA.ACM.MCLK_OUT0, LSIO.GPIO1.IO11 */
#define SC_P_ADC_IN2 102 /* ADMA.ADC.IN2, M40.UART0.RX, M40.GPIO0.IO02, ADMA.ACM.MCLK_IN0, LSIO.GPIO1.IO12 */
#define SC_P_ADC_IN5 103 /* ADMA.ADC.IN5, M40.TPM0.CH1, M40.GPIO0.IO05, LSIO.GPIO1.IO13 */
#define SC_P_ADC_IN4 104 /* ADMA.ADC.IN4, M40.TPM0.CH0, M40.GPIO0.IO04, LSIO.GPIO1.IO14 */
#define SC_P_FLEXCAN0_RX 105 /* ADMA.FLEXCAN0.RX, ADMA.SAI2.RXC, ADMA.UART0.RTS_B, ADMA.SAI1.TXC, LSIO.GPIO1.IO15 */
#define SC_P_FLEXCAN0_TX 106 /* ADMA.FLEXCAN0.TX, ADMA.SAI2.RXD, ADMA.UART0.CTS_B, ADMA.SAI1.TXFS, LSIO.GPIO1.IO16 */
#define SC_P_FLEXCAN1_RX 107 /* ADMA.FLEXCAN1.RX, ADMA.SAI2.RXFS, ADMA.FTM.CH2, ADMA.SAI1.TXD, LSIO.GPIO1.IO17 */
#define SC_P_FLEXCAN1_TX 108 /* ADMA.FLEXCAN1.TX, ADMA.SAI3.RXC, ADMA.DMA0.REQ_IN0, ADMA.SAI1.RXD, LSIO.GPIO1.IO18 */
#define SC_P_FLEXCAN2_RX 109 /* ADMA.FLEXCAN2.RX, ADMA.SAI3.RXD, ADMA.UART3.RX, ADMA.SAI1.RXFS, LSIO.GPIO1.IO19 */
#define SC_P_FLEXCAN2_TX 110 /* ADMA.FLEXCAN2.TX, ADMA.SAI3.RXFS, ADMA.UART3.TX, ADMA.SAI1.RXC, LSIO.GPIO1.IO20 */
#define SC_P_UART0_RX 111 /* ADMA.UART0.RX, ADMA.MQS.R, ADMA.FLEXCAN0.RX, SCU.UART0.RX, LSIO.GPIO1.IO21 */
#define SC_P_UART0_TX 112 /* ADMA.UART0.TX, ADMA.MQS.L, ADMA.FLEXCAN0.TX, SCU.UART0.TX, LSIO.GPIO1.IO22 */
#define SC_P_UART2_TX 113 /* ADMA.UART2.TX, ADMA.FTM.CH1, ADMA.FLEXCAN1.TX, LSIO.GPIO1.IO23 */
#define SC_P_UART2_RX 114 /* ADMA.UART2.RX, ADMA.FTM.CH0, ADMA.FLEXCAN1.RX, LSIO.GPIO1.IO24 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIOLH 115 /* */
#define SC_P_MIPI_DSI0_I2C0_SCL 116 /* MIPI_DSI0.I2C0.SCL, MIPI_DSI1.GPIO0.IO02, LSIO.GPIO1.IO25 */
#define SC_P_MIPI_DSI0_I2C0_SDA 117 /* MIPI_DSI0.I2C0.SDA, MIPI_DSI1.GPIO0.IO03, LSIO.GPIO1.IO26 */
#define SC_P_MIPI_DSI0_GPIO0_00 118 /* MIPI_DSI0.GPIO0.IO00, ADMA.I2C1.SCL, MIPI_DSI0.PWM0.OUT, LSIO.GPIO1.IO27 */
#define SC_P_MIPI_DSI0_GPIO0_01 119 /* MIPI_DSI0.GPIO0.IO01, ADMA.I2C1.SDA, LSIO.GPIO1.IO28 */
#define SC_P_MIPI_DSI1_I2C0_SCL 120 /* MIPI_DSI1.I2C0.SCL, MIPI_DSI0.GPIO0.IO02, LSIO.GPIO1.IO29 */
#define SC_P_MIPI_DSI1_I2C0_SDA 121 /* MIPI_DSI1.I2C0.SDA, MIPI_DSI0.GPIO0.IO03, LSIO.GPIO1.IO30 */
#define SC_P_MIPI_DSI1_GPIO0_00 122 /* MIPI_DSI1.GPIO0.IO00, ADMA.I2C2.SCL, MIPI_DSI1.PWM0.OUT, LSIO.GPIO1.IO31 */
#define SC_P_MIPI_DSI1_GPIO0_01 123 /* MIPI_DSI1.GPIO0.IO01, ADMA.I2C2.SDA, LSIO.GPIO2.IO00 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO 124 /* */
#define SC_P_JTAG_TRST_B 125 /* SCU.JTAG.TRST_B, SCU.WDOG0.WDOG_OUT */
#define SC_P_PMIC_I2C_SCL 126 /* SCU.PMIC_I2C.SCL, SCU.GPIO0.IOXX_PMIC_A35_ON, LSIO.GPIO2.IO01 */
#define SC_P_PMIC_I2C_SDA 127 /* SCU.PMIC_I2C.SDA, SCU.GPIO0.IOXX_PMIC_GPU_ON, LSIO.GPIO2.IO02 */
#define SC_P_PMIC_INT_B 128 /* SCU.DSC.PMIC_INT_B */
#define SC_P_SCU_GPIO0_00 129 /* SCU.GPIO0.IO00, SCU.UART0.RX, M40.UART0.RX, ADMA.UART3.RX, LSIO.GPIO2.IO03 */
#define SC_P_SCU_GPIO0_01 130 /* SCU.GPIO0.IO01, SCU.UART0.TX, M40.UART0.TX, ADMA.UART3.TX, SCU.WDOG0.WDOG_OUT */
#define SC_P_SCU_PMIC_STANDBY 131 /* SCU.DSC.PMIC_STANDBY */
#define SC_P_SCU_BOOT_MODE0 132 /* SCU.DSC.BOOT_MODE0 */
#define SC_P_SCU_BOOT_MODE1 133 /* SCU.DSC.BOOT_MODE1 */
#define SC_P_SCU_BOOT_MODE2 134 /* SCU.DSC.BOOT_MODE2, SCU.PMIC_I2C.SDA */
#define SC_P_SCU_BOOT_MODE3 135 /* SCU.DSC.BOOT_MODE3, SCU.PMIC_I2C.SCL, SCU.DSC.RTC_CLOCK_OUTPUT_32K */
#define SC_P_CSI_D00 136 /* CI_PI.D02, ADMA.SAI0.RXC */
#define SC_P_CSI_D01 137 /* CI_PI.D03, ADMA.SAI0.RXD */
#define SC_P_CSI_D02 138 /* CI_PI.D04, ADMA.SAI0.RXFS */
#define SC_P_CSI_D03 139 /* CI_PI.D05, ADMA.SAI2.RXC */
#define SC_P_CSI_D04 140 /* CI_PI.D06, ADMA.SAI2.RXD */
#define SC_P_CSI_D05 141 /* CI_PI.D07, ADMA.SAI2.RXFS */
#define SC_P_CSI_D06 142 /* CI_PI.D08, ADMA.SAI3.RXC */
#define SC_P_CSI_D07 143 /* CI_PI.D09, ADMA.SAI3.RXD */
#define SC_P_CSI_HSYNC 144 /* CI_PI.HSYNC, CI_PI.D00, ADMA.SAI3.RXFS */
#define SC_P_CSI_VSYNC 145 /* CI_PI.VSYNC, CI_PI.D01 */
#define SC_P_CSI_PCLK 146 /* CI_PI.PCLK, MIPI_CSI0.I2C0.SCL, ADMA.SPI1.SCK, LSIO.GPIO3.IO00 */
#define SC_P_CSI_MCLK 147 /* CI_PI.MCLK, MIPI_CSI0.I2C0.SDA, ADMA.SPI1.SDO, LSIO.GPIO3.IO01 */
#define SC_P_CSI_EN 148 /* CI_PI.EN, CI_PI.I2C.SCL, ADMA.I2C3.SCL, ADMA.SPI1.SDI, LSIO.GPIO3.IO02 */
#define SC_P_CSI_RESET 149 /* CI_PI.RESET, CI_PI.I2C.SDA, ADMA.I2C3.SDA, ADMA.SPI1.CS0, LSIO.GPIO3.IO03 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHD 150 /* */
#define SC_P_MIPI_CSI0_MCLK_OUT 151 /* MIPI_CSI0.ACM.MCLK_OUT, LSIO.GPIO3.IO04 */
#define SC_P_MIPI_CSI0_I2C0_SCL 152 /* MIPI_CSI0.I2C0.SCL, MIPI_CSI0.GPIO0.IO02, LSIO.GPIO3.IO05 */
#define SC_P_MIPI_CSI0_I2C0_SDA 153 /* MIPI_CSI0.I2C0.SDA, MIPI_CSI0.GPIO0.IO03, LSIO.GPIO3.IO06 */
#define SC_P_MIPI_CSI0_GPIO0_01 154 /* MIPI_CSI0.GPIO0.IO01, ADMA.I2C0.SDA, LSIO.GPIO3.IO07 */
#define SC_P_MIPI_CSI0_GPIO0_00 155 /* MIPI_CSI0.GPIO0.IO00, ADMA.I2C0.SCL, LSIO.GPIO3.IO08 */
#define SC_P_QSPI0A_DATA0 156 /* LSIO.QSPI0A.DATA0, LSIO.GPIO3.IO09 */
#define SC_P_QSPI0A_DATA1 157 /* LSIO.QSPI0A.DATA1, LSIO.GPIO3.IO10 */
#define SC_P_QSPI0A_DATA2 158 /* LSIO.QSPI0A.DATA2, LSIO.GPIO3.IO11 */
#define SC_P_QSPI0A_DATA3 159 /* LSIO.QSPI0A.DATA3, LSIO.GPIO3.IO12 */
#define SC_P_QSPI0A_DQS 160 /* LSIO.QSPI0A.DQS, LSIO.GPIO3.IO13 */
#define SC_P_QSPI0A_SS0_B 161 /* LSIO.QSPI0A.SS0_B, LSIO.GPIO3.IO14 */
#define SC_P_QSPI0A_SS1_B 162 /* LSIO.QSPI0A.SS1_B, LSIO.GPIO3.IO15 */
#define SC_P_QSPI0A_SCLK 163 /* LSIO.QSPI0A.SCLK, LSIO.GPIO3.IO16 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0A 164 /* */
#define SC_P_QSPI0B_SCLK 165 /* LSIO.QSPI0B.SCLK, LSIO.QSPI1A.SCLK, LSIO.KPP0.COL0, LSIO.GPIO3.IO17 */
#define SC_P_QSPI0B_DATA0 166 /* LSIO.QSPI0B.DATA0, LSIO.QSPI1A.DATA0, LSIO.KPP0.COL1, LSIO.GPIO3.IO18 */
#define SC_P_QSPI0B_DATA1 167 /* LSIO.QSPI0B.DATA1, LSIO.QSPI1A.DATA1, LSIO.KPP0.COL2, LSIO.GPIO3.IO19 */
#define SC_P_QSPI0B_DATA2 168 /* LSIO.QSPI0B.DATA2, LSIO.QSPI1A.DATA2, LSIO.KPP0.COL3, LSIO.GPIO3.IO20 */
#define SC_P_QSPI0B_DATA3 169 /* LSIO.QSPI0B.DATA3, LSIO.QSPI1A.DATA3, LSIO.KPP0.ROW0, LSIO.GPIO3.IO21 */
#define SC_P_QSPI0B_DQS 170 /* LSIO.QSPI0B.DQS, LSIO.QSPI1A.DQS, LSIO.KPP0.ROW1, LSIO.GPIO3.IO22 */
#define SC_P_QSPI0B_SS0_B 171 /* LSIO.QSPI0B.SS0_B, LSIO.QSPI1A.SS0_B, LSIO.KPP0.ROW2, LSIO.GPIO3.IO23 */
#define SC_P_QSPI0B_SS1_B 172 /* LSIO.QSPI0B.SS1_B, LSIO.QSPI1A.SS1_B, LSIO.KPP0.ROW3, LSIO.GPIO3.IO24 */
#define SC_P_COMP_CTL_GPIO_1V8_3V3_QSPI0B 173 /* */
/*@}*/
#endif /* SC_PADS_H */

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLAT_IMX8_H__
#define __PLAT_IMX8_H__
#include <gicv3.h>
unsigned int plat_calc_core_pos(uint64_t mpidr);
void imx_mailbox_init(uintptr_t base_addr);
void plat_gic_driver_init(void);
void plat_gic_init(void);
void plat_gic_cpuif_enable(void);
void plat_gic_cpuif_disable(void);
void plat_gic_pcpu_init(void);
#endif /*__PLAT_IMX8_H__ */

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* the below macros print out relevant GIC
* registers whenever an unhandled exception is
* taken in BL3-1
*/
.macro plat_print_gic_regs
/* TODO */
.endm
/*
* the below macros print out relevant interconnect
* registers whenever an unhandled exception is
* taken in BL3-1
*/
.macro plat_print_interconnect_regs
/* TODO */
.endm
/* ---------------------------------------------
* The below required platform porting macro
* prints out relevant platform registers
* whenever an unhandled exception is taken in
* BL31.
* ---------------------------------------------
*/
.macro plat_crash_print_regs
/* TODO */
.endm

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _SC_SCI_H
#define _SC_SCI_H
/* Defines */
/* Includes */
#include <sci/sci_ipc.h>
#include <sci/svc/pad/sci_pad_api.h>
#include <sci/svc/pm/sci_pm_api.h>
#include <sci/svc/rm/sci_rm_api.h>
#endif /* _SC_SCI_H */

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file for the IPC implementation.
*/
#ifndef SC_IPC_H
#define SC_IPC_H
/* Includes */
#include <sci/sci_types.h>
/* Defines */
/* Types */
/* Functions */
/*!
* This function opens an IPC channel.
*
* @param[out] ipc return pointer for ipc handle
* @param[in] id id of channel to open
*
* @return Returns an error code (SC_ERR_NONE = success, SC_ERR_IPC
* otherwise).
*
* The \a id parameter is implementation specific. Could be an MU
* address, pointer to a driver path, channel index, etc.
*/
sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id);
/*!
* This function closes an IPC channel.
*
* @param[in] ipc id of channel to close
*/
void sc_ipc_close(sc_ipc_t ipc);
/*!
* This function reads a message from an IPC channel.
*
* @param[in] ipc id of channel read from
* @param[out] data pointer to message buffer to read
*
* This function will block if no message is available to be read.
*/
void sc_ipc_read(sc_ipc_t ipc, void *data);
/*!
* This function writes a message to an IPC channel.
*
* @param[in] ipc id of channel to write to
* @param[in] data pointer to message buffer to write
*
* This function will block if the outgoing buffer is full.
*/
void sc_ipc_write(sc_ipc_t ipc, void *data);
sc_ipc_t ipc_handle;
#endif /* SC_IPC_H */

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file for the RPC implementation.
*/
#ifndef SC_RPC_H
#define SC_RPC_H
/* Includes */
#include <sci/sci_types.h>
#include <sci/sci_ipc.h>
#include <stdbool.h>
/* Defines */
#define SC_RPC_VERSION 1U
#define SC_RPC_MAX_MSG 8U
#define RPC_VER(MSG) ((MSG)->version)
#define RPC_SIZE(MSG) ((MSG)->size)
#define RPC_SVC(MSG) ((MSG)->svc)
#define RPC_FUNC(MSG) ((MSG)->func)
#define RPC_R8(MSG) ((MSG)->func)
#define RPC_I32(MSG, IDX) ((MSG)->DATA.i32[(IDX) / 4U])
#define RPC_I16(MSG, IDX) ((MSG)->DATA.i16[(IDX) / 2U])
#define RPC_I8(MSG, IDX) ((MSG)->DATA.i8[(IDX)])
#define RPC_U32(MSG, IDX) ((MSG)->DATA.u32[(IDX) / 4U])
#define RPC_U16(MSG, IDX) ((MSG)->DATA.u16[(IDX) / 2U])
#define RPC_U8(MSG, IDX) ((MSG)->DATA.u8[(IDX)])
#define SC_RPC_SVC_UNKNOWN 0U
#define SC_RPC_SVC_RETURN 1U
#define SC_RPC_SVC_PM 2U
#define SC_RPC_SVC_RM 3U
#define SC_RPC_SVC_TIMER 5U
#define SC_RPC_SVC_PAD 6U
#define SC_RPC_SVC_MISC 7U
#define SC_RPC_SVC_IRQ 8U
#define SC_RPC_SVC_ABORT 9U
#define SC_RPC_ASYNC_STATE_RD_START 0U
#define SC_RPC_ASYNC_STATE_RD_ACTIVE 1U
#define SC_RPC_ASYNC_STATE_RD_DONE 2U
#define SC_RPC_ASYNC_STATE_WR_START 3U
#define SC_RPC_ASYNC_STATE_WR_ACTIVE 4U
#define SC_RPC_ASYNC_STATE_WR_DONE 5U
#define SC_RPC_MU_GIR_SVC 0x1U
#define SC_RPC_MU_GIR_DBG 0x8U
/* Types */
typedef uint8_t sc_rpc_svc_t;
typedef struct sc_rpc_msg_s {
uint8_t version;
uint8_t size;
uint8_t svc;
uint8_t func;
union {
int32_t i32[(SC_RPC_MAX_MSG - 1U)];
int16_t i16[(SC_RPC_MAX_MSG - 1U) * 2U];
int8_t i8[(SC_RPC_MAX_MSG - 1U) * 4U];
uint32_t u32[(SC_RPC_MAX_MSG - 1U)];
uint16_t u16[(SC_RPC_MAX_MSG - 1U) * 2U];
uint8_t u8[(SC_RPC_MAX_MSG - 1U) * 4U];
} DATA;
} sc_rpc_msg_t;
typedef uint8_t sc_rpc_async_state_t;
typedef struct sc_rpc_async_msg_s {
sc_rpc_async_state_t state;
uint8_t wordIdx;
sc_rpc_msg_t msg;
uint32_t timeStamp;
} sc_rpc_async_msg_t;
/* Functions */
/*!
* This is an internal function to send an RPC message over an IPC
* channel. It is called by client-side SCFW API function shims.
*
* @param[in] ipc IPC handle
* @param[in,out] msg handle to a message
* @param[in] no_resp response flag
*
* If \a no_resp is SC_FALSE then this function waits for a response
* and returns the result in \a msg.
*/
void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp);
/*!
* This is an internal function to dispath an RPC call that has
* arrived via IPC over an MU. It is called by server-side SCFW.
*
* @param[in] mu MU message arrived on
* @param[in,out] msg handle to a message
*
* The function result is returned in \a msg.
*/
void sc_rpc_dispatch(sc_rsrc_t mu, sc_rpc_msg_t *msg);
/*!
* This function translates an RPC message and forwards on to the
* normal RPC API. It is used only by hypervisors.
*
* @param[in] ipc IPC handle
* @param[in,out] msg handle to a message
*
* This function decodes a message, calls macros to translate the
* resources, pads, addresses, partitions, memory regions, etc. and
* then forwards on to the hypervisors SCFW API.Return results are
* translated back abd placed back into the message to be returned
* to the original API.
*/
void sc_rpc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
#endif /* SC_RPC_H */

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _SC_SCFW_H
#define _SC_SCFW_H
/* Includes */
#include <types.h>
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*!
* This type is used to declare a handle for an IPC communication
* channel. Its meaning is specific to the IPC implementation.
*/
typedef uint64_t sc_ipc_t;
/*!
* This type is used to declare an ID for an IPC communication
* channel. For the reference IPC implementation, this ID
* selects the base address of the MU used for IPC.
*/
typedef uint64_t sc_ipc_id_t;
#endif /* _SC_SCFW_H */

View File

@ -0,0 +1,849 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file containing types used across multiple service APIs.
*/
#ifndef SC_TYPES_H
#define SC_TYPES_H
/* Includes */
#include <sci/sci_scfw.h>
/* Defines */
/*!
* @name Defines for common frequencies
*/
/*@{*/
#define SC_32KHZ 32768U /* 32KHz */
#define SC_10MHZ 10000000U /* 10MHz */
#define SC_20MHZ 20000000U /* 20MHz */
#define SC_25MHZ 25000000U /* 25MHz */
#define SC_27MHZ 27000000U /* 27MHz */
#define SC_40MHZ 40000000U /* 40MHz */
#define SC_45MHZ 45000000U /* 45MHz */
#define SC_50MHZ 50000000U /* 50MHz */
#define SC_60MHZ 60000000U /* 60MHz */
#define SC_66MHZ 66666666U /* 66MHz */
#define SC_74MHZ 74250000U /* 74.25MHz */
#define SC_80MHZ 80000000U /* 80MHz */
#define SC_83MHZ 83333333U /* 83MHz */
#define SC_84MHZ 84375000U /* 84.37MHz */
#define SC_100MHZ 100000000U /* 100MHz */
#define SC_125MHZ 125000000U /* 125MHz */
#define SC_133MHZ 133333333U /* 133MHz */
#define SC_135MHZ 135000000U /* 135MHz */
#define SC_150MHZ 150000000U /* 150MHz */
#define SC_160MHZ 160000000U /* 160MHz */
#define SC_166MHZ 166666666U /* 166MHz */
#define SC_175MHZ 175000000U /* 175MHz */
#define SC_180MHZ 180000000U /* 180MHz */
#define SC_200MHZ 200000000U /* 200MHz */
#define SC_250MHZ 250000000U /* 250MHz */
#define SC_266MHZ 266666666U /* 266MHz */
#define SC_300MHZ 300000000U /* 300MHz */
#define SC_312MHZ 312500000U /* 312.5MHZ */
#define SC_320MHZ 320000000U /* 320MHz */
#define SC_325MHZ 325000000U /* 325MHz */
#define SC_333MHZ 333333333U /* 333MHz */
#define SC_350MHZ 350000000U /* 350MHz */
#define SC_372MHZ 372000000U /* 372MHz */
#define SC_375MHZ 375000000U /* 375MHz */
#define SC_400MHZ 400000000U /* 400MHz */
#define SC_500MHZ 500000000U /* 500MHz */
#define SC_594MHZ 594000000U /* 594MHz */
#define SC_625MHZ 625000000U /* 625MHz */
#define SC_640MHZ 640000000U /* 640MHz */
#define SC_650MHZ 650000000U /* 650MHz */
#define SC_667MHZ 666666667U /* 667MHz */
#define SC_675MHZ 675000000U /* 675MHz */
#define SC_700MHZ 700000000U /* 700MHz */
#define SC_720MHZ 720000000U /* 720MHz */
#define SC_750MHZ 750000000U /* 750MHz */
#define SC_800MHZ 800000000U /* 800MHz */
#define SC_850MHZ 850000000U /* 850MHz */
#define SC_900MHZ 900000000U /* 900MHz */
#define SC_1000MHZ 1000000000U /* 1GHz */
#define SC_1056MHZ 1056000000U /* 1.056GHz */
#define SC_1188MHZ 1188000000U /* 1.188GHz */
#define SC_1260MHZ 1260000000U /* 1.26GHz */
#define SC_1280MHZ 1280000000U /* 1.28GHz */
#define SC_1300MHZ 1300000000U /* 1.3GHz */
#define SC_1400MHZ 1400000000U /* 1.4GHz */
#define SC_1500MHZ 1500000000U /* 1.5GHz */
#define SC_1600MHZ 1600000000U /* 1.6GHz */
#define SC_1800MHZ 1800000000U /* 1.8GHz */
#define SC_2000MHZ 2000000000U /* 2.0GHz */
#define SC_2112MHZ 2112000000U /* 2.12GHz */
/*@}*/
/*!
* @name Defines for 24M related frequencies
*/
/*@{*/
#define SC_8MHZ 8000000U /* 8MHz */
#define SC_12MHZ 12000000U /* 12MHz */
#define SC_19MHZ 19800000U /* 19.8MHz */
#define SC_24MHZ 24000000U /* 24MHz */
#define SC_48MHZ 48000000U /* 48MHz */
#define SC_120MHZ 120000000U /* 120MHz */
#define SC_132MHZ 132000000U /* 132MHz */
#define SC_144MHZ 144000000U /* 144MHz */
#define SC_192MHZ 192000000U /* 192MHz */
#define SC_211MHZ 211200000U /* 211.2MHz */
#define SC_240MHZ 240000000U /* 240MHz */
#define SC_264MHZ 264000000U /* 264MHz */
#define SC_352MHZ 352000000U /* 352MHz */
#define SC_360MHZ 360000000U /* 360MHz */
#define SC_384MHZ 384000000U /* 384MHz */
#define SC_396MHZ 396000000U /* 396MHz */
#define SC_432MHZ 432000000U /* 432MHz */
#define SC_480MHZ 480000000U /* 480MHz */
#define SC_600MHZ 600000000U /* 600MHz */
#define SC_744MHZ 744000000U /* 744MHz */
#define SC_792MHZ 792000000U /* 792MHz */
#define SC_864MHZ 864000000U /* 864MHz */
#define SC_960MHZ 960000000U /* 960MHz */
#define SC_1056MHZ 1056000000U /* 1056MHz */
#define SC_1200MHZ 1200000000U /* 1.2GHz */
#define SC_1464MHZ 1464000000U /* 1.464GHz */
#define SC_2400MHZ 2400000000U /* 2.4GHz */
/*@}*/
/*!
* @name Defines for A/V related frequencies
*/
/*@{*/
#define SC_62MHZ 62937500U /* 62.9375MHz */
#define SC_755MHZ 755250000U /* 755.25MHz */
/*@}*/
/*!
* @name Defines for type widths
*/
/*@{*/
#define SC_FADDR_W 36U /* Width of sc_faddr_t */
#define SC_BOOL_W 1U /* Width of sc_bool_t */
#define SC_ERR_W 4U /* Width of sc_err_t */
#define SC_RSRC_W 10U /* Width of sc_rsrc_t */
#define SC_CTRL_W 6U /* Width of sc_ctrl_t */
/*@}*/
/*!
* @name Defines for sc_bool_t
*/
/*@{*/
#define SC_FALSE ((sc_bool_t) 0U) /* True */
#define SC_TRUE ((sc_bool_t) 1U) /* False */
/*@}*/
/*!
* @name Defines for sc_err_t.
*/
/*@{*/
#define SC_ERR_NONE 0U /* Success */
#define SC_ERR_VERSION 1U /* Incompatible API version */
#define SC_ERR_CONFIG 2U /* Configuration error */
#define SC_ERR_PARM 3U /* Bad parameter */
#define SC_ERR_NOACCESS 4U /* Permission error (no access) */
#define SC_ERR_LOCKED 5U /* Permission error (locked) */
#define SC_ERR_UNAVAILABLE 6U /* Unavailable (out of resources) */
#define SC_ERR_NOTFOUND 7U /* Not found */
#define SC_ERR_NOPOWER 8U /* No power */
#define SC_ERR_IPC 9U /* Generic IPC error */
#define SC_ERR_BUSY 10U /* Resource is currently busy/active */
#define SC_ERR_FAIL 11U /* General I/O failure */
#define SC_ERR_LAST 12U
/*@}*/
/*!
* @name Defines for sc_rsrc_t.
*/
/*@{*/
#define SC_R_A53 0U
#define SC_R_A53_0 1U
#define SC_R_A53_1 2U
#define SC_R_A53_2 3U
#define SC_R_A53_3 4U
#define SC_R_A72 5U
#define SC_R_A72_0 6U
#define SC_R_A72_1 7U
#define SC_R_A72_2 8U
#define SC_R_A72_3 9U
#define SC_R_CCI 10U
#define SC_R_DB 11U
#define SC_R_DRC_0 12U
#define SC_R_DRC_1 13U
#define SC_R_GIC_SMMU 14U
#define SC_R_IRQSTR_M4_0 15U
#define SC_R_IRQSTR_M4_1 16U
#define SC_R_SMMU 17U
#define SC_R_GIC 18U
#define SC_R_DC_0_BLIT0 19U
#define SC_R_DC_0_BLIT1 20U
#define SC_R_DC_0_BLIT2 21U
#define SC_R_DC_0_BLIT_OUT 22U
#define SC_R_DC_0_CAPTURE0 23U
#define SC_R_DC_0_CAPTURE1 24U
#define SC_R_DC_0_WARP 25U
#define SC_R_DC_0_INTEGRAL0 26U
#define SC_R_DC_0_INTEGRAL1 27U
#define SC_R_DC_0_VIDEO0 28U
#define SC_R_DC_0_VIDEO1 29U
#define SC_R_DC_0_FRAC0 30U
#define SC_R_DC_0_FRAC1 31U
#define SC_R_DC_0 32U
#define SC_R_GPU_2_PID0 33U
#define SC_R_DC_0_PLL_0 34U
#define SC_R_DC_0_PLL_1 35U
#define SC_R_DC_1_BLIT0 36U
#define SC_R_DC_1_BLIT1 37U
#define SC_R_DC_1_BLIT2 38U
#define SC_R_DC_1_BLIT_OUT 39U
#define SC_R_DC_1_CAPTURE0 40U
#define SC_R_DC_1_CAPTURE1 41U
#define SC_R_DC_1_WARP 42U
#define SC_R_DC_1_INTEGRAL0 43U
#define SC_R_DC_1_INTEGRAL1 44U
#define SC_R_DC_1_VIDEO0 45U
#define SC_R_DC_1_VIDEO1 46U
#define SC_R_DC_1_FRAC0 47U
#define SC_R_DC_1_FRAC1 48U
#define SC_R_DC_1 49U
#define SC_R_GPU_3_PID0 50U
#define SC_R_DC_1_PLL_0 51U
#define SC_R_DC_1_PLL_1 52U
#define SC_R_SPI_0 53U
#define SC_R_SPI_1 54U
#define SC_R_SPI_2 55U
#define SC_R_SPI_3 56U
#define SC_R_UART_0 57U
#define SC_R_UART_1 58U
#define SC_R_UART_2 59U
#define SC_R_UART_3 60U
#define SC_R_UART_4 61U
#define SC_R_EMVSIM_0 62U
#define SC_R_EMVSIM_1 63U
#define SC_R_DMA_0_CH0 64U
#define SC_R_DMA_0_CH1 65U
#define SC_R_DMA_0_CH2 66U
#define SC_R_DMA_0_CH3 67U
#define SC_R_DMA_0_CH4 68U
#define SC_R_DMA_0_CH5 69U
#define SC_R_DMA_0_CH6 70U
#define SC_R_DMA_0_CH7 71U
#define SC_R_DMA_0_CH8 72U
#define SC_R_DMA_0_CH9 73U
#define SC_R_DMA_0_CH10 74U
#define SC_R_DMA_0_CH11 75U
#define SC_R_DMA_0_CH12 76U
#define SC_R_DMA_0_CH13 77U
#define SC_R_DMA_0_CH14 78U
#define SC_R_DMA_0_CH15 79U
#define SC_R_DMA_0_CH16 80U
#define SC_R_DMA_0_CH17 81U
#define SC_R_DMA_0_CH18 82U
#define SC_R_DMA_0_CH19 83U
#define SC_R_DMA_0_CH20 84U
#define SC_R_DMA_0_CH21 85U
#define SC_R_DMA_0_CH22 86U
#define SC_R_DMA_0_CH23 87U
#define SC_R_DMA_0_CH24 88U
#define SC_R_DMA_0_CH25 89U
#define SC_R_DMA_0_CH26 90U
#define SC_R_DMA_0_CH27 91U
#define SC_R_DMA_0_CH28 92U
#define SC_R_DMA_0_CH29 93U
#define SC_R_DMA_0_CH30 94U
#define SC_R_DMA_0_CH31 95U
#define SC_R_I2C_0 96U
#define SC_R_I2C_1 97U
#define SC_R_I2C_2 98U
#define SC_R_I2C_3 99U
#define SC_R_I2C_4 100U
#define SC_R_ADC_0 101U
#define SC_R_ADC_1 102U
#define SC_R_FTM_0 103U
#define SC_R_FTM_1 104U
#define SC_R_CAN_0 105U
#define SC_R_CAN_1 106U
#define SC_R_CAN_2 107U
#define SC_R_DMA_1_CH0 108U
#define SC_R_DMA_1_CH1 109U
#define SC_R_DMA_1_CH2 110U
#define SC_R_DMA_1_CH3 111U
#define SC_R_DMA_1_CH4 112U
#define SC_R_DMA_1_CH5 113U
#define SC_R_DMA_1_CH6 114U
#define SC_R_DMA_1_CH7 115U
#define SC_R_DMA_1_CH8 116U
#define SC_R_DMA_1_CH9 117U
#define SC_R_DMA_1_CH10 118U
#define SC_R_DMA_1_CH11 119U
#define SC_R_DMA_1_CH12 120U
#define SC_R_DMA_1_CH13 121U
#define SC_R_DMA_1_CH14 122U
#define SC_R_DMA_1_CH15 123U
#define SC_R_DMA_1_CH16 124U
#define SC_R_DMA_1_CH17 125U
#define SC_R_DMA_1_CH18 126U
#define SC_R_DMA_1_CH19 127U
#define SC_R_DMA_1_CH20 128U
#define SC_R_DMA_1_CH21 129U
#define SC_R_DMA_1_CH22 130U
#define SC_R_DMA_1_CH23 131U
#define SC_R_DMA_1_CH24 132U
#define SC_R_DMA_1_CH25 133U
#define SC_R_DMA_1_CH26 134U
#define SC_R_DMA_1_CH27 135U
#define SC_R_DMA_1_CH28 136U
#define SC_R_DMA_1_CH29 137U
#define SC_R_DMA_1_CH30 138U
#define SC_R_DMA_1_CH31 139U
#define SC_R_UNUSED1 140U
#define SC_R_UNUSED2 141U
#define SC_R_UNUSED3 142U
#define SC_R_UNUSED4 143U
#define SC_R_GPU_0_PID0 144U
#define SC_R_GPU_0_PID1 145U
#define SC_R_GPU_0_PID2 146U
#define SC_R_GPU_0_PID3 147U
#define SC_R_GPU_1_PID0 148U
#define SC_R_GPU_1_PID1 149U
#define SC_R_GPU_1_PID2 150U
#define SC_R_GPU_1_PID3 151U
#define SC_R_PCIE_A 152U
#define SC_R_SERDES_0 153U
#define SC_R_MATCH_0 154U
#define SC_R_MATCH_1 155U
#define SC_R_MATCH_2 156U
#define SC_R_MATCH_3 157U
#define SC_R_MATCH_4 158U
#define SC_R_MATCH_5 159U
#define SC_R_MATCH_6 160U
#define SC_R_MATCH_7 161U
#define SC_R_MATCH_8 162U
#define SC_R_MATCH_9 163U
#define SC_R_MATCH_10 164U
#define SC_R_MATCH_11 165U
#define SC_R_MATCH_12 166U
#define SC_R_MATCH_13 167U
#define SC_R_MATCH_14 168U
#define SC_R_PCIE_B 169U
#define SC_R_SATA_0 170U
#define SC_R_SERDES_1 171U
#define SC_R_HSIO_GPIO 172U
#define SC_R_MATCH_15 173U
#define SC_R_MATCH_16 174U
#define SC_R_MATCH_17 175U
#define SC_R_MATCH_18 176U
#define SC_R_MATCH_19 177U
#define SC_R_MATCH_20 178U
#define SC_R_MATCH_21 179U
#define SC_R_MATCH_22 180U
#define SC_R_MATCH_23 181U
#define SC_R_MATCH_24 182U
#define SC_R_MATCH_25 183U
#define SC_R_MATCH_26 184U
#define SC_R_MATCH_27 185U
#define SC_R_MATCH_28 186U
#define SC_R_LCD_0 187U
#define SC_R_LCD_0_PWM_0 188U
#define SC_R_LCD_0_I2C_0 189U
#define SC_R_LCD_0_I2C_1 190U
#define SC_R_PWM_0 191U
#define SC_R_PWM_1 192U
#define SC_R_PWM_2 193U
#define SC_R_PWM_3 194U
#define SC_R_PWM_4 195U
#define SC_R_PWM_5 196U
#define SC_R_PWM_6 197U
#define SC_R_PWM_7 198U
#define SC_R_GPIO_0 199U
#define SC_R_GPIO_1 200U
#define SC_R_GPIO_2 201U
#define SC_R_GPIO_3 202U
#define SC_R_GPIO_4 203U
#define SC_R_GPIO_5 204U
#define SC_R_GPIO_6 205U
#define SC_R_GPIO_7 206U
#define SC_R_GPT_0 207U
#define SC_R_GPT_1 208U
#define SC_R_GPT_2 209U
#define SC_R_GPT_3 210U
#define SC_R_GPT_4 211U
#define SC_R_KPP 212U
#define SC_R_MU_0A 213U
#define SC_R_MU_1A 214U
#define SC_R_MU_2A 215U
#define SC_R_MU_3A 216U
#define SC_R_MU_4A 217U
#define SC_R_MU_5A 218U
#define SC_R_MU_6A 219U
#define SC_R_MU_7A 220U
#define SC_R_MU_8A 221U
#define SC_R_MU_9A 222U
#define SC_R_MU_10A 223U
#define SC_R_MU_11A 224U
#define SC_R_MU_12A 225U
#define SC_R_MU_13A 226U
#define SC_R_MU_5B 227U
#define SC_R_MU_6B 228U
#define SC_R_MU_7B 229U
#define SC_R_MU_8B 230U
#define SC_R_MU_9B 231U
#define SC_R_MU_10B 232U
#define SC_R_MU_11B 233U
#define SC_R_MU_12B 234U
#define SC_R_MU_13B 235U
#define SC_R_ROM_0 236U
#define SC_R_FSPI_0 237U
#define SC_R_FSPI_1 238U
#define SC_R_IEE 239U
#define SC_R_IEE_R0 240U
#define SC_R_IEE_R1 241U
#define SC_R_IEE_R2 242U
#define SC_R_IEE_R3 243U
#define SC_R_IEE_R4 244U
#define SC_R_IEE_R5 245U
#define SC_R_IEE_R6 246U
#define SC_R_IEE_R7 247U
#define SC_R_SDHC_0 248U
#define SC_R_SDHC_1 249U
#define SC_R_SDHC_2 250U
#define SC_R_ENET_0 251U
#define SC_R_ENET_1 252U
#define SC_R_MLB_0 253U
#define SC_R_DMA_2_CH0 254U
#define SC_R_DMA_2_CH1 255U
#define SC_R_DMA_2_CH2 256U
#define SC_R_DMA_2_CH3 257U
#define SC_R_DMA_2_CH4 258U
#define SC_R_USB_0 259U
#define SC_R_USB_1 260U
#define SC_R_USB_0_PHY 261U
#define SC_R_USB_2 262U
#define SC_R_USB_2_PHY 263U
#define SC_R_DTCP 264U
#define SC_R_NAND 265U
#define SC_R_LVDS_0 266U
#define SC_R_LVDS_0_PWM_0 267U
#define SC_R_LVDS_0_I2C_0 268U
#define SC_R_LVDS_0_I2C_1 269U
#define SC_R_LVDS_1 270U
#define SC_R_LVDS_1_PWM_0 271U
#define SC_R_LVDS_1_I2C_0 272U
#define SC_R_LVDS_1_I2C_1 273U
#define SC_R_LVDS_2 274U
#define SC_R_LVDS_2_PWM_0 275U
#define SC_R_LVDS_2_I2C_0 276U
#define SC_R_LVDS_2_I2C_1 277U
#define SC_R_M4_0_PID0 278U
#define SC_R_M4_0_PID1 279U
#define SC_R_M4_0_PID2 280U
#define SC_R_M4_0_PID3 281U
#define SC_R_M4_0_PID4 282U
#define SC_R_M4_0_RGPIO 283U
#define SC_R_M4_0_SEMA42 284U
#define SC_R_M4_0_TPM 285U
#define SC_R_M4_0_PIT 286U
#define SC_R_M4_0_UART 287U
#define SC_R_M4_0_I2C 288U
#define SC_R_M4_0_INTMUX 289U
#define SC_R_M4_0_SIM 290U
#define SC_R_M4_0_WDOG 291U
#define SC_R_M4_0_MU_0B 292U
#define SC_R_M4_0_MU_0A0 293U
#define SC_R_M4_0_MU_0A1 294U
#define SC_R_M4_0_MU_0A2 295U
#define SC_R_M4_0_MU_0A3 296U
#define SC_R_M4_0_MU_1A 297U
#define SC_R_M4_1_PID0 298U
#define SC_R_M4_1_PID1 299U
#define SC_R_M4_1_PID2 300U
#define SC_R_M4_1_PID3 301U
#define SC_R_M4_1_PID4 302U
#define SC_R_M4_1_RGPIO 303U
#define SC_R_M4_1_SEMA42 304U
#define SC_R_M4_1_TPM 305U
#define SC_R_M4_1_PIT 306U
#define SC_R_M4_1_UART 307U
#define SC_R_M4_1_I2C 308U
#define SC_R_M4_1_INTMUX 309U
#define SC_R_M4_1_SIM 310U
#define SC_R_M4_1_WDOG 311U
#define SC_R_M4_1_MU_0B 312U
#define SC_R_M4_1_MU_0A0 313U
#define SC_R_M4_1_MU_0A1 314U
#define SC_R_M4_1_MU_0A2 315U
#define SC_R_M4_1_MU_0A3 316U
#define SC_R_M4_1_MU_1A 317U
#define SC_R_SAI_0 318U
#define SC_R_SAI_1 319U
#define SC_R_SAI_2 320U
#define SC_R_IRQSTR_SCU2 321U
#define SC_R_IRQSTR_DSP 322U
#define SC_R_UNUSED5 323U
#define SC_R_OCRAM 324U
#define SC_R_AUDIO_PLL_0 325U
#define SC_R_PI_0 326U
#define SC_R_PI_0_PWM_0 327U
#define SC_R_PI_0_PWM_1 328U
#define SC_R_PI_0_I2C_0 329U
#define SC_R_PI_0_PLL 330U
#define SC_R_PI_1 331U
#define SC_R_PI_1_PWM_0 332U
#define SC_R_PI_1_PWM_1 333U
#define SC_R_PI_1_I2C_0 334U
#define SC_R_PI_1_PLL 335U
#define SC_R_SC_PID0 336U
#define SC_R_SC_PID1 337U
#define SC_R_SC_PID2 338U
#define SC_R_SC_PID3 339U
#define SC_R_SC_PID4 340U
#define SC_R_SC_SEMA42 341U
#define SC_R_SC_TPM 342U
#define SC_R_SC_PIT 343U
#define SC_R_SC_UART 344U
#define SC_R_SC_I2C 345U
#define SC_R_SC_MU_0B 346U
#define SC_R_SC_MU_0A0 347U
#define SC_R_SC_MU_0A1 348U
#define SC_R_SC_MU_0A2 349U
#define SC_R_SC_MU_0A3 350U
#define SC_R_SC_MU_1A 351U
#define SC_R_SYSCNT_RD 352U
#define SC_R_SYSCNT_CMP 353U
#define SC_R_DEBUG 354U
#define SC_R_SYSTEM 355U
#define SC_R_SNVS 356U
#define SC_R_OTP 357U
#define SC_R_VPU_PID0 358U
#define SC_R_VPU_PID1 359U
#define SC_R_VPU_PID2 360U
#define SC_R_VPU_PID3 361U
#define SC_R_VPU_PID4 362U
#define SC_R_VPU_PID5 363U
#define SC_R_VPU_PID6 364U
#define SC_R_VPU_PID7 365U
#define SC_R_VPU_UART 366U
#define SC_R_VPUCORE 367U
#define SC_R_VPUCORE_0 368U
#define SC_R_VPUCORE_1 369U
#define SC_R_VPUCORE_2 370U
#define SC_R_VPUCORE_3 371U
#define SC_R_DMA_4_CH0 372U
#define SC_R_DMA_4_CH1 373U
#define SC_R_DMA_4_CH2 374U
#define SC_R_DMA_4_CH3 375U
#define SC_R_DMA_4_CH4 376U
#define SC_R_ISI_CH0 377U
#define SC_R_ISI_CH1 378U
#define SC_R_ISI_CH2 379U
#define SC_R_ISI_CH3 380U
#define SC_R_ISI_CH4 381U
#define SC_R_ISI_CH5 382U
#define SC_R_ISI_CH6 383U
#define SC_R_ISI_CH7 384U
#define SC_R_MJPEG_DEC_S0 385U
#define SC_R_MJPEG_DEC_S1 386U
#define SC_R_MJPEG_DEC_S2 387U
#define SC_R_MJPEG_DEC_S3 388U
#define SC_R_MJPEG_ENC_S0 389U
#define SC_R_MJPEG_ENC_S1 390U
#define SC_R_MJPEG_ENC_S2 391U
#define SC_R_MJPEG_ENC_S3 392U
#define SC_R_MIPI_0 393U
#define SC_R_MIPI_0_PWM_0 394U
#define SC_R_MIPI_0_I2C_0 395U
#define SC_R_MIPI_0_I2C_1 396U
#define SC_R_MIPI_1 397U
#define SC_R_MIPI_1_PWM_0 398U
#define SC_R_MIPI_1_I2C_0 399U
#define SC_R_MIPI_1_I2C_1 400U
#define SC_R_CSI_0 401U
#define SC_R_CSI_0_PWM_0 402U
#define SC_R_CSI_0_I2C_0 403U
#define SC_R_CSI_1 404U
#define SC_R_CSI_1_PWM_0 405U
#define SC_R_CSI_1_I2C_0 406U
#define SC_R_HDMI 407U
#define SC_R_HDMI_I2S 408U
#define SC_R_HDMI_I2C_0 409U
#define SC_R_HDMI_PLL_0 410U
#define SC_R_HDMI_RX 411U
#define SC_R_HDMI_RX_BYPASS 412U
#define SC_R_HDMI_RX_I2C_0 413U
#define SC_R_ASRC_0 414U
#define SC_R_ESAI_0 415U
#define SC_R_SPDIF_0 416U
#define SC_R_SPDIF_1 417U
#define SC_R_SAI_3 418U
#define SC_R_SAI_4 419U
#define SC_R_SAI_5 420U
#define SC_R_GPT_5 421U
#define SC_R_GPT_6 422U
#define SC_R_GPT_7 423U
#define SC_R_GPT_8 424U
#define SC_R_GPT_9 425U
#define SC_R_GPT_10 426U
#define SC_R_DMA_2_CH5 427U
#define SC_R_DMA_2_CH6 428U
#define SC_R_DMA_2_CH7 429U
#define SC_R_DMA_2_CH8 430U
#define SC_R_DMA_2_CH9 431U
#define SC_R_DMA_2_CH10 432U
#define SC_R_DMA_2_CH11 433U
#define SC_R_DMA_2_CH12 434U
#define SC_R_DMA_2_CH13 435U
#define SC_R_DMA_2_CH14 436U
#define SC_R_DMA_2_CH15 437U
#define SC_R_DMA_2_CH16 438U
#define SC_R_DMA_2_CH17 439U
#define SC_R_DMA_2_CH18 440U
#define SC_R_DMA_2_CH19 441U
#define SC_R_DMA_2_CH20 442U
#define SC_R_DMA_2_CH21 443U
#define SC_R_DMA_2_CH22 444U
#define SC_R_DMA_2_CH23 445U
#define SC_R_DMA_2_CH24 446U
#define SC_R_DMA_2_CH25 447U
#define SC_R_DMA_2_CH26 448U
#define SC_R_DMA_2_CH27 449U
#define SC_R_DMA_2_CH28 450U
#define SC_R_DMA_2_CH29 451U
#define SC_R_DMA_2_CH30 452U
#define SC_R_DMA_2_CH31 453U
#define SC_R_ASRC_1 454U
#define SC_R_ESAI_1 455U
#define SC_R_SAI_6 456U
#define SC_R_SAI_7 457U
#define SC_R_AMIX 458U
#define SC_R_MQS_0 459U
#define SC_R_DMA_3_CH0 460U
#define SC_R_DMA_3_CH1 461U
#define SC_R_DMA_3_CH2 462U
#define SC_R_DMA_3_CH3 463U
#define SC_R_DMA_3_CH4 464U
#define SC_R_DMA_3_CH5 465U
#define SC_R_DMA_3_CH6 466U
#define SC_R_DMA_3_CH7 467U
#define SC_R_DMA_3_CH8 468U
#define SC_R_DMA_3_CH9 469U
#define SC_R_DMA_3_CH10 470U
#define SC_R_DMA_3_CH11 471U
#define SC_R_DMA_3_CH12 472U
#define SC_R_DMA_3_CH13 473U
#define SC_R_DMA_3_CH14 474U
#define SC_R_DMA_3_CH15 475U
#define SC_R_DMA_3_CH16 476U
#define SC_R_DMA_3_CH17 477U
#define SC_R_DMA_3_CH18 478U
#define SC_R_DMA_3_CH19 479U
#define SC_R_DMA_3_CH20 480U
#define SC_R_DMA_3_CH21 481U
#define SC_R_DMA_3_CH22 482U
#define SC_R_DMA_3_CH23 483U
#define SC_R_DMA_3_CH24 484U
#define SC_R_DMA_3_CH25 485U
#define SC_R_DMA_3_CH26 486U
#define SC_R_DMA_3_CH27 487U
#define SC_R_DMA_3_CH28 488U
#define SC_R_DMA_3_CH29 489U
#define SC_R_DMA_3_CH30 490U
#define SC_R_DMA_3_CH31 491U
#define SC_R_AUDIO_PLL_1 492U
#define SC_R_AUDIO_CLK_0 493U
#define SC_R_AUDIO_CLK_1 494U
#define SC_R_MCLK_OUT_0 495U
#define SC_R_MCLK_OUT_1 496U
#define SC_R_PMIC_0 497U
#define SC_R_PMIC_1 498U
#define SC_R_SECO 499U
#define SC_R_CAAM_JR1 500U
#define SC_R_CAAM_JR2 501U
#define SC_R_CAAM_JR3 502U
#define SC_R_SECO_MU_2 503U
#define SC_R_SECO_MU_3 504U
#define SC_R_SECO_MU_4 505U
#define SC_R_HDMI_RX_PWM_0 506U
#define SC_R_A35 507U
#define SC_R_A35_0 508U
#define SC_R_A35_1 509U
#define SC_R_A35_2 510U
#define SC_R_A35_3 511U
#define SC_R_DSP 512U
#define SC_R_DSP_RAM 513U
#define SC_R_CAAM_JR1_OUT 514U
#define SC_R_CAAM_JR2_OUT 515U
#define SC_R_CAAM_JR3_OUT 516U
#define SC_R_VPU_DEC_0 517U
#define SC_R_VPU_ENC_0 518U
#define SC_R_CAAM_JR0 519U
#define SC_R_CAAM_JR0_OUT 520U
#define SC_R_PMIC_2 521U
#define SC_R_DBLOGIC 522U
#define SC_R_HDMI_PLL_1 523U
#define SC_R_BOARD_R0 524U
#define SC_R_BOARD_R1 525U
#define SC_R_BOARD_R2 526U
#define SC_R_BOARD_R3 527U
#define SC_R_BOARD_R4 528U
#define SC_R_BOARD_R5 529U
#define SC_R_BOARD_R6 530U
#define SC_R_BOARD_R7 531U
#define SC_R_MJPEG_DEC_MP 532U
#define SC_R_MJPEG_ENC_MP 533U
#define SC_R_VPU_TS_0 534U
#define SC_R_VPU_MU_0 535U
#define SC_R_VPU_MU_1 536U
#define SC_R_VPU_MU_2 537U
#define SC_R_VPU_MU_3 538U
#define SC_R_VPU_ENC_1 539U
#define SC_R_VPU 540U
#define SC_R_LAST 541U
#define SC_R_ALL ((sc_rsrc_t) UINT16_MAX) /* All resources */
/*@}*/
/* NOTE - please add by replacing some of the UNUSED from above! */
/*!
* Defnes for sc_ctrl_t.
*/
#define SC_C_TEMP 0U
#define SC_C_TEMP_HI 1U
#define SC_C_TEMP_LOW 2U
#define SC_C_PXL_LINK_MST1_ADDR 3U
#define SC_C_PXL_LINK_MST2_ADDR 4U
#define SC_C_PXL_LINK_MST_ENB 5U
#define SC_C_PXL_LINK_MST1_ENB 6U
#define SC_C_PXL_LINK_MST2_ENB 7U
#define SC_C_PXL_LINK_SLV1_ADDR 8U
#define SC_C_PXL_LINK_SLV2_ADDR 9U
#define SC_C_PXL_LINK_MST_VLD 10U
#define SC_C_PXL_LINK_MST1_VLD 11U
#define SC_C_PXL_LINK_MST2_VLD 12U
#define SC_C_SINGLE_MODE 13U
#define SC_C_ID 14U
#define SC_C_PXL_CLK_POLARITY 15U
#define SC_C_LINESTATE 16U
#define SC_C_PCIE_G_RST 17U
#define SC_C_PCIE_BUTTON_RST 18U
#define SC_C_PCIE_PERST 19U
#define SC_C_PHY_RESET 20U
#define SC_C_PXL_LINK_RATE_CORRECTION 21U
#define SC_C_PANIC 22U
#define SC_C_PRIORITY_GROUP 23U
#define SC_C_TXCLK 24U
#define SC_C_CLKDIV 25U
#define SC_C_DISABLE_50 26U
#define SC_C_DISABLE_125 27U
#define SC_C_SEL_125 28U
#define SC_C_MODE 29U
#define SC_C_SYNC_CTRL0 30U
#define SC_C_KACHUNK_CNT 31U
#define SC_C_KACHUNK_SEL 32U
#define SC_C_SYNC_CTRL1 33U
#define SC_C_DPI_RESET 34U
#define SC_C_MIPI_RESET 35U
#define SC_C_DUAL_MODE 36U
#define SC_C_VOLTAGE 37U
#define SC_C_PXL_LINK_SEL 38U
#define SC_C_OFS_SEL 39U
#define SC_C_OFS_AUDIO 40U
#define SC_C_OFS_PERIPH 41U
#define SC_C_OFS_IRQ 42U
#define SC_C_RST0 43U
#define SC_C_RST1 44U
#define SC_C_SEL0 45U
#define SC_C_LAST 46U
#define SC_P_ALL ((sc_pad_t) UINT16_MAX) /* All pads */
/* Types */
/*!
* This type is used to store a boolean
*/
typedef uint8_t sc_bool_t;
/*!
* This type is used to store a system (full-size) address.
*/
typedef uint64_t sc_faddr_t;
/*!
* This type is used to indicate error response for most functions.
*/
typedef uint8_t sc_err_t;
/*!
* This type is used to indicate a resource. Resources include peripherals
* and bus masters (but not memory regions). Note items from list should
* never be changed or removed (only added to at the end of the list).
*/
typedef uint16_t sc_rsrc_t;
/*!
* This type is used to indicate a control.
*/
typedef uint8_t sc_ctrl_t;
/*!
* This type is used to indicate a pad. Valid values are SoC specific.
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
typedef uint16_t sc_pad_t;
/* Extra documentation of standard types */
#ifdef DOXYGEN
/*!
* Type used to declare an 8-bit integer.
*/
typedef __INT8_TYPE__ int8_t;
/*!
* Type used to declare a 16-bit integer.
*/
typedef __INT16_TYPE__ int16_t;
/*!
* Type used to declare a 32-bit integer.
*/
typedef __INT32_TYPE__ int32_t;
/*!
* Type used to declare a 64-bit integer.
*/
typedef __INT64_TYPE__ int64_t;
/*!
* Type used to declare an 8-bit unsigned integer.
*/
typedef __UINT8_TYPE__ uint8_t;
/*!
* Type used to declare a 16-bit unsigned integer.
*/
typedef __UINT16_TYPE__ uint16_t;
/*!
* Type used to declare a 32-bit unsigned integer.
*/
typedef __UINT32_TYPE__ uint32_t;
/*!
* Type used to declare a 64-bit unsigned integer.
*/
typedef __UINT64_TYPE__ uint64_t;
#endif
#endif /* SC_TYPES_H */

View File

@ -0,0 +1,572 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file containing the public API for the System Controller (SC)
* Pad Control (PAD) function.
*
* @addtogroup PAD_SVC (SVC) Pad Service
*
* Module for the Pad Control (PAD) service.
*
* @details
*
* Pad configuration is managed by SC firmware. The pad configuration
* features supported by the SC firmware include:
*
* - Configuring the mux, input/output connection, and low-power isolation
mode.
* - Configuring the technology-specific pad setting such as drive strength,
* pullup/pulldown, etc.
* - Configuring compensation for pad groups with dual voltage capability.
*
* Pad functions fall into one of three categories. Generic functions are
* common to all SoCs and all process technologies. SoC functions are raw
* low-level functions. Technology-specific functions are specific to the
* process technology.
*
* The list of pads is SoC specific. Refer to the SoC [Pad List](@ref PADS)
* for valid pad values. Note that all pads exist on a die but may or
* may not be brought out by the specific package. Mapping of pads to
* package pins/balls is documented in the associated Data Sheet. Some pads
* may not be brought out because the part (die+package) is defeatured and
* some pads may connect to the substrate in the package.
*
* Some pads (SC_P_COMP_*) that can be specified are not individual pads
* but are in fact pad groups. These groups have additional configuration
* that can be done using the sc_pad_set_gp_28fdsoi_comp() function. More
* info on these can be found in the associated Reference Manual.
*
* Pads are managed as a resource by the Resource Manager (RM). They have
* assigned owners and only the owners can configure the pads. Some of the
* pads are reserved for use by the SCFW itself and this can be overriden
* with the implementation of board_config_sc(). Additionally, pads may
* be assigned to various other partitions via the implementation of
* board_system_config().
*
* Note muxing two input pads to the same IP functional signal will
* result in undefined behavior.
* @{
*/
#ifndef SC_PAD_API_H
#define SC_PAD_API_H
/* Includes */
#include <sci/sci_types.h>
#include <sci/svc/rm/sci_rm_api.h>
/* Defines */
/*!
* @name Defines for type widths
*/
/*@{*/
#define SC_PAD_MUX_W 3 /* Width of mux parameter */
/*@}*/
/*!
* @name Defines for sc_pad_config_t
*/
/*@{*/
#define SC_PAD_CONFIG_NORMAL 0U /* Normal */
#define SC_PAD_CONFIG_OD 1U /* Open Drain */
#define SC_PAD_CONFIG_OD_IN 2U /* Open Drain and input */
#define SC_PAD_CONFIG_OUT_IN 3U /* Output and input */
/*@}*/
/*!
* @name Defines for sc_pad_iso_t
*/
/*@{*/
#define SC_PAD_ISO_OFF 0U /* ISO latch is transparent */
#define SC_PAD_ISO_EARLY 1U /* Follow EARLY_ISO */
#define SC_PAD_ISO_LATE 2U /* Follow LATE_ISO */
#define SC_PAD_ISO_ON 3U /* ISO latched data is held */
/*@}*/
/*!
* @name Defines for sc_pad_28fdsoi_dse_t
*/
/*@{*/
#define SC_PAD_28FDSOI_DSE_18V_1MA 0U /* Drive strength of 1mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_2MA 1U /* Drive strength of 2mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_4MA 2U /* Drive strength of 4mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_6MA 3U /* Drive strength of 6mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_8MA 4U /* Drive strength of 8mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_10MA 5U /* Drive strength of 10mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_12MA 6U /* Drive strength of 12mA for 1.8v */
#define SC_PAD_28FDSOI_DSE_18V_HS 7U /* High-speed drive strength for 1.8v */
#define SC_PAD_28FDSOI_DSE_33V_2MA 0U /* Drive strength of 2mA for 3.3v */
#define SC_PAD_28FDSOI_DSE_33V_4MA 1U /* Drive strength of 4mA for 3.3v */
#define SC_PAD_28FDSOI_DSE_33V_8MA 2U /* Drive strength of 8mA for 3.3v */
#define SC_PAD_28FDSOI_DSE_33V_12MA 3U /* Drive strength of 12mA for 3.3v */
#define SC_PAD_28FDSOI_DSE_DV_HIGH 0U /* High drive strength for dual volt */
#define SC_PAD_28FDSOI_DSE_DV_LOW 1U /* Low drive strength for dual volt */
/*@}*/
/*!
* @name Defines for sc_pad_28fdsoi_ps_t
*/
/*@{*/
#define SC_PAD_28FDSOI_PS_KEEPER 0U /* Bus-keeper (only valid for 1.8v) */
#define SC_PAD_28FDSOI_PS_PU 1U /* Pull-up */
#define SC_PAD_28FDSOI_PS_PD 2U /* Pull-down */
#define SC_PAD_28FDSOI_PS_NONE 3U /* No pull (disabled) */
/*@}*/
/*!
* @name Defines for sc_pad_28fdsoi_pus_t
*/
/*@{*/
#define SC_PAD_28FDSOI_PUS_30K_PD 0U /* 30K pull-down */
#define SC_PAD_28FDSOI_PUS_100K_PU 1U /* 100K pull-up */
#define SC_PAD_28FDSOI_PUS_3K_PU 2U /* 3K pull-up */
#define SC_PAD_28FDSOI_PUS_30K_PU 3U /* 30K pull-up */
/*@}*/
/*!
* @name Defines for sc_pad_wakeup_t
*/
/*@{*/
#define SC_PAD_WAKEUP_OFF 0U /* Off */
#define SC_PAD_WAKEUP_CLEAR 1U /* Clears pending flag */
#define SC_PAD_WAKEUP_LOW_LVL 4U /* Low level */
#define SC_PAD_WAKEUP_FALL_EDGE 5U /* Falling edge */
#define SC_PAD_WAKEUP_RISE_EDGE 6U /* Rising edge */
#define SC_PAD_WAKEUP_HIGH_LVL 7U /* High-level */
/*@}*/
/* Types */
/*!
* This type is used to declare a pad config. It determines how the
* output data is driven, pull-up is controlled, and input signal is
* connected. Normal and OD are typical and only connect the input
* when the output is not driven. The IN options are less common and
* force an input connection even when driving the output.
*/
typedef uint8_t sc_pad_config_t;
/*!
* This type is used to declare a pad low-power isolation config.
* ISO_LATE is the most common setting. ISO_EARLY is only used when
* an output pad is directly determined by another input pad. The
* other two are only used when SW wants to directly contol isolation.
*/
typedef uint8_t sc_pad_iso_t;
/*!
* This type is used to declare a drive strength. Note it is specific
* to 28FDSOI. Also note that valid values depend on the pad type.
*/
typedef uint8_t sc_pad_28fdsoi_dse_t;
/*!
* This type is used to declare a pull select. Note it is specific
* to 28FDSOI.
*/
typedef uint8_t sc_pad_28fdsoi_ps_t;
/*!
* This type is used to declare a pull-up select. Note it is specific
* to 28FDSOI HSIC pads.
*/
typedef uint8_t sc_pad_28fdsoi_pus_t;
/*!
* This type is used to declare a wakeup mode of a pad.
*/
typedef uint8_t sc_pad_wakeup_t;
/* Functions */
/*!
* @name Generic Functions
* @{
*/
/*!
* This function configures the mux settings for a pad. This includes
* the signal mux, pad config, and low-power isolation mode.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] mux mux setting
* @param[in] config pad config
* @param[in] iso low-power isolation mode
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Note muxing two input pads to the same IP functional signal will
* result in undefined behavior.
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_mux(sc_ipc_t ipc, sc_pad_t pad,
uint8_t mux, sc_pad_config_t config, sc_pad_iso_t iso);
/*!
* This function gets the mux settings for a pad. This includes
* the signal mux, pad config, and low-power isolation mode.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] mux pointer to return mux setting
* @param[out] config pointer to return pad config
* @param[out] iso pointer to return low-power isolation mode
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_mux(sc_ipc_t ipc, sc_pad_t pad,
uint8_t *mux, sc_pad_config_t *config,
sc_pad_iso_t *iso);
/*!
* This function configures the general purpose pad control. This
* is technology dependent and includes things like drive strength,
* slew rate, pull up/down, etc. Refer to the SoC Reference Manual
* for bit field details.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] ctrl control value to set
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t ctrl);
/*!
* This function gets the general purpose pad control. This
* is technology dependent and includes things like drive strength,
* slew rate, pull up/down, etc. Refer to the SoC Reference Manual
* for bit field details.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] ctrl pointer to return control value
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t *ctrl);
/*!
* This function configures the wakeup mode of the pad.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] wakeup wakeup to set
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_wakeup(sc_ipc_t ipc, sc_pad_t pad, sc_pad_wakeup_t wakeup);
/*!
* This function gets the wakeup mode of a pad.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] wakeup pointer to return wakeup
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_wakeup(sc_ipc_t ipc, sc_pad_t pad, sc_pad_wakeup_t *wakeup);
/*!
* This function configures a pad.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] mux mux setting
* @param[in] config pad config
* @param[in] iso low-power isolation mode
* @param[in] ctrl control value
* @param[in] wakeup wakeup to set
*
* @see sc_pad_set_mux().
* @see sc_pad_set_gp().
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Note muxing two input pads to the same IP functional signal will
* result in undefined behavior.
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t mux,
sc_pad_config_t config, sc_pad_iso_t iso, uint32_t ctrl,
sc_pad_wakeup_t wakeup);
/*!
* This function gets a pad's config.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] mux pointer to return mux setting
* @param[out] config pointer to return pad config
* @param[out] iso pointer to return low-power isolation mode
* @param[out] ctrl pointer to return control value
* @param[out] wakeup pointer to return wakeup to set
*
* @see sc_pad_set_mux().
* @see sc_pad_set_gp().
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t *mux,
sc_pad_config_t *config, sc_pad_iso_t *iso,
uint32_t *ctrl, sc_pad_wakeup_t *wakeup);
/* @} */
/*!
* @name SoC Specific Functions
* @{
*/
/*!
* This function configures the settings for a pad. This setting is SoC
* specific.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] val value to set
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, uint32_t val);
/*!
* This function gets the settings for a pad. This setting is SoC
* specific.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] val pointer to return setting
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val);
/* @} */
/*!
* @name Technology Specific Functions
* @{
*/
/*!
* This function configures the pad control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] dse drive strength
* @param[in] ps pull select
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t dse,
sc_pad_28fdsoi_ps_t ps);
/*!
* This function gets the pad control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] dse pointer to return drive strength
* @param[out] ps pointer to return pull select
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t *dse,
sc_pad_28fdsoi_ps_t *ps);
/*!
* This function configures the pad control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] dse drive strength
* @param[in] hys hysteresis
* @param[in] pus pull-up select
* @param[in] pke pull keeper enable
* @param[in] pue pull-up enable
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_set_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t dse, sc_bool_t hys,
sc_pad_28fdsoi_pus_t pus, sc_bool_t pke,
sc_bool_t pue);
/*!
* This function gets the pad control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] dse pointer to return drive strength
* @param[out] hys pointer to return hysteresis
* @param[out] pus pointer to return pull-up select
* @param[out] pke pointer to return pull keeper enable
* @param[out] pue pointer to return pull-up enable
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t *dse, sc_bool_t *hys,
sc_pad_28fdsoi_pus_t *pus, sc_bool_t *pke,
sc_bool_t *pue);
/*!
* This function configures the compensation control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to configure
* @param[in] compen compensation/freeze mode
* @param[in] fastfrz fast freeze
* @param[in] rasrcp compensation code for PMOS
* @param[in] rasrcn compensation code for NMOS
* @param[in] nasrc_sel NASRC read select
* @param[in] psw_ovr 2.5v override
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*
* Note \a psw_ovr is only applicable to pads supporting 2.5 volt
* operation (e.g. some Ethernet pads).
*/
sc_err_t sc_pad_set_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
uint8_t compen, sc_bool_t fastfrz,
uint8_t rasrcp, uint8_t rasrcn,
sc_bool_t nasrc_sel, sc_bool_t psw_ovr);
/*!
* This function gets the compensation control specific to 28FDSOI.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to query
* @param[out] compen pointer to return compensation/freeze mode
* @param[out] fastfrz pointer to return fast freeze
* @param[out] rasrcp pointer to return compensation code for PMOS
* @param[out] rasrcn pointer to return compensation code for NMOS
* @param[out] nasrc_sel pointer to return NASRC read select
* @param[out] compok pointer to return compensation status
* @param[out] nasrc pointer to return NASRCP/NASRCN
* @param[out] psw_ovr pointer to return the 2.5v override
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner,
* - SC_ERR_UNAVAILABLE if process not applicable
*
* Refer to the SoC [Pad List](@ref PADS) for valid pad values.
*/
sc_err_t sc_pad_get_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
uint8_t *compen, sc_bool_t *fastfrz,
uint8_t *rasrcp, uint8_t *rasrcn,
sc_bool_t *nasrc_sel, sc_bool_t *compok,
uint8_t *nasrc, sc_bool_t *psw_ovr);
/* @} */
#endif /* SC_PAD_API_H */
/**@}*/

View File

@ -0,0 +1,684 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file containing the public API for the System Controller (SC)
* Power Management (PM) function. This includes functions for power state
* control, clock control, reset control, and wake-up event control.
*
* @addtogroup PM_SVC (SVC) Power Management Service
*
* Module for the Power Management (PM) service.
*
* @{
*/
#ifndef SC_PM_API_H
#define SC_PM_API_H
/* Includes */
#include <sci/sci_types.h>
#include <sci/svc/rm/sci_rm_api.h>
/* Defines */
/*!
* @name Defines for type widths
*/
/*@{*/
#define SC_PM_POWER_MODE_W 2 /* Width of sc_pm_power_mode_t */
#define SC_PM_CLOCK_MODE_W 3 /* Width of sc_pm_clock_mode_t */
#define SC_PM_RESET_TYPE_W 2 /* Width of sc_pm_reset_type_t */
#define SC_PM_RESET_REASON_W 3 /* Width of sc_pm_reset_reason_t */
/*@}*/
/*!
* @name Defines for clock indexes (sc_pm_clk_t)
*/
/*@{*/
/*@}*/
/*!
* @name Defines for ALL parameters
*/
/*@{*/
#define SC_PM_CLK_ALL UINT8_MAX /* All clocks */
/*@}*/
/*!
* @name Defines for sc_pm_power_mode_t
*/
/*@{*/
#define SC_PM_PW_MODE_OFF 0U /* Power off */
#define SC_PM_PW_MODE_STBY 1U /* Power in standby */
#define SC_PM_PW_MODE_LP 2U /* Power in low-power */
#define SC_PM_PW_MODE_ON 3U /* Power on */
/*@}*/
/*!
* @name Defines for sc_pm_clk_t
*/
/*@{*/
#define SC_PM_CLK_SLV_BUS 0U /* Slave bus clock */
#define SC_PM_CLK_MST_BUS 1U /* Master bus clock */
#define SC_PM_CLK_PER 2U /* Peripheral clock */
#define SC_PM_CLK_PHY 3U /* Phy clock */
#define SC_PM_CLK_MISC 4U /* Misc clock */
#define SC_PM_CLK_MISC0 0U /* Misc 0 clock */
#define SC_PM_CLK_MISC1 1U /* Misc 1 clock */
#define SC_PM_CLK_MISC2 2U /* Misc 2 clock */
#define SC_PM_CLK_MISC3 3U /* Misc 3 clock */
#define SC_PM_CLK_MISC4 4U /* Misc 4 clock */
#define SC_PM_CLK_CPU 2U /* CPU clock */
#define SC_PM_CLK_PLL 4U /* PLL */
#define SC_PM_CLK_BYPASS 4U /* Bypass clock */
/*@}*/
/*!
* @name Defines for sc_pm_clk_mode_t
*/
/*@{*/
#define SC_PM_CLK_MODE_ROM_INIT 0U /* Clock is initialized by ROM. */
#define SC_PM_CLK_MODE_OFF 1U /* Clock is disabled */
#define SC_PM_CLK_MODE_ON 2U /* Clock is enabled. */
#define SC_PM_CLK_MODE_AUTOGATE_SW 3U /* Clock is in SW autogate mode */
#define SC_PM_CLK_MODE_AUTOGATE_HW 4U /* Clock is in HW autogate mode */
#define SC_PM_CLK_MODE_AUTOGATE_SW_HW 5U /* Clock is in SW-HW autogate mode */
/*@}*/
/*!
* @name Defines for sc_pm_clk_parent_t
*/
/*@{*/
#define SC_PM_PARENT_XTAL 0U /* Parent is XTAL. */
#define SC_PM_PARENT_PLL0 1U /* Parent is PLL0 */
#define SC_PM_PARENT_PLL1 2U /* Parent is PLL1 or PLL0/2 */
#define SC_PM_PARENT_PLL2 3U /* Parent in PLL2 or PLL0/4 */
#define SC_PM_PARENT_BYPS 4U /* Parent is a bypass clock. */
/*@}*/
/*!
* @name Defines for sc_pm_reset_type_t
*/
/*@{*/
#define SC_PM_RESET_TYPE_COLD 0U /* Cold reset */
#define SC_PM_RESET_TYPE_WARM 1U /* Warm reset */
#define SC_PM_RESET_TYPE_BOARD 2U /* Board reset */
/*@}*/
/*!
* @name Defines for sc_pm_reset_cause_t
*/
/*@{*/
#define SC_PM_RESET_CAUSE_TEMP 0U /* Reset due to temp panic alarm */
#define SC_PM_RESET_CAUSE_FAULT 1U /* Reset due to fault exception */
#define SC_PM_RESET_CAUSE_IRQ 2U /* Reset due to SCU reset IRQ */
#define SC_PM_RESET_CAUSE_WDOG 3U /* Reset due to SW WDOG */
#define SC_PM_RESET_CAUSE_API 4U /* Reset due to pm_reset() or monitor */
/*@}*/
/*!
* @name Defines for sc_pm_reset_reason_t
*/
/*@{*/
#define SC_PM_RESET_REASON_POR 0U /* Power on reset */
#define SC_PM_RESET_REASON_WARM 1U /* Warm reset */
#define SC_PM_RESET_REASON_SW 2U /* Software reset */
#define SC_PM_RESET_REASON_WDOG 3U /* Watchdog reset */
#define SC_PM_RESET_REASON_LOCKUP 4U /* Lockup reset */
#define SC_PM_RESET_REASON_TAMPER 5U /* Tamper reset */
#define SC_PM_RESET_REASON_TEMP 6U /* Temp reset */
#define SC_PM_RESET_REASON_LOW_VOLT 7U /* Low voltage reset */
/*@}*/
/*!
* @name Defines for sc_pm_sys_if_t
*/
/*@{*/
#define SC_PM_SYS_IF_INTERCONNECT 0U /* System interconnect */
#define SC_PM_SYS_IF_MU 1U /* AP -> SCU message units */
#define SC_PM_SYS_IF_OCMEM 2U /* On-chip memory (ROM/OCRAM) */
#define SC_PM_SYS_IF_DDR 3U /* DDR memory */
/*@}*/
/*!
* @name Defines for sc_pm_wake_src_t
*/
/*@{*/
#define SC_PM_WAKE_SRC_NONE 0U /* No wake source, used for self-kill */
#define SC_PM_WAKE_SRC_SCU 1U /* Wakeup from SCU to resume CPU (IRQSTEER & GIC powered down) */
#define SC_PM_WAKE_SRC_IRQSTEER 2U /* Wakeup from IRQSTEER to resume CPU (GIC powered down) */
#define SC_PM_WAKE_SRC_IRQSTEER_GIC 3U /* Wakeup from IRQSTEER+GIC to wake CPU (GIC clock gated) */
#define SC_PM_WAKE_SRC_GIC 4U /* Wakeup from GIC to wake CPU */
/*@}*/
/* Types */
/*!
* This type is used to declare a power mode. Note resources only use
* SC_PM_PW_MODE_OFF and SC_PM_PW_MODE_ON. The other modes are used only
* as system power modes.
*/
typedef uint8_t sc_pm_power_mode_t;
/*!
* This type is used to declare a clock.
*/
typedef uint8_t sc_pm_clk_t;
/*!
* This type is used to declare a clock mode.
*/
typedef uint8_t sc_pm_clk_mode_t;
/*!
* This type is used to declare the clock parent.
*/
typedef uint8_t sc_pm_clk_parent_t;
/*!
* This type is used to declare clock rates.
*/
typedef uint32_t sc_pm_clock_rate_t;
/*!
* This type is used to declare a desired reset type.
*/
typedef uint8_t sc_pm_reset_type_t;
/*!
* This type is used to declare a desired reset type.
*/
typedef uint8_t sc_pm_reset_cause;
/*!
* This type is used to declare a reason for a reset.
*/
typedef uint8_t sc_pm_reset_reason_t;
/*!
* This type is used to specify a system-level interface to be power managed.
*/
typedef uint8_t sc_pm_sys_if_t;
/*!
* This type is used to specify a wake source for CPU resources.
*/
typedef uint8_t sc_pm_wake_src_t;
/* Functions */
/*!
* @name Power Functions
* @{
*/
/*!
* This function sets the system power mode. Only the owner of the
* SC_R_SYSTEM resource can do this.
*
* @param[in] ipc IPC handle
* @param[in] mode power mode to apply
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid mode,
* - SC_ERR_NOACCESS if caller not the owner of SC_R_SYSTEM
*
* @see sc_pm_set_sys_power_mode().
*/
sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode);
/*!
* This function sets the power mode of a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition
* @param[in] mode power mode to apply
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid partition or mode,
* - SC_ERR_NOACCESS if caller's partition is not the owner or
* parent of \a pt
*
* The power mode of the partitions is a max power any resource will
* be set to. Calling this will result in all resources owned
* by \a pt to have their power changed to the lower of \a mode or the
* individual resource mode set using sc_pm_set_resource_power_mode().
*/
sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_power_mode_t mode);
/*!
* This function gets the power mode of a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition
* @param[out] mode pointer to return power mode
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid partition
*/
sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_power_mode_t *mode);
/*!
* This function sets the power mode of a resource.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] mode power mode to apply
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or mode,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner
*
* This function will record the individual resource power mode
* and change it if the requested mode is lower than or equal to the
* partition power mode set with sc_pm_set_partition_power_mode().
* In other words, the power mode of the resource will be the minimum
* of the resource power mode and the partition power mode.
*
* Note some resources are still not accessible even when powered up if bus
* transactions go through a fabric not powered up. Examples of this are
* resources in display and capture subsystems which require the display
* controller or the imaging subsytem to be powered up first.
*
* Not that resources are grouped into power domains by the underlying
* hardware. If any resource in the domain is on, the entire power domain
* will be on. Other power domains required to access the resource will
* also be turned on. Clocks required to access the peripheral will be
* turned on. Refer to the SoC RM for more info on power domains and access
* infrastructure (bus fabrics, clock domains, etc.).
*/
sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode);
/*!
* This function gets the power mode of a resource.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[out] mode pointer to return power mode
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Note only SC_PM_PW_MODE_OFF and SC_PM_PW_MODE_ON are valid. The value
* returned does not reflect the power mode of the partition..
*/
sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t *mode);
/*!
* This function requests the low power mode some of the resources
* can enter based on their state. This API is only valid for the
* following resources : SC_R_A53, SC_R_A53_0, SC_R_A53_1, SC_A53_2,
* SC_A53_3, SC_R_A72, SC_R_A72_0, SC_R_A72_1, SC_R_CC1, SC_R_A35,
* SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3.
* For all other resources it will return SC_ERR_PARAM.
* This function will set the low power mode the cores, cluster
* and cluster associated resources will enter when all the cores
* in a given cluster execute WFI
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] mode power mode to apply
*
* @return Returns an error code (SC_ERR_NONE = success).
*
*/
sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode);
/*!
* This function requests low-power mode entry for CPU/cluster
* resources. This API is only valid for the following resources:
* SC_R_A53, SC_R_A53_x, SC_R_A72, SC_R_A72_x, SC_R_A35, SC_R_A35_x,
* SC_R_CCI. For all other resources it will return SC_ERR_PARAM.
* For individual core resources, the specified power mode
* and wake source will be applied after the core has entered
* WFI. For cluster resources, the specified power mode is
* applied after all cores in the cluster have entered low-power mode.
* For multicluster resources, the specified power mode is applied
* after all clusters have reached low-power mode.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] mode power mode to apply
* @param[in] wake_src wake source for low-power exit
*
* @return Returns an error code (SC_ERR_NONE = success).
*
*/
sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode,
sc_pm_wake_src_t wake_src);
/*!
* This function is used to set the resume address of a CPU.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the CPU resource
* @param[in] address 64-bit resume address
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or address,
* - SC_ERR_NOACCESS if caller's partition is not the parent of the
* resource (CPU) owner
*/
sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource,
sc_faddr_t address);
/*!
* This function is used to set parameters for CPU resume from
* low-power mode.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the CPU resource
* @param[in] isPrimary set SC_TRUE if primary wake CPU
* @param[in] address 64-bit resume address
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or address,
* - SC_ERR_NOACCESS if caller's partition is not the parent of the
* resource (CPU) owner
*/
sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource,
sc_bool_t isPrimary, sc_faddr_t address);
/*!
* This function requests the power mode configuration for system-level
* interfaces including messaging units, interconnect, and memories. This API
* is only valid for the following resources : SC_R_A53, SC_R_A72, and
* SC_R_M4_x_PID_y. For all other resources, it will return SC_ERR_PARAM.
* The requested power mode will be captured and applied to system-level
* resources as system conditions allow.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] sys_if system-level interface to be configured
* @param[in] hpm high-power mode for the system interface
* @param[in] lpm low-power mode for the system interface
*
* @return Returns an error code (SC_ERR_NONE = success).
*
*/
sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_sys_if_t sys_if,
sc_pm_power_mode_t hpm,
sc_pm_power_mode_t lpm);
/* @} */
/*!
* @name Clock/PLL Functions
* @{
*/
/*!
* This function sets the rate of a resource's clock/PLL.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] clk clock/PLL to affect
* @param[in,out] rate pointer to rate to set,
* return actual rate
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or clock/PLL,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner,
* - SC_ERR_UNAVAILABLE if clock/PLL not applicable to this resource,
* - SC_ERR_LOCKED if rate locked (usually because shared clock/PLL)
*
* Refer to the [Clock List](@ref CLOCKS) for valid clock/PLL values.
*/
sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clock_rate_t *rate);
/*!
* This function gets the rate of a resource's clock/PLL.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] clk clock/PLL to affect
* @param[out] rate pointer to return rate
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or clock/PLL,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner,
* - SC_ERR_UNAVAILABLE if clock/PLL not applicable to this resource
*
* Refer to the [Clock List](@ref CLOCKS) for valid clock/PLL values.
*/
sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clock_rate_t *rate);
/*!
* This function enables/disables a resource's clock.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] clk clock to affect
* @param[in] enable enable if SC_TRUE; otherwise disabled
* @param[in] autog HW auto clock gating
*
* If \a resource is SC_R_ALL then all resources owned will be affected.
* No error will be returned.
*
* If \a clk is SC_PM_CLK_ALL, then an error will be returned if any
* of the available clocks returns an error.
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or clock,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner,
* - SC_ERR_UNAVAILABLE if clock not applicable to this resource
*
* Refer to the [Clock List](@ref CLOCKS) for valid clock values.
*/
sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog);
/*!
* This function sets the parent of a resource's clock.
* This function should only be called when the clock is disabled.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] clk clock to affect
* @param[in] parent New parent of the clock.
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or clock,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner,
* - SC_ERR_UNAVAILABLE if clock not applicable to this resource
* - SC_ERR_BUSY if clock is currently enabled.
* - SC_ERR_NOPOWER if resource not powered
*
* Refer to the [Clock List](@ref CLOCKS) for valid clock values.
*/
sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clk_parent_t parent);
/*!
* This function gets the parent of a resource's clock.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the resource
* @param[in] clk clock to affect
* @param[out] parent pointer to return parent of clock.
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or clock,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner
* or parent of the owner,
* - SC_ERR_UNAVAILABLE if clock not applicable to this resource
*
* Refer to the [Clock List](@ref CLOCKS) for valid clock values.
*/
sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clk_parent_t *parent);
/* @} */
/*!
* @name Reset Functions
* @{
*/
/*!
* This function is used to reset the system. Only the owner of the
* SC_R_SYSTEM resource can do this.
*
* @param[in] ipc IPC handle
* @param[in] type reset type
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid type,
* - SC_ERR_NOACCESS if caller not the owner of SC_R_SYSTEM
*
* If this function returns, then the reset did not occur due to an
* invalid parameter.
*/
sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type);
/*!
* This function gets a caller's reset reason.
*
* @param[in] ipc IPC handle
* @param[out] reason pointer to return reset reason
*
* @return Returns an error code (SC_ERR_NONE = success).
*/
sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason);
/*!
* This function is used to boot a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to boot
* @param[in] resource_cpu ID of the CPU resource to start
* @param[in] boot_addr 64-bit boot address
* @param[in] resource_mu ID of the MU that must be powered
* @param[in] resource_dev ID of the boot device that must be powered
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid partition, resource, or addr,
* - SC_ERR_NOACCESS if caller's partition is not the parent of the
* partition to boot
*/
sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
sc_rsrc_t resource_mu, sc_rsrc_t resource_dev);
/*!
* This function is used to reboot the caller's partition.
*
* @param[in] ipc IPC handle
* @param[in] type reset type
*
* If \a type is SC_PM_RESET_TYPE_COLD, then most peripherals owned by
* the calling partition will be reset if possible. SC state (partitions,
* power, clocks, etc.) is reset. The boot SW of the booting CPU must be
* able to handle peripherals that that are not reset.
*
* If \a type is SC_PM_RESET_TYPE_WARM, then only the boot CPU is reset.
* SC state (partitions, power, clocks, etc.) are NOT reset. The boot SW
* of the booting CPU must be able to handle peripherals and SC state that
* that are not reset.
*
* If \a type is SC_PM_RESET_TYPE_BOARD, then return with no action.
*
* If this function returns, then the reset did not occur due to an
* invalid parameter.
*/
void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type);
/*!
* This function is used to reboot a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to reboot
* @param[in] type reset type
*
* If \a type is SC_PM_RESET_TYPE_COLD, then most peripherals owned by
* the calling partition will be reset if possible. SC state (partitions,
* power, clocks, etc.) is reset. The boot SW of the booting CPU must be
* able to handle peripherals that that are not reset.
*
* If \a type is SC_PM_RESET_TYPE_WARM, then only the boot CPU is reset.
* SC state (partitions, power, clocks, etc.) are NOT reset. The boot SW
* of the booting CPU must be able to handle peripherals and SC state that
* that are not reset.
*
* If \a type is SC_PM_RESET_TYPE_BOARD, then return with no action.
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid partition or type
* - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
*
* Most peripherals owned by the partition will be reset if
* possible. SC state (partitions, power, clocks, etc.) is reset. The
* boot SW of the booting CPU must be able to handle peripherals that
* that are not reset.
*/
sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_reset_type_t type);
/*!
* This function is used to start/stop a CPU.
*
* @param[in] ipc IPC handle
* @param[in] resource ID of the CPU resource
* @param[in] enable start if SC_TRUE; otherwise stop
* @param[in] address 64-bit boot address
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if invalid resource or address,
* - SC_ERR_NOACCESS if caller's partition is not the parent of the
* resource (CPU) owner
*/
sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
sc_faddr_t address);
/* @} */
#endif /* SC_PM_API_H */
/**@}*/

View File

@ -0,0 +1,757 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file containing the public API for the System Controller (SC)
* Resource Management (RM) function. This includes functions for
* partitioning resources, pads, and memory regions.
*
* @addtogroup RM_SVC (SVC) Resource Management Service
*
* Module for the Resource Management (RM) service.
*
* @includedoc rm/details.dox
*
* @{
*/
#ifndef SC_RM_API_H
#define SC_RM_API_H
/* Includes */
#include <sci/sci_types.h>
/* Defines */
/*!
* @name Defines for type widths
*/
/*@{*/
#define SC_RM_PARTITION_W 5 /* Width of sc_rm_pt_t */
#define SC_RM_MEMREG_W 6 /* Width of sc_rm_mr_t */
#define SC_RM_DID_W 4 /* Width of sc_rm_did_t */
#define SC_RM_SID_W 6 /* Width of sc_rm_sid_t */
#define SC_RM_SPA_W 2 /* Width of sc_rm_spa_t */
#define SC_RM_PERM_W 3 /* Width of sc_rm_perm_t */
/*@}*/
/*!
* @name Defines for ALL parameters
*/
/*@{*/
#define SC_RM_PT_ALL ((sc_rm_pt_t) UINT8_MAX) /* All partitions */
#define SC_RM_MR_ALL ((sc_rm_mr_t) UINT8_MAX) /* All memory regions */
/*@}*/
/*!
* @name Defines for sc_rm_spa_t
*/
/*@{*/
#define SC_RM_SPA_PASSTHRU 0U /* Pass through (attribute driven by master) */
#define SC_RM_SPA_PASSSID 1U /* Pass through and output on SID */
#define SC_RM_SPA_ASSERT 2U /* Assert (force to be secure/privileged) */
#define SC_RM_SPA_NEGATE 3U /* Negate (force to be non-secure/user) */
/*@}*/
/*!
* @name Defines for sc_rm_perm_t
*/
/*@{*/
#define SC_RM_PERM_NONE 0U /* No access */
#define SC_RM_PERM_SEC_R 1U /* Secure RO */
#define SC_RM_PERM_SECPRIV_RW 2U /* Secure privilege R/W */
#define SC_RM_PERM_SEC_RW 3U /* Secure R/W */
#define SC_RM_PERM_NSPRIV_R 4U /* Secure R/W, non-secure privilege RO */
#define SC_RM_PERM_NS_R 5U /* Secure R/W, non-secure RO */
#define SC_RM_PERM_NSPRIV_RW 6U /* Secure R/W, non-secure privilege R/W */
#define SC_RM_PERM_FULL 7U /* Full access */
/*@}*/
/* Types */
/*!
* This type is used to declare a resource partition.
*/
typedef uint8_t sc_rm_pt_t;
/*!
* This type is used to declare a memory region.
*/
typedef uint8_t sc_rm_mr_t;
/*!
* This type is used to declare a resource domain ID used by the
* isolation HW.
*/
typedef uint8_t sc_rm_did_t;
/*!
* This type is used to declare an SMMU StreamID.
*/
typedef uint16_t sc_rm_sid_t;
/*!
* This type is a used to declare master transaction attributes.
*/
typedef uint8_t sc_rm_spa_t;
/*!
* This type is used to declare a resource/memory region access permission.
* Refer to the XRDC2 Block Guide for more information.
*/
typedef uint8_t sc_rm_perm_t;
/* Functions */
/*!
* @name Partition Functions
* @{
*/
/*!
* This function requests that the SC create a new resource partition.
*
* @param[in] ipc IPC handle
* @param[out] pt return handle for partition; used for subsequent function
* calls associated with this partition
* @param[in] secure boolean indicating if this partition should be secure; only
* valid if caller is secure
* @param[in] isolated boolean indicating if this partition should be HW isolated
* via XRDC; set SC_TRUE if new DID is desired
* @param[in] restricted boolean indicating if this partition should be restricted; set
* SC_TRUE if masters in this partition cannot create new partitions
* @param[in] grant boolean indicating if this partition should always grant
* access and control to the parent
* @param[in] coherent boolean indicating if this partition is coherent;
* set SC_TRUE if only this partition will contain both AP clusters
* and they will be coherent via the CCI
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_ERR_PARM if caller's partition is not secure but a new secure partition is requested,
* - SC_ERR_LOCKED if caller's partition is locked,
* - SC_ERR_UNAVAILABLE if partition table is full (no more allocation space)
*
* Marking as non-secure prevents subsequent functions from configuring masters in this
* partition to assert the secure signal. If restricted then the new partition is limited
* in what functions it can call, especially those associated with managing partitions.
*
* The grant option is usually used to isolate a bus master's traffic to specific
* memory without isolating the peripheral interface of the master or the API
* controls of that master.
*/
sc_err_t sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
sc_bool_t isolated, sc_bool_t restricted,
sc_bool_t grant, sc_bool_t coherent);
/*!
* This function makes a partition confidential.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition that is granting
* @param[in] retro retroactive
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if \a pt out of range,
* - SC_ERR_NOACCESS if caller's not allowed to change \a pt
* - SC_ERR_LOCKED if partition \a pt is locked
*
* Call to make a partition confidential. Confidential means only this
* partition should be able to grant access permissions to this partition.
*
* If retroactive, then all resources owned by other partitions will have
* access rights for this partition removed, even if locked.
*/
sc_err_t sc_rm_set_confidential(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t retro);
/*!
* This function frees a partition and assigns all resources to the caller.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to free
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if \a pt out of range or invalid,
* - SC_ERR_NOACCESS if \a pt is the SC partition,
* - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
* - SC_ERR_LOCKED if \a pt or caller's partition is locked
*
* All resources, memory regions, and pads are assigned to the caller/parent.
* The partition watchdog is disabled (even if locked). DID is freed.
*/
sc_err_t sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt);
/*!
* This function returns the DID of a partition.
*
* @param[in] ipc IPC handle
*
* @return Returns the domain ID (DID) of the caller's partition.
*
* The DID is a SoC-specific internal ID used by the HW resource
* protection mechanism. It is only required by clients when using the
* SEMA42 module as the DID is sometimes connected to the master ID.
*/
sc_rm_did_t sc_rm_get_did(sc_ipc_t ipc);
/*!
* This function forces a partition to use a specific static DID.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to assign \a did
* @param[in] did static DID to assign
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if \a pt or \a did out of range,
* - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
* - SC_ERR_LOCKED if \a pt is locked
*
* Assumes no assigned resources or memory regions yet! The number of static
* DID is fixed by the SC at boot.
*/
sc_err_t sc_rm_partition_static(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_did_t did);
/*!
* This function locks a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to lock
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if \a pt out of range,
* - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt
*
* If a partition is locked it cannot be freed, have resources/pads assigned
* to/from it, memory regions created/assigned, DID changed, or parent changed.
*/
sc_err_t sc_rm_partition_lock(sc_ipc_t ipc, sc_rm_pt_t pt);
/*!
* This function gets the partition handle of the caller.
*
* @param[in] ipc IPC handle
* @param[out] pt return handle for caller's partition
*
* @return Returns an error code (SC_ERR_NONE = success).
*/
sc_err_t sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt);
/*!
* This function sets a new parent for a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition for which parent is to be
* changed
* @param[in] pt_parent handle of partition to set as parent
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the parent of \a pt,
* - SC_ERR_LOCKED if either partition is locked
*/
sc_err_t sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_pt_t pt_parent);
/*!
* This function moves all movable resources/pads owned by a source partition
* to a destination partition. It can be used to more quickly set up a new
* partition if a majority of the caller's resources are to be moved to a
* new partition.
*
* @param[in] ipc IPC handle
* @param[in] pt_src handle of partition from which resources should
* be moved from
* @param[in] pt_dst handle of partition to which resources should be
* moved to
* @param[in] move_rsrc boolean to indicate if resources should be moved
* @param[in] move_pads boolean to indicate if pads should be moved
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* By default, all resources are movable. This can be changed using the
* sc_rm_set_resource_movable() function. Note all masters defaulted to SMMU
* bypass.
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not \a pt_src or the
* parent of \a pt_src,
* - SC_ERR_LOCKED if either partition is locked
*/
sc_err_t sc_rm_move_all(sc_ipc_t ipc, sc_rm_pt_t pt_src, sc_rm_pt_t pt_dst,
sc_bool_t move_rsrc, sc_bool_t move_pads);
/* @} */
/*!
* @name Resource Functions
* @{
*/
/*!
* This function assigns ownership of a resource to a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to which resource should be
* assigned
* @param[in] resource resource to assign
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* This action resets the resource's master and peripheral attributes.
* Privilege attribute will be PASSTHRU, security attribute will be
* ASSERT if the partition si secure and NEGATE if it is not, and
* masters will defaulted to SMMU bypass. Access permissions will reset
* to SEC_RW for the owning partition only for secure partitions, FULL for
* non-secure. DEfault is no access by other partitions.
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition or \a pt is locked
*/
sc_err_t sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rsrc_t resource);
/*!
* This function flags resources as movable or not.
*
* @param[in] ipc IPC handle
* @param[in] resource_fst first resource for which flag should be set
* @param[in] resource_lst last resource for which flag should be set
* @param[in] movable movable flag (SC_TRUE is movable)
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if resources are out of range,
* - SC_ERR_NOACCESS if caller's partition is not a parent of a resource owner,
* - SC_ERR_LOCKED if the owning partition is locked
*
* This function is used to determine the set of resources that will be
* moved using the sc_rm_move_all() function. All resources are movable
* by default so this function is normally used to prevent a set of
* resources from moving.
*/
sc_err_t sc_rm_set_resource_movable(sc_ipc_t ipc, sc_rsrc_t resource_fst,
sc_rsrc_t resource_lst, sc_bool_t movable);
/*!
* This function flags all of a subsystem's resources as movable
* or not.
*
* @param[in] ipc IPC handle
* @param[in] resource resource to use to identify subsystem
* @param[in] movable movable flag (SC_TRUE is movable)
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if a function argument is out of range
*
* Note \a resource is used to find the associated subsystem. Only
* resources owned by the caller are set.
*/
sc_err_t sc_rm_set_subsys_rsrc_movable(sc_ipc_t ipc, sc_rsrc_t resource,
sc_bool_t movable);
/*!
* This function sets attributes for a resource which is a bus master (i.e.
* capable of DMA).
*
* @param[in] ipc IPC handle
* @param[in] resource master resource for which attributes should apply
* @param[in] sa security attribute
* @param[in] pa privilege attribute
* @param[in] smmu_bypass SMMU bypass mode
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not a parent of the resource owner,
* - SC_ERR_LOCKED if the owning partition is locked
*
* This function configures how the HW isolation will see bus transactions
* from the specified master. Note the security attribute will only be
* changed if the caller's partition is secure.
*/
sc_err_t sc_rm_set_master_attributes(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_spa_t sa, sc_rm_spa_t pa,
sc_bool_t smmu_bypass);
/*!
* This function sets the StreamID for a resource which is a bus master (i.e.
* capable of DMA).
*
* @param[in] ipc IPC handle
* @param[in] resource master resource for which attributes should apply
* @param[in] sid StreamID
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition is locked
*
* This function configures the SID attribute associated with all bus transactions
* from this master. Note 0 is not a valid SID as it is reserved to indicate
* bypass.
*/
sc_err_t sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_sid_t sid);
/*!
* This function sets access permissions for a peripheral resource.
*
* @param[in] ipc IPC handle
* @param[in] resource peripheral resource for which permissions should apply
* @param[in] pt handle of partition \a perm should by applied for
* @param[in] perm permissions to apply to \a resource for \a pt
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition is locked
* - SC_ERR_LOCKED if the \a pt is confidential and the caller isn't \a pt
*
* This function configures how the HW isolation will restrict access to a
* peripheral based on the attributes of a transaction from bus master.
*/
sc_err_t sc_rm_set_peripheral_permissions(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_pt_t pt, sc_rm_perm_t perm);
/*!
* This function gets ownership status of a resource.
*
* @param[in] ipc IPC handle
* @param[in] resource resource to check
*
* @return Returns a boolean (SC_TRUE if caller's partition owns the resource).
*
* If \a resource is out of range then SC_FALSE is returned.
*/
sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource);
/*!
* This function is used to test if a resource is a bus master.
*
* @param[in] ipc IPC handle
* @param[in] resource resource to check
*
* @return Returns a boolean (SC_TRUE if the resource is a bus master).
*
* If \a resource is out of range then SC_FALSE is returned.
*/
sc_bool_t sc_rm_is_resource_master(sc_ipc_t ipc, sc_rsrc_t resource);
/*!
* This function is used to test if a resource is a peripheral.
*
* @param[in] ipc IPC handle
* @param[in] resource resource to check
*
* @return Returns a boolean (SC_TRUE if the resource is a peripheral).
*
* If \a resource is out of range then SC_FALSE is returned.
*/
sc_bool_t sc_rm_is_resource_peripheral(sc_ipc_t ipc, sc_rsrc_t resource);
/*!
* This function is used to obtain info about a resource.
*
* @param[in] ipc IPC handle
* @param[in] resource resource to inquire about
* @param[out] sid pointer to return StreamID
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if \a resource is out of range
*/
sc_err_t sc_rm_get_resource_info(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_sid_t *sid);
/* @} */
/*!
* @name Memory Region Functions
* @{
*/
/*!
* This function requests that the SC create a new memory region.
*
* @param[in] ipc IPC handle
* @param[out] mr return handle for region; used for
* subsequent function calls
* associated with this region
* @param[in] addr_start start address of region (physical)
* @param[in] addr_end end address of region (physical)
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if the new memory region is misaligned,
* - SC_ERR_LOCKED if caller's partition is locked,
* - SC_ERR_PARM if the new memory region spans multiple existing regions,
* - SC_ERR_NOACCESS if caller's partition does not own the memory containing
* the new region,
* - SC_ERR_UNAVAILABLE if memory region table is full (no more allocation
* space)
*
* The area covered by the memory region must currently be owned by the caller.
* By default, the new region will have access permission set to allow the
* caller to access.
*/
sc_err_t sc_rm_memreg_alloc(sc_ipc_t ipc, sc_rm_mr_t *mr,
sc_faddr_t addr_start, sc_faddr_t addr_end);
/*!
* This function requests that the SC split a memory region.
*
* @param[in] ipc IPC handle
* @param[in] mr handle of memory region to split
* @param[out] mr_ret return handle for new region; used for
* subsequent function calls
* associated with this region
* @param[in] addr_start start address of region (physical)
* @param[in] addr_end end address of region (physical)
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_PARM if the new memory region is not start/end part of mr,
* - SC_ERR_LOCKED if caller's partition is locked,
* - SC_ERR_PARM if the new memory region spans multiple existing regions,
* - SC_ERR_NOACCESS if caller's partition does not own the memory containing
* the new region,
* - SC_ERR_UNAVAILABLE if memory region table is full (no more allocation
* space)
*
* Note the new region must start or end on the split region.
*/
sc_err_t sc_rm_memreg_split(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_rm_mr_t *mr_ret, sc_faddr_t addr_start,
sc_faddr_t addr_end);
/*!
* This function frees a memory region.
*
* @param[in] ipc IPC handle
* @param[in] mr handle of memory region to free
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if \a mr out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not a parent of \a mr,
* - SC_ERR_LOCKED if the owning partition of \a mr is locked
*/
sc_err_t sc_rm_memreg_free(sc_ipc_t ipc, sc_rm_mr_t mr);
/*!
* Internal SC function to find a memory region.
*
* @see sc_rm_find_memreg().
*/
/*!
* This function finds a memory region.
*
* @param[in] ipc IPC handle
* @param[out] mr return handle for region; used for
* subsequent function calls
* associated with this region
* @param[in] addr_start start address of region to search for
* @param[in] addr_end end address of region to search for
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOTFOUND if region not found,
*
* Searches only for regions owned by the caller. Finds first
* region containing the range specified.
*/
sc_err_t sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr,
sc_faddr_t addr_start, sc_faddr_t addr_end);
/*!
* This function assigns ownership of a memory region.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to which memory region
* should be assigned
* @param[in] mr handle of memory region to assign
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the \a mr owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition or \a pt is locked
*/
sc_err_t sc_rm_assign_memreg(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_mr_t mr);
/*!
* This function sets access permissions for a memory region.
*
* @param[in] ipc IPC handle
* @param[in] mr handle of memory region for which permissions
* should apply
* @param[in] pt handle of partition \a perm should by
* applied for
* @param[in] perm permissions to apply to \a mr for \a pt
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the region owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition is locked
* - SC_ERR_LOCKED if the \a pt is confidential and the caller isn't \a pt
*
* This function configures how the HW isolation will restrict access to a
* memory region based on the attributes of a transaction from bus master.
*/
sc_err_t sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_rm_pt_t pt, sc_rm_perm_t perm);
/*!
* This function gets ownership status of a memory region.
*
* @param[in] ipc IPC handle
* @param[in] mr handle of memory region to check
*
* @return Returns a boolean (SC_TRUE if caller's partition owns the
* memory region).
*
* If \a mr is out of range then SC_FALSE is returned.
*/
sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);
/*!
* This function is used to obtain info about a memory region.
*
* @param[in] ipc IPC handle
* @param[in] mr handle of memory region to inquire about
* @param[out] addr_start pointer to return start address
* @param[out] addr_end pointer to return end address
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if \a mr is out of range
*/
sc_err_t sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_faddr_t *addr_start, sc_faddr_t *addr_end);
/* @} */
/*!
* @name Pad Functions
* @{
*/
/*!
* This function assigns ownership of a pad to a partition.
*
* @param[in] ipc IPC handle
* @param[in] pt handle of partition to which pad should
* be assigned
* @param[in] pad pad to assign
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_ERR_NOACCESS if caller's partition is restricted,
* - SC_PARM if arguments out of range or invalid,
* - SC_ERR_NOACCESS if caller's partition is not the pad owner or parent
* of the owner,
* - SC_ERR_LOCKED if the owning partition or \a pt is locked
*/
sc_err_t sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad);
/*!
* This function flags pads as movable or not.
*
* @param[in] ipc IPC handle
* @param[in] pad_fst first pad for which flag should be set
* @param[in] pad_lst last pad for which flag should be set
* @param[in] movable movable flag (SC_TRUE is movable)
*
* @return Returns an error code (SC_ERR_NONE = success).
*
* Return errors:
* - SC_PARM if pads are out of range,
* - SC_ERR_NOACCESS if caller's partition is not a parent of a pad owner,
* - SC_ERR_LOCKED if the owning partition is locked
*
* This function is used to determine the set of pads that will be
* moved using the sc_rm_move_all() function. All pads are movable
* by default so this function is normally used to prevent a set of
* pads from moving.
*/
sc_err_t sc_rm_set_pad_movable(sc_ipc_t ipc, sc_pad_t pad_fst,
sc_pad_t pad_lst, sc_bool_t movable);
/*!
* This function gets ownership status of a pad.
*
* @param[in] ipc IPC handle
* @param[in] pad pad to check
*
* @return Returns a boolean (SC_TRUE if caller's partition owns the pad).
*
* If \a pad is out of range then SC_FALSE is returned.
*/
sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad);
/* @} */
/*!
* @name Debug Functions
* @{
*/
/*!
* This function dumps the RM state for debug.
*
* @param[in] ipc IPC handle
*/
void sc_rm_dump(sc_ipc_t ipc);
/* @} */
#endif /* SC_RM_API_H */
/**@}*/

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <console_macros.S>
#include <assert_macros.S>
#include "imx8_lpuart.h"
.globl console_lpuart_register
.globl console_lpuart_init
.globl console_lpuart_putc
.globl console_lpuart_getc
func console_lpuart_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
str x0, [x6, #CONSOLE_T_DRVDATA]
bl console_lpuart_init
cbz x0, register_fail
mov x0, x6
mov x30, x7
finish_console_register lpuart
register_fail:
ret x7
endfunc console_lpuart_register
func console_lpuart_init
mov w0, #1
ret
endfunc console_lpuart_init
func console_lpuart_putc
ldr x1, [x1, #CONSOLE_T_DRVDATA]
cbz x1, putc_error
/* Prepare '\r' to '\n' */
cmp w0, #0xA
b.ne 2f
1:
/* Check if the transmit FIFO is full */
ldr w2, [x1, #STAT]
tbz w2, #23, 1b
mov w2, #0xD
str w2, [x1, #DATA]
2:
/* Check if the transmit FIFO is full */
ldr w2, [x1, #STAT]
tbz w2, #23, 2b
str w0, [x1, #DATA]
ret
putc_error:
mov w0, #-1
ret
endfunc console_lpuart_putc
func console_lpuart_getc
ldr x0, [x0, #CONSOLE_T_DRVDATA]
cbz x0, getc_error
/* Check if the receive FIFO state */
ret
getc_error:
mov w0, #-1
ret
endfunc console_lpuart_getc

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <gicv3.h>
#include <plat_imx8.h>
#include <platform.h>
#include <platform_def.h>
#include <utils.h>
/* the GICv3 driver only needs to be initialized in EL3 */
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
/* array of Group1 secure interrupts to be configured by the gic driver */
const unsigned int g1s_interrupt_array[] = { 6 };
/* array of Group0 interrupts to be configured by the gic driver */
const unsigned int g0_interrupt_array[] = { 7 };
static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr)
{
return (unsigned int)plat_core_pos_by_mpidr(mpidr);
}
const gicv3_driver_data_t arm_gic_data = {
.gicd_base = PLAT_GICD_BASE,
.gicr_base = PLAT_GICR_BASE,
.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
.g1s_interrupt_num = ARRAY_SIZE(g1s_interrupt_array),
.g0_interrupt_array = g0_interrupt_array,
.g1s_interrupt_array = g1s_interrupt_array,
.rdistif_num = PLATFORM_CORE_COUNT,
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = plat_imx_mpidr_to_core_pos,
};
void plat_gic_driver_init(void)
{
/*
* the GICv3 driver is initialized in EL3 and does not need
* to be initialized again in S-EL1. 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(&arm_gic_data);
#endif
}
void plat_gic_init(void)
{
gicv3_distif_init();
gicv3_rdistif_init(plat_my_core_pos());
gicv3_cpuif_enable(plat_my_core_pos());
}
void plat_gic_cpuif_enable(void)
{
gicv3_cpuif_enable(plat_my_core_pos());
}
void plat_gic_cpuif_disable(void)
{
gicv3_cpuif_disable(plat_my_core_pos());
}
void plat_gic_pcpu_init(void)
{
gicv3_rdistif_init(plat_my_core_pos());
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include "imx8_mu.h"
void MU_EnableRxFullInt(uint32_t base, uint32_t index)
{
uint32_t reg = mmio_read_32(base + MU_ACR_OFFSET1);
reg &= ~(MU_CR_GIRn_MASK1 | MU_CR_NMI_MASK1);
reg |= MU_CR_RIE0_MASK1 >> index;
mmio_write_32(base + MU_ACR_OFFSET1, reg);
}
void MU_EnableGeneralInt(uint32_t base, uint32_t index)
{
uint32_t reg = mmio_read_32(base + MU_ACR_OFFSET1);
reg &= ~(MU_CR_GIRn_MASK1 | MU_CR_NMI_MASK1);
reg |= MU_CR_GIE0_MASK1 >> index;
mmio_write_32(base + MU_ACR_OFFSET1, reg);
}
void MU_SendMessage(uint32_t base, uint32_t regIndex, uint32_t msg)
{
uint32_t mask = MU_SR_TE0_MASK1 >> regIndex;
/* Wait TX register to be empty. */
while (!(mmio_read_32(base + MU_ASR_OFFSET1) & mask))
;
mmio_write_32(base + MU_ATR0_OFFSET1 + (regIndex * 4), msg);
}
void MU_ReceiveMsg(uint32_t base, uint32_t regIndex, uint32_t *msg)
{
uint32_t mask = MU_SR_RF0_MASK1 >> regIndex;
/* Wait RX register to be full. */
while (!(mmio_read_32(base + MU_ASR_OFFSET1) & mask))
;
*msg = mmio_read_32(base + MU_ARR0_OFFSET1 + (regIndex * 4));
}
void MU_Init(uint32_t base)
{
uint32_t reg;
reg = mmio_read_32(base + MU_ACR_OFFSET1);
/* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
reg &= ~(MU_CR_GIEn_MASK1 | MU_CR_RIEn_MASK1 | MU_CR_TIEn_MASK1
| MU_CR_GIRn_MASK1 | MU_CR_Fn_MASK1);
mmio_write_32(base + MU_ACR_OFFSET1, reg);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#define MU_ATR0_OFFSET1 0x0
#define MU_ARR0_OFFSET1 0x10
#define MU_ASR_OFFSET1 0x20
#define MU_ACR_OFFSET1 0x24
#define MU_TR_COUNT1 4
#define MU_RR_COUNT1 4
#define MU_CR_GIEn_MASK1 (0xF << 28)
#define MU_CR_RIEn_MASK1 (0xF << 24)
#define MU_CR_TIEn_MASK1 (0xF << 20)
#define MU_CR_GIRn_MASK1 (0xF << 16)
#define MU_CR_NMI_MASK1 (1 << 3)
#define MU_CR_Fn_MASK1 0x7
#define MU_SR_TE0_MASK1 (1 << 23)
#define MU_SR_RF0_MASK1 (1 << 27)
#define MU_CR_RIE0_MASK1 (1 << 27)
#define MU_CR_GIE0_MASK1 (1 << 31)
#define MU_TR_COUNT 4
#define MU_RR_COUNT 4
void MU_Init(uint32_t base);
void MU_SendMessage(uint32_t base, uint32_t regIndex, uint32_t msg);
void MU_ReceiveMsg(uint32_t base, uint32_t regIndex, uint32_t *msg);
void MU_EnableGeneralInt(uint32_t base, uint32_t index);
void MU_EnableRxFullInt(uint32_t base, uint32_t index);

116
plat/imx/common/sci/ipc.c Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bakery_lock.h>
#include <sci/sci_scfw.h>
#include <sci/sci_ipc.h>
#include <sci/sci_rpc.h>
#include <stdlib.h>
#include "imx8_mu.h"
DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock);
#define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock)
#define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock)
#define sc_ipc_unlock() bakery_lock_release(&sc_ipc_bakery_lock)
void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp)
{
sc_ipc_lock();
sc_ipc_write(ipc, msg);
if (!no_resp)
sc_ipc_read(ipc, msg);
sc_ipc_unlock();
}
sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id)
{
uint32_t base = id;
uint32_t i;
/* Get MU base associated with IPC channel */
if ((ipc == NULL) || (base == 0))
return SC_ERR_IPC;
sc_ipc_lock_init();
/* Init MU */
MU_Init(base);
/* Enable all RX interrupts */
for (i = 0; i < MU_RR_COUNT; i++) {
MU_EnableRxFullInt(base, i);
}
/* Return MU address as handle */
*ipc = (sc_ipc_t) id;
return SC_ERR_NONE;
}
void sc_ipc_close(sc_ipc_t ipc)
{
uint32_t base = ipc;
if (base != 0)
MU_Init(base);
}
void sc_ipc_read(sc_ipc_t ipc, void *data)
{
uint32_t base = ipc;
sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
uint8_t count = 0;
/* Check parms */
if ((base == 0) || (msg == NULL))
return;
/* Read first word */
MU_ReceiveMsg(base, 0, (uint32_t *) msg);
count++;
/* Check size */
if (msg->size > SC_RPC_MAX_MSG) {
*((uint32_t *) msg) = 0;
return;
}
/* Read remaining words */
while (count < msg->size) {
MU_ReceiveMsg(base, count % MU_RR_COUNT,
&(msg->DATA.u32[count - 1]));
count++;
}
}
void sc_ipc_write(sc_ipc_t ipc, void *data)
{
sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
uint32_t base = ipc;
uint8_t count = 0;
/* Check parms */
if ((base == 0) || (msg == NULL))
return;
/* Check size */
if (msg->size > SC_RPC_MAX_MSG)
return;
/* Write first word */
MU_SendMessage(base, 0, *((uint32_t *) msg));
count++;
/* Write remaining words */
while (count < msg->size) {
MU_SendMessage(base, count % MU_TR_COUNT,
msg->DATA.u32[count - 1]);
count++;
}
}

View File

@ -0,0 +1,11 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
BL31_SOURCES += plat/imx/common/sci/ipc.c \
plat/imx/common/sci/imx8_mu.c \
plat/imx/common/sci/svc/pad/pad_rpc_clnt.c \
plat/imx/common/sci/svc/pm/pm_rpc_clnt.c \
plat/imx/common/sci/svc/rm/rm_rpc_clnt.c

View File

@ -0,0 +1,453 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* File containing client-side RPC functions for the PAD service. These
* functions are ported to clients that communicate to the SC.
*
* @addtogroup PAD_SVC
* @{
*/
/* Includes */
#include <sci/sci_types.h>
#include <sci/svc/rm/sci_rm_api.h>
#include <sci/svc/pad/sci_pad_api.h>
#include <sci/sci_rpc.h>
#include <stdlib.h>
#include "sci_pad_rpc.h"
/* Local Defines */
/* Local Types */
/* Local Functions */
sc_err_t sc_pad_set_mux(sc_ipc_t ipc, sc_pad_t pad,
uint8_t mux, sc_pad_config_t config, sc_pad_iso_t iso)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_MUX;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)mux;
RPC_U8(&msg, 3U) = (uint8_t)config;
RPC_U8(&msg, 4U) = (uint8_t)iso;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_mux(sc_ipc_t ipc, sc_pad_t pad,
uint8_t *mux, sc_pad_config_t *config,
sc_pad_iso_t *iso)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_MUX;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mux != NULL) {
*mux = RPC_U8(&msg, 0U);
}
if (config != NULL) {
*config = RPC_U8(&msg, 1U);
}
if (iso != NULL) {
*iso = RPC_U8(&msg, 2U);
}
return (sc_err_t)result;
}
sc_err_t sc_pad_set_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t ctrl)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_GP;
RPC_U32(&msg, 0U) = (uint32_t)ctrl;
RPC_U16(&msg, 4U) = (uint16_t)pad;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_gp(sc_ipc_t ipc, sc_pad_t pad, uint32_t *ctrl)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_GP;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (ctrl != NULL) {
*ctrl = RPC_U32(&msg, 0U);
}
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_set_wakeup(sc_ipc_t ipc, sc_pad_t pad, sc_pad_wakeup_t wakeup)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_WAKEUP;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)wakeup;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_wakeup(sc_ipc_t ipc, sc_pad_t pad, sc_pad_wakeup_t *wakeup)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_WAKEUP;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (wakeup != NULL) {
*wakeup = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_pad_set_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t mux,
sc_pad_config_t config, sc_pad_iso_t iso, uint32_t ctrl,
sc_pad_wakeup_t wakeup)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_ALL;
RPC_U32(&msg, 0U) = (uint32_t)ctrl;
RPC_U16(&msg, 4U) = (uint16_t)pad;
RPC_U8(&msg, 6U) = (uint8_t)mux;
RPC_U8(&msg, 7U) = (uint8_t)config;
RPC_U8(&msg, 8U) = (uint8_t)iso;
RPC_U8(&msg, 9U) = (uint8_t)wakeup;
RPC_SIZE(&msg) = 4U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_all(sc_ipc_t ipc, sc_pad_t pad, uint8_t *mux,
sc_pad_config_t *config, sc_pad_iso_t *iso,
uint32_t *ctrl, sc_pad_wakeup_t *wakeup)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_ALL;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (ctrl != NULL) {
*ctrl = RPC_U32(&msg, 0U);
}
result = RPC_R8(&msg);
if (mux != NULL) {
*mux = RPC_U8(&msg, 4U);
}
if (config != NULL) {
*config = RPC_U8(&msg, 5U);
}
if (iso != NULL) {
*iso = RPC_U8(&msg, 6U);
}
if (wakeup != NULL) {
*wakeup = RPC_U8(&msg, 7U);
}
return (sc_err_t)result;
}
sc_err_t sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, uint32_t val)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET;
RPC_U32(&msg, 0U) = (uint32_t)val;
RPC_U16(&msg, 4U) = (uint16_t)pad;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (val != NULL) {
*val = RPC_U32(&msg, 0U);
}
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_set_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t dse, sc_pad_28fdsoi_ps_t ps)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_GP_28FDSOI;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)dse;
RPC_U8(&msg, 3U) = (uint8_t)ps;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_gp_28fdsoi(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t *dse,
sc_pad_28fdsoi_ps_t *ps)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_GP_28FDSOI;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (dse != NULL) {
*dse = RPC_U8(&msg, 0U);
}
if (ps != NULL) {
*ps = RPC_U8(&msg, 1U);
}
return (sc_err_t)result;
}
sc_err_t sc_pad_set_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t dse, sc_bool_t hys,
sc_pad_28fdsoi_pus_t pus, sc_bool_t pke,
sc_bool_t pue)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_GP_28FDSOI_HSIC;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)dse;
RPC_U8(&msg, 3U) = (uint8_t)pus;
RPC_U8(&msg, 4U) = (uint8_t)hys;
RPC_U8(&msg, 5U) = (uint8_t)pke;
RPC_U8(&msg, 6U) = (uint8_t)pue;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_gp_28fdsoi_hsic(sc_ipc_t ipc, sc_pad_t pad,
sc_pad_28fdsoi_dse_t *dse, sc_bool_t *hys,
sc_pad_28fdsoi_pus_t *pus, sc_bool_t *pke,
sc_bool_t *pue)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_GP_28FDSOI_HSIC;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (dse != NULL) {
*dse = RPC_U8(&msg, 0U);
}
if (pus != NULL) {
*pus = RPC_U8(&msg, 1U);
}
if (hys != NULL) {
*hys = RPC_U8(&msg, 2U);
}
if (pke != NULL) {
*pke = RPC_U8(&msg, 3U);
}
if (pue != NULL) {
*pue = RPC_U8(&msg, 4U);
}
return (sc_err_t)result;
}
sc_err_t sc_pad_set_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
uint8_t compen, sc_bool_t fastfrz,
uint8_t rasrcp, uint8_t rasrcn,
sc_bool_t nasrc_sel, sc_bool_t psw_ovr)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_SET_GP_28FDSOI_COMP;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)compen;
RPC_U8(&msg, 3U) = (uint8_t)rasrcp;
RPC_U8(&msg, 4U) = (uint8_t)rasrcn;
RPC_U8(&msg, 5U) = (uint8_t)fastfrz;
RPC_U8(&msg, 6U) = (uint8_t)nasrc_sel;
RPC_U8(&msg, 7U) = (uint8_t)psw_ovr;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pad_get_gp_28fdsoi_comp(sc_ipc_t ipc, sc_pad_t pad,
uint8_t *compen, sc_bool_t *fastfrz,
uint8_t *rasrcp, uint8_t *rasrcn,
sc_bool_t *nasrc_sel, sc_bool_t *compok,
uint8_t *nasrc, sc_bool_t *psw_ovr)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PAD;
RPC_FUNC(&msg) = (uint8_t)PAD_FUNC_GET_GP_28FDSOI_COMP;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (compen != NULL) {
*compen = RPC_U8(&msg, 0U);
}
if (rasrcp != NULL) {
*rasrcp = RPC_U8(&msg, 1U);
}
if (rasrcn != NULL) {
*rasrcn = RPC_U8(&msg, 2U);
}
if (nasrc != NULL) {
*nasrc = RPC_U8(&msg, 3U);
}
if (fastfrz != NULL) {
*fastfrz = RPC_U8(&msg, 4U);
}
if (nasrc_sel != NULL) {
*nasrc_sel = RPC_U8(&msg, 5U);
}
if (compok != NULL) {
*compok = RPC_U8(&msg, 6U);
}
if (psw_ovr != NULL) {
*psw_ovr = RPC_U8(&msg, 7U);
}
return (sc_err_t)result;
}
/**@}*/

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file for the PAD RPC implementation.
*
* @addtogroup PAD_SVC
* @{
*/
#ifndef SC_PAD_RPC_H
#define SC_PAD_RPC_H
/* Includes */
/* Defines */
/*!
* @name Defines for RPC PAD function calls
*/
/*@{*/
#define PAD_FUNC_UNKNOWN 0 /* Unknown function */
#define PAD_FUNC_SET_MUX 1U /* Index for pad_set_mux() RPC call */
#define PAD_FUNC_GET_MUX 6U /* Index for pad_get_mux() RPC call */
#define PAD_FUNC_SET_GP 2U /* Index for pad_set_gp() RPC call */
#define PAD_FUNC_GET_GP 7U /* Index for pad_get_gp() RPC call */
#define PAD_FUNC_SET_WAKEUP 4U /* Index for pad_set_wakeup() RPC call */
#define PAD_FUNC_GET_WAKEUP 9U /* Index for pad_get_wakeup() RPC call */
#define PAD_FUNC_SET_ALL 5U /* Index for pad_set_all() RPC call */
#define PAD_FUNC_GET_ALL 10U /* Index for pad_get_all() RPC call */
#define PAD_FUNC_SET 15U /* Index for pad_set() RPC call */
#define PAD_FUNC_GET 16U /* Index for pad_get() RPC call */
#define PAD_FUNC_SET_GP_28FDSOI 11U /* Index for pad_set_gp_28fdsoi() RPC call */
#define PAD_FUNC_GET_GP_28FDSOI 12U /* Index for pad_get_gp_28fdsoi() RPC call */
#define PAD_FUNC_SET_GP_28FDSOI_HSIC 3U /* Index for pad_set_gp_28fdsoi_hsic() RPC call */
#define PAD_FUNC_GET_GP_28FDSOI_HSIC 8U /* Index for pad_get_gp_28fdsoi_hsic() RPC call */
#define PAD_FUNC_SET_GP_28FDSOI_COMP 13U /* Index for pad_set_gp_28fdsoi_comp() RPC call */
#define PAD_FUNC_GET_GP_28FDSOI_COMP 14U /* Index for pad_get_gp_28fdsoi_comp() RPC call */
/*@}*/
/* Types */
/* Functions */
/*!
* This function dispatches an incoming PAD RPC request.
*
* @param[in] caller_pt caller partition
* @param[in] msg pointer to RPC message
*/
void pad_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
/*!
* This function translates and dispatches an PAD RPC request.
*
* @param[in] ipc IPC handle
* @param[in] msg pointer to RPC message
*/
void pad_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
#endif /* SC_PAD_RPC_H */
/**@}*/

View File

@ -0,0 +1,457 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* File containing client-side RPC functions for the PM service. These
* functions are ported to clients that communicate to the SC.
*
* @addtogroup PM_SVC
* @{
*/
/* Includes */
#include <sci/sci_types.h>
#include <sci/svc/rm/sci_rm_api.h>
#include <sci/svc/pm/sci_pm_api.h>
#include <sci/sci_rpc.h>
#include <stdlib.h>
#include "sci_pm_rpc.h"
/* Local Defines */
/* Local Types */
/* Local Functions */
sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_SYS_POWER_MODE;
RPC_U8(&msg, 0U) = (uint8_t)mode;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_power_mode_t mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_PARTITION_POWER_MODE;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)mode;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_power_mode_t *mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_SYS_POWER_MODE;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mode != NULL) {
*mode = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_RESOURCE_POWER_MODE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)mode;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t *mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_RESOURCE_POWER_MODE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mode != NULL) {
*mode = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_LOW_POWER_MODE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)mode;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode,
sc_pm_wake_src_t wake_src)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_CPU_LOW_POWER_MODE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)mode;
RPC_U8(&msg, 3U) = (uint8_t)wake_src;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource,
sc_faddr_t address)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME_ADDR;
RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)address;
RPC_U16(&msg, 8U) = (uint16_t)resource;
RPC_SIZE(&msg) = 4U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource,
sc_bool_t isPrimary, sc_faddr_t address)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME;
RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)address;
RPC_U16(&msg, 8U) = (uint16_t)resource;
RPC_U8(&msg, 10U) = (uint8_t)isPrimary;
RPC_SIZE(&msg) = 4U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_sys_if_t sys_if,
sc_pm_power_mode_t hpm,
sc_pm_power_mode_t lpm)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_SYS_IF_POWER_MODE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)sys_if;
RPC_U8(&msg, 3U) = (uint8_t)hpm;
RPC_U8(&msg, 4U) = (uint8_t)lpm;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_RATE;
RPC_U32(&msg, 0U) = *(uint32_t *)rate;
RPC_U16(&msg, 4U) = (uint16_t)resource;
RPC_U8(&msg, 6U) = (uint8_t)clk;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
*rate = RPC_U32(&msg, 0U);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_RATE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)clk;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (rate != NULL) {
*rate = RPC_U32(&msg, 0U);
}
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CLOCK_ENABLE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)clk;
RPC_U8(&msg, 3U) = (uint8_t)enable;
RPC_U8(&msg, 4U) = (uint8_t)autog;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_PARENT;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)clk;
RPC_U8(&msg, 3U) = (uint8_t)parent;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_clk_t clk, sc_pm_clk_parent_t *parent)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_PARENT;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)clk;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (parent != NULL) {
*parent = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET;
RPC_U8(&msg, 0U) = (uint8_t)type;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET_REASON;
RPC_SIZE(&msg) = 1U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (reason != NULL) {
*reason = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
sc_rsrc_t resource_mu, sc_rsrc_t resource_dev)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_BOOT;
RPC_U32(&msg, 0U) = (uint32_t)(boot_addr >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)boot_addr;
RPC_U16(&msg, 8U) = (uint16_t)resource_cpu;
RPC_U16(&msg, 10U) = (uint16_t)resource_mu;
RPC_U16(&msg, 12U) = (uint16_t)resource_dev;
RPC_U8(&msg, 14U) = (uint8_t)pt;
RPC_SIZE(&msg) = 5U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type)
{
sc_rpc_msg_t msg;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT;
RPC_U8(&msg, 0U) = (uint8_t)type;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_TRUE);
return;
}
sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
sc_pm_reset_type_t type)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT_PARTITION;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)type;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
sc_faddr_t address)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CPU_START;
RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)address;
RPC_U16(&msg, 8U) = (uint16_t)resource;
RPC_U8(&msg, 10U) = (uint8_t)enable;
RPC_SIZE(&msg) = 4U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
/**@}*/

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file for the PM RPC implementation.
*
* @addtogroup PM_SVC
* @{
*/
#ifndef SC_PM_RPC_H
#define SC_PM_RPC_H
/* Includes */
/* Defines */
/*!
* @name Defines for RPC PM function calls
*/
/*@{*/
#define PM_FUNC_UNKNOWN 0 /* Unknown function */
#define PM_FUNC_SET_SYS_POWER_MODE 19U /* Index for pm_set_sys_power_mode() RPC call */
#define PM_FUNC_SET_PARTITION_POWER_MODE 1U /* Index for pm_set_partition_power_mode() RPC call */
#define PM_FUNC_GET_SYS_POWER_MODE 2U /* Index for pm_get_sys_power_mode() RPC call */
#define PM_FUNC_SET_RESOURCE_POWER_MODE 3U /* Index for pm_set_resource_power_mode() RPC call */
#define PM_FUNC_GET_RESOURCE_POWER_MODE 4U /* Index for pm_get_resource_power_mode() RPC call */
#define PM_FUNC_REQ_LOW_POWER_MODE 16U /* Index for pm_req_low_power_mode() RPC call */
#define PM_FUNC_REQ_CPU_LOW_POWER_MODE 20U /* Index for pm_req_cpu_low_power_mode() RPC call */
#define PM_FUNC_SET_CPU_RESUME_ADDR 17U /* Index for pm_set_cpu_resume_addr() RPC call */
#define PM_FUNC_SET_CPU_RESUME 21U /* Index for pm_set_cpu_resume() RPC call */
#define PM_FUNC_REQ_SYS_IF_POWER_MODE 18U /* Index for pm_req_sys_if_power_mode() RPC call */
#define PM_FUNC_SET_CLOCK_RATE 5U /* Index for pm_set_clock_rate() RPC call */
#define PM_FUNC_GET_CLOCK_RATE 6U /* Index for pm_get_clock_rate() RPC call */
#define PM_FUNC_CLOCK_ENABLE 7U /* Index for pm_clock_enable() RPC call */
#define PM_FUNC_SET_CLOCK_PARENT 14U /* Index for pm_set_clock_parent() RPC call */
#define PM_FUNC_GET_CLOCK_PARENT 15U /* Index for pm_get_clock_parent() RPC call */
#define PM_FUNC_RESET 13U /* Index for pm_reset() RPC call */
#define PM_FUNC_RESET_REASON 10U /* Index for pm_reset_reason() RPC call */
#define PM_FUNC_BOOT 8U /* Index for pm_boot() RPC call */
#define PM_FUNC_REBOOT 9U /* Index for pm_reboot() RPC call */
#define PM_FUNC_REBOOT_PARTITION 12U /* Index for pm_reboot_partition() RPC call */
#define PM_FUNC_CPU_START 11U /* Index for pm_cpu_start() RPC call */
/*@}*/
/* Types */
/* Functions */
/*!
* This function dispatches an incoming PM RPC request.
*
* @param[in] caller_pt caller partition
* @param[in] msg pointer to RPC message
*/
void pm_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
/*!
* This function translates and dispatches an PM RPC request.
*
* @param[in] ipc IPC handle
* @param[in] msg pointer to RPC message
*/
void pm_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
#endif /* SC_PM_RPC_H */
/**@}*/

View File

@ -0,0 +1,637 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* File containing client-side RPC functions for the RM service. These
* functions are ported to clients that communicate to the SC.
*
* @addtogroup RM_SVC
* @{
*/
/* Includes */
#include <sci/sci_types.h>
#include <sci/svc/rm/sci_rm_api.h>
#include <sci/sci_rpc.h>
#include <stdlib.h>
#include "sci_rm_rpc.h"
/* Local Defines */
/* Local Types */
/* Local Functions */
sc_err_t sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
sc_bool_t isolated, sc_bool_t restricted,
sc_bool_t grant, sc_bool_t coherent)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_PARTITION_ALLOC;
RPC_U8(&msg, 0U) = (uint8_t)secure;
RPC_U8(&msg, 1U) = (uint8_t)isolated;
RPC_U8(&msg, 2U) = (uint8_t)restricted;
RPC_U8(&msg, 3U) = (uint8_t)grant;
RPC_U8(&msg, 4U) = (uint8_t)coherent;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (pt != NULL) {
*pt = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_rm_set_confidential(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t retro)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_CONFIDENTIAL;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)retro;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_PARTITION_FREE;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_rm_did_t sc_rm_get_did(sc_ipc_t ipc)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_GET_DID;
RPC_SIZE(&msg) = 1U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_rm_did_t) result;
}
sc_err_t sc_rm_partition_static(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_did_t did)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_PARTITION_STATIC;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)did;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_partition_lock(sc_ipc_t ipc, sc_rm_pt_t pt)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_PARTITION_LOCK;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_GET_PARTITION;
RPC_SIZE(&msg) = 1U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (pt != NULL) {
*pt = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_pt_t pt_parent)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_PARENT;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)pt_parent;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_move_all(sc_ipc_t ipc, sc_rm_pt_t pt_src, sc_rm_pt_t pt_dst,
sc_bool_t move_rsrc, sc_bool_t move_pads)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_MOVE_ALL;
RPC_U8(&msg, 0U) = (uint8_t)pt_src;
RPC_U8(&msg, 1U) = (uint8_t)pt_dst;
RPC_U8(&msg, 2U) = (uint8_t)move_rsrc;
RPC_U8(&msg, 3U) = (uint8_t)move_pads;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rsrc_t resource)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_ASSIGN_RESOURCE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)pt;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_resource_movable(sc_ipc_t ipc, sc_rsrc_t resource_fst,
sc_rsrc_t resource_lst, sc_bool_t movable)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_RESOURCE_MOVABLE;
RPC_U16(&msg, 0U) = (uint16_t)resource_fst;
RPC_U16(&msg, 2U) = (uint16_t)resource_lst;
RPC_U8(&msg, 4U) = (uint8_t)movable;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_subsys_rsrc_movable(sc_ipc_t ipc, sc_rsrc_t resource,
sc_bool_t movable)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_SUBSYS_RSRC_MOVABLE;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)movable;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_master_attributes(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_spa_t sa, sc_rm_spa_t pa,
sc_bool_t smmu_bypass)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_MASTER_ATTRIBUTES;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)sa;
RPC_U8(&msg, 3U) = (uint8_t)pa;
RPC_U8(&msg, 4U) = (uint8_t)smmu_bypass;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_MASTER_SID;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U16(&msg, 2U) = (uint16_t)sid;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_peripheral_permissions(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_pt_t pt, sc_rm_perm_t perm)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_PERIPHERAL_PERMISSIONS;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_U8(&msg, 2U) = (uint8_t)pt;
RPC_U8(&msg, 3U) = (uint8_t)perm;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_IS_RESOURCE_OWNED;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_bool_t)result;
}
sc_bool_t sc_rm_is_resource_master(sc_ipc_t ipc, sc_rsrc_t resource)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_IS_RESOURCE_MASTER;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_bool_t)result;
}
sc_bool_t sc_rm_is_resource_peripheral(sc_ipc_t ipc, sc_rsrc_t resource)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_IS_RESOURCE_PERIPHERAL;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_bool_t)result;
}
sc_err_t sc_rm_get_resource_info(sc_ipc_t ipc, sc_rsrc_t resource,
sc_rm_sid_t *sid)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_GET_RESOURCE_INFO;
RPC_U16(&msg, 0U) = (uint16_t)resource;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (sid != NULL) {
*sid = RPC_U16(&msg, 0U);
}
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_memreg_alloc(sc_ipc_t ipc, sc_rm_mr_t *mr,
sc_faddr_t addr_start, sc_faddr_t addr_end)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_MEMREG_ALLOC;
RPC_U32(&msg, 0U) = (uint32_t)(addr_start >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)addr_start;
RPC_U32(&msg, 8U) = (uint32_t)(addr_end >> 32U);
RPC_U32(&msg, 12U) = (uint32_t)addr_end;
RPC_SIZE(&msg) = 5U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mr != NULL) {
*mr = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_rm_memreg_split(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_rm_mr_t *mr_ret, sc_faddr_t addr_start,
sc_faddr_t addr_end)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_MEMREG_SPLIT;
RPC_U32(&msg, 0U) = (uint32_t)(addr_start >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)addr_start;
RPC_U32(&msg, 8U) = (uint32_t)(addr_end >> 32U);
RPC_U32(&msg, 12U) = (uint32_t)addr_end;
RPC_U8(&msg, 16U) = (uint8_t)mr;
RPC_SIZE(&msg) = 6U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mr_ret != NULL) {
*mr_ret = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_rm_memreg_free(sc_ipc_t ipc, sc_rm_mr_t mr)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_MEMREG_FREE;
RPC_U8(&msg, 0U) = (uint8_t)mr;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr,
sc_faddr_t addr_start, sc_faddr_t addr_end)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_FIND_MEMREG;
RPC_U32(&msg, 0U) = (uint32_t)(addr_start >> 32U);
RPC_U32(&msg, 4U) = (uint32_t)addr_start;
RPC_U32(&msg, 8U) = (uint32_t)(addr_end >> 32U);
RPC_U32(&msg, 12U) = (uint32_t)addr_end;
RPC_SIZE(&msg) = 5U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
if (mr != NULL) {
*mr = RPC_U8(&msg, 0U);
}
return (sc_err_t)result;
}
sc_err_t sc_rm_assign_memreg(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_mr_t mr)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_ASSIGN_MEMREG;
RPC_U8(&msg, 0U) = (uint8_t)pt;
RPC_U8(&msg, 1U) = (uint8_t)mr;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_rm_pt_t pt, sc_rm_perm_t perm)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_MEMREG_PERMISSIONS;
RPC_U8(&msg, 0U) = (uint8_t)mr;
RPC_U8(&msg, 1U) = (uint8_t)pt;
RPC_U8(&msg, 2U) = (uint8_t)perm;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_IS_MEMREG_OWNED;
RPC_U8(&msg, 0U) = (uint8_t)mr;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_bool_t)result;
}
sc_err_t sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr,
sc_faddr_t *addr_start, sc_faddr_t *addr_end)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_GET_MEMREG_INFO;
RPC_U8(&msg, 0U) = (uint8_t)mr;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
if (addr_start != NULL) {
*addr_start =
((uint64_t) RPC_U32(&msg, 0U) << 32U) | RPC_U32(&msg, 4U);
}
if (addr_end != NULL) {
*addr_end =
((uint64_t) RPC_U32(&msg, 8U) << 32U) | RPC_U32(&msg, 12U);
}
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_ASSIGN_PAD;
RPC_U16(&msg, 0U) = (uint16_t)pad;
RPC_U8(&msg, 2U) = (uint8_t)pt;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_err_t sc_rm_set_pad_movable(sc_ipc_t ipc, sc_pad_t pad_fst,
sc_pad_t pad_lst, sc_bool_t movable)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_SET_PAD_MOVABLE;
RPC_U16(&msg, 0U) = (uint16_t)pad_fst;
RPC_U16(&msg, 2U) = (uint16_t)pad_lst;
RPC_U8(&msg, 4U) = (uint8_t)movable;
RPC_SIZE(&msg) = 3U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_err_t)result;
}
sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad)
{
sc_rpc_msg_t msg;
uint8_t result;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_IS_PAD_OWNED;
RPC_U8(&msg, 0U) = (uint8_t)pad;
RPC_SIZE(&msg) = 2U;
sc_call_rpc(ipc, &msg, SC_FALSE);
result = RPC_R8(&msg);
return (sc_bool_t)result;
}
void sc_rm_dump(sc_ipc_t ipc)
{
sc_rpc_msg_t msg;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_RM;
RPC_FUNC(&msg) = (uint8_t)RM_FUNC_DUMP;
RPC_SIZE(&msg) = 1U;
sc_call_rpc(ipc, &msg, SC_FALSE);
return;
}
/**@}*/

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!
* Header file for the RM RPC implementation.
*
* @addtogroup RM_SVC
* @{
*/
#ifndef SC_RM_RPC_H
#define SC_RM_RPC_H
/* Includes */
/* Defines */
/*!
* @name Defines for RPC RM function calls
*/
/*@{*/
#define RM_FUNC_UNKNOWN 0 /* Unknown function */
#define RM_FUNC_PARTITION_ALLOC 1U /* Index for rm_partition_alloc() RPC call */
#define RM_FUNC_SET_CONFIDENTIAL 31U /* Index for rm_set_confidential() RPC call */
#define RM_FUNC_PARTITION_FREE 2U /* Index for rm_partition_free() RPC call */
#define RM_FUNC_GET_DID 26U /* Index for rm_get_did() RPC call */
#define RM_FUNC_PARTITION_STATIC 3U /* Index for rm_partition_static() RPC call */
#define RM_FUNC_PARTITION_LOCK 4U /* Index for rm_partition_lock() RPC call */
#define RM_FUNC_GET_PARTITION 5U /* Index for rm_get_partition() RPC call */
#define RM_FUNC_SET_PARENT 6U /* Index for rm_set_parent() RPC call */
#define RM_FUNC_MOVE_ALL 7U /* Index for rm_move_all() RPC call */
#define RM_FUNC_ASSIGN_RESOURCE 8U /* Index for rm_assign_resource() RPC call */
#define RM_FUNC_SET_RESOURCE_MOVABLE 9U /* Index for rm_set_resource_movable() RPC call */
#define RM_FUNC_SET_SUBSYS_RSRC_MOVABLE 28U /* Index for rm_set_subsys_rsrc_movable() RPC call */
#define RM_FUNC_SET_MASTER_ATTRIBUTES 10U /* Index for rm_set_master_attributes() RPC call */
#define RM_FUNC_SET_MASTER_SID 11U /* Index for rm_set_master_sid() RPC call */
#define RM_FUNC_SET_PERIPHERAL_PERMISSIONS 12U /* Index for rm_set_peripheral_permissions() RPC call */
#define RM_FUNC_IS_RESOURCE_OWNED 13U /* Index for rm_is_resource_owned() RPC call */
#define RM_FUNC_IS_RESOURCE_MASTER 14U /* Index for rm_is_resource_master() RPC call */
#define RM_FUNC_IS_RESOURCE_PERIPHERAL 15U /* Index for rm_is_resource_peripheral() RPC call */
#define RM_FUNC_GET_RESOURCE_INFO 16U /* Index for rm_get_resource_info() RPC call */
#define RM_FUNC_MEMREG_ALLOC 17U /* Index for rm_memreg_alloc() RPC call */
#define RM_FUNC_MEMREG_SPLIT 29U /* Index for rm_memreg_split() RPC call */
#define RM_FUNC_MEMREG_FREE 18U /* Index for rm_memreg_free() RPC call */
#define RM_FUNC_FIND_MEMREG 30U /* Index for rm_find_memreg() RPC call */
#define RM_FUNC_ASSIGN_MEMREG 19U /* Index for rm_assign_memreg() RPC call */
#define RM_FUNC_SET_MEMREG_PERMISSIONS 20U /* Index for rm_set_memreg_permissions() RPC call */
#define RM_FUNC_IS_MEMREG_OWNED 21U /* Index for rm_is_memreg_owned() RPC call */
#define RM_FUNC_GET_MEMREG_INFO 22U /* Index for rm_get_memreg_info() RPC call */
#define RM_FUNC_ASSIGN_PAD 23U /* Index for rm_assign_pad() RPC call */
#define RM_FUNC_SET_PAD_MOVABLE 24U /* Index for rm_set_pad_movable() RPC call */
#define RM_FUNC_IS_PAD_OWNED 25U /* Index for rm_is_pad_owned() RPC call */
#define RM_FUNC_DUMP 27U /* Index for rm_dump() RPC call */
/*@}*/
/* Types */
/* Functions */
/*!
* This function dispatches an incoming RM RPC request.
*
* @param[in] caller_pt caller partition
* @param[in] msg pointer to RPC message
*/
void rm_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
/*!
* This function translates and dispatches an RM RPC request.
*
* @param[in] ipc IPC handle
* @param[in] msg pointer to RPC message
*/
void rm_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
#endif /* SC_RM_RPC_H */
/**@}*/

View File

@ -0,0 +1,392 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <cci.h>
#include <console.h>
#include <context.h>
#include <context_mgmt.h>
#include <debug.h>
#include <imx8qm_pads.h>
#include <imx8_iomux.h>
#include <imx8_lpuart.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <plat_imx8.h>
#include <sci/sci.h>
#include <sec_rsrc.h>
#include <stdbool.h>
#include <xlat_tables.h>
IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START);
IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END);
IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_START);
IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_END);
IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START);
IMPORT_SYM(unsigned long, __RW_END__, BL31_RW_END);
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
#define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
(SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
(SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
const static int imx8qm_cci_map[] = {
CLUSTER0_CCI_SLVAE_IFACE,
CLUSTER1_CCI_SLVAE_IFACE
};
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(PLAT_CCI_BASE, PLAT_CCI_SIZE, MT_DEVICE | MT_RW),
{0}
};
static uint32_t get_spsr_for_bl33_entry(void)
{
unsigned long el_status;
unsigned long mode;
uint32_t spsr;
/* figure out what mode we enter the non-secure world */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
el_status &= ID_AA64PFR0_ELX_MASK;
mode = (el_status) ? MODE_EL2 : MODE_EL1;
spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
return spsr;
}
#if DEBUG_CONSOLE_A53
static void lpuart32_serial_setbrg(unsigned int base, int baudrate)
{
unsigned int sbr, osr, baud_diff, tmp_osr, tmp_sbr;
unsigned int diff1, diff2, tmp, rate;
if (baudrate == 0)
panic();
sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
baud_diff = baudrate;
osr = 0;
sbr = 0;
for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
tmp_sbr = (rate / (baudrate * tmp_osr));
if (tmp_sbr == 0)
tmp_sbr = 1;
/* calculate difference in actual baud w/ current values */
diff1 = rate / (tmp_osr * tmp_sbr) - baudrate;
diff2 = rate / (tmp_osr * (tmp_sbr + 1));
/* select best values between sbr and sbr+1 */
if (diff1 > (baudrate - diff2)) {
diff1 = baudrate - diff2;
tmp_sbr++;
}
if (diff1 <= baud_diff) {
baud_diff = diff1;
osr = tmp_osr;
sbr = tmp_sbr;
}
}
tmp = mmio_read_32(IMX_BOOT_UART_BASE + BAUD);
if ((osr > 3) && (osr < 8))
tmp |= LPUART_BAUD_BOTHEDGE_MASK;
tmp &= ~LPUART_BAUD_OSR_MASK;
tmp |= LPUART_BAUD_OSR(osr - 1);
tmp &= ~LPUART_BAUD_SBR_MASK;
tmp |= LPUART_BAUD_SBR(sbr);
/* explicitly disable 10 bit mode & set 1 stop bit */
tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
mmio_write_32(IMX_BOOT_UART_BASE + BAUD, tmp);
}
static int lpuart32_serial_init(unsigned int base)
{
unsigned int tmp;
/* disable TX & RX before enabling clocks */
tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
tmp &= ~(CTRL_TE | CTRL_RE);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
mmio_write_32(IMX_BOOT_UART_BASE + MODIR, 0);
mmio_write_32(IMX_BOOT_UART_BASE + FIFO, ~(FIFO_TXFE | FIFO_RXFE));
mmio_write_32(IMX_BOOT_UART_BASE + MATCH, 0);
/* provide data bits, parity, stop bit, etc */
lpuart32_serial_setbrg(base, IMX_BOOT_UART_BAUDRATE);
/* eight data bits no parity bit */
tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
tmp &= ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, CTRL_RE | CTRL_TE);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x0A);
return 0;
}
#endif
void mx8_partition_resources(void)
{
sc_rm_pt_t secure_part, os_part;
sc_rm_mr_t mr, mr_record = 64;
sc_faddr_t start, end;
bool owned, owned2;
sc_err_t err;
int i;
err = sc_rm_get_partition(ipc_handle, &secure_part);
err = sc_rm_partition_alloc(ipc_handle, &os_part, false, false,
false, false, false);
err = sc_rm_set_parent(ipc_handle, os_part, secure_part);
/* set secure resources to NOT-movable */
for (i = 0; i < ARRAY_SIZE(secure_rsrcs); i++) {
err = sc_rm_set_resource_movable(ipc_handle, secure_rsrcs[i],
secure_rsrcs[i], false);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
secure_rsrcs[i], err);
}
owned = sc_rm_is_resource_owned(ipc_handle, SC_R_M4_0_PID0);
if (owned) {
err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_0_PID0,
SC_R_M4_0_PID0, false);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
SC_R_M4_0_PID0, err);
}
owned2 = sc_rm_is_resource_owned(ipc_handle, SC_R_M4_1_PID0);
if (owned2) {
err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_1_PID0,
SC_R_M4_1_PID0, false);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
SC_R_M4_1_PID0, err);
}
/* move all movable resources and pins to non-secure partition */
err = sc_rm_move_all(ipc_handle, secure_part, os_part, true, true);
if (err)
ERROR("sc_rm_move_all: %u\n", err);
/* iterate through peripherals to give NS OS part access */
for (i = 0; i < ARRAY_SIZE(ns_access_allowed); i++) {
err = sc_rm_set_peripheral_permissions(ipc_handle, ns_access_allowed[i],
os_part, SC_RM_PERM_FULL);
if (err)
ERROR("sc_rm_set_peripheral_permissions: rsrc %u, \
ret %u\n", ns_access_allowed[i], err);
}
if (owned) {
err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_0_PID0,
SC_R_M4_0_PID0, true);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
SC_R_M4_0_PID0, err);
err = sc_rm_assign_resource(ipc_handle, os_part, SC_R_M4_0_PID0);
if (err)
ERROR("sc_rm_assign_resource: rsrc %u, ret %u\n",
SC_R_M4_0_PID0, err);
}
if (owned2) {
err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_1_PID0,
SC_R_M4_1_PID0, true);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
SC_R_M4_1_PID0, err);
err = sc_rm_assign_resource(ipc_handle, os_part, SC_R_M4_1_PID0);
if (err)
ERROR("sc_rm_assign_resource: rsrc %u, ret %u\n",
SC_R_M4_1_PID0, err);
}
/*
* sc_rm_set_peripheral_permissions
* sc_rm_set_memreg_permissions
* sc_rm_set_pin_movable
*/
for (mr = 0; mr < 64; mr++) {
owned = sc_rm_is_memreg_owned(ipc_handle, mr);
if (owned) {
err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
if (err)
ERROR("Memreg get info failed, %u\n", mr);
NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
mr_record = mr; /* Record the mr for ATF running */
} else {
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
err %d\n", start, end, err);
}
}
}
if (mr_record != 64) {
err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end);
if (err)
ERROR("Memreg get info failed, %u\n", mr_record);
if ((BL31_LIMIT - 1) < end) {
err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
if (err)
ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
(sc_faddr_t)BL31_LIMIT, end);
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
(sc_faddr_t)BL31_LIMIT, end);
}
if (start < (BL31_BASE - 1)) {
err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
if (err)
ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
start, (sc_faddr_t)BL31_BASE - 1);
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
start, (sc_faddr_t)BL31_BASE - 1);
}
}
if (err)
NOTICE("Partitioning Failed\n");
else
NOTICE("Non-secure Partitioning Succeeded\n");
}
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
#if DEBUG_CONSOLE
static console_lpuart_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
#if DEBUG_CONSOLE_A53
sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON);
sc_pm_clock_rate_t rate = 80000000;
sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false);
/* configure UART pads */
sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL);
sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL);
sc_pad_set(ipc_handle, SC_P_UART0_RTS_B, UART_PAD_CTRL);
sc_pad_set(ipc_handle, SC_P_UART0_CTS_B, UART_PAD_CTRL);
lpuart32_serial_init(IMX_BOOT_UART_BASE);
#endif
#if DEBUG_CONSOLE
console_lpuart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
#endif
/* turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
/*
* create new partition for non-secure OS/Hypervisor
* uses global structs defined in sec_rsrc.h
*/
mx8_partition_resources();
bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
/* init the first cluster's cci slave interface */
cci_init(PLAT_CCI_BASE, imx8qm_cci_map, PLATFORM_CLUSTER_COUNT);
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
}
void bl31_plat_arch_setup(void)
{
unsigned long ro_start = BL31_RO_START;
unsigned long ro_size = BL31_RO_END - BL31_RO_START;
unsigned long rw_start = BL31_RW_START;
unsigned long rw_size = BL31_RW_END - BL31_RW_START;
#if USE_COHERENT_MEM
unsigned long coh_start = BL31_COHERENT_RAM_START;
unsigned long coh_size = BL31_COHERENT_RAM_END - BL31_COHERENT_RAM_START;
#endif
mmap_add_region(ro_start, ro_start, ro_size,
MT_RO | MT_MEMORY | MT_SECURE);
mmap_add_region(rw_start, rw_start, rw_size,
MT_RW | MT_MEMORY | MT_SECURE);
mmap_add(imx_mmap);
#if USE_COHERENT_MEM
mmap_add_region(coh_start, coh_start, coh_size,
MT_DEVICE | MT_RW | MT_SECURE);
#endif
/* setup xlat table */
init_xlat_tables();
/* enable the MMU */
enable_mmu_el3(0);
}
void bl31_platform_setup(void)
{
plat_gic_driver_init();
plat_gic_init();
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
{
if (type == NON_SECURE)
return &bl33_image_ep_info;
if (type == SECURE)
return &bl32_image_ep_info;
return NULL;
}
unsigned int plat_get_syscnt_freq2(void)
{
return COUNTER_FREQUENCY;
}
void bl31_plat_runtime_setup(void)
{
return;
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <cci.h>
#include <debug.h>
#include <gicv3.h>
#include <mmio.h>
#include <plat_imx8.h>
#include <psci.h>
#include <sci/sci.h>
#include <stdbool.h>
const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A53_0, SC_R_A53_1, SC_R_A53_2,
SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
};
/* need to enable USE_COHERENT_MEM to avoid coherence issue */
#if USE_COHERENT_MEM
static unsigned int a53_cpu_on_number __section("tzfw_coherent_mem");
static unsigned int a72_cpu_on_number __section("tzfw_coherent_mem");
#endif
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
unsigned int cluster_id, cpu_id;
cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
tf_printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
if (cluster_id == 0) {
if (a53_cpu_on_number == 0)
sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
ERROR("cluster0 core %d power on failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
true, BL31_BASE) != SC_ERR_NONE) {
ERROR("boot cluster0 core %d failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
} else {
if (a72_cpu_on_number == 0)
sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
ERROR(" cluster1 core %d power on failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4],
true, BL31_BASE) != SC_ERR_NONE) {
ERROR("boot cluster1 core %d failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
}
return ret;
}
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
uint64_t mpidr = read_mpidr_el1();
unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
if (cluster_id == 0 && a53_cpu_on_number++ == 0)
cci_enable_snoop_dvm_reqs(0);
if (cluster_id == 1 && a72_cpu_on_number++ == 0)
cci_enable_snoop_dvm_reqs(1);
plat_gic_pcpu_init();
plat_gic_cpuif_enable();
}
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
return PSCI_E_SUCCESS;
}
static const plat_psci_ops_t imx_plat_psci_ops = {
.pwr_domain_on = imx_pwr_domain_on,
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
uint64_t mpidr = read_mpidr_el1();
unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
if (cluster_id == 0)
a53_cpu_on_number++;
else
a72_cpu_on_number++;
return 0;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
#define PLATFORM_STACK_SIZE 0X400
#define CACHE_WRITEBACK_GRANULE 64
#define PLAT_PRIMARY_CPU 0x0
#define PLATFORM_MAX_CPU_PER_CLUSTER 4
#define PLATFORM_CLUSTER_COUNT 2
#define PLATFORM_CLUSTER0_CORE_COUNT 4
#define PLATFORM_CLUSTER1_CORE_COUNT 2
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \
PLATFORM_CLUSTER1_CORE_COUNT)
#define IMX_PWR_LVL0 MPIDR_AFFLVL0
#define IMX_PWR_LVL1 MPIDR_AFFLVL1
#define IMX_PWR_LVL2 MPIDR_AFFLVL2
#define PWR_DOMAIN_AT_MAX_LVL 1
#define PLAT_MAX_PWR_LVL 2
#define PLAT_MAX_OFF_STATE 2
#define PLAT_MAX_RET_STATE 1
#define BL31_BASE 0x80000000
#define BL31_LIMIT 0x80020000
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_SIZE 0xc0000
#define PLAT_CCI_BASE 0x52090000
#define PLAT_CCI_SIZE 0x10000
#define CLUSTER0_CCI_SLVAE_IFACE 3
#define CLUSTER1_CCI_SLVAE_IFACE 4
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_SIZE 0x10000
#define COUNTER_FREQUENCY 8000000 /* 8MHz */
/* non-secure uboot base */
#define PLAT_NS_IMAGE_OFFSET 0x80020000
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 12
#define DEBUG_CONSOLE 0
#define DEBUG_CONSOLE_A53 0
#define PLAT_IMX8QM 1

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* resources that are going to stay in secure partition */
sc_rsrc_t secure_rsrcs[] = {
SC_R_MU_0A,
SC_R_A53,
SC_R_A53_0,
SC_R_A53_1,
SC_R_A53_2,
SC_R_A53_3,
SC_R_A72,
SC_R_A72_0,
SC_R_A72_1,
SC_R_GIC,
SC_R_GIC_SMMU,
SC_R_CCI,
SC_R_SYSTEM,
SC_R_IRQSTR_SCU2
};
/* resources that have register access for non-secure domain */
sc_rsrc_t ns_access_allowed[] = {
SC_R_GIC,
SC_R_GIC_SMMU,
SC_R_CCI
};

View File

@ -0,0 +1,40 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
PLAT_INCLUDES := -Iplat/imx/imx8qm/include \
-Iplat/imx/common/include \
IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
drivers/arm/gic/v3/arm_gicv3_common.c \
drivers/arm/gic/v3/gic500.c \
drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/common/gic_common.c \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
plat/imx/common/plat_imx8_gic.c
BL31_SOURCES += plat/imx/common/lpuart_console.S \
plat/imx/common/imx8_helpers.S \
plat/imx/imx8qm/imx8qm_bl31_setup.c \
plat/imx/imx8qm/imx8qm_psci.c \
plat/imx/common/imx8_topology.c \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a72.S \
drivers/console/aarch64/console.S \
drivers/arm/cci/cci.c \
${IMX_GIC_SOURCES} \
include plat/imx/common/sci/sci_api.mk
ENABLE_PLAT_COMPAT := 0
USE_COHERENT_MEM := 1
RESET_TO_BL31 := 1
ARM_GIC_ARCH := 3
A53_DISABLE_NON_TEMPORAL_HINT := 0
MULTI_CONSOLE_API := 1
ERRATA_A72_859971 := 1

View File

@ -0,0 +1,342 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <cci.h>
#include <console.h>
#include <context.h>
#include <context_mgmt.h>
#include <debug.h>
#include <imx8qx_pads.h>
#include <imx8_iomux.h>
#include <imx8_lpuart.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <plat_imx8.h>
#include <sci/sci.h>
#include <sec_rsrc.h>
#include <stdbool.h>
#include <xlat_tables.h>
IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START);
IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END);
IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_START);
IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_END);
IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START);
IMPORT_SYM(unsigned long, __RW_END__, BL31_RW_END);
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
#define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
(SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
(SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
{0}
};
static uint32_t get_spsr_for_bl33_entry(void)
{
unsigned long el_status;
unsigned long mode;
uint32_t spsr;
/* figure out what mode we enter the non-secure world */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
el_status &= ID_AA64PFR0_ELX_MASK;
mode = (el_status) ? MODE_EL2 : MODE_EL1;
spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
return spsr;
}
#if DEBUG_CONSOLE_A35
static void lpuart32_serial_setbrg(unsigned int base, int baudrate)
{
unsigned int sbr, osr, baud_diff, tmp_osr, tmp_sbr;
unsigned int diff1, diff2, tmp, rate;
if (baudrate == 0)
panic();
sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
baud_diff = baudrate;
osr = 0;
sbr = 0;
for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
tmp_sbr = (rate / (baudrate * tmp_osr));
if (tmp_sbr == 0)
tmp_sbr = 1;
/* calculate difference in actual baud w/ current values */
diff1 = rate / (tmp_osr * tmp_sbr) - baudrate;
diff2 = rate / (tmp_osr * (tmp_sbr + 1));
/* select best values between sbr and sbr+1 */
if (diff1 > (baudrate - diff2)) {
diff1 = baudrate - diff2;
tmp_sbr++;
}
if (diff1 <= baud_diff) {
baud_diff = diff1;
osr = tmp_osr;
sbr = tmp_sbr;
}
}
tmp = mmio_read_32(IMX_BOOT_UART_BASE + BAUD);
if ((osr > 3) && (osr < 8))
tmp |= LPUART_BAUD_BOTHEDGE_MASK;
tmp &= ~LPUART_BAUD_OSR_MASK;
tmp |= LPUART_BAUD_OSR(osr - 1);
tmp &= ~LPUART_BAUD_SBR_MASK;
tmp |= LPUART_BAUD_SBR(sbr);
/* explicitly disable 10 bit mode & set 1 stop bit */
tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
mmio_write_32(IMX_BOOT_UART_BASE + BAUD, tmp);
}
static int lpuart32_serial_init(unsigned int base)
{
unsigned int tmp;
/* disable TX & RX before enabling clocks */
tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
tmp &= ~(CTRL_TE | CTRL_RE);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
mmio_write_32(IMX_BOOT_UART_BASE + MODIR, 0);
mmio_write_32(IMX_BOOT_UART_BASE + FIFO, ~(FIFO_TXFE | FIFO_RXFE));
mmio_write_32(IMX_BOOT_UART_BASE + MATCH, 0);
/* provide data bits, parity, stop bit, etc */
lpuart32_serial_setbrg(base, IMX_BOOT_UART_BAUDRATE);
/* eight data bits no parity bit */
tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
tmp &= ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
mmio_write_32(IMX_BOOT_UART_BASE + CTRL, CTRL_RE | CTRL_TE);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x0A);
return 0;
}
#endif
void imx8_partition_resources(void)
{
sc_rm_pt_t secure_part, os_part;
sc_rm_mr_t mr, mr_record = 64;
sc_faddr_t start, end;
sc_err_t err;
bool owned;
int i;
err = sc_rm_get_partition(ipc_handle, &secure_part);
if (err)
ERROR("sc_rm_get_partition failed: %u\n", err);
err = sc_rm_partition_alloc(ipc_handle, &os_part, false, false,
false, false, false);
if (err)
ERROR("sc_rm_partition_alloc failed: %u\n", err);
err = sc_rm_set_parent(ipc_handle, os_part, secure_part);
if (err)
ERROR("sc_rm_set_parent: %u\n", err);
/* set secure resources to NOT-movable */
for (i = 0; i < (ARRAY_SIZE(secure_rsrcs)); i++) {
err = sc_rm_set_resource_movable(ipc_handle,
secure_rsrcs[i], secure_rsrcs[i], false);
if (err)
ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
secure_rsrcs[i], err);
}
/* move all movable resources and pins to non-secure partition */
err = sc_rm_move_all(ipc_handle, secure_part, os_part, true, true);
if (err)
ERROR("sc_rm_move_all: %u\n", err);
/* iterate through peripherals to give NS OS part access */
for (i = 0; i < ARRAY_SIZE(ns_access_allowed); i++) {
err = sc_rm_set_peripheral_permissions(ipc_handle,
ns_access_allowed[i], os_part, SC_RM_PERM_FULL);
if (err)
ERROR("sc_rm_set_peripheral_permissions: rsrc %u, \
ret %u\n", ns_access_allowed[i], err);
}
/*
* sc_rm_set_peripheral_permissions
* sc_rm_set_memreg_permissions
* sc_rm_set_pin_movable
*/
for (mr = 0; mr < 64; mr++) {
owned = sc_rm_is_memreg_owned(ipc_handle, mr);
if (owned) {
err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
if (err)
ERROR("Memreg get info failed, %u\n", mr);
NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
mr_record = mr; /* Record the mr for ATF running */
} else {
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
err %d\n", start, end, err);
}
}
}
if (mr_record != 64) {
err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end);
if (err)
ERROR("Memreg get info failed, %u\n", mr_record);
if ((BL31_LIMIT - 1) < end) {
err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
if (err)
ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
(sc_faddr_t)BL31_LIMIT, end);
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
(sc_faddr_t)BL31_LIMIT, end);
}
if (start < (BL31_BASE - 1)) {
err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
if (err)
ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
start, (sc_faddr_t)BL31_BASE - 1);
err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
if (err)
ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
start, (sc_faddr_t)BL31_BASE - 1);
}
}
if (err)
NOTICE("Partitioning Failed\n");
else
NOTICE("Non-secure Partitioning Succeeded\n");
}
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
#if DEBUG_CONSOLE
static console_lpuart_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
#if DEBUG_CONSOLE_A35
sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON);
sc_pm_clock_rate_t rate = 80000000;
sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false);
/* Configure UART pads */
sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL);
sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL);
lpuart32_serial_init(IMX_BOOT_UART_BASE);
#endif
#if DEBUG_CONSOLE
console_lpuart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
#endif
/* Turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
/*
* create new partition for non-secure OS/Hypervisor
* uses global structs defined in sec_rsrc.h
*/
imx8_partition_resources();
bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
void bl31_plat_arch_setup(void)
{
unsigned long ro_start = BL31_RO_START;
unsigned long ro_size = BL31_RO_END - BL31_RO_START;
unsigned long rw_start = BL31_RW_START;
unsigned long rw_size = BL31_RW_END - BL31_RW_START;
#if USE_COHERENT_MEM
unsigned long coh_start = BL31_COHERENT_RAM_START;
unsigned long coh_size = BL31_COHERENT_RAM_END - BL31_COHERENT_RAM_START;
#endif
mmap_add_region(ro_start, ro_start, ro_size,
MT_RO | MT_MEMORY | MT_SECURE);
mmap_add_region(rw_start, rw_start, rw_size,
MT_RW | MT_MEMORY | MT_SECURE);
mmap_add(imx_mmap);
#if USE_COHERENT_MEM
mmap_add_region(coh_start, coh_start, coh_size,
MT_DEVICE | MT_RW | MT_SECURE);
#endif
init_xlat_tables();
enable_mmu_el3(0);
}
void bl31_platform_setup(void)
{
plat_gic_driver_init();
plat_gic_init();
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
{
if (type == NON_SECURE)
return &bl33_image_ep_info;
if (type == SECURE)
return &bl32_image_ep_info;
return NULL;
}
unsigned int plat_get_syscnt_freq2(void)
{
return COUNTER_FREQUENCY;
}
void bl31_plat_runtime_setup(void)
{
return;
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <debug.h>
#include <gicv3.h>
#include <mmio.h>
#include <plat_imx8.h>
#include <psci.h>
#include <sci/sci.h>
#include <stdbool.h>
const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
};
plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
const plat_local_state_t *target_state,
unsigned int ncpu)
{
return 0;
}
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
unsigned int cpu_id;
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
tf_printf("imx_pwr_domain_on cpu_id %d\n", cpu_id);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
ERROR("core %d power on failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
true, BL31_BASE) != SC_ERR_NONE) {
ERROR("boot core %d failed!\n", cpu_id);
ret = PSCI_E_INTERN_FAIL;
}
return ret;
}
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
plat_gic_pcpu_init();
plat_gic_cpuif_enable();
}
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
return PSCI_E_SUCCESS;
}
static const plat_psci_ops_t imx_plat_psci_ops = {
.pwr_domain_on = imx_pwr_domain_on,
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
return 0;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
#define PLATFORM_STACK_SIZE 0x400
#define CACHE_WRITEBACK_GRANULE 64
#define PLAT_PRIMARY_CPU 0x0
#define PLATFORM_MAX_CPU_PER_CLUSTER 4
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_CORE_COUNT 4
#define PWR_DOMAIN_AT_MAX_LVL 1
#define PLAT_MAX_PWR_LVL 2
#define PLAT_MAX_OFF_STATE 2
#define PLAT_MAX_RET_STATE 1
#define BL31_BASE 0x80000000
#define BL31_LIMIT 0x80020000
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 8
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_SIZE 0xc0000
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_SIZE 0x10000
#define COUNTER_FREQUENCY 8000000
/* non-secure u-boot base */
#define PLAT_NS_IMAGE_OFFSET 0x80020000
#define DEBUG_CONSOLE 0
#define DEBUG_CONSOLE_A35 0
#define PLAT_IMX8QX 1
#endif /* __PLATFORM_DEF_H__ */

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* resources that are going to stay in secure partition */
sc_rsrc_t secure_rsrcs[] = {
SC_R_MU_0A,
SC_R_A35,
SC_R_A35_0,
SC_R_A35_1,
SC_R_A35_2,
SC_R_A35_3,
SC_R_GIC,
SC_R_SYSTEM,
SC_R_IRQSTR_SCU2
};
/* resources that have register access for non-secure domain */
sc_rsrc_t ns_access_allowed[] = {
SC_R_GIC,
};

View File

@ -0,0 +1,35 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
PLAT_INCLUDES := -Iplat/imx/imx8qx/include \
-Iplat/imx/common/include \
IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
drivers/arm/gic/v3/arm_gicv3_common.c \
drivers/arm/gic/v3/gic500.c \
drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/common/gic_common.c \
plat/common/plat_gicv3.c \
plat/imx/common/plat_imx8_gic.c
BL31_SOURCES += plat/imx/common/lpuart_console.S \
plat/imx/common/imx8_helpers.S \
plat/imx/imx8qx/imx8qx_bl31_setup.c \
plat/imx/imx8qx/imx8qx_psci.c \
plat/imx/common/imx8_topology.c \
lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/cpus/aarch64/cortex_a35.S \
drivers/console/aarch64/console.S \
${IMX_GIC_SOURCES} \
include plat/imx/common/sci/sci_api.mk
ENABLE_PLAT_COMPAT := 0
USE_COHERENT_MEM := 1
RESET_TO_BL31 := 1
ARM_GIC_ARCH := 3
MULTI_CONSOLE_API := 1