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