1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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;
}
|