arm: imx8ulp: add rdc support
There is xrdc inside i.MX8ULP, we need to configure permission to make sure AP non-secure world could access the resources. Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
@@ -13,4 +13,6 @@ extern unsigned long rom_pointer[];
|
||||
ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf);
|
||||
ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev);
|
||||
enum bt_mode get_boot_mode(void);
|
||||
int xrdc_config_pdac(u32 bridge, u32 index, u32 dom, u32 perm);
|
||||
int xrdc_config_pdac_openacc(u32 bridge, u32 index);
|
||||
#endif
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
#
|
||||
|
||||
obj-y += lowlevel_init.o
|
||||
obj-y += soc.o clock.o iomux.o pcc.o cgc.o
|
||||
obj-y += soc.o clock.o iomux.o pcc.o cgc.o rdc.o
|
||||
|
||||
144
arch/arm/mach-imx/imx8ulp/rdc.c
Normal file
144
arch/arm/mach-imx/imx8ulp/rdc.c
Normal file
@@ -0,0 +1,144 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <div64.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define XRDC_ADDR 0x292f0000
|
||||
#define MRC_OFFSET 0x2000
|
||||
#define MRC_STEP 0x200
|
||||
|
||||
#define SP(X) ((X) << 9)
|
||||
#define SU(X) ((X) << 6)
|
||||
#define NP(X) ((X) << 3)
|
||||
#define NU(X) ((X) << 0)
|
||||
|
||||
#define RWX 7
|
||||
#define RW 6
|
||||
#define R 4
|
||||
#define X 1
|
||||
|
||||
#define D7SEL_CODE (SP(RW) | SU(RW) | NP(RWX) | NU(RWX))
|
||||
#define D6SEL_CODE (SP(RW) | SU(RW) | NP(RWX))
|
||||
#define D5SEL_CODE (SP(RW) | SU(RWX))
|
||||
#define D4SEL_CODE SP(RWX)
|
||||
#define D3SEL_CODE (SP(X) | SU(X) | NP(X) | NU(X))
|
||||
#define D0SEL_CODE 0
|
||||
|
||||
#define D7SEL_DAT (SP(RW) | SU(RW) | NP(RW) | NU(RW))
|
||||
#define D6SEL_DAT (SP(RW) | SU(RW) | NP(RW))
|
||||
#define D5SEL_DAT (SP(RW) | SU(RW) | NP(R) | NU(R))
|
||||
#define D4SEL_DAT (SP(RW) | SU(RW))
|
||||
#define D3SEL_DAT SP(RW)
|
||||
|
||||
union dxsel_perm {
|
||||
struct {
|
||||
u8 dx;
|
||||
u8 perm;
|
||||
};
|
||||
|
||||
u32 dom_perm;
|
||||
};
|
||||
|
||||
int xrdc_config_mrc_dx_perm(u32 mrc_con, u32 region, u32 dom, u32 dxsel)
|
||||
{
|
||||
ulong w2_addr;
|
||||
u32 val = 0;
|
||||
|
||||
w2_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0x8;
|
||||
|
||||
val = (readl(w2_addr) & (~(7 << (3 * dom)))) | (dxsel << (3 * dom));
|
||||
writel(val, w2_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xrdc_config_mrc_w0_w1(u32 mrc_con, u32 region, u32 w0, u32 size)
|
||||
{
|
||||
ulong w0_addr, w1_addr;
|
||||
|
||||
w0_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20;
|
||||
w1_addr = w0_addr + 4;
|
||||
|
||||
if ((size % 32) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
writel(w0 & ~0x1f, w0_addr);
|
||||
writel(w0 + size - 1, w1_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xrdc_config_mrc_w3_w4(u32 mrc_con, u32 region, u32 w3, u32 w4)
|
||||
{
|
||||
ulong w3_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0xC;
|
||||
ulong w4_addr = w3_addr + 4;
|
||||
|
||||
writel(w3, w3_addr);
|
||||
writel(w4, w4_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xrdc_config_pdac_openacc(u32 bridge, u32 index)
|
||||
{
|
||||
ulong w0_addr;
|
||||
u32 val;
|
||||
|
||||
switch (bridge) {
|
||||
case 3:
|
||||
w0_addr = XRDC_ADDR + 0x1000 + 0x8 * index;
|
||||
break;
|
||||
case 4:
|
||||
w0_addr = XRDC_ADDR + 0x1400 + 0x8 * index;
|
||||
break;
|
||||
case 5:
|
||||
w0_addr = XRDC_ADDR + 0x1800 + 0x8 * index;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
writel(0xffffff, w0_addr);
|
||||
|
||||
val = readl(w0_addr + 4);
|
||||
writel(val | BIT(31), w0_addr + 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xrdc_config_pdac(u32 bridge, u32 index, u32 dom, u32 perm)
|
||||
{
|
||||
ulong w0_addr;
|
||||
u32 val;
|
||||
|
||||
switch (bridge) {
|
||||
case 3:
|
||||
w0_addr = XRDC_ADDR + 0x1000 + 0x8 * index;
|
||||
break;
|
||||
case 4:
|
||||
w0_addr = XRDC_ADDR + 0x1400 + 0x8 * index;
|
||||
break;
|
||||
case 5:
|
||||
w0_addr = XRDC_ADDR + 0x1800 + 0x8 * index;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
val = readl(w0_addr);
|
||||
writel((val & ~(0x7 << (dom * 3))) | (perm << (dom * 3)), w0_addr);
|
||||
|
||||
val = readl(w0_addr + 4);
|
||||
writel(val | BIT(31), w0_addr + 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user