Amanda Huang | 6a5c50b | 2024-05-27 16:38:09 +0800 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
| 3 | #include <baseboard/variants.h> |
| 4 | #include <gpio.h> |
| 5 | #include <soc/romstage.h> |
| 6 | |
| 7 | static const struct mb_cfg variant_memcfg = { |
| 8 | .type = MEM_TYPE_LP5X, |
| 9 | |
| 10 | .rcomp = { |
| 11 | /* Baseboard uses only 100ohm Rcomp resistors */ |
| 12 | .resistor = 100, |
| 13 | }, |
| 14 | |
| 15 | /* DQ byte map */ |
| 16 | .lpx_dq_map = { |
| 17 | .ddr0 = { |
| 18 | .dq0 = { 12, 9, 10, 11, 14, 13, 8, 15 }, |
| 19 | .dq1 = { 3, 1, 2, 0, 4, 7, 5, 6 }, |
| 20 | }, |
| 21 | .ddr1 = { |
| 22 | .dq0 = { 3, 1, 2, 0, 4, 7, 5, 6 }, |
| 23 | .dq1 = { 13, 9, 8, 11, 10, 14, 15, 12 }, |
| 24 | }, |
| 25 | .ddr2 = { |
| 26 | .dq0 = { 2, 1, 3, 0, 4, 6, 5, 7 }, |
| 27 | .dq1 = { 8, 9, 10, 11, 13, 14, 12, 15 }, |
| 28 | }, |
| 29 | .ddr3 = { |
| 30 | .dq0 = { 3, 0, 1, 2, 5, 6, 4, 7 }, |
| 31 | .dq1 = { 13, 9, 11, 8, 14, 15, 10, 12 }, |
| 32 | }, |
| 33 | .ddr4 = { |
| 34 | .dq0 = { 12, 9, 10, 11, 14, 13, 8, 15 }, |
| 35 | .dq1 = { 3, 1, 2, 0, 4, 7, 5, 6 }, |
| 36 | }, |
| 37 | .ddr5 = { |
| 38 | .dq0 = { 3, 1, 2, 0, 4, 7, 5, 6 }, |
| 39 | .dq1 = { 13, 9, 8, 11, 10, 14, 15, 12 }, |
| 40 | }, |
| 41 | .ddr6 = { |
| 42 | .dq0 = { 2, 1, 3, 0, 4, 6, 5, 7 }, |
| 43 | .dq1 = { 8, 9, 10, 11, 13, 14, 12, 15 }, |
| 44 | }, |
| 45 | .ddr7 = { |
| 46 | .dq0 = { 3, 0, 1, 2, 5, 6, 4, 7 }, |
| 47 | .dq1 = { 13, 9, 11, 8, 14, 15, 10, 12 }, |
| 48 | }, |
| 49 | }, |
| 50 | |
| 51 | /* DQS CPU<>DRAM map */ |
| 52 | .lpx_dqs_map = { |
| 53 | .ddr0 = { .dqs0 = 1, .dqs1 = 0 }, |
| 54 | .ddr1 = { .dqs0 = 0, .dqs1 = 1 }, |
| 55 | .ddr2 = { .dqs0 = 0, .dqs1 = 1 }, |
| 56 | .ddr3 = { .dqs0 = 0, .dqs1 = 1 }, |
| 57 | .ddr4 = { .dqs0 = 1, .dqs1 = 0 }, |
| 58 | .ddr5 = { .dqs0 = 0, .dqs1 = 1 }, |
| 59 | .ddr6 = { .dqs0 = 0, .dqs1 = 1 }, |
| 60 | .ddr7 = { .dqs0 = 0, .dqs1 = 1 }, |
| 61 | }, |
| 62 | |
| 63 | .lp5x_config = { |
| 64 | .ccc_config = 0xff, |
| 65 | }, |
| 66 | |
| 67 | .ect = 1, /* Early Command Training */ |
| 68 | |
| 69 | .UserBd = BOARD_TYPE_MOBILE, |
| 70 | }; |
| 71 | |
| 72 | const struct mb_cfg *variant_memory_params(void) |
| 73 | { |
| 74 | return &variant_memcfg; |
| 75 | } |
| 76 | |
| 77 | int variant_memory_sku(void) |
| 78 | { |
| 79 | /* |
| 80 | * Memory configuration board straps |
| 81 | * GPIO_MEM_CONFIG_0 GPP_E1 |
| 82 | * GPIO_MEM_CONFIG_1 GPP_E2 |
| 83 | * GPIO_MEM_CONFIG_2 GPP_E12 |
| 84 | */ |
| 85 | gpio_t spd_gpios[] = { |
| 86 | GPP_E1, |
| 87 | GPP_E2, |
| 88 | GPP_E12, |
| 89 | }; |
| 90 | |
| 91 | return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); |
| 92 | } |
| 93 | |
| 94 | bool variant_is_half_populated(void) |
| 95 | { |
| 96 | /* |
| 97 | * Ideally half_populated is used in platforms with multiple channels to |
| 98 | * enable only one half of the channel. Alder Lake N has single channel, |
| 99 | * and it would require for new structures to be defined in meminit block |
| 100 | * driver for LPx memory configurations. In order to avoid adding new |
| 101 | * structures, set half_populated to true. This has the same effect as |
| 102 | * having single channel with 64-bit width. |
| 103 | */ |
| 104 | return true; |
| 105 | } |
| 106 | |
| 107 | void variant_get_spd_info(struct mem_spd *spd_info) |
| 108 | { |
| 109 | spd_info->topo = MEM_TOPO_MEMORY_DOWN; |
| 110 | spd_info->cbfs_index = variant_memory_sku(); |
| 111 | } |