Merge tag 'x86-asm-2024-03-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-block.git] / drivers / ras / amd / atl / map.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * AMD Address Translation Library
4  *
5  * map.c : Functions to read and decode DRAM address maps
6  *
7  * Copyright (c) 2023, Advanced Micro Devices, Inc.
8  * All Rights Reserved.
9  *
10  * Author: Yazen Ghannam <Yazen.Ghannam@amd.com>
11  */
12
13 #include "internal.h"
14
15 static int df2_get_intlv_mode(struct addr_ctx *ctx)
16 {
17         ctx->map.intlv_mode = FIELD_GET(DF2_INTLV_NUM_CHAN, ctx->map.base);
18
19         if (ctx->map.intlv_mode == 8)
20                 ctx->map.intlv_mode = DF2_2CHAN_HASH;
21
22         if (ctx->map.intlv_mode != NONE &&
23             ctx->map.intlv_mode != NOHASH_2CHAN &&
24             ctx->map.intlv_mode != DF2_2CHAN_HASH)
25                 return -EINVAL;
26
27         return 0;
28 }
29
30 static int df3_get_intlv_mode(struct addr_ctx *ctx)
31 {
32         ctx->map.intlv_mode = FIELD_GET(DF3_INTLV_NUM_CHAN, ctx->map.base);
33         return 0;
34 }
35
36 static int df3p5_get_intlv_mode(struct addr_ctx *ctx)
37 {
38         ctx->map.intlv_mode = FIELD_GET(DF3p5_INTLV_NUM_CHAN, ctx->map.base);
39
40         if (ctx->map.intlv_mode == DF3_6CHAN)
41                 return -EINVAL;
42
43         return 0;
44 }
45
46 static int df4_get_intlv_mode(struct addr_ctx *ctx)
47 {
48         ctx->map.intlv_mode = FIELD_GET(DF4_INTLV_NUM_CHAN, ctx->map.intlv);
49
50         if (ctx->map.intlv_mode == DF3_COD4_2CHAN_HASH ||
51             ctx->map.intlv_mode == DF3_COD2_4CHAN_HASH ||
52             ctx->map.intlv_mode == DF3_COD1_8CHAN_HASH ||
53             ctx->map.intlv_mode == DF3_6CHAN)
54                 return -EINVAL;
55
56         return 0;
57 }
58
59 static int df4p5_get_intlv_mode(struct addr_ctx *ctx)
60 {
61         ctx->map.intlv_mode = FIELD_GET(DF4p5_INTLV_NUM_CHAN, ctx->map.intlv);
62
63         if (ctx->map.intlv_mode <= NOHASH_32CHAN)
64                 return 0;
65
66         if (ctx->map.intlv_mode >= MI3_HASH_8CHAN &&
67             ctx->map.intlv_mode <= MI3_HASH_32CHAN)
68                 return 0;
69
70         /*
71          * Modes matching the ranges above are returned as-is.
72          *
73          * All other modes are "fixed up" by adding 20h to make a unique value.
74          */
75         ctx->map.intlv_mode += 0x20;
76
77         return 0;
78 }
79
80 static int get_intlv_mode(struct addr_ctx *ctx)
81 {
82         int ret;
83
84         switch (df_cfg.rev) {
85         case DF2:
86                 ret = df2_get_intlv_mode(ctx);
87                 break;
88         case DF3:
89                 ret = df3_get_intlv_mode(ctx);
90                 break;
91         case DF3p5:
92                 ret = df3p5_get_intlv_mode(ctx);
93                 break;
94         case DF4:
95                 ret = df4_get_intlv_mode(ctx);
96                 break;
97         case DF4p5:
98                 ret = df4p5_get_intlv_mode(ctx);
99                 break;
100         default:
101                 ret = -EINVAL;
102         }
103
104         if (ret)
105                 atl_debug_on_bad_df_rev();
106
107         return ret;
108 }
109
110 static u64 get_hi_addr_offset(u32 reg_dram_offset)
111 {
112         u8 shift = DF_DRAM_BASE_LIMIT_LSB;
113         u64 hi_addr_offset;
114
115         switch (df_cfg.rev) {
116         case DF2:
117                 hi_addr_offset = FIELD_GET(DF2_HI_ADDR_OFFSET, reg_dram_offset);
118                 break;
119         case DF3:
120         case DF3p5:
121                 hi_addr_offset = FIELD_GET(DF3_HI_ADDR_OFFSET, reg_dram_offset);
122                 break;
123         case DF4:
124         case DF4p5:
125                 hi_addr_offset = FIELD_GET(DF4_HI_ADDR_OFFSET, reg_dram_offset);
126                 break;
127         default:
128                 hi_addr_offset = 0;
129                 atl_debug_on_bad_df_rev();
130         }
131
132         if (df_cfg.rev == DF4p5 && df_cfg.flags.heterogeneous)
133                 shift = MI300_DRAM_LIMIT_LSB;
134
135         return hi_addr_offset << shift;
136 }
137
138 /*
139  * Returns:     0 if offset is disabled.
140  *              1 if offset is enabled.
141  *              -EINVAL on error.
142  */
143 static int get_dram_offset(struct addr_ctx *ctx, u64 *norm_offset)
144 {
145         u32 reg_dram_offset;
146         u8 map_num;
147
148         /* Should not be called for map 0. */
149         if (!ctx->map.num) {
150                 atl_debug(ctx, "Trying to find DRAM offset for map 0");
151                 return -EINVAL;
152         }
153
154         /*
155          * DramOffset registers don't exist for map 0, so the base register
156          * actually refers to map 1.
157          * Adjust the map_num for the register offsets.
158          */
159         map_num = ctx->map.num - 1;
160
161         if (df_cfg.rev >= DF4) {
162                 /* Read D18F7x140 (DramOffset) */
163                 if (df_indirect_read_instance(ctx->node_id, 7, 0x140 + (4 * map_num),
164                                               ctx->inst_id, &reg_dram_offset))
165                         return -EINVAL;
166
167         } else {
168                 /* Read D18F0x1B4 (DramOffset) */
169                 if (df_indirect_read_instance(ctx->node_id, 0, 0x1B4 + (4 * map_num),
170                                               ctx->inst_id, &reg_dram_offset))
171                         return -EINVAL;
172         }
173
174         if (!FIELD_GET(DF_HI_ADDR_OFFSET_EN, reg_dram_offset))
175                 return 0;
176
177         *norm_offset = get_hi_addr_offset(reg_dram_offset);
178
179         return 1;
180 }
181
182 static int df3_6ch_get_dram_addr_map(struct addr_ctx *ctx)
183 {
184         u16 dst_fabric_id = FIELD_GET(DF3_DST_FABRIC_ID, ctx->map.limit);
185         u8 i, j, shift = 4, mask = 0xF;
186         u32 reg, offset = 0x60;
187         u16 dst_node_id;
188
189         /* Get Socket 1 register. */
190         if (dst_fabric_id & df_cfg.socket_id_mask)
191                 offset = 0x68;
192
193         /* Read D18F0x06{0,8} (DF::Skt0CsTargetRemap0)/(DF::Skt0CsTargetRemap1) */
194         if (df_indirect_read_broadcast(ctx->node_id, 0, offset, &reg))
195                 return -EINVAL;
196
197         /* Save 8 remap entries. */
198         for (i = 0, j = 0; i < 8; i++, j++)
199                 ctx->map.remap_array[i] = (reg >> (j * shift)) & mask;
200
201         dst_node_id = dst_fabric_id & df_cfg.node_id_mask;
202         dst_node_id >>= df_cfg.node_id_shift;
203
204         /* Read D18F2x090 (DF::Np2ChannelConfig) */
205         if (df_indirect_read_broadcast(dst_node_id, 2, 0x90, &reg))
206                 return -EINVAL;
207
208         ctx->map.np2_bits = FIELD_GET(DF_LOG2_ADDR_64K_SPACE0, reg);
209         return 0;
210 }
211
212 static int df2_get_dram_addr_map(struct addr_ctx *ctx)
213 {
214         /* Read D18F0x110 (DramBaseAddress). */
215         if (df_indirect_read_instance(ctx->node_id, 0, 0x110 + (8 * ctx->map.num),
216                                       ctx->inst_id, &ctx->map.base))
217                 return -EINVAL;
218
219         /* Read D18F0x114 (DramLimitAddress). */
220         if (df_indirect_read_instance(ctx->node_id, 0, 0x114 + (8 * ctx->map.num),
221                                       ctx->inst_id, &ctx->map.limit))
222                 return -EINVAL;
223
224         return 0;
225 }
226
227 static int df3_get_dram_addr_map(struct addr_ctx *ctx)
228 {
229         if (df2_get_dram_addr_map(ctx))
230                 return -EINVAL;
231
232         /* Read D18F0x3F8 (DfGlobalCtl). */
233         if (df_indirect_read_instance(ctx->node_id, 0, 0x3F8,
234                                       ctx->inst_id, &ctx->map.ctl))
235                 return -EINVAL;
236
237         return 0;
238 }
239
240 static int df4_get_dram_addr_map(struct addr_ctx *ctx)
241 {
242         u8 remap_sel, i, j, shift = 4, mask = 0xF;
243         u32 remap_reg;
244
245         /* Read D18F7xE00 (DramBaseAddress). */
246         if (df_indirect_read_instance(ctx->node_id, 7, 0xE00 + (16 * ctx->map.num),
247                                       ctx->inst_id, &ctx->map.base))
248                 return -EINVAL;
249
250         /* Read D18F7xE04 (DramLimitAddress). */
251         if (df_indirect_read_instance(ctx->node_id, 7, 0xE04 + (16 * ctx->map.num),
252                                       ctx->inst_id, &ctx->map.limit))
253                 return -EINVAL;
254
255         /* Read D18F7xE08 (DramAddressCtl). */
256         if (df_indirect_read_instance(ctx->node_id, 7, 0xE08 + (16 * ctx->map.num),
257                                       ctx->inst_id, &ctx->map.ctl))
258                 return -EINVAL;
259
260         /* Read D18F7xE0C (DramAddressIntlv). */
261         if (df_indirect_read_instance(ctx->node_id, 7, 0xE0C + (16 * ctx->map.num),
262                                       ctx->inst_id, &ctx->map.intlv))
263                 return -EINVAL;
264
265         /* Check if Remap Enable bit is valid. */
266         if (!FIELD_GET(DF4_REMAP_EN, ctx->map.ctl))
267                 return 0;
268
269         /* Fill with bogus values, because '0' is a valid value. */
270         memset(&ctx->map.remap_array, 0xFF, sizeof(ctx->map.remap_array));
271
272         /* Get Remap registers. */
273         remap_sel = FIELD_GET(DF4_REMAP_SEL, ctx->map.ctl);
274
275         /* Read D18F7x180 (CsTargetRemap0A). */
276         if (df_indirect_read_instance(ctx->node_id, 7, 0x180 + (8 * remap_sel),
277                                       ctx->inst_id, &remap_reg))
278                 return -EINVAL;
279
280         /* Save first 8 remap entries. */
281         for (i = 0, j = 0; i < 8; i++, j++)
282                 ctx->map.remap_array[i] = (remap_reg >> (j * shift)) & mask;
283
284         /* Read D18F7x184 (CsTargetRemap0B). */
285         if (df_indirect_read_instance(ctx->node_id, 7, 0x184 + (8 * remap_sel),
286                                       ctx->inst_id, &remap_reg))
287                 return -EINVAL;
288
289         /* Save next 8 remap entries. */
290         for (i = 8, j = 0; i < 16; i++, j++)
291                 ctx->map.remap_array[i] = (remap_reg >> (j * shift)) & mask;
292
293         return 0;
294 }
295
296 static int df4p5_get_dram_addr_map(struct addr_ctx *ctx)
297 {
298         u8 remap_sel, i, j, shift = 5, mask = 0x1F;
299         u32 remap_reg;
300
301         /* Read D18F7x200 (DramBaseAddress). */
302         if (df_indirect_read_instance(ctx->node_id, 7, 0x200 + (16 * ctx->map.num),
303                                       ctx->inst_id, &ctx->map.base))
304                 return -EINVAL;
305
306         /* Read D18F7x204 (DramLimitAddress). */
307         if (df_indirect_read_instance(ctx->node_id, 7, 0x204 + (16 * ctx->map.num),
308                                       ctx->inst_id, &ctx->map.limit))
309                 return -EINVAL;
310
311         /* Read D18F7x208 (DramAddressCtl). */
312         if (df_indirect_read_instance(ctx->node_id, 7, 0x208 + (16 * ctx->map.num),
313                                       ctx->inst_id, &ctx->map.ctl))
314                 return -EINVAL;
315
316         /* Read D18F7x20C (DramAddressIntlv). */
317         if (df_indirect_read_instance(ctx->node_id, 7, 0x20C + (16 * ctx->map.num),
318                                       ctx->inst_id, &ctx->map.intlv))
319                 return -EINVAL;
320
321         /* Check if Remap Enable bit is valid. */
322         if (!FIELD_GET(DF4_REMAP_EN, ctx->map.ctl))
323                 return 0;
324
325         /* Fill with bogus values, because '0' is a valid value. */
326         memset(&ctx->map.remap_array, 0xFF, sizeof(ctx->map.remap_array));
327
328         /* Get Remap registers. */
329         remap_sel = FIELD_GET(DF4p5_REMAP_SEL, ctx->map.ctl);
330
331         /* Read D18F7x180 (CsTargetRemap0A). */
332         if (df_indirect_read_instance(ctx->node_id, 7, 0x180 + (24 * remap_sel),
333                                       ctx->inst_id, &remap_reg))
334                 return -EINVAL;
335
336         /* Save first 6 remap entries. */
337         for (i = 0, j = 0; i < 6; i++, j++)
338                 ctx->map.remap_array[i] = (remap_reg >> (j * shift)) & mask;
339
340         /* Read D18F7x184 (CsTargetRemap0B). */
341         if (df_indirect_read_instance(ctx->node_id, 7, 0x184 + (24 * remap_sel),
342                                       ctx->inst_id, &remap_reg))
343                 return -EINVAL;
344
345         /* Save next 6 remap entries. */
346         for (i = 6, j = 0; i < 12; i++, j++)
347                 ctx->map.remap_array[i] = (remap_reg >> (j * shift)) & mask;
348
349         /* Read D18F7x188 (CsTargetRemap0C). */
350         if (df_indirect_read_instance(ctx->node_id, 7, 0x188 + (24 * remap_sel),
351                                       ctx->inst_id, &remap_reg))
352                 return -EINVAL;
353
354         /* Save next 6 remap entries. */
355         for (i = 12, j = 0; i < 18; i++, j++)
356                 ctx->map.remap_array[i] = (remap_reg >> (j * shift)) & mask;
357
358         return 0;
359 }
360
361 static int get_dram_addr_map(struct addr_ctx *ctx)
362 {
363         switch (df_cfg.rev) {
364         case DF2:       return df2_get_dram_addr_map(ctx);
365         case DF3:
366         case DF3p5:     return df3_get_dram_addr_map(ctx);
367         case DF4:       return df4_get_dram_addr_map(ctx);
368         case DF4p5:     return df4p5_get_dram_addr_map(ctx);
369         default:
370                         atl_debug_on_bad_df_rev();
371                         return -EINVAL;
372         }
373 }
374
375 static int get_coh_st_fabric_id(struct addr_ctx *ctx)
376 {
377         u32 reg;
378
379         /*
380          * On MI300 systems, the Coherent Station Fabric ID is derived
381          * later. And it does not depend on the register value.
382          */
383         if (df_cfg.rev == DF4p5 && df_cfg.flags.heterogeneous)
384                 return 0;
385
386         /* Read D18F0x50 (FabricBlockInstanceInformation3). */
387         if (df_indirect_read_instance(ctx->node_id, 0, 0x50, ctx->inst_id, &reg))
388                 return -EINVAL;
389
390         if (df_cfg.rev < DF4p5)
391                 ctx->coh_st_fabric_id = FIELD_GET(DF2_COH_ST_FABRIC_ID, reg);
392         else
393                 ctx->coh_st_fabric_id = FIELD_GET(DF4p5_COH_ST_FABRIC_ID, reg);
394
395         return 0;
396 }
397
398 static int find_normalized_offset(struct addr_ctx *ctx, u64 *norm_offset)
399 {
400         u64 last_offset = 0;
401         int ret;
402
403         for (ctx->map.num = 1; ctx->map.num < df_cfg.num_coh_st_maps; ctx->map.num++) {
404                 ret = get_dram_offset(ctx, norm_offset);
405                 if (ret < 0)
406                         return ret;
407
408                 /* Continue search if this map's offset is not enabled. */
409                 if (!ret)
410                         continue;
411
412                 /* Enabled offsets should never be 0. */
413                 if (*norm_offset == 0) {
414                         atl_debug(ctx, "Enabled map %u offset is 0", ctx->map.num);
415                         return -EINVAL;
416                 }
417
418                 /* Offsets should always increase from one map to the next. */
419                 if (*norm_offset <= last_offset) {
420                         atl_debug(ctx, "Map %u offset (0x%016llx) <= previous (0x%016llx)",
421                                   ctx->map.num, *norm_offset, last_offset);
422                         return -EINVAL;
423                 }
424
425                 /* Match if this map's offset is less than the current calculated address. */
426                 if (ctx->ret_addr >= *norm_offset)
427                         break;
428
429                 last_offset = *norm_offset;
430         }
431
432         /*
433          * Finished search without finding a match.
434          * Reset to map 0 and no offset.
435          */
436         if (ctx->map.num >= df_cfg.num_coh_st_maps) {
437                 ctx->map.num = 0;
438                 *norm_offset = 0;
439         }
440
441         return 0;
442 }
443
444 static bool valid_map(struct addr_ctx *ctx)
445 {
446         if (df_cfg.rev >= DF4)
447                 return FIELD_GET(DF_ADDR_RANGE_VAL, ctx->map.ctl);
448         else
449                 return FIELD_GET(DF_ADDR_RANGE_VAL, ctx->map.base);
450 }
451
452 static int get_address_map_common(struct addr_ctx *ctx)
453 {
454         u64 norm_offset = 0;
455
456         if (get_coh_st_fabric_id(ctx))
457                 return -EINVAL;
458
459         if (find_normalized_offset(ctx, &norm_offset))
460                 return -EINVAL;
461
462         if (get_dram_addr_map(ctx))
463                 return -EINVAL;
464
465         if (!valid_map(ctx))
466                 return -EINVAL;
467
468         ctx->ret_addr -= norm_offset;
469
470         return 0;
471 }
472
473 static u8 get_num_intlv_chan(struct addr_ctx *ctx)
474 {
475         switch (ctx->map.intlv_mode) {
476         case NONE:
477                 return 1;
478         case NOHASH_2CHAN:
479         case DF2_2CHAN_HASH:
480         case DF3_COD4_2CHAN_HASH:
481         case DF4_NPS4_2CHAN_HASH:
482         case DF4p5_NPS4_2CHAN_1K_HASH:
483         case DF4p5_NPS4_2CHAN_2K_HASH:
484                 return 2;
485         case DF4_NPS4_3CHAN_HASH:
486         case DF4p5_NPS4_3CHAN_1K_HASH:
487         case DF4p5_NPS4_3CHAN_2K_HASH:
488                 return 3;
489         case NOHASH_4CHAN:
490         case DF3_COD2_4CHAN_HASH:
491         case DF4_NPS2_4CHAN_HASH:
492         case DF4p5_NPS2_4CHAN_1K_HASH:
493         case DF4p5_NPS2_4CHAN_2K_HASH:
494                 return 4;
495         case DF4_NPS2_5CHAN_HASH:
496         case DF4p5_NPS2_5CHAN_1K_HASH:
497         case DF4p5_NPS2_5CHAN_2K_HASH:
498                 return 5;
499         case DF3_6CHAN:
500         case DF4_NPS2_6CHAN_HASH:
501         case DF4p5_NPS2_6CHAN_1K_HASH:
502         case DF4p5_NPS2_6CHAN_2K_HASH:
503                 return 6;
504         case NOHASH_8CHAN:
505         case DF3_COD1_8CHAN_HASH:
506         case DF4_NPS1_8CHAN_HASH:
507         case MI3_HASH_8CHAN:
508         case DF4p5_NPS1_8CHAN_1K_HASH:
509         case DF4p5_NPS1_8CHAN_2K_HASH:
510                 return 8;
511         case DF4_NPS1_10CHAN_HASH:
512         case DF4p5_NPS1_10CHAN_1K_HASH:
513         case DF4p5_NPS1_10CHAN_2K_HASH:
514                 return 10;
515         case DF4_NPS1_12CHAN_HASH:
516         case DF4p5_NPS1_12CHAN_1K_HASH:
517         case DF4p5_NPS1_12CHAN_2K_HASH:
518                 return 12;
519         case NOHASH_16CHAN:
520         case MI3_HASH_16CHAN:
521         case DF4p5_NPS1_16CHAN_1K_HASH:
522         case DF4p5_NPS1_16CHAN_2K_HASH:
523                 return 16;
524         case DF4p5_NPS0_24CHAN_1K_HASH:
525         case DF4p5_NPS0_24CHAN_2K_HASH:
526                 return 24;
527         case NOHASH_32CHAN:
528         case MI3_HASH_32CHAN:
529                 return 32;
530         default:
531                 atl_debug_on_bad_intlv_mode(ctx);
532                 return 0;
533         }
534 }
535
536 static void calculate_intlv_bits(struct addr_ctx *ctx)
537 {
538         ctx->map.num_intlv_chan = get_num_intlv_chan(ctx);
539
540         ctx->map.total_intlv_chan = ctx->map.num_intlv_chan;
541         ctx->map.total_intlv_chan *= ctx->map.num_intlv_dies;
542         ctx->map.total_intlv_chan *= ctx->map.num_intlv_sockets;
543
544         /*
545          * Get the number of bits needed to cover this many channels.
546          * order_base_2() rounds up automatically.
547          */
548         ctx->map.total_intlv_bits = order_base_2(ctx->map.total_intlv_chan);
549 }
550
551 static u8 get_intlv_bit_pos(struct addr_ctx *ctx)
552 {
553         u8 addr_sel = 0;
554
555         switch (df_cfg.rev) {
556         case DF2:
557                 addr_sel = FIELD_GET(DF2_INTLV_ADDR_SEL, ctx->map.base);
558                 break;
559         case DF3:
560         case DF3p5:
561                 addr_sel = FIELD_GET(DF3_INTLV_ADDR_SEL, ctx->map.base);
562                 break;
563         case DF4:
564         case DF4p5:
565                 addr_sel = FIELD_GET(DF4_INTLV_ADDR_SEL, ctx->map.intlv);
566                 break;
567         default:
568                 atl_debug_on_bad_df_rev();
569                 break;
570         }
571
572         /* Add '8' to get the 'interleave bit position'. */
573         return addr_sel + 8;
574 }
575
576 static u8 get_num_intlv_dies(struct addr_ctx *ctx)
577 {
578         u8 dies = 0;
579
580         switch (df_cfg.rev) {
581         case DF2:
582                 dies = FIELD_GET(DF2_INTLV_NUM_DIES, ctx->map.limit);
583                 break;
584         case DF3:
585                 dies = FIELD_GET(DF3_INTLV_NUM_DIES, ctx->map.base);
586                 break;
587         case DF3p5:
588                 dies = FIELD_GET(DF3p5_INTLV_NUM_DIES, ctx->map.base);
589                 break;
590         case DF4:
591         case DF4p5:
592                 dies = FIELD_GET(DF4_INTLV_NUM_DIES, ctx->map.intlv);
593                 break;
594         default:
595                 atl_debug_on_bad_df_rev();
596                 break;
597         }
598
599         /* Register value is log2, e.g. 0 -> 1 die, 1 -> 2 dies, etc. */
600         return 1 << dies;
601 }
602
603 static u8 get_num_intlv_sockets(struct addr_ctx *ctx)
604 {
605         u8 sockets = 0;
606
607         switch (df_cfg.rev) {
608         case DF2:
609                 sockets = FIELD_GET(DF2_INTLV_NUM_SOCKETS, ctx->map.limit);
610                 break;
611         case DF3:
612         case DF3p5:
613                 sockets = FIELD_GET(DF2_INTLV_NUM_SOCKETS, ctx->map.base);
614                 break;
615         case DF4:
616         case DF4p5:
617                 sockets = FIELD_GET(DF4_INTLV_NUM_SOCKETS, ctx->map.intlv);
618                 break;
619         default:
620                 atl_debug_on_bad_df_rev();
621                 break;
622         }
623
624         /* Register value is log2, e.g. 0 -> 1 sockets, 1 -> 2 sockets, etc. */
625         return 1 << sockets;
626 }
627
628 static int get_global_map_data(struct addr_ctx *ctx)
629 {
630         if (get_intlv_mode(ctx))
631                 return -EINVAL;
632
633         if (ctx->map.intlv_mode == DF3_6CHAN &&
634             df3_6ch_get_dram_addr_map(ctx))
635                 return -EINVAL;
636
637         ctx->map.intlv_bit_pos          = get_intlv_bit_pos(ctx);
638         ctx->map.num_intlv_dies         = get_num_intlv_dies(ctx);
639         ctx->map.num_intlv_sockets      = get_num_intlv_sockets(ctx);
640         calculate_intlv_bits(ctx);
641
642         return 0;
643 }
644
645 static void dump_address_map(struct dram_addr_map *map)
646 {
647         u8 i;
648
649         pr_debug("intlv_mode=0x%x",             map->intlv_mode);
650         pr_debug("num=0x%x",                    map->num);
651         pr_debug("base=0x%x",                   map->base);
652         pr_debug("limit=0x%x",                  map->limit);
653         pr_debug("ctl=0x%x",                    map->ctl);
654         pr_debug("intlv=0x%x",                  map->intlv);
655
656         for (i = 0; i < MAX_COH_ST_CHANNELS; i++)
657                 pr_debug("remap_array[%u]=0x%x", i, map->remap_array[i]);
658
659         pr_debug("intlv_bit_pos=%u",            map->intlv_bit_pos);
660         pr_debug("num_intlv_chan=%u",           map->num_intlv_chan);
661         pr_debug("num_intlv_dies=%u",           map->num_intlv_dies);
662         pr_debug("num_intlv_sockets=%u",        map->num_intlv_sockets);
663         pr_debug("total_intlv_chan=%u",         map->total_intlv_chan);
664         pr_debug("total_intlv_bits=%u",         map->total_intlv_bits);
665 }
666
667 int get_address_map(struct addr_ctx *ctx)
668 {
669         int ret;
670
671         ret = get_address_map_common(ctx);
672         if (ret)
673                 return ret;
674
675         ret = get_global_map_data(ctx);
676         if (ret)
677                 return ret;
678
679         dump_address_map(&ctx->map);
680
681         return ret;
682 }