@@ -68,6 +68,8 @@ struct xor_bits {
68
68
};
69
69
70
70
#define NUM_BANK_BITS 4
71
+ #define NUM_COL_BITS 5
72
+ #define NUM_SID_BITS 2
71
73
72
74
static struct {
73
75
/* UMC::CH::AddrHashBank */
@@ -80,7 +82,22 @@ static struct {
80
82
u8 bank_xor ;
81
83
} addr_hash ;
82
84
85
+ static struct {
86
+ u8 bank [NUM_BANK_BITS ];
87
+ u8 col [NUM_COL_BITS ];
88
+ u8 sid [NUM_SID_BITS ];
89
+ u8 num_row_lo ;
90
+ u8 num_row_hi ;
91
+ u8 row_lo ;
92
+ u8 row_hi ;
93
+ u8 pc ;
94
+ } bit_shifts ;
95
+
83
96
#define MI300_UMC_CH_BASE 0x90000
97
+ #define MI300_ADDR_CFG (MI300_UMC_CH_BASE + 0x30)
98
+ #define MI300_ADDR_SEL (MI300_UMC_CH_BASE + 0x40)
99
+ #define MI300_COL_SEL_LO (MI300_UMC_CH_BASE + 0x50)
100
+ #define MI300_ADDR_SEL_2 (MI300_UMC_CH_BASE + 0xA4)
84
101
#define MI300_ADDR_HASH_BANK0 (MI300_UMC_CH_BASE + 0xC8)
85
102
#define MI300_ADDR_HASH_PC (MI300_UMC_CH_BASE + 0xE0)
86
103
#define MI300_ADDR_HASH_PC2 (MI300_UMC_CH_BASE + 0xE4)
@@ -90,17 +107,42 @@ static struct {
90
107
#define ADDR_HASH_ROW_XOR GENMASK(31, 14)
91
108
#define ADDR_HASH_BANK_XOR GENMASK(5, 0)
92
109
110
+ #define ADDR_CFG_NUM_ROW_LO GENMASK(11, 8)
111
+ #define ADDR_CFG_NUM_ROW_HI GENMASK(15, 12)
112
+
113
+ #define ADDR_SEL_BANK0 GENMASK(3, 0)
114
+ #define ADDR_SEL_BANK1 GENMASK(7, 4)
115
+ #define ADDR_SEL_BANK2 GENMASK(11, 8)
116
+ #define ADDR_SEL_BANK3 GENMASK(15, 12)
117
+ #define ADDR_SEL_BANK4 GENMASK(20, 16)
118
+ #define ADDR_SEL_ROW_LO GENMASK(27, 24)
119
+ #define ADDR_SEL_ROW_HI GENMASK(31, 28)
120
+
121
+ #define COL_SEL_LO_COL0 GENMASK(3, 0)
122
+ #define COL_SEL_LO_COL1 GENMASK(7, 4)
123
+ #define COL_SEL_LO_COL2 GENMASK(11, 8)
124
+ #define COL_SEL_LO_COL3 GENMASK(15, 12)
125
+ #define COL_SEL_LO_COL4 GENMASK(19, 16)
126
+
127
+ #define ADDR_SEL_2_BANK5 GENMASK(4, 0)
128
+ #define ADDR_SEL_2_CHAN GENMASK(15, 12)
129
+
93
130
/*
94
131
* Read UMC::CH::AddrHash{Bank,PC,PC2} registers to get XOR bits used
95
- * for hashing. Do this during module init, since the values will not
96
- * change during run time.
132
+ * for hashing.
133
+ *
134
+ * Also, read UMC::CH::Addr{Cfg,Sel,Sel2} and UMC::CH:ColSelLo registers to
135
+ * get the values needed to reconstruct the normalized address. Apply additional
136
+ * offsets to the raw register values, as needed.
137
+ *
138
+ * Do this during module init, since the values will not change during run time.
97
139
*
98
140
* These registers are instantiated for each UMC across each AMD Node.
99
141
* However, they should be identically programmed due to the fixed hardware
100
142
* design of MI300 systems. So read the values from Node 0 UMC 0 and keep a
101
143
* single global structure for simplicity.
102
144
*/
103
- int get_addr_hash_mi300 (void )
145
+ int get_umc_info_mi300 (void )
104
146
{
105
147
u32 temp ;
106
148
int ret ;
@@ -130,6 +172,44 @@ int get_addr_hash_mi300(void)
130
172
131
173
addr_hash .bank_xor = FIELD_GET (ADDR_HASH_BANK_XOR , temp );
132
174
175
+ ret = amd_smn_read (0 , MI300_ADDR_CFG , & temp );
176
+ if (ret )
177
+ return ret ;
178
+
179
+ bit_shifts .num_row_hi = FIELD_GET (ADDR_CFG_NUM_ROW_HI , temp );
180
+ bit_shifts .num_row_lo = 10 + FIELD_GET (ADDR_CFG_NUM_ROW_LO , temp );
181
+
182
+ ret = amd_smn_read (0 , MI300_ADDR_SEL , & temp );
183
+ if (ret )
184
+ return ret ;
185
+
186
+ bit_shifts .bank [0 ] = 5 + FIELD_GET (ADDR_SEL_BANK0 , temp );
187
+ bit_shifts .bank [1 ] = 5 + FIELD_GET (ADDR_SEL_BANK1 , temp );
188
+ bit_shifts .bank [2 ] = 5 + FIELD_GET (ADDR_SEL_BANK2 , temp );
189
+ bit_shifts .bank [3 ] = 5 + FIELD_GET (ADDR_SEL_BANK3 , temp );
190
+ /* Use BankBit4 for the SID0 position. */
191
+ bit_shifts .sid [0 ] = 5 + FIELD_GET (ADDR_SEL_BANK4 , temp );
192
+ bit_shifts .row_lo = 12 + FIELD_GET (ADDR_SEL_ROW_LO , temp );
193
+ bit_shifts .row_hi = 24 + FIELD_GET (ADDR_SEL_ROW_HI , temp );
194
+
195
+ ret = amd_smn_read (0 , MI300_COL_SEL_LO , & temp );
196
+ if (ret )
197
+ return ret ;
198
+
199
+ bit_shifts .col [0 ] = 2 + FIELD_GET (COL_SEL_LO_COL0 , temp );
200
+ bit_shifts .col [1 ] = 2 + FIELD_GET (COL_SEL_LO_COL1 , temp );
201
+ bit_shifts .col [2 ] = 2 + FIELD_GET (COL_SEL_LO_COL2 , temp );
202
+ bit_shifts .col [3 ] = 2 + FIELD_GET (COL_SEL_LO_COL3 , temp );
203
+ bit_shifts .col [4 ] = 2 + FIELD_GET (COL_SEL_LO_COL4 , temp );
204
+
205
+ ret = amd_smn_read (0 , MI300_ADDR_SEL_2 , & temp );
206
+ if (ret )
207
+ return ret ;
208
+
209
+ /* Use BankBit5 for the SID1 position. */
210
+ bit_shifts .sid [1 ] = 5 + FIELD_GET (ADDR_SEL_2_BANK5 , temp );
211
+ bit_shifts .pc = 5 + FIELD_GET (ADDR_SEL_2_CHAN , temp );
212
+
133
213
return 0 ;
134
214
}
135
215
@@ -146,9 +226,6 @@ int get_addr_hash_mi300(void)
146
226
* The MCA address format is as follows:
147
227
* MCA_ADDR[27:0] = {S[1:0], P[0], R[14:0], B[3:0], C[4:0], Z[0]}
148
228
*
149
- * The normalized address format is fixed in hardware and is as follows:
150
- * NA[30:0] = {S[1:0], R[13:0], C4, B[1:0], B[3:2], C[3:2], P, C[1:0], Z[4:0]}
151
- *
152
229
* Additionally, the PC and Bank bits may be hashed. This must be accounted for before
153
230
* reconstructing the normalized address.
154
231
*/
@@ -158,18 +235,10 @@ int get_addr_hash_mi300(void)
158
235
#define MI300_UMC_MCA_PC BIT(25)
159
236
#define MI300_UMC_MCA_SID GENMASK(27, 26)
160
237
161
- #define MI300_NA_COL_1_0 GENMASK(6, 5)
162
- #define MI300_NA_PC BIT(7)
163
- #define MI300_NA_COL_3_2 GENMASK(9, 8)
164
- #define MI300_NA_BANK_3_2 GENMASK(11, 10)
165
- #define MI300_NA_BANK_1_0 GENMASK(13, 12)
166
- #define MI300_NA_COL_4 BIT(14)
167
- #define MI300_NA_ROW GENMASK(28, 15)
168
- #define MI300_NA_SID GENMASK(30, 29)
169
-
170
238
static unsigned long convert_dram_to_norm_addr_mi300 (unsigned long addr )
171
239
{
172
- u16 i , col , row , bank , pc , sid , temp ;
240
+ u16 i , col , row , bank , pc , sid ;
241
+ u32 temp ;
173
242
174
243
col = FIELD_GET (MI300_UMC_MCA_COL , addr );
175
244
bank = FIELD_GET (MI300_UMC_MCA_BANK , addr );
@@ -189,49 +258,48 @@ static unsigned long convert_dram_to_norm_addr_mi300(unsigned long addr)
189
258
190
259
/* Calculate hash for PC bit. */
191
260
if (addr_hash .pc .xor_enable ) {
192
- /* Bits SID[1:0] act as Bank[6:5] for PC hash, so apply them here. */
193
- bank |= sid << 5 ;
194
-
195
261
temp = bitwise_xor_bits (col & addr_hash .pc .col_xor );
196
262
temp ^= bitwise_xor_bits (row & addr_hash .pc .row_xor );
197
- temp ^= bitwise_xor_bits (bank & addr_hash .bank_xor );
263
+ /* Bits SID[1:0] act as Bank[5:4] for PC hash, so apply them here. */
264
+ temp ^= bitwise_xor_bits ((bank | sid << NUM_BANK_BITS ) & addr_hash .bank_xor );
198
265
pc ^= temp ;
199
-
200
- /* Drop SID bits for the sake of debug printing later. */
201
- bank &= 0x1F ;
202
266
}
203
267
204
268
/* Reconstruct the normalized address starting with NA[4:0] = 0 */
205
269
addr = 0 ;
206
270
207
- /* NA[6:5] = Column[1:0] */
208
- temp = col & 0x3 ;
209
- addr |= FIELD_PREP (MI300_NA_COL_1_0 , temp );
210
-
211
- /* NA[7] = PC */
212
- addr |= FIELD_PREP (MI300_NA_PC , pc );
213
-
214
- /* NA[9:8] = Column[3:2] */
215
- temp = (col >> 2 ) & 0x3 ;
216
- addr |= FIELD_PREP (MI300_NA_COL_3_2 , temp );
271
+ /* Column bits */
272
+ for (i = 0 ; i < NUM_COL_BITS ; i ++ ) {
273
+ temp = (col >> i ) & 0x1 ;
274
+ addr |= temp << bit_shifts .col [i ];
275
+ }
217
276
218
- /* NA[11:10] = Bank[3:2] */
219
- temp = (bank >> 2 ) & 0x3 ;
220
- addr |= FIELD_PREP (MI300_NA_BANK_3_2 , temp );
277
+ /* Bank bits */
278
+ for (i = 0 ; i < NUM_BANK_BITS ; i ++ ) {
279
+ temp = (bank >> i ) & 0x1 ;
280
+ addr |= temp << bit_shifts .bank [i ];
281
+ }
221
282
222
- /* NA[13:12] = Bank[1:0] */
223
- temp = bank & 0x3 ;
224
- addr |= FIELD_PREP (MI300_NA_BANK_1_0 , temp );
283
+ /* Row lo bits */
284
+ for (i = 0 ; i < bit_shifts .num_row_lo ; i ++ ) {
285
+ temp = (row >> i ) & 0x1 ;
286
+ addr |= temp << (i + bit_shifts .row_lo );
287
+ }
225
288
226
- /* NA[14] = Column[4] */
227
- temp = (col >> 4 ) & 0x1 ;
228
- addr |= FIELD_PREP (MI300_NA_COL_4 , temp );
289
+ /* Row hi bits */
290
+ for (i = 0 ; i < bit_shifts .num_row_hi ; i ++ ) {
291
+ temp = (row >> (i + bit_shifts .num_row_lo )) & 0x1 ;
292
+ addr |= temp << (i + bit_shifts .row_hi );
293
+ }
229
294
230
- /* NA[28:15] = Row[13:0] */
231
- addr |= FIELD_PREP ( MI300_NA_ROW , row ) ;
295
+ /* PC bit */
296
+ addr |= pc << bit_shifts . pc ;
232
297
233
- /* NA[30:29] = SID[1:0] */
234
- addr |= FIELD_PREP (MI300_NA_SID , sid );
298
+ /* SID bits */
299
+ for (i = 0 ; i < NUM_SID_BITS ; i ++ ) {
300
+ temp = (sid >> i ) & 0x1 ;
301
+ addr |= temp << bit_shifts .sid [i ];
302
+ }
235
303
236
304
pr_debug ("Addr=0x%016lx" , addr );
237
305
pr_debug ("Bank=%u Row=%u Column=%u PC=%u SID=%u" , bank , row , col , pc , sid );
0 commit comments