mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00
Merge changes from topic "imx93_basic_support" into integration
* changes: docs(imx9): add imx93 platform feat(imx93): add OPTEE support feat(imx93): protect OPTEE memory to secure access only feat(imx93): add cpuidle and basic suspend support feat(imx93): add reset & poweroff support feat(imx93): allow SoC masters access to system TCM feat(imx93): update the ocram trdc config for did10 feat(imx93): add the basic support feat(imx93): add the trdc driver build(changelog): add new scopes for nxp imx platform
This commit is contained in:
commit
0e74b661ad
15 changed files with 1878 additions and 0 deletions
|
@ -406,6 +406,13 @@ subsections:
|
|||
- title: i.MX 8
|
||||
scope: imx8
|
||||
|
||||
- title: i.MX 9
|
||||
scope: imx9
|
||||
|
||||
subsections:
|
||||
- title: i.MX93
|
||||
scope: imx93
|
||||
|
||||
- title: Layerscape
|
||||
scope: layerscape
|
||||
|
||||
|
@ -1044,6 +1051,9 @@ subsections:
|
|||
- title: TZC-380
|
||||
scope: nxp-tzc380
|
||||
|
||||
- title: TRDC
|
||||
scope: imx-trdc
|
||||
|
||||
- title: Renesas
|
||||
scope: renesas-drivers
|
||||
|
||||
|
|
60
docs/plat/imx9.rst
Normal file
60
docs/plat/imx9.rst
Normal file
|
@ -0,0 +1,60 @@
|
|||
NXP i.MX 9 Series
|
||||
==================
|
||||
|
||||
Building on the market-proven i.MX 6 and i.MX 8 series, i.MX 9 series applications
|
||||
processors bring together higher performance applications cores, an independent
|
||||
MCU-like real-time domain, Energy Flex architecture, state-of-the-art security
|
||||
with EdgeLock® secure enclave and dedicated multi-sensory data processing engines
|
||||
(graphics, image, display, audio and voice). The i.MX 9 series, part of the EdgeVerse™
|
||||
edge computing platform, integrates hardware neural processing units across many
|
||||
members of the series for acceleration of machine learning applications at the edge
|
||||
`i.MX9 Applications Processors`_.
|
||||
|
||||
Boot Sequence
|
||||
-------------
|
||||
|
||||
BootROM --> SPL --> BL31 --> BL33(u-boot) --> Linux kernel
|
||||
|
||||
How to build
|
||||
------------
|
||||
|
||||
Build Procedure
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
- Prepare AARCH64 toolchain.
|
||||
|
||||
- Get the ELE FW image from NXP linux SDK package
|
||||
|
||||
- Build SPL and u-boot firstly, and get binary images: u-boot-spl.bin,
|
||||
u-boot.bin and dtb
|
||||
|
||||
- Build TF-A
|
||||
|
||||
Build bl31:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
|
||||
|
||||
Target_SoC should be "imx93" for i.MX93 SoC.
|
||||
|
||||
Deploy TF-A Images
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
TF-A binary(bl31.bin), u-boot-spl.bin u-boot.bin, ELE FW image 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.
|
||||
|
||||
Reference Documentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Details on how to prepare, generate & deploy the boot image be found in following documents:
|
||||
|
||||
- i.MX Linux User's Guide
|
||||
`link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
|
||||
- i.MX Linux Reference Manual
|
||||
`link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
|
||||
|
||||
.. _i.MX9 Applications Processors: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-9-processors:IMX9-PROCESSORS
|
||||
|
|
@ -27,6 +27,7 @@ Platform Ports
|
|||
warp7
|
||||
imx8
|
||||
imx8m
|
||||
imx9
|
||||
nxp/index
|
||||
poplar
|
||||
qemu
|
||||
|
|
365
drivers/nxp/trdc/imx_trdc.c
Normal file
365
drivers/nxp/trdc/imx_trdc.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/nxp/trdc/imx_trdc.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
|
||||
int trdc_mda_set_cpu(uintptr_t trdc_base, uint32_t mda_inst,
|
||||
uint32_t mda_reg, uint8_t sa, uint8_t dids,
|
||||
uint8_t did, uint8_t pe, uint8_t pidm, uint8_t pid)
|
||||
{
|
||||
uint32_t val = mmio_read_32(trdc_base + MDAC_W_X(mda_inst, mda_reg));
|
||||
/* invalid: config non-cpu master with cpu config format. */
|
||||
if ((val & MDA_DFMT) != 0U) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = MDA_VLD | MDA_DFMT0_DID(pid) | MDA_DFMT0_PIDM(pidm) | MDA_DFMT0_PE(pe) |
|
||||
MDA_DFMT0_SA(sa) | MDA_DFMT0_DIDS(dids) | MDA_DFMT0_DID(did);
|
||||
|
||||
mmio_write_32(trdc_base + MDAC_W_X(mda_inst, mda_reg), val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trdc_mda_set_noncpu(uintptr_t trdc_base, uint32_t mda_inst,
|
||||
bool did_bypass, uint8_t sa, uint8_t pa,
|
||||
uint8_t did)
|
||||
{
|
||||
uint32_t val = mmio_read_32(trdc_base + MDAC_W_X(mda_inst, 0));
|
||||
|
||||
/* invalid: config cpu master with non-cpu config format. */
|
||||
if ((val & MDA_DFMT) == 0U) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = MDA_VLD | MDA_DFMT1_SA(sa) | MDA_DFMT1_PA(pa) | MDA_DFMT1_DID(did) |
|
||||
MDA_DFMT1_DIDB(did_bypass ? 1U : 0U);
|
||||
|
||||
mmio_write_32(trdc_base + MDAC_W_X(mda_inst, 0), val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uintptr_t trdc_get_mbc_base(uintptr_t trdc_reg, uint32_t mbc_x)
|
||||
{
|
||||
struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
|
||||
uint32_t mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
|
||||
|
||||
if (mbc_x >= mbc_num) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return trdc_reg + 0x10000 + 0x2000 * mbc_x;
|
||||
}
|
||||
|
||||
static uintptr_t trdc_get_mrc_base(uintptr_t trdc_reg, uint32_t mrc_x)
|
||||
{
|
||||
struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
|
||||
uint32_t mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
|
||||
uint32_t mrc_num = MRC_NUM(trdc_base->trdc_hwcfg0);
|
||||
|
||||
if (mrc_x >= mrc_num) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return trdc_reg + 0x10000 + 0x2000 * mbc_num + 0x1000 * mrc_x;
|
||||
}
|
||||
|
||||
uint32_t trdc_mbc_blk_num(uintptr_t trdc_reg, uint32_t mbc_x, uint32_t mem_x)
|
||||
{
|
||||
uint32_t glbcfg;
|
||||
struct mbc_mem_dom *mbc_dom;
|
||||
struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
|
||||
|
||||
if (mbc_base == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only first dom has the glbcfg */
|
||||
mbc_dom = &mbc_base->mem_dom[0];
|
||||
glbcfg = mmio_read_32((uintptr_t)&mbc_dom->mem_glbcfg[mem_x]);
|
||||
|
||||
return MBC_BLK_NUM(glbcfg);
|
||||
}
|
||||
|
||||
uint32_t trdc_mrc_rgn_num(uintptr_t trdc_reg, uint32_t mrc_x)
|
||||
{
|
||||
uint32_t glbcfg;
|
||||
struct mrc_rgn_dom *mrc_dom;
|
||||
struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
|
||||
|
||||
if (mrc_base == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only first dom has the glbcfg */
|
||||
mrc_dom = &mrc_base->mrc_dom[0];
|
||||
glbcfg = mmio_read_32((uintptr_t)&mrc_dom->mrc_glbcfg[0]);
|
||||
|
||||
return MBC_BLK_NUM(glbcfg);
|
||||
}
|
||||
|
||||
int trdc_mbc_set_control(uintptr_t trdc_reg, uint32_t mbc_x,
|
||||
uint32_t glbac_id, uint32_t glbac_val)
|
||||
{
|
||||
struct mbc_mem_dom *mbc_dom;
|
||||
struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
|
||||
|
||||
if (mbc_base == NULL || glbac_id >= GLBAC_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* only first dom has the glbac */
|
||||
mbc_dom = &mbc_base->mem_dom[0];
|
||||
|
||||
mmio_write_32((uintptr_t)&mbc_dom->memn_glbac[glbac_id], glbac_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trdc_mbc_blk_config(uintptr_t trdc_reg, uint32_t mbc_x,
|
||||
uint32_t dom_x, uint32_t mem_x, uint32_t blk_x,
|
||||
bool sec_access, uint32_t glbac_id)
|
||||
{
|
||||
uint32_t *cfg_w;
|
||||
uint32_t index, offset, val;
|
||||
struct mbc_mem_dom *mbc_dom;
|
||||
struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
|
||||
|
||||
if (mbc_base == NULL || glbac_id >= GLBAC_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mbc_dom = &mbc_base->mem_dom[dom_x];
|
||||
|
||||
switch (mem_x) {
|
||||
case 0:
|
||||
cfg_w = &mbc_dom->mem0_blk_cfg_w[blk_x / 8];
|
||||
break;
|
||||
case 1:
|
||||
cfg_w = &mbc_dom->mem1_blk_cfg_w[blk_x / 8];
|
||||
break;
|
||||
case 2:
|
||||
cfg_w = &mbc_dom->mem2_blk_cfg_w[blk_x / 8];
|
||||
break;
|
||||
case 3:
|
||||
cfg_w = &mbc_dom->mem3_blk_cfg_w[blk_x / 8];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
index = blk_x % 8;
|
||||
offset = index * 4;
|
||||
|
||||
val = mmio_read_32((uintptr_t)cfg_w);
|
||||
val &= ~(0xF << offset);
|
||||
|
||||
/*
|
||||
* MBC0-3
|
||||
* Global 0, 0x7777 secure pri/user read/write/execute,
|
||||
* S400 has already set it. So select MBC0_MEMN_GLBAC0
|
||||
*/
|
||||
if (sec_access) {
|
||||
val |= ((0x0 | (glbac_id & 0x7)) << offset);
|
||||
mmio_write_32((uintptr_t)cfg_w, val);
|
||||
} else {
|
||||
/* nse bit set */
|
||||
val |= ((0x8 | (glbac_id & 0x7)) << offset);
|
||||
mmio_write_32((uintptr_t)cfg_w, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trdc_mrc_set_control(uintptr_t trdc_reg, uint32_t mrc_x,
|
||||
uint32_t glbac_id, uint32_t glbac_val)
|
||||
{
|
||||
struct mrc_rgn_dom *mrc_dom;
|
||||
struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
|
||||
|
||||
if (mrc_base == NULL || glbac_id >= GLBAC_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* only first dom has the glbac */
|
||||
mrc_dom = &mrc_base->mrc_dom[0];
|
||||
|
||||
mmio_write_32((uintptr_t)&mrc_dom->memn_glbac[glbac_id], glbac_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trdc_mrc_rgn_config(uintptr_t trdc_reg, uint32_t mrc_x,
|
||||
uint32_t dom_x, uint32_t rgn_id,
|
||||
uint32_t addr_start, uint32_t addr_size,
|
||||
bool sec_access, uint32_t glbac_id)
|
||||
{
|
||||
uint32_t *desc_w;
|
||||
uint32_t addr_end;
|
||||
struct mrc_rgn_dom *mrc_dom;
|
||||
struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
|
||||
|
||||
if (mrc_base == NULL || glbac_id >= GLBAC_NUM || rgn_id >= MRC_REG_ALL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mrc_dom = &mrc_base->mrc_dom[dom_x];
|
||||
|
||||
addr_end = addr_start + addr_size - 1;
|
||||
addr_start &= ~0x3fff;
|
||||
addr_end &= ~0x3fff;
|
||||
|
||||
desc_w = &mrc_dom->rgn_desc_words[rgn_id][0];
|
||||
|
||||
if (sec_access) {
|
||||
mmio_write_32((uintptr_t)desc_w, addr_start | (glbac_id & 0x7));
|
||||
mmio_write_32((uintptr_t)(desc_w + 1), addr_end | 0x1);
|
||||
} else {
|
||||
mmio_write_32((uintptr_t)desc_w, addr_start | (glbac_id & 0x7));
|
||||
mmio_write_32((uintptr_t)(desc_w + 1), (addr_end | 0x1 | 0x10));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool trdc_mrc_enabled(uintptr_t mrc_base)
|
||||
{
|
||||
return (mmio_read_32(mrc_base) & BIT(15));
|
||||
}
|
||||
|
||||
bool trdc_mbc_enabled(uintptr_t mbc_base)
|
||||
{
|
||||
return (mmio_read_32(mbc_base) & BIT(14));
|
||||
}
|
||||
|
||||
static bool is_trdc_mgr_slot(uintptr_t trdc_base, uint8_t mbc_id,
|
||||
uint8_t mem_id, uint16_t blk_id)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0U; i < trdc_mgr_num; i++) {
|
||||
if (trdc_mgr_blks[i].trdc_base == trdc_base) {
|
||||
if (mbc_id == trdc_mgr_blks[i].mbc_id &&
|
||||
mem_id == trdc_mgr_blks[i].mbc_mem_id &&
|
||||
(blk_id == trdc_mgr_blks[i].blk_mgr ||
|
||||
blk_id == trdc_mgr_blks[i].blk_mc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* config the TRDC MGR & MC's access policy. only the secure privilege
|
||||
* mode SW can access it.
|
||||
*/
|
||||
void trdc_mgr_mbc_setup(struct trdc_mgr_info *mgr)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* If the MBC is global enabled, need to cconfigure the MBCs of
|
||||
* TRDC MGR & MC correctly.
|
||||
*/
|
||||
if (trdc_mbc_enabled(mgr->trdc_base)) {
|
||||
/* ONLY secure privilige can access */
|
||||
trdc_mbc_set_control(mgr->trdc_base, mgr->mbc_id, 7, 0x6000);
|
||||
for (i = 0U; i < 16U; i++) {
|
||||
trdc_mbc_blk_config(mgr->trdc_base, mgr->mbc_id, i,
|
||||
mgr->mbc_mem_id, mgr->blk_mgr, true, 7);
|
||||
|
||||
trdc_mbc_blk_config(mgr->trdc_base, mgr->mbc_id, i,
|
||||
mgr->mbc_mem_id, mgr->blk_mc, true, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the TRDC access policy for all the resources under
|
||||
* the TRDC control.
|
||||
*/
|
||||
void trdc_setup(struct trdc_config_info *cfg)
|
||||
{
|
||||
unsigned int i, j, num;
|
||||
bool is_mgr;
|
||||
|
||||
/* config the MRCs */
|
||||
if (trdc_mrc_enabled(cfg->trdc_base)) {
|
||||
/* set global access policy */
|
||||
for (i = 0U; i < cfg->num_mrc_glbac; i++) {
|
||||
trdc_mrc_set_control(cfg->trdc_base,
|
||||
cfg->mrc_glbac[i].mbc_mrc_id,
|
||||
cfg->mrc_glbac[i].glbac_id,
|
||||
cfg->mrc_glbac[i].glbac_val);
|
||||
}
|
||||
|
||||
/* set each MRC region access policy */
|
||||
for (i = 0U; i < cfg->num_mrc_cfg; i++) {
|
||||
trdc_mrc_rgn_config(cfg->trdc_base, cfg->mrc_cfg[i].mrc_id,
|
||||
cfg->mrc_cfg[i].dom_id,
|
||||
cfg->mrc_cfg[i].region_id,
|
||||
cfg->mrc_cfg[i].region_start,
|
||||
cfg->mrc_cfg[i].region_size,
|
||||
cfg->mrc_cfg[i].secure,
|
||||
cfg->mrc_cfg[i].glbac_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* config the MBCs */
|
||||
if (trdc_mbc_enabled(cfg->trdc_base)) {
|
||||
/* set MBC global access policy */
|
||||
for (i = 0U; i < cfg->num_mbc_glbac; i++) {
|
||||
trdc_mbc_set_control(cfg->trdc_base,
|
||||
cfg->mbc_glbac[i].mbc_mrc_id,
|
||||
cfg->mbc_glbac[i].glbac_id,
|
||||
cfg->mbc_glbac[i].glbac_val);
|
||||
}
|
||||
|
||||
for (i = 0U; i < cfg->num_mbc_cfg; i++) {
|
||||
if (cfg->mbc_cfg[i].blk_id == MBC_BLK_ALL) {
|
||||
num = trdc_mbc_blk_num(cfg->trdc_base,
|
||||
cfg->mbc_cfg[i].mbc_id,
|
||||
cfg->mbc_cfg[i].mem_id);
|
||||
|
||||
for (j = 0U; j < num; j++) {
|
||||
/* Skip mgr and mc */
|
||||
is_mgr = is_trdc_mgr_slot(cfg->trdc_base,
|
||||
cfg->mbc_cfg[i].mbc_id,
|
||||
cfg->mbc_cfg[i].mem_id, j);
|
||||
if (is_mgr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
trdc_mbc_blk_config(cfg->trdc_base,
|
||||
cfg->mbc_cfg[i].mbc_id,
|
||||
cfg->mbc_cfg[i].dom_id,
|
||||
cfg->mbc_cfg[i].mem_id, j,
|
||||
cfg->mbc_cfg[i].secure,
|
||||
cfg->mbc_cfg[i].glbac_id);
|
||||
}
|
||||
} else {
|
||||
trdc_mbc_blk_config(cfg->trdc_base,
|
||||
cfg->mbc_cfg[i].mbc_id,
|
||||
cfg->mbc_cfg[i].dom_id,
|
||||
cfg->mbc_cfg[i].mem_id,
|
||||
cfg->mbc_cfg[i].blk_id,
|
||||
cfg->mbc_cfg[i].secure,
|
||||
cfg->mbc_cfg[i].glbac_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
172
include/drivers/nxp/trdc/imx_trdc.h
Normal file
172
include/drivers/nxp/trdc/imx_trdc.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IMX_TRDC_H
|
||||
#define IMX_XRDC_H
|
||||
|
||||
#define MBC_BLK_ALL U(255)
|
||||
#define MRC_REG_ALL U(16)
|
||||
#define GLBAC_NUM U(8)
|
||||
|
||||
#define DID_NUM U(16)
|
||||
#define MBC_MAX_NUM U(4)
|
||||
#define MRC_MAX_NUM U(2)
|
||||
#define MBC_NUM(HWCFG) (((HWCFG) >> 16) & 0xF)
|
||||
#define MRC_NUM(HWCFG) (((HWCFG) >> 24) & 0x1F)
|
||||
|
||||
#define MBC_BLK_NUM(GLBCFG) ((GLBCFG) & 0x3FF)
|
||||
#define MRC_RGN_NUM(GLBCFG) ((GLBCFG) & 0x1F)
|
||||
|
||||
#define MDAC_W_X(m, r) (0x800 + (m) * 0x20 + (r) * 0x4)
|
||||
|
||||
/* CPU/non-CPU domain common bits */
|
||||
#define MDA_VLD BIT(31)
|
||||
#define MDA_LK1 BIT(30)
|
||||
#define MDA_DFMT BIT(29)
|
||||
|
||||
/* CPU domain bits */
|
||||
#define MDA_DFMT0_DID(x) ((x) & 0xF)
|
||||
#define MDA_DFMT0_DIDS(x) (((x) & 0x3) << 4)
|
||||
#define MDA_DFMT0_PE(x) (((x) & 0x3) << 6)
|
||||
#define MDA_DFMT0_PIDM(x) (((x) & 0x3F) << 8)
|
||||
#define MDA_DFMT0_SA(x) (((x) & 0x3) << 14)
|
||||
#define MDA_DFMT0_PID(x) (((x) & 0x3F) << 16)
|
||||
|
||||
/* non-CPU domain bits */
|
||||
#define MDA_DFMT1_DID(x) ((x) & 0xF)
|
||||
#define MDA_DFMT1_PA(x) (((x) & 0x3) << 4)
|
||||
#define MDA_DFMT1_SA(x) (((x) & 0x3) << 6)
|
||||
#define MDA_DFMT1_DIDB(x) ((x) << 8)
|
||||
|
||||
#define SP(X) ((X) << 12)
|
||||
#define SU(X) ((X) << 8)
|
||||
#define NP(X) ((X) << 4)
|
||||
#define NU(X) ((X) << 0)
|
||||
|
||||
#define RWX U(7)
|
||||
#define RW U(6)
|
||||
#define RX U(5)
|
||||
#define R U(4)
|
||||
#define X U(1)
|
||||
|
||||
struct mbc_mem_dom {
|
||||
uint32_t mem_glbcfg[4];
|
||||
uint32_t nse_blk_index;
|
||||
uint32_t nse_blk_set;
|
||||
uint32_t nse_blk_clr;
|
||||
uint32_t nsr_blk_clr_all;
|
||||
uint32_t memn_glbac[8];
|
||||
/* The upper only existed in the beginning of each MBC */
|
||||
uint32_t mem0_blk_cfg_w[64];
|
||||
uint32_t mem0_blk_nse_w[16];
|
||||
uint32_t mem1_blk_cfg_w[8];
|
||||
uint32_t mem1_blk_nse_w[2];
|
||||
uint32_t mem2_blk_cfg_w[8];
|
||||
uint32_t mem2_blk_nse_w[2];
|
||||
uint32_t mem3_blk_cfg_w[8];
|
||||
uint32_t mem3_blk_nse_w[2]; /*0x1F0, 0x1F4 */
|
||||
uint32_t reserved[2];
|
||||
};
|
||||
|
||||
struct mrc_rgn_dom {
|
||||
uint32_t mrc_glbcfg[4];
|
||||
uint32_t nse_rgn_indirect;
|
||||
uint32_t nse_rgn_set;
|
||||
uint32_t nse_rgn_clr;
|
||||
uint32_t nse_rgn_clr_all;
|
||||
uint32_t memn_glbac[8];
|
||||
/* The upper only existed in the beginning of each MRC */
|
||||
uint32_t rgn_desc_words[16][2]; /* 16 regions at max, 2 words per region */
|
||||
uint32_t rgn_nse;
|
||||
uint32_t reserved2[15];
|
||||
};
|
||||
|
||||
struct mda_inst {
|
||||
uint32_t mda_w[8];
|
||||
};
|
||||
|
||||
struct trdc_mgr {
|
||||
uint32_t trdc_cr;
|
||||
uint32_t res0[59];
|
||||
uint32_t trdc_hwcfg0;
|
||||
uint32_t trdc_hwcfg1;
|
||||
uint32_t res1[450];
|
||||
struct mda_inst mda[128];
|
||||
};
|
||||
|
||||
struct trdc_mbc {
|
||||
struct mbc_mem_dom mem_dom[DID_NUM];
|
||||
};
|
||||
|
||||
struct trdc_mrc {
|
||||
struct mrc_rgn_dom mrc_dom[DID_NUM];
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
* Below structs used fro provding the TRDC configuration info
|
||||
* that will be used to init the TRDC based on use case.
|
||||
***************************************************************/
|
||||
struct trdc_glbac_config {
|
||||
uint8_t mbc_mrc_id;
|
||||
uint8_t glbac_id;
|
||||
uint32_t glbac_val;
|
||||
};
|
||||
|
||||
struct trdc_mbc_config {
|
||||
uint8_t mbc_id;
|
||||
uint8_t dom_id;
|
||||
uint8_t mem_id;
|
||||
uint8_t blk_id;
|
||||
uint8_t glbac_id;
|
||||
bool secure;
|
||||
};
|
||||
|
||||
struct trdc_mrc_config {
|
||||
uint8_t mrc_id;
|
||||
uint8_t dom_id;
|
||||
uint8_t region_id;
|
||||
uint32_t region_start;
|
||||
uint32_t region_size;
|
||||
uint8_t glbac_id;
|
||||
bool secure;
|
||||
};
|
||||
|
||||
struct trdc_mgr_info {
|
||||
uintptr_t trdc_base;
|
||||
uint8_t mbc_id;
|
||||
uint8_t mbc_mem_id;
|
||||
uint8_t blk_mgr;
|
||||
uint8_t blk_mc;
|
||||
};
|
||||
|
||||
struct trdc_config_info {
|
||||
uintptr_t trdc_base;
|
||||
struct trdc_glbac_config *mbc_glbac;
|
||||
uint32_t num_mbc_glbac;
|
||||
struct trdc_mbc_config *mbc_cfg;
|
||||
uint32_t num_mbc_cfg;
|
||||
struct trdc_glbac_config *mrc_glbac;
|
||||
uint32_t num_mrc_glbac;
|
||||
struct trdc_mrc_config *mrc_cfg;
|
||||
uint32_t num_mrc_cfg;
|
||||
};
|
||||
|
||||
extern struct trdc_mgr_info trdc_mgr_blks[];
|
||||
extern unsigned int trdc_mgr_num;
|
||||
/* APIs to apply and enable TRDC */
|
||||
int trdc_mda_set_cpu(uintptr_t trdc_base, uint32_t mda_inst,
|
||||
uint32_t mda_reg, uint8_t sa, uint8_t dids,
|
||||
uint8_t did, uint8_t pe, uint8_t pidm, uint8_t pid);
|
||||
|
||||
int trdc_mda_set_noncpu(uintptr_t trdc_base, uint32_t mda_inst,
|
||||
bool did_bypass, uint8_t sa, uint8_t pa,
|
||||
uint8_t did);
|
||||
|
||||
void trdc_mgr_mbc_setup(struct trdc_mgr_info *mgr);
|
||||
void trdc_setup(struct trdc_config_info *cfg);
|
||||
void trdc_config(void);
|
||||
|
||||
#endif /* IMX_TRDC_H */
|
74
plat/imx/imx93/aarch64/plat_helpers.S
Normal file
74
plat/imx/imx93/aarch64/plat_helpers.S
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
#include <cortex_a55.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl plat_my_core_pos
|
||||
.globl plat_calc_core_pos
|
||||
.globl platform_mem_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
|
||||
|
||||
/* ----------------------------------------------
|
||||
* 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
|
||||
mov_imm x1, MPIDR_AFFINITY_MASK
|
||||
and x0, x0, x1
|
||||
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
|
||||
mov x1, #MPIDR_AFFLVL_MASK
|
||||
and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
|
||||
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
|
||||
mov x1, #MPIDR_AFFLVL_MASK
|
||||
and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
|
||||
ret
|
||||
endfunc plat_calc_core_pos
|
||||
|
||||
func platform_mem_init
|
||||
ret
|
||||
endfunc platform_mem_init
|
160
plat/imx/imx93/imx93_bl31_setup.c
Normal file
160
plat/imx/imx93/imx93_bl31_setup.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <context.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/nxp/trdc/imx_trdc.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <imx8_lpuart.h>
|
||||
#include <plat_imx8.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#define MAP_BL31_TOTAL \
|
||||
MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
|
||||
#define MAP_BL31_RO \
|
||||
MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
|
||||
|
||||
static const mmap_region_t imx_mmap[] = {
|
||||
AIPS1_MAP, AIPS2_MAP, AIPS4_MAP, GIC_MAP,
|
||||
TRDC_A_MAP, TRDC_W_MAP, TRDC_M_MAP,
|
||||
TRDC_N_MAP,
|
||||
{0},
|
||||
};
|
||||
|
||||
static entry_point_info_t bl32_image_ep_info;
|
||||
static entry_point_info_t bl33_image_ep_info;
|
||||
|
||||
/* get SPSR for BL33 entry */
|
||||
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;
|
||||
}
|
||||
|
||||
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
{
|
||||
static console_t console;
|
||||
|
||||
console_lpuart_register(IMX_LPUART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
|
||||
IMX_CONSOLE_BAUDRATE, &console);
|
||||
|
||||
/* This console is only used for boot stage */
|
||||
console_set_scope(&console, CONSOLE_FLAG_BOOT);
|
||||
|
||||
/*
|
||||
* tell BL3-1 where the non-secure software image is located
|
||||
* and the entry state information.
|
||||
*/
|
||||
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);
|
||||
|
||||
#if defined(SPD_opteed)
|
||||
/* Populate entry point information for BL32 */
|
||||
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
|
||||
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
|
||||
bl32_image_ep_info.pc = BL32_BASE;
|
||||
bl32_image_ep_info.spsr = 0;
|
||||
|
||||
/* Pass TEE base and size to bl33 */
|
||||
bl33_image_ep_info.args.arg1 = BL32_BASE;
|
||||
bl33_image_ep_info.args.arg2 = BL32_SIZE;
|
||||
|
||||
/* Make sure memory is clean */
|
||||
mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
|
||||
bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
|
||||
bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bl31_plat_arch_setup(void)
|
||||
{
|
||||
/* no coherence memory support on i.MX9 */
|
||||
const mmap_region_t bl_regions[] = {
|
||||
MAP_BL31_TOTAL,
|
||||
MAP_BL31_RO,
|
||||
};
|
||||
|
||||
/* Assign all the GPIO pins to non-secure world by default */
|
||||
mmio_write_32(GPIO2_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(GPIO2_BASE + 0x14, 0x3);
|
||||
mmio_write_32(GPIO2_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(GPIO2_BASE + 0x1c, 0x3);
|
||||
|
||||
mmio_write_32(GPIO3_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(GPIO3_BASE + 0x14, 0x3);
|
||||
mmio_write_32(GPIO3_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(GPIO3_BASE + 0x1c, 0x3);
|
||||
|
||||
mmio_write_32(GPIO4_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(GPIO4_BASE + 0x14, 0x3);
|
||||
mmio_write_32(GPIO4_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(GPIO4_BASE + 0x1c, 0x3);
|
||||
|
||||
mmio_write_32(GPIO1_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(GPIO1_BASE + 0x14, 0x3);
|
||||
mmio_write_32(GPIO1_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(GPIO1_BASE + 0x1c, 0x3);
|
||||
|
||||
setup_page_tables(bl_regions, imx_mmap);
|
||||
enable_mmu_el3(0);
|
||||
|
||||
/* trdc must be initialized */
|
||||
trdc_config();
|
||||
}
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
generic_delay_timer_init();
|
||||
|
||||
plat_gic_driver_init();
|
||||
plat_gic_init();
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
console_switch_state(CONSOLE_FLAG_RUNTIME);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
253
plat/imx/imx93/imx93_psci.c
Normal file
253
plat/imx/imx93/imx93_psci.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/psci/psci.h>
|
||||
|
||||
#include <plat_imx8.h>
|
||||
#include <pwr_ctrl.h>
|
||||
|
||||
#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
|
||||
#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
|
||||
#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
|
||||
|
||||
/* platform secure warm boot entry */
|
||||
static uintptr_t secure_entrypoint;
|
||||
|
||||
static bool boot_stage = true;
|
||||
|
||||
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
|
||||
{
|
||||
/* The non-secure entrypoint should be in RAM space */
|
||||
if (ns_entrypoint < PLAT_NS_IMAGE_OFFSET) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
int imx_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state)
|
||||
{
|
||||
int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
|
||||
int pwr_type = psci_get_pstate_type(power_state);
|
||||
int state_id = psci_get_pstate_id(power_state);
|
||||
|
||||
if (pwr_lvl > PLAT_MAX_PWR_LVL) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
if (pwr_type == PSTATE_TYPE_STANDBY) {
|
||||
CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
|
||||
CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
|
||||
}
|
||||
|
||||
if (pwr_type == PSTATE_TYPE_POWERDOWN && state_id == 0x33) {
|
||||
CORE_PWR_STATE(req_state) = PLAT_MAX_OFF_STATE;
|
||||
CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void imx_set_cpu_boot_entry(unsigned int core_id, uint64_t boot_entry)
|
||||
{
|
||||
/* set the cpu core reset entry: BLK_CTRL_S */
|
||||
mmio_write_32(BLK_CTRL_S_BASE + CA55_RVBADDR0_L + core_id * 8, boot_entry >> 2);
|
||||
}
|
||||
|
||||
int imx_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
unsigned int core_id;
|
||||
|
||||
core_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
|
||||
imx_set_cpu_boot_entry(core_id, secure_entrypoint);
|
||||
|
||||
/*
|
||||
* When the core is first time boot up, the core is already ON after SoC POR,
|
||||
* So 'SW_WAKEUP' can not work, so need to toggle core's reset then release
|
||||
* the core from cpu_wait.
|
||||
*/
|
||||
if (boot_stage) {
|
||||
/* assert CPU core SW reset */
|
||||
mmio_clrbits_32(SRC_SLICE(SRC_A55C0 + core_id) + 0x24, BIT(2) | BIT(0));
|
||||
/* deassert CPU core SW reset */
|
||||
mmio_setbits_32(SRC_SLICE(SRC_A55C0 + core_id) + 0x24, BIT(2) | BIT(0));
|
||||
/* release the cpuwait to kick the cpu */
|
||||
mmio_clrbits_32(BLK_CTRL_S_BASE + CA55_CPUWAIT, BIT(core_id));
|
||||
} else {
|
||||
/* assert the CMC MISC SW WAKEUP BIT to kick the offline core */
|
||||
gpc_assert_sw_wakeup(CPU_A55C0 + core_id);
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint64_t mpidr = read_mpidr_el1();
|
||||
unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
|
||||
plat_gic_pcpu_init();
|
||||
plat_gic_cpuif_enable();
|
||||
|
||||
/* below config is ok both for boot & hotplug */
|
||||
/* clear the CPU power mode */
|
||||
gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_RUN);
|
||||
/* clear the SW wakeup */
|
||||
gpc_deassert_sw_wakeup(CPU_A55C0 + core_id);
|
||||
/* switch to GIC wakeup source */
|
||||
gpc_select_wakeup_gic(CPU_A55C0 + core_id);
|
||||
|
||||
if (boot_stage) {
|
||||
/* SRC config */
|
||||
/* config the MEM LPM */
|
||||
src_mem_lpm_en(SRC_A55P0_MEM + core_id, MEM_OFF);
|
||||
/* LPM config to only ON in run mode to its domain */
|
||||
src_mix_set_lpm(SRC_A55C0 + core_id, core_id, CM_MODE_WAIT);
|
||||
/* white list config, only enable its own domain */
|
||||
src_authen_config(SRC_A55C0 + core_id, 1 << core_id, 0x1);
|
||||
|
||||
boot_stage = false;
|
||||
}
|
||||
}
|
||||
|
||||
void imx_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint64_t mpidr = read_mpidr_el1();
|
||||
unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
unsigned int i;
|
||||
|
||||
plat_gic_cpuif_disable();
|
||||
write_clusterpwrdn(DSU_CLUSTER_PWR_OFF);
|
||||
|
||||
/*
|
||||
* mask all the GPC IRQ wakeup to make sure no IRQ can wakeup this core
|
||||
* as we need to use SW_WAKEUP for hotplug purpose
|
||||
*/
|
||||
for (i = 0U; i < IMR_NUM; i++) {
|
||||
gpc_set_irq_mask(CPU_A55C0 + core_id, i, 0xffffffff);
|
||||
}
|
||||
/* switch to GPC wakeup source */
|
||||
gpc_select_wakeup_raw_irq(CPU_A55C0 + core_id);
|
||||
/* config the target mode to suspend */
|
||||
gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_SUSPEND);
|
||||
}
|
||||
|
||||
void imx_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint64_t mpidr = read_mpidr_el1();
|
||||
unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
|
||||
/* do cpu level config */
|
||||
if (is_local_state_off(CORE_PWR_STATE(target_state))) {
|
||||
plat_gic_cpuif_disable();
|
||||
imx_set_cpu_boot_entry(core_id, secure_entrypoint);
|
||||
/* config the target mode to WAIT */
|
||||
gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_WAIT);
|
||||
}
|
||||
|
||||
/* do cluster level config */
|
||||
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
|
||||
/* config the A55 cluster target mode to WAIT */
|
||||
gpc_set_cpu_mode(CPU_A55_PLAT, CM_MODE_WAIT);
|
||||
|
||||
/* config DSU for cluster power down with L3 MEM RET */
|
||||
if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) {
|
||||
write_clusterpwrdn(DSU_CLUSTER_PWR_OFF | BIT(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imx_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint64_t mpidr = read_mpidr_el1();
|
||||
unsigned int core_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
|
||||
/* cluster level */
|
||||
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
|
||||
/* set the cluster's target mode to RUN */
|
||||
gpc_set_cpu_mode(CPU_A55_PLAT, CM_MODE_RUN);
|
||||
}
|
||||
|
||||
/* do core level */
|
||||
if (is_local_state_off(CORE_PWR_STATE(target_state))) {
|
||||
/* set A55 CORE's power mode to RUN */
|
||||
gpc_set_cpu_mode(CPU_A55C0 + core_id, CM_MODE_RUN);
|
||||
plat_gic_cpuif_enable();
|
||||
}
|
||||
}
|
||||
|
||||
void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
|
||||
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
|
||||
}
|
||||
|
||||
SYSTEM_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
|
||||
CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
|
||||
}
|
||||
|
||||
void __dead2 imx_system_reset(void)
|
||||
{
|
||||
mmio_write_32(WDOG3_BASE + WDOG_CNT, 0xd928c520);
|
||||
while ((mmio_read_32(WDOG3_BASE + WDOG_CS) & WDOG_CS_ULK) == 0U) {
|
||||
;
|
||||
}
|
||||
|
||||
mmio_write_32(WDOG3_BASE + WDOG_TOVAL, 0x10);
|
||||
mmio_write_32(WDOG3_BASE + WDOG_CS, 0x21e3);
|
||||
|
||||
while (1) {
|
||||
wfi();
|
||||
}
|
||||
}
|
||||
|
||||
void __dead2 imx_system_off(void)
|
||||
{
|
||||
mmio_setbits_32(BBNSM_BASE + BBNSM_CTRL, BBNSM_DP_EN | BBNSM_TOSP);
|
||||
|
||||
while (1) {
|
||||
wfi();
|
||||
}
|
||||
}
|
||||
|
||||
static const plat_psci_ops_t imx_plat_psci_ops = {
|
||||
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
|
||||
.validate_power_state = imx_validate_power_state,
|
||||
.pwr_domain_on = imx_pwr_domain_on,
|
||||
.pwr_domain_off = imx_pwr_domain_off,
|
||||
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
|
||||
.pwr_domain_suspend = imx_pwr_domain_suspend,
|
||||
.pwr_domain_suspend_finish = imx_pwr_domain_suspend_finish,
|
||||
.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
|
||||
.system_reset = imx_system_reset,
|
||||
.system_off = imx_system_off,
|
||||
};
|
||||
|
||||
/* export the platform specific psci ops */
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
/* sec_entrypoint is used for warm reset */
|
||||
secure_entrypoint = sec_entrypoint;
|
||||
imx_set_cpu_boot_entry(0, sec_entrypoint);
|
||||
|
||||
pwr_sys_init();
|
||||
|
||||
*psci_ops = &imx_plat_psci_ops;
|
||||
|
||||
return 0;
|
||||
}
|
97
plat/imx/imx93/include/platform_def.h
Normal file
97
plat/imx/imx93/include/platform_def.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef PLATFORM_DEF_H
|
||||
#define PLATFORM_DEF_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
|
||||
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
|
||||
#define PLATFORM_LINKER_ARCH aarch64
|
||||
|
||||
#define PLATFORM_STACK_SIZE 0xB00
|
||||
#define CACHE_WRITEBACK_GRANULE 64
|
||||
|
||||
#define PLAT_PRIMARY_CPU U(0x0)
|
||||
#define PLATFORM_MAX_CPU_PER_CLUSTER U(2)
|
||||
#define PLATFORM_CLUSTER_COUNT U(1)
|
||||
#define PLATFORM_CLUSTER0_CORE_COUNT U(2)
|
||||
#define PLATFORM_CORE_COUNT U(2)
|
||||
|
||||
#define IMX_PWR_LVL0 MPIDR_AFFLVL0
|
||||
|
||||
#define PWR_DOMAIN_AT_MAX_LVL U(1)
|
||||
#define PLAT_MAX_PWR_LVL U(2)
|
||||
#define PLAT_MAX_OFF_STATE U(4)
|
||||
#define PLAT_MAX_RET_STATE U(2)
|
||||
|
||||
#define BL31_BASE U(0x204E0000)
|
||||
#define BL31_LIMIT U(0x20520000)
|
||||
|
||||
/* non-secure uboot base */
|
||||
/* TODO */
|
||||
#define PLAT_NS_IMAGE_OFFSET U(0x80200000)
|
||||
#define BL32_FDT_OVERLAY_ADDR (PLAT_NS_IMAGE_OFFSET + 0x3000000)
|
||||
|
||||
/* GICv4 base address */
|
||||
#define PLAT_GICD_BASE U(0x48000000)
|
||||
#define PLAT_GICR_BASE U(0x48040000)
|
||||
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
|
||||
#define MAX_XLAT_TABLES 8
|
||||
#define MAX_MMAP_REGIONS 16
|
||||
|
||||
#define IMX_LPUART_BASE U(0x44380000)
|
||||
#define IMX_BOOT_UART_CLK_IN_HZ U(24000000) /* Select 24MHz oscillator */
|
||||
#define IMX_CONSOLE_BAUDRATE 115200
|
||||
|
||||
#define AIPSx_SIZE U(0x800000)
|
||||
#define AIPS1_BASE U(0x44000000)
|
||||
#define AIPS2_BASE U(0x42000000)
|
||||
#define AIPS3_BASE U(0x42800000)
|
||||
#define AIPS4_BASE U(0x49000000)
|
||||
#define GPIO1_BASE U(0x47400000)
|
||||
#define GPIO2_BASE U(0x43810000)
|
||||
#define GPIO3_BASE U(0x43820000)
|
||||
#define GPIO4_BASE U(0x43830000)
|
||||
|
||||
#define TRDC_A_BASE U(0x44270000)
|
||||
#define TRDC_W_BASE U(0x42460000)
|
||||
#define TRDC_M_BASE U(0x42810000)
|
||||
#define TRDC_N_BASE U(0x49010000)
|
||||
#define TRDC_x_SISE U(0x20000)
|
||||
|
||||
#define WDOG3_BASE U(0x42490000)
|
||||
#define WDOG_CS U(0x0)
|
||||
#define WDOG_CS_ULK BIT(11)
|
||||
#define WDOG_CNT U(0x4)
|
||||
#define WDOG_TOVAL U(0x8)
|
||||
|
||||
#define BBNSM_BASE U(0x44440000)
|
||||
#define BBNSM_CTRL U(0x8)
|
||||
#define BBNSM_DP_EN BIT(24)
|
||||
#define BBNSM_TOSP BIT(25)
|
||||
|
||||
#define SRC_BASE U(0x44460000)
|
||||
#define GPC_BASE U(0x44470000)
|
||||
#define BLK_CTRL_S_BASE U(0x444F0000)
|
||||
#define S400_MU_BASE U(0x47520000)
|
||||
|
||||
/* system memory map define */
|
||||
#define AIPS2_MAP MAP_REGION_FLAT(AIPS2_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW | MT_NS)
|
||||
#define AIPS1_MAP MAP_REGION_FLAT(AIPS1_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW)
|
||||
#define AIPS4_MAP MAP_REGION_FLAT(AIPS4_BASE, AIPSx_SIZE, MT_DEVICE | MT_RW | MT_NS)
|
||||
#define GIC_MAP MAP_REGION_FLAT(PLAT_GICD_BASE, 0x200000, MT_DEVICE | MT_RW)
|
||||
#define TRDC_A_MAP MAP_REGION_FLAT(TRDC_A_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
|
||||
#define TRDC_W_MAP MAP_REGION_FLAT(TRDC_W_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
|
||||
#define TRDC_M_MAP MAP_REGION_FLAT(TRDC_M_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
|
||||
#define TRDC_N_MAP MAP_REGION_FLAT(TRDC_N_BASE, TRDC_x_SISE, MT_DEVICE | MT_RW)
|
||||
|
||||
#define COUNTER_FREQUENCY 24000000
|
||||
|
||||
#endif /* platform_def.h */
|
216
plat/imx/imx93/include/pwr_ctrl.h
Normal file
216
plat/imx/imx93/include/pwr_ctrl.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PWR_CTRL_H
|
||||
#define PWR_CTRL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* GPC definitions & declarations
|
||||
******************************************************************************/
|
||||
/* GPC GLOBAL */
|
||||
#define GPC_GLOBAL_BASE U(GPC_BASE + 0x4000)
|
||||
#define GPC_AUTHEN_CTRL U(0x4)
|
||||
#define GPC_DOMAIN U(0x10)
|
||||
#define GPC_MASTER U(0x1c)
|
||||
#define GPC_SYS_SLEEP U(0x40)
|
||||
#define PMIC_CTRL U(0x100)
|
||||
#define PMIC_PRE_DLY_CTRL U(0x104)
|
||||
#define PMIC_STBY_ACK_CTRL U(0x108)
|
||||
#define GPC_ROSC_CTRL U(0x200)
|
||||
#define GPC_AON_MEM_CTRL U(0x204)
|
||||
#define GPC_EFUSE_CTRL U(0x208)
|
||||
|
||||
#define FORCE_CPUx_DISABLE(x) (1 << (16 + (x)))
|
||||
#define PMIC_STBY_EN BIT(0)
|
||||
#define ROSC_OFF_EN BIT(0)
|
||||
|
||||
/* GPC CPU_CTRL */
|
||||
#define CM_SLICE(x) (GPC_BASE + 0x800 * (x))
|
||||
#define CM_AUTHEN_CTRL U(0x4)
|
||||
#define CM_MISC U(0xc)
|
||||
#define CM_MODE_CTRL U(0x10)
|
||||
#define CM_IRQ_WAKEUP_MASK0 U(0x100)
|
||||
#define CM_SYS_SLEEP_CTRL U(0x380)
|
||||
#define IMR_NUM U(8)
|
||||
|
||||
/* CM_MISC */
|
||||
#define SLEEP_HOLD_EN BIT(1)
|
||||
#define IRQ_MUX BIT(5)
|
||||
#define SW_WAKEUP BIT(6)
|
||||
|
||||
/* CM_SYS_SLEEP_CTRL */
|
||||
#define SS_WAIT BIT(0)
|
||||
#define SS_STOP BIT(1)
|
||||
#define SS_SUSPEND BIT(2)
|
||||
|
||||
#define CM_MODE_RUN U(0x0)
|
||||
#define CM_MODE_WAIT U(0x1)
|
||||
#define CM_MODE_STOP U(0x2)
|
||||
#define CM_MODE_SUSPEND U(0x3)
|
||||
|
||||
#define LPM_SETTING(d, m) ((m) << (((d) % 8) * 4))
|
||||
|
||||
enum gpc_cmc_slice {
|
||||
CPU_M33,
|
||||
CPU_A55C0,
|
||||
CPU_A55C1,
|
||||
CPU_A55_PLAT,
|
||||
};
|
||||
|
||||
/* set gpc domain assignment */
|
||||
static inline void gpc_assign_domains(unsigned int domains)
|
||||
{
|
||||
mmio_write_32(GPC_GLOBAL_BASE + GPC_DOMAIN, domains);
|
||||
}
|
||||
|
||||
/* force a cpu into sleep status */
|
||||
static inline void gpc_force_cpu_suspend(unsigned int cpu)
|
||||
{
|
||||
mmio_setbits_32(GPC_GLOBAL_BASE + GPC_SYS_SLEEP, FORCE_CPUx_DISABLE(cpu));
|
||||
}
|
||||
|
||||
static inline void gpc_pmic_stby_en(bool en)
|
||||
{
|
||||
mmio_write_32(GPC_GLOBAL_BASE + PMIC_CTRL, en ? 1 : 0);
|
||||
}
|
||||
|
||||
static inline void gpc_rosc_off(bool off)
|
||||
{
|
||||
mmio_write_32(GPC_GLOBAL_BASE + GPC_ROSC_CTRL, off ? 1 : 0);
|
||||
}
|
||||
|
||||
static inline void gpc_set_cpu_mode(unsigned int cpu, unsigned int mode)
|
||||
{
|
||||
mmio_write_32(CM_SLICE(cpu) + CM_MODE_CTRL, mode);
|
||||
}
|
||||
|
||||
static inline void gpc_select_wakeup_gic(unsigned int cpu)
|
||||
{
|
||||
mmio_setbits_32(CM_SLICE(cpu) + CM_MISC, IRQ_MUX);
|
||||
}
|
||||
|
||||
static inline void gpc_select_wakeup_raw_irq(unsigned int cpu)
|
||||
{
|
||||
mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, IRQ_MUX);
|
||||
}
|
||||
|
||||
static inline void gpc_assert_sw_wakeup(unsigned int cpu)
|
||||
{
|
||||
mmio_setbits_32(CM_SLICE(cpu) + CM_MISC, SW_WAKEUP);
|
||||
}
|
||||
|
||||
static inline void gpc_deassert_sw_wakeup(unsigned int cpu)
|
||||
{
|
||||
mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, SW_WAKEUP);
|
||||
}
|
||||
|
||||
static inline void gpc_clear_cpu_sleep_hold(unsigned int cpu)
|
||||
{
|
||||
mmio_clrbits_32(CM_SLICE(cpu) + CM_MISC, SLEEP_HOLD_EN);
|
||||
}
|
||||
|
||||
static inline void gpc_set_irq_mask(unsigned int cpu, unsigned int idx, uint32_t mask)
|
||||
{
|
||||
mmio_write_32(CM_SLICE(cpu) + idx * 0x4 + CM_IRQ_WAKEUP_MASK0, mask);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* SRC definitions & declarations
|
||||
******************************************************************************/
|
||||
#define SRC_SLICE(x) (SRC_BASE + 0x400 * (x))
|
||||
#define SRC_AUTHEN_CTRL U(0x4)
|
||||
#define SRC_LPM_SETTING0 U(0x10)
|
||||
#define SRC_LPM_SETTING1 U(0x14)
|
||||
#define SRC_LPM_SETTING2 U(0x18)
|
||||
#define SRC_SLICE_SW_CTRL U(0x20)
|
||||
|
||||
#define SRC_MEM_CTRL U(0x4)
|
||||
#define MEM_LP_EN BIT(2)
|
||||
#define MEM_LP_RETN BIT(1)
|
||||
|
||||
enum mix_mem_mode {
|
||||
MEM_OFF,
|
||||
MEM_RETN,
|
||||
};
|
||||
|
||||
enum src_mix_mem_slice {
|
||||
SRC_GLOBAL,
|
||||
|
||||
/* MIX slice */
|
||||
SRC_SENTINEL,
|
||||
SRC_AON,
|
||||
SRC_WKUP,
|
||||
SRC_DDR,
|
||||
SRC_DPHY,
|
||||
SRC_ML,
|
||||
SRC_NIC,
|
||||
SRC_HSIO,
|
||||
SRC_MEDIA,
|
||||
SRC_M33P,
|
||||
SRC_A55C0,
|
||||
SRC_A55C1,
|
||||
SRC_A55P,
|
||||
|
||||
/* MEM slice */
|
||||
SRC_AON_MEM,
|
||||
SRC_WKUP_MEM,
|
||||
SRC_DDR_MEM,
|
||||
SRC_DPHY_MEM,
|
||||
SRC_ML_MEM,
|
||||
SRC_NIC_MEM,
|
||||
SRC_NIC_OCRAM,
|
||||
SRC_HSIO_MEM,
|
||||
SRC_MEDIA_MEM,
|
||||
SRC_A55P0_MEM,
|
||||
SRC_A55P1_MEM,
|
||||
SRC_A55_SCU_MEM,
|
||||
SRC_A55_L3_MEM,
|
||||
};
|
||||
|
||||
static inline void src_authen_config(unsigned int mix, unsigned int wlist,
|
||||
unsigned int lpm_en)
|
||||
{
|
||||
mmio_write_32(SRC_SLICE(mix) + SRC_AUTHEN_CTRL, (wlist << 16) | (lpm_en << 2));
|
||||
}
|
||||
|
||||
static inline void src_mix_set_lpm(unsigned int mix, unsigned int did, unsigned int lpm_mode)
|
||||
{
|
||||
mmio_clrsetbits_32(SRC_SLICE(mix) + SRC_LPM_SETTING1 + (did / 8) * 0x4,
|
||||
LPM_SETTING(did, 0x7), LPM_SETTING(did, lpm_mode));
|
||||
}
|
||||
|
||||
static inline void src_mem_lpm_en(unsigned int mix, bool retn)
|
||||
{
|
||||
mmio_setbits_32(SRC_SLICE(mix) + SRC_MEM_CTRL, MEM_LP_EN | (retn ? MEM_LP_RETN : 0));
|
||||
}
|
||||
|
||||
static inline void src_mem_lpm_dis(unsigned int mix)
|
||||
{
|
||||
mmio_clrbits_32(SRC_SLICE(mix) + SRC_MEM_CTRL, MEM_LP_EN | MEM_LP_RETN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* BLK_CTRL_S definitions & declarations
|
||||
******************************************************************************/
|
||||
#define HW_LP_HANDHSK U(0x110)
|
||||
#define HW_LP_HANDHSK2 U(0x114)
|
||||
#define CA55_CPUWAIT U(0x118)
|
||||
#define CA55_RVBADDR0_L U(0x11c)
|
||||
#define CA55_RVBADDR0_H U(0x120)
|
||||
|
||||
/*******************************************************************************
|
||||
* Other definitions & declarations
|
||||
******************************************************************************/
|
||||
void pwr_sys_init(void);
|
||||
|
||||
#endif /* PWR_CTRL_H */
|
||||
|
39
plat/imx/imx93/plat_topology.c
Normal file
39
plat/imx/imx93/plat_topology.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
const unsigned char imx_power_domain_tree_desc[] = {
|
||||
PWR_DOMAIN_AT_MAX_LVL,
|
||||
PLATFORM_CLUSTER_COUNT,
|
||||
PLATFORM_CLUSTER0_CORE_COUNT,
|
||||
};
|
||||
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return imx_power_domain_tree_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only one cluster is planned for i.MX9 family, no need
|
||||
* to consider the cluster id
|
||||
*/
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
unsigned int cpu_id;
|
||||
|
||||
mpidr &= MPIDR_AFFINITY_MASK;
|
||||
|
||||
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
|
||||
|
||||
return cpu_id;
|
||||
}
|
46
plat/imx/imx93/platform.mk
Normal file
46
plat/imx/imx93/platform.mk
Normal file
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# Copyright 2022-2023 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
PLAT_INCLUDES := -Iplat/imx/common/include \
|
||||
-Iplat/imx/imx93/include \
|
||||
# Translation tables library
|
||||
include lib/xlat_tables_v2/xlat_tables.mk
|
||||
|
||||
GICV3_SUPPORT_GIC600 := 1
|
||||
|
||||
# Include GICv3 driver files
|
||||
include drivers/arm/gic/v3/gicv3.mk
|
||||
|
||||
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
|
||||
plat/common/plat_gicv3.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/imx/common/plat_imx8_gic.c
|
||||
|
||||
BL31_SOURCES += plat/common/aarch64/crash_console_helpers.S \
|
||||
plat/imx/imx93/aarch64/plat_helpers.S \
|
||||
plat/imx/imx93/plat_topology.c \
|
||||
plat/imx/common/lpuart_console.S \
|
||||
plat/imx/imx93/trdc.c \
|
||||
plat/imx/imx93/pwr_ctrl.c \
|
||||
plat/imx/imx93/imx93_bl31_setup.c \
|
||||
plat/imx/imx93/imx93_psci.c \
|
||||
lib/cpus/aarch64/cortex_a55.S \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
drivers/nxp/trdc/imx_trdc.c \
|
||||
${IMX_GIC_SOURCES} \
|
||||
${XLAT_TABLES_LIB_SRCS}
|
||||
|
||||
RESET_TO_BL31 := 1
|
||||
HW_ASSISTED_COHERENCY := 1
|
||||
USE_COHERENT_MEM := 0
|
||||
PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
COLD_BOOT_SINGLE_CPU := 1
|
||||
|
||||
BL32_BASE ?= 0x96000000
|
||||
BL32_SIZE ?= 0x02000000
|
||||
$(eval $(call add_define,BL32_BASE))
|
||||
$(eval $(call add_define,BL32_SIZE))
|
63
plat/imx/imx93/pwr_ctrl.c
Normal file
63
plat/imx/imx93/pwr_ctrl.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <pwr_ctrl.h>
|
||||
|
||||
/*Do the necessary GPC, SRC, BLK_CTRL_S init */
|
||||
void pwr_sys_init(void)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
/*
|
||||
* Assigned A55 cluster to 3, m33 to 2, A55 CORE0 & CORE1 to 0/1.
|
||||
* domain0/1 only used for trigger LPM of themselves. A55 cluster & M33's
|
||||
* domain assignment should be align with the TRDC DID.
|
||||
*/
|
||||
gpc_assign_domains(0x3102);
|
||||
|
||||
/* CA55 core0/1 config */
|
||||
for (cpu = CPU_A55C0; cpu <= CPU_A55_PLAT; cpu++) {
|
||||
/* clear the cpu sleep hold */
|
||||
gpc_clear_cpu_sleep_hold(cpu);
|
||||
/* use gic wakeup source by default */
|
||||
gpc_select_wakeup_gic(cpu);
|
||||
/*
|
||||
* Ignore A55 core0/1's LPM trigger for system sleep.
|
||||
* normally, for A55 side, only the A55 cluster(plat)
|
||||
* domain will be used to trigger the system wide low
|
||||
* power mode transition.
|
||||
*/
|
||||
if (cpu != CPU_A55_PLAT) {
|
||||
gpc_force_cpu_suspend(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
/* boot core(A55C0) */
|
||||
src_mem_lpm_en(SRC_A55P0_MEM, MEM_OFF);
|
||||
/* For A55 core, only need to be on in RUN mode */
|
||||
src_mix_set_lpm(SRC_A55C0, 0x0, CM_MODE_WAIT);
|
||||
/* whitelist: 0x1 for domain 0 only */
|
||||
src_authen_config(SRC_A55C0, 0x1, 0x1);
|
||||
|
||||
/* A55 cluster */
|
||||
gpc_select_wakeup_gic(CPU_A55_PLAT);
|
||||
gpc_clear_cpu_sleep_hold(CPU_A55_PLAT);
|
||||
|
||||
/* SCU MEM must be OFF when A55 PLAT OFF */
|
||||
src_mem_lpm_en(SRC_A55_SCU_MEM, MEM_OFF);
|
||||
/* L3 memory in retention by default */
|
||||
src_mem_lpm_en(SRC_A55_L3_MEM, MEM_RETN);
|
||||
|
||||
src_mix_set_lpm(SRC_A55P, 0x3, 0x1);
|
||||
/* whitelist: 0x8 for domain 3 only */
|
||||
src_authen_config(SRC_A55P, 0x8, 0x1);
|
||||
|
||||
/* enable the HW LP handshake between S401 & A55 cluster */
|
||||
mmio_setbits_32(BLK_CTRL_S_BASE + HW_LP_HANDHSK, BIT(5));
|
||||
}
|
||||
|
68
plat/imx/imx93/trdc.c
Normal file
68
plat/imx/imx93/trdc.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include "trdc_config.h"
|
||||
|
||||
struct trdc_mgr_info trdc_mgr_blks[] = {
|
||||
{ TRDC_A_BASE, 0, 0, 39, 40 },
|
||||
{ TRDC_W_BASE, 0, 0, 70, 71 },
|
||||
{ TRDC_M_BASE, 1, 0, 1, 2 },
|
||||
{ TRDC_N_BASE, 0, 1, 1, 2 },
|
||||
};
|
||||
|
||||
unsigned int trdc_mgr_num = ARRAY_SIZE(trdc_mgr_blks);
|
||||
|
||||
struct trdc_config_info trdc_cfg_info[] = {
|
||||
{ TRDC_A_BASE,
|
||||
trdc_a_mbc_glbac, ARRAY_SIZE(trdc_a_mbc_glbac),
|
||||
trdc_a_mbc, ARRAY_SIZE(trdc_a_mbc),
|
||||
trdc_a_mrc_glbac, ARRAY_SIZE(trdc_a_mrc_glbac),
|
||||
trdc_a_mrc, ARRAY_SIZE(trdc_a_mrc)
|
||||
}, /* TRDC_A */
|
||||
{ TRDC_W_BASE,
|
||||
trdc_w_mbc_glbac, ARRAY_SIZE(trdc_w_mbc_glbac),
|
||||
trdc_w_mbc, ARRAY_SIZE(trdc_w_mbc),
|
||||
trdc_w_mrc_glbac, ARRAY_SIZE(trdc_w_mrc_glbac),
|
||||
trdc_w_mrc, ARRAY_SIZE(trdc_w_mrc)
|
||||
}, /* TRDC_W */
|
||||
{ TRDC_N_BASE,
|
||||
trdc_n_mbc_glbac, ARRAY_SIZE(trdc_n_mbc_glbac),
|
||||
trdc_n_mbc, ARRAY_SIZE(trdc_n_mbc),
|
||||
trdc_n_mrc_glbac, ARRAY_SIZE(trdc_n_mrc_glbac),
|
||||
trdc_n_mrc, ARRAY_SIZE(trdc_n_mrc)
|
||||
}, /* TRDC_N */
|
||||
};
|
||||
|
||||
void trdc_config(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Set MTR to DID1 */
|
||||
trdc_mda_set_noncpu(TRDC_A_BASE, 4, false, 0x2, 0x2, 0x1);
|
||||
|
||||
/* Set M33 to DID2*/
|
||||
trdc_mda_set_cpu(TRDC_A_BASE, 1, 0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0);
|
||||
|
||||
/* Configure the access permission for TRDC MGR and MC slots */
|
||||
for (i = 0U; i < ARRAY_SIZE(trdc_mgr_blks); i++) {
|
||||
trdc_mgr_mbc_setup(&trdc_mgr_blks[i]);
|
||||
}
|
||||
|
||||
/* Configure TRDC user settings from config table */
|
||||
for (i = 0U; i < ARRAY_SIZE(trdc_cfg_info); i++) {
|
||||
trdc_setup(&trdc_cfg_info[i]);
|
||||
}
|
||||
|
||||
NOTICE("TRDC init done\n");
|
||||
}
|
254
plat/imx/imx93/trdc_config.h
Normal file
254
plat/imx/imx93/trdc_config.h
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <drivers/nxp/trdc/imx_trdc.h>
|
||||
|
||||
#define TRDC_A_BASE U(0x44270000)
|
||||
#define TRDC_W_BASE U(0x42460000)
|
||||
#define TRDC_M_BASE U(0x42460000)
|
||||
#define TRDC_N_BASE U(0x49010000)
|
||||
|
||||
/* GLBAC7 is used for TRDC only, any setting to GLBAC7 will be ignored */
|
||||
|
||||
/* aonmix */
|
||||
struct trdc_glbac_config trdc_a_mbc_glbac[] = {
|
||||
/* MBC0 */
|
||||
{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
/* MBC1 */
|
||||
{ 1, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
{ 1, 1, SP(RW) | SU(R) | NP(RW) | NU(R) },
|
||||
{ 1, 2, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
|
||||
};
|
||||
|
||||
struct trdc_mbc_config trdc_a_mbc[] = {
|
||||
{ 0, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for S401 DID0 */
|
||||
{ 0, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for S401 DID0 */
|
||||
{ 0, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO1 for S401 DID0 */
|
||||
{ 1, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC1 CM33 code TCM for S401 DID0 */
|
||||
{ 1, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC1 CM33 system TCM for S401 DID0 */
|
||||
|
||||
{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for MTR DID1 */
|
||||
{ 0, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for MTR DID1 */
|
||||
|
||||
{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS1 for M33 DID2 */
|
||||
{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 Sentinel_SOC_In for M33 DID2 */
|
||||
{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO1 for M33 DID2 */
|
||||
{ 1, 2, 0, MBC_BLK_ALL, 2, true }, /* MBC1 CM33 code TCM for M33 DID2 */
|
||||
{ 1, 2, 1, MBC_BLK_ALL, 2, true }, /* MBC1 CM33 system TCM for M33 DID2 */
|
||||
|
||||
{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS1 for A55 DID3 */
|
||||
{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 Sentinel_SOC_In for A55 DID3 */
|
||||
{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO1 for A55 DID3 */
|
||||
{ 1, 3, 0, MBC_BLK_ALL, 1, false }, /* MBC1 CM33 code TCM for A55 DID3 */
|
||||
{ 1, 3, 1, MBC_BLK_ALL, 1, false }, /* MBC1 CM33 system TCM for A55 DID3 */
|
||||
{ 1, 10, 1, MBC_BLK_ALL, 2, false }, /* MBC1 CM33 system TCM for SoC masters DID10 */
|
||||
|
||||
{ 0, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS1 for eDMA DID7 */
|
||||
};
|
||||
|
||||
struct trdc_glbac_config trdc_a_mrc_glbac[] = {
|
||||
{ 0, 0, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
|
||||
{ 0, 1, SP(R) | SU(0) | NP(R) | NU(0) },
|
||||
};
|
||||
|
||||
struct trdc_mrc_config trdc_a_mrc[] = {
|
||||
{ 0, 2, 0, 0x00000000, 0x00040000, 0, true }, /* MRC0 M33 ROM for M33 DID2 */
|
||||
{ 0, 3, 0, 0x00100000, 0x00040000, 1, true }, /* MRC0 M33 ROM for A55 DID3 */
|
||||
};
|
||||
|
||||
/* wakeupmix */
|
||||
struct trdc_glbac_config trdc_w_mbc_glbac[] = {
|
||||
/* MBC0 */
|
||||
{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
/* MBC1 */
|
||||
{ 1, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
};
|
||||
|
||||
struct trdc_mbc_config trdc_w_mbc[] = {
|
||||
{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS2 for MTR DID1 */
|
||||
{ 1, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC1 AIPS3 for MTR DID1 */
|
||||
|
||||
{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS2 for M33 DID2 */
|
||||
{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO2_In for M33 DID2 */
|
||||
{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 GPIO3 for M33 DID2 */
|
||||
{ 0, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC0 DAP for M33 DID2 */
|
||||
{ 1, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC1 AIPS3 for M33 DID2 */
|
||||
{ 1, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC1 AHB_ISPAP for M33 DID2 */
|
||||
{ 1, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC1 NIC_MAIN_GPV for M33 DID2 */
|
||||
{ 1, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC1 GPIO4 for M33 DID2 */
|
||||
|
||||
{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS2 for A55 DID3 */
|
||||
{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO2_In for A55 DID3 */
|
||||
{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 GPIO3 for A55 DID3 */
|
||||
{ 0, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC0 DAP for A55 DID3 */
|
||||
{ 1, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC1 AIPS3 for A55 DID3 */
|
||||
{ 1, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC1 AHB_ISPAP for A55 DID3 */
|
||||
{ 1, 3, 2, MBC_BLK_ALL, 0, true }, /* MBC1 NIC_MAIN_GPV for A55 DID3 */
|
||||
{ 1, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC1 GPIO4 for A55 DID3 */
|
||||
|
||||
{ 0, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS2 for eDMA DID7 */
|
||||
{ 1, 7, 0, MBC_BLK_ALL, 0, false }, /* MBC1 AIPS3 for eDMA DID7 */
|
||||
};
|
||||
|
||||
struct trdc_glbac_config trdc_w_mrc_glbac[] = {
|
||||
/* MRC0 */
|
||||
{ 0, 0, SP(RX) | SU(RX) | NP(RX) | NU(RX) },
|
||||
/* MRC1 */
|
||||
{ 1, 0, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
|
||||
};
|
||||
|
||||
struct trdc_mrc_config trdc_w_mrc[] = {
|
||||
{ 0, 3, 0, 0x00000000, 0x00040000, 0, false }, /* MRC0 A55 ROM for A55 DID3 */
|
||||
{ 1, 2, 0, 0x28000000, 0x08000000, 0, true }, /* MRC1 FLEXSPI1 for M33 DID2 */
|
||||
{ 1, 3, 0, 0x28000000, 0x08000000, 0, false }, /* MRC1 FLEXSPI1 for A55 DID3 */
|
||||
};
|
||||
|
||||
/* nicmix */
|
||||
struct trdc_glbac_config trdc_n_mbc_glbac[] = {
|
||||
/* MBC0 */
|
||||
{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
/* MBC1 */
|
||||
{ 1, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
/* MBC2 */
|
||||
{ 2, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
{ 2, 1, SP(R) | SU(R) | NP(R) | NU(R) },
|
||||
/* MBC3 */
|
||||
{ 3, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
{ 3, 1, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
|
||||
};
|
||||
|
||||
struct trdc_mbc_config trdc_n_mbc[] = {
|
||||
{ 0, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for S401 DID0 */
|
||||
{ 0, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for S401 DID0 */
|
||||
{ 0, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for S401 DID0 */
|
||||
{ 0, 0, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for S401 DID0 */
|
||||
{ 1, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for S401 DID0 */
|
||||
{ 1, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for S401 DID0 */
|
||||
{ 1, 0, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for S401 DID0 */
|
||||
{ 1, 0, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for S401 DID0 */
|
||||
{ 2, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC2 GIC for S401 DID0 */
|
||||
{ 2, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC2 GIC for S401 DID0 */
|
||||
{ 3, 0, 0, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for S401 DID0 */
|
||||
{ 3, 0, 1, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for S401 DID0 */
|
||||
|
||||
{ 0, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for MTR DID1 */
|
||||
{ 0, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for MTR DID1 */
|
||||
{ 0, 1, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for MTR DID1 */
|
||||
{ 0, 1, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for MTR DID1 */
|
||||
{ 1, 1, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for MTR DID1 */
|
||||
{ 1, 1, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for MTR DID1 */
|
||||
{ 1, 1, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for MTR DID1 */
|
||||
{ 1, 1, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for MTR DID1 */
|
||||
|
||||
{ 0, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC0 DDRCFG for M33 DID2 */
|
||||
{ 0, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC0 AIPS4 for M33 DID2 */
|
||||
{ 0, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC0 MEDIAMIX for M33 DID2 */
|
||||
{ 0, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC0 HSIOMIX for M33 DID2 */
|
||||
{ 1, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for M33 DID2 */
|
||||
{ 1, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC1 MTR_DCA, TCU, TROUT for M33 DID2 */
|
||||
{ 1, 2, 2, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for M33 DID2 */
|
||||
{ 1, 2, 3, MBC_BLK_ALL, 0, true }, /* MBC1 MLMIX for M33 DID2 */
|
||||
{ 2, 2, 0, MBC_BLK_ALL, 1, true }, /* MBC2 GIC for M33 DID2 */
|
||||
{ 2, 2, 1, MBC_BLK_ALL, 1, true }, /* MBC2 GIC for M33 DID2 */
|
||||
{ 3, 2, 0, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for M33 DID2 */
|
||||
{ 3, 2, 1, MBC_BLK_ALL, 0, true }, /* MBC3 OCRAM for M33 DID2 */
|
||||
|
||||
{ 0, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC0 DDRCFG for A55 DID3 */
|
||||
{ 0, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS4 for A55 DID3 */
|
||||
{ 0, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC0 MEDIAMIX for A55 DID3 */
|
||||
{ 0, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC0 HSIOMIX for A55 DID3 */
|
||||
{ 1, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC1 MTR_DCA, TCU, TROUT for A55 DID3 */
|
||||
{ 1, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC1 MTR_DCA, TCU, TROUT for A55 DID3 */
|
||||
{ 1, 3, 2, MBC_BLK_ALL, 0, false }, /* MBC1 MLMIX for A55 DID3 */
|
||||
{ 1, 3, 3, MBC_BLK_ALL, 0, false }, /* MBC1 MLMIX for A55 DID3 */
|
||||
{ 2, 3, 0, MBC_BLK_ALL, 0, false }, /* MBC2 GIC for A55 DID3 */
|
||||
{ 2, 3, 1, MBC_BLK_ALL, 0, false }, /* MBC2 GIC for A55 DID3 */
|
||||
{ 3, 3, 0, MBC_BLK_ALL, 1, true }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, MBC_BLK_ALL, 1, true }, /* MBC3 OCRAM for A55 DID3 */
|
||||
|
||||
{ 3, 3, 0, 0, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 0, 1, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 0, 2, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 0, 3, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 0, 4, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 0, 5, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 0, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 1, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 2, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 3, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 4, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
{ 3, 3, 1, 5, 0, false }, /* MBC3 OCRAM for A55 DID3 */
|
||||
|
||||
{ 0, 7, 1, MBC_BLK_ALL, 0, false }, /* MBC0 AIPS4 for eDMA DID7 */
|
||||
{ 0, 7, 2, MBC_BLK_ALL, 0, false }, /* MBC0 MEDIAMIX for eDMA DID7 */
|
||||
{ 0, 7, 3, MBC_BLK_ALL, 0, false }, /* MBC0 HSIOMIX for eDMA DID7 */
|
||||
|
||||
{ 3, 10, 0, MBC_BLK_ALL, 0, false }, /* MBC3 OCRAM for DID10 */
|
||||
{ 3, 10, 1, MBC_BLK_ALL, 0, false }, /* MBC3 OCRAM for DID10 */
|
||||
};
|
||||
|
||||
struct trdc_glbac_config trdc_n_mrc_glbac[] = {
|
||||
{ 0, 0, SP(RW) | SU(RW) | NP(RW) | NU(RW) },
|
||||
{ 0, 1, SP(RWX) | SU(RWX) | NP(RWX) | NU(RWX) },
|
||||
};
|
||||
|
||||
#if defined(SPD_opteed)
|
||||
#define TEE_SHM_SIZE 0x200000
|
||||
|
||||
#define DRAM_MEM_0_START (0x80000000)
|
||||
#define DRAM_MEM_0_SIZE (BL32_BASE - 0x80000000)
|
||||
|
||||
#define DRAM_MEM_1_START (BL32_BASE)
|
||||
#define DRAM_MEM_1_SIZE (BL32_SIZE - TEE_SHM_SIZE)
|
||||
|
||||
#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
|
||||
#define DRAM_MEM_2_SIZE (0x80000000 - DRAM_MEM_1_SIZE - DRAM_MEM_0_SIZE)
|
||||
|
||||
struct trdc_mrc_config trdc_n_mrc[] = {
|
||||
{ 0, 0, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for S400 DID0 */
|
||||
{ 0, 1, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for MTR DID1 */
|
||||
{ 0, 2, 0, 0x80000000, 0x80000000, 0, true }, /* MRC0 DRAM for M33 DID2 */
|
||||
{ 0, 8, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for Coresight, Testport DID8 */
|
||||
{ 0, 9, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for DAP DID9 */
|
||||
|
||||
{ 0, 3, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 1, false }, /* MRC0 DRAM for A55 DID3 */
|
||||
{ 0, 5, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
|
||||
{ 0, 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
|
||||
{ 0, 7, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for eDMA DID7 */
|
||||
{ 0, 10, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
|
||||
{ 0, 11, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, 0, false }, /* MRC0 DRAM for USB DID11 */
|
||||
|
||||
/* OPTEE memory for secure access only. */
|
||||
{ 0, 3, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 1, true }, /* MRC0 DRAM for A55 DID3 */
|
||||
{ 0, 5, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USDHC1 DID5 */
|
||||
{ 0, 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USDHC2 DID6 */
|
||||
{ 0, 7, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for eDMA DID7 */
|
||||
{ 0, 10, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for SoC masters DID10 */
|
||||
{ 0, 11, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, 0, true }, /* MRC0 DRAM for USB DID11 */
|
||||
|
||||
{ 0, 3, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 1, false }, /* MRC0 DRAM for A55 DID3 */
|
||||
{ 0, 5, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
|
||||
{ 0, 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
|
||||
{ 0, 7, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for eDMA DID7 */
|
||||
{ 0, 10, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
|
||||
{ 0, 11, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, 0, false }, /* MRC0 DRAM for USB DID11 */
|
||||
|
||||
};
|
||||
#else
|
||||
struct trdc_mrc_config trdc_n_mrc[] = {
|
||||
{ 0, 0, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for S400 DID0 */
|
||||
{ 0, 1, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for MTR DID1 */
|
||||
{ 0, 2, 0, 0x80000000, 0x80000000, 0, true }, /* MRC0 DRAM for M33 DID2 */
|
||||
{ 0, 3, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for A55 DID3 */
|
||||
{ 0, 5, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */
|
||||
{ 0, 6, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */
|
||||
{ 0, 7, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for eDMA DID7 */
|
||||
{ 0, 8, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for Coresight, Testport DID8 */
|
||||
{ 0, 9, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for DAP DID9 */
|
||||
{ 0, 10, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for SoC masters DID10 */
|
||||
{ 0, 11, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USB DID11 */
|
||||
};
|
||||
#endif
|
Loading…
Add table
Reference in a new issue