mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-12 16:07:30 +00:00
367ff4bc84
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>
144 lines
2.8 KiB
C
144 lines
2.8 KiB
C
// 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;
|
|
}
|