Angel Pons | 5f249e6 | 2020-04-04 18:51:01 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Angel Pons | 5f249e6 | 2020-04-04 18:51:01 +0200 | [diff] [blame] | 2 | |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 3 | /* |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 4 | * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0. |
| 5 | */ |
| 6 | |
| 7 | #include <console/console.h> |
| 8 | #include <soc/sdram.h> |
| 9 | |
| 10 | #include <libbdk-arch/bdk-warn.h> |
| 11 | #include <libbdk-arch/bdk-csrs-rst.h> |
| 12 | #include <libbdk-boot/bdk-watchdog.h> |
| 13 | #include <libbdk-dram/bdk-dram-config.h> |
| 14 | #include <libbdk-dram/bdk-dram-test.h> |
| 15 | #include <libbdk-hal/bdk-config.h> |
| 16 | #include <libbdk-hal/bdk-utils.h> |
| 17 | #include <libbdk-hal/bdk-l2c.h> |
| 18 | #include <libdram/libdram-config.h> |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 19 | #include <soc/ecam.h> |
| 20 | #include <device/pci_ops.h> |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 21 | #include <device/mmio.h> |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 22 | #include <device/pci.h> |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 23 | |
| 24 | size_t sdram_size_mb(void) |
| 25 | { |
| 26 | return bdk_dram_get_size_mbytes(0); |
| 27 | } |
| 28 | |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 29 | #define BDK_RNM_CTL_STATUS 0 |
| 30 | #define BDK_RNM_RANDOM 0x100000 |
| 31 | |
Kyösti Mälkki | 11cac78 | 2022-04-07 07:16:48 +0300 | [diff] [blame] | 32 | #if ENV_RAMINIT |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 33 | /* Enable RNG for DRAM init */ |
| 34 | static void rnm_init(void) |
| 35 | { |
| 36 | /* Bus numbers are hardcoded in ASIC. No need to program bridges. */ |
| 37 | pci_devfn_t dev = PCI_DEV(2, 0, 0); |
| 38 | |
| 39 | u64 *bar = (u64 *)ecam0_get_bar_val(dev, 0); |
| 40 | if (!bar) { |
| 41 | printk(BIOS_ERR, "RNG: Failed to get BAR0\n"); |
| 42 | return; |
| 43 | } |
| 44 | |
| 45 | printk(BIOS_DEBUG, "RNG: BAR0 at %p\n", bar); |
| 46 | |
| 47 | u64 reg = read64(&bar[BDK_RNM_CTL_STATUS]); |
| 48 | /* |
| 49 | * Enables the output of the RNG. |
| 50 | * Entropy enable for random number generator. |
| 51 | */ |
| 52 | reg |= 3; |
| 53 | write64(&bar[BDK_RNM_CTL_STATUS], reg); |
| 54 | |
| 55 | /* Read back after enable so we know it is done. */ |
| 56 | reg = read64(&bar[BDK_RNM_CTL_STATUS]); |
| 57 | /* |
| 58 | * Errata (RNM-22528) First consecutive reads to RNM_RANDOM return same |
| 59 | * value. Before using the random entropy, read RNM_RANDOM at least once |
| 60 | * and discard the data |
| 61 | */ |
| 62 | reg = read64(&bar[BDK_RNM_RANDOM]); |
| 63 | printk(BIOS_SPEW, "RNG: RANDOM %llx\n", reg); |
| 64 | reg = read64(&bar[BDK_RNM_RANDOM]); |
| 65 | printk(BIOS_SPEW, "RNG: RANDOM %llx\n", reg); |
| 66 | } |
| 67 | |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 68 | /* based on bdk_boot_dram() */ |
| 69 | void sdram_init(void) |
| 70 | { |
| 71 | printk(BIOS_DEBUG, "Initializing DRAM\n"); |
| 72 | |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 73 | rnm_init(); |
| 74 | |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 75 | /** |
| 76 | * FIXME: second arg is actually a desired frequency if set (the |
| 77 | * function usually obtains frequency via the config). That might |
| 78 | * be useful if FDT or u-boot env is too cumbersome. |
| 79 | */ |
| 80 | int mbytes = bdk_dram_config(0, 0); |
| 81 | if (mbytes < 0) { |
| 82 | bdk_error("N0: Failed DRAM init\n"); |
| 83 | die("DRAM INIT FAILED !\n"); |
| 84 | } |
| 85 | |
| 86 | /* Poke the watchdog */ |
| 87 | bdk_watchdog_poke(); |
| 88 | |
| 89 | /* Report DRAM status */ |
| 90 | printf("N0: DRAM:%s\n", bdk_dram_get_info_string(0)); |
| 91 | |
| 92 | /* See if we should test this node's DRAM during boot */ |
| 93 | int test_dram = bdk_config_get_int(BDK_CONFIG_DRAM_BOOT_TEST, 0); |
Patrick Rudolph | 3f4f5a3 | 2018-06-14 15:11:57 +0200 | [diff] [blame] | 94 | if (test_dram == 1) { |
| 95 | static const u8 tests[] = {13, 0, 1}; |
| 96 | for (size_t i = 0; i < ARRAY_SIZE(tests); i++) { |
| 97 | /* Run the address test to make sure DRAM works */ |
| 98 | if (bdk_dram_test(tests[i], 4 * MiB, |
| 99 | sdram_size_mb() * MiB - 4 * MiB, |
| 100 | BDK_DRAM_TEST_NO_STATS | |
| 101 | BDK_DRAM_TEST_NODE0)) { |
| 102 | printk(BIOS_CRIT, "%s: Failed DRAM test.\n", |
| 103 | __func__); |
| 104 | } |
| 105 | bdk_watchdog_poke(); |
| 106 | } |
| 107 | } else { |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 108 | /* Run the address test to make sure DRAM works */ |
Patrick Rudolph | 3f4f5a3 | 2018-06-14 15:11:57 +0200 | [diff] [blame] | 109 | if (bdk_dram_test(13, 4 * MiB, |
| 110 | sdram_size_mb() * MiB - 4 * MiB, |
| 111 | BDK_DRAM_TEST_NO_STATS | |
| 112 | BDK_DRAM_TEST_NODE0)) { |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 113 | /** |
Patrick Rudolph | 3f4f5a3 | 2018-06-14 15:11:57 +0200 | [diff] [blame] | 114 | * FIXME(dhendrix): This should be handled by mainboard |
| 115 | * code since we don't necessarily have a BMC to report |
| 116 | * to. Also, we need to figure out if we need to keep |
| 117 | * going as to avoid getting into a boot loop. |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 118 | */ |
| 119 | // bdk_boot_status(BDK_BOOT_STATUS_REQUEST_POWER_CYCLE); |
Patrick Rudolph | 3f4f5a3 | 2018-06-14 15:11:57 +0200 | [diff] [blame] | 120 | printk(BIOS_CRIT, "%s: Failed DRAM test.\n", __func__); |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 121 | } |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 122 | } |
| 123 | |
Patrick Rudolph | 3f4f5a3 | 2018-06-14 15:11:57 +0200 | [diff] [blame] | 124 | bdk_watchdog_poke(); |
| 125 | |
David Hendricks | 8cbd569 | 2017-12-01 20:49:48 -0800 | [diff] [blame] | 126 | /* Unlock L2 now that DRAM works */ |
| 127 | if (0 == bdk_numa_master()) { |
| 128 | uint64_t l2_size = bdk_l2c_get_cache_size_bytes(0); |
| 129 | BDK_TRACE(INIT, "Unlocking L2\n"); |
| 130 | bdk_l2c_unlock_mem_region(0, 0, l2_size); |
| 131 | bdk_watchdog_poke(); |
| 132 | } |
| 133 | |
| 134 | printk(BIOS_INFO, "SDRAM initialization finished.\n"); |
| 135 | } |
Patrick Rudolph | 6220f8d | 2019-02-22 12:06:41 +0100 | [diff] [blame] | 136 | #endif |