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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
/*
* Copyright (c) 2016, NVIDIA Corporation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __TEGRA18_EMC_H__
#define __TEGRA18_EMC_H__
/* HW Register offsets */
#define EMC_INTSTATUS 0x0
#define ECC_ERR_BUF_OVF_INT_MASK 0x1
#define ECC_ERR_BUF_OVF_INT_SHIFT 12
#define ECC_CORR_ERR_INT_MASK 0x1
#define ECC_CORR_ERR_INT_SHIFT 11
#define ECC_UNCORR_ERR_INT_MASK 0x1
#define ECC_UNCORR_ERR_INT_SHIFT 10
#define EMC_INTMASK 0x4
#define EMC_NONCRITICAL_INTMASK 0x514
#define EMC_CRITICAL_INTMASK 0x510
#define EMC_ECC_CONTROL 0xac0
#define ERR_BUFFER_MODE_MASK 0x1
#define ERR_BUFFER_MODE_SHIFT 0
#define ERR_BUFFER_RESET_MASK 0x1
#define ERR_BUFFER_RESET_SHIFT 1
#define ERR_BUFFER_LOAD_MASK 0x1
#define ERR_BUFFER_LOAD_SHIFT 2
#define ERR_BUFFER_LIMIT_MASK 0xFF
#define ERR_BUFFER_LIMIT_SHIFT 8
#define EMC_ECC_STATUS 0xac4
#define ERR_BUFFER_CNT_MASK 0xFF
#define ERR_BUFFER_CNT_SHIFT 16
#define ERR_BUFFER_DEPTH_MASK 0xFF
#define ERR_BUFFER_DEPTH_SHIFT 24
#define EMC_ECC_ERR_REQ 0xad4
#define ECC_ERR_CGID_MASK 0xFF
#define ECC_ERR_CGID_SHIFT 24
#define ECC_ERR_SEQ_MASK 0x3
#define ECC_ERR_SEQ_SHIFT 20
#define ECC_ERR_EMC_ID_MASK 0x3
#define ECC_ERR_EMC_ID_SHIFT 6
#define ECC_ERR_DEVICE_MASK 0x1
#define ECC_ERR_DEVICE_SHIFT 16
#define ECC_ERR_SIZE_MASK 0x3
#define ECC_ERR_SIZE_SHIFT 17
#define ECC_ERR_SWAP_MASK 0x1
#define ECC_ERR_SWAP_SHIFT 19
#define ECC_ERR_COL_SP0_MASK 0x7
#define ECC_ERR_COL_SP0_SHIFT 8
#define ECC_ERR_COL_SP1_MASK 0x7
#define ECC_ERR_COL_SP1_SHIFT 12
#define EMC_ECC_ERR_SP0 0xac8
#define EMC_ECC_ERR_SP1 0xacc
#define ECC_EERR_PAR_MASK 0x3
#define ECC_EERR_PAR_SHIFT 16
#define ECC_DERR_PAR_MASK 0x3
#define ECC_DERR_PAR_SHIFT 0
#define ECC_ERR_POISON_MASK 0x1
#define ECC_ERR_POISON_SHIFT 3
#define ECC_DERR_SYNDROME_MASK 0x3FF
#define ECC_DERR_SYNDROME_SHIFT 6
#define EMC_ECC_ERR_ADDR 0xad0
#define ECC_ERR_ROW_MASK 0xFFFF
#define ECC_ERR_ROW_SHIFT 8
#define ECC_ERR_BANK_MASK 0x7
#define ECC_ERR_BANK_SHIFT 28
#define ECC_ERR_GOB_MASK 0x3F
#define ECC_ERR_GOB_SHIFT 0
#define EMC_ECC_CONTROL 0xac0
#define MC_MEM_SCRUBBER_ECC_ADDR 0xf18
#define MC_MEM_SCRUBBER_ECC_REG_CTRL 0xf20
#define SCRUB_ECC_TRIGGER_SHIFT 0
#define SCRUB_ECC_PENDING_MASK 0x1
#define SCRUB_ECC_PENDING_SHIFT 1
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_ECC_CONTROL 0x1880
#define EMC_MCH_GLOBAL_NONCRITICAL_INTSTATUS 0x474
#define EMC_MCH_GLOBAL_CRITICAL_INTSTATUS 0x450
#define EMC_MCH_GLOBAL_INTSTATUS 0x44c
#define EMC_BROADCAST_CHANNEL -1
/**
* Read from the EMC.
*
* @idx The EMC channel to read from.
* @reg The offset of the register to read.
*
* Read from the specified EMC channel: 0 -> EMC0, 1 -> EMC1, etc. If @idx
* corresponds to a non-existent channel then 0 is returned.
*/
static inline u32 __emc_readl(int idx, u32 reg)
{
if (WARN(!emc, "Read before EMC init'ed"))
return 0;
if ((idx != EMC_BROADCAST_CHANNEL && idx < 0) ||
idx >= MAX_CHANNELS)
return 0;
if (idx == EMC_BROADCAST_CHANNEL)
return readl(emc + reg);
else
return readl(emc_regs[idx] + reg);
}
/**
* Write to the EMC.
*
* @idx The EMC channel to write to.
* @val Value to write.
* @reg The offset of the register to write.
*
* Write to the specified EMC channel: 0 -> EMC0, 1 -> EMC1, etc. For writes
* there is a special channel, %EMC_BROADCAST_CHANNEL, which writes to all
* channels. If @idx corresponds to a non-existent channel then the
* write is dropped.
*/
static inline void __emc_writel(int idx, u32 val, u32 reg)
{
if (WARN(!emc, "Write before EMC init'ed"))
return;
if ((idx != EMC_BROADCAST_CHANNEL && idx < 0) ||
idx >= MAX_CHANNELS)
return;
if (idx == EMC_BROADCAST_CHANNEL)
writel(val, emc + reg);
else
writel(val, emc_regs[idx] + reg);
}
#define emc_readl(reg) __emc_readl(EMC_BROADCAST_CHANNEL, reg)
#define emc_writel(val, reg) __emc_writel(EMC_BROADCAST_CHANNEL, val, reg)
#endif
|