1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> 4 */ 5 6 #include <common.h> 7 #include <errno.h> 8 #include <fdtdec.h> 9 #include <malloc.h> 10 #include <asm/mrccache.h> 11 #include <asm/mtrr.h> 12 #include <asm/post.h> 13 #include <asm/arch/mrc.h> 14 #include <asm/arch/msg_port.h> 15 #include <asm/arch/quark.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 static __maybe_unused int prepare_mrc_cache(struct mrc_params *mrc_params) 20 { 21 struct mrc_data_container *cache; 22 struct mrc_region entry; 23 int ret; 24 25 ret = mrccache_get_region(NULL, &entry); 26 if (ret) 27 return ret; 28 29 cache = mrccache_find_current(&entry); 30 if (!cache) 31 return -ENOENT; 32 33 debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__, 34 cache->data, cache->data_size, cache->checksum); 35 36 /* copy mrc cache to the mrc_params */ 37 memcpy(&mrc_params->timings, cache->data, cache->data_size); 38 39 return 0; 40 } 41 42 static int mrc_configure_params(struct mrc_params *mrc_params) 43 { 44 const void *blob = gd->fdt_blob; 45 int node; 46 int mrc_flags; 47 48 node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_QRK_MRC); 49 if (node < 0) { 50 debug("%s: Cannot find MRC node\n", __func__); 51 return -EINVAL; 52 } 53 54 #ifdef CONFIG_ENABLE_MRC_CACHE 55 mrc_params->boot_mode = prepare_mrc_cache(mrc_params); 56 if (mrc_params->boot_mode) 57 mrc_params->boot_mode = BM_COLD; 58 else 59 mrc_params->boot_mode = BM_FAST; 60 #else 61 mrc_params->boot_mode = BM_COLD; 62 #endif 63 64 /* 65 * TODO: 66 * 67 * We need determine ECC by pin strap state 68 * 69 * Disable ECC by default for now 70 */ 71 mrc_params->ecc_enables = 0; 72 73 mrc_flags = fdtdec_get_int(blob, node, "flags", 0); 74 if (mrc_flags & MRC_FLAG_SCRAMBLE_EN) 75 mrc_params->scrambling_enables = 1; 76 else 77 mrc_params->scrambling_enables = 0; 78 79 mrc_params->dram_width = fdtdec_get_int(blob, node, "dram-width", 0); 80 mrc_params->ddr_speed = fdtdec_get_int(blob, node, "dram-speed", 0); 81 mrc_params->ddr_type = fdtdec_get_int(blob, node, "dram-type", 0); 82 83 mrc_params->rank_enables = fdtdec_get_int(blob, node, "rank-mask", 0); 84 mrc_params->channel_enables = fdtdec_get_int(blob, node, 85 "chan-mask", 0); 86 mrc_params->channel_width = fdtdec_get_int(blob, node, 87 "chan-width", 0); 88 mrc_params->address_mode = fdtdec_get_int(blob, node, "addr-mode", 0); 89 90 mrc_params->refresh_rate = fdtdec_get_int(blob, node, 91 "refresh-rate", 0); 92 mrc_params->sr_temp_range = fdtdec_get_int(blob, node, 93 "sr-temp-range", 0); 94 mrc_params->ron_value = fdtdec_get_int(blob, node, 95 "ron-value", 0); 96 mrc_params->rtt_nom_value = fdtdec_get_int(blob, node, 97 "rtt-nom-value", 0); 98 mrc_params->rd_odt_value = fdtdec_get_int(blob, node, 99 "rd-odt-value", 0); 100 101 mrc_params->params.density = fdtdec_get_int(blob, node, 102 "dram-density", 0); 103 mrc_params->params.cl = fdtdec_get_int(blob, node, "dram-cl", 0); 104 mrc_params->params.ras = fdtdec_get_int(blob, node, "dram-ras", 0); 105 mrc_params->params.wtr = fdtdec_get_int(blob, node, "dram-wtr", 0); 106 mrc_params->params.rrd = fdtdec_get_int(blob, node, "dram-rrd", 0); 107 mrc_params->params.faw = fdtdec_get_int(blob, node, "dram-faw", 0); 108 109 debug("MRC dram_width %d\n", mrc_params->dram_width); 110 debug("MRC rank_enables %d\n", mrc_params->rank_enables); 111 debug("MRC ddr_speed %d\n", mrc_params->ddr_speed); 112 debug("MRC flags: %s\n", 113 (mrc_params->scrambling_enables) ? "SCRAMBLE_EN" : ""); 114 115 debug("MRC density=%d tCL=%d tRAS=%d tWTR=%d tRRD=%d tFAW=%d\n", 116 mrc_params->params.density, mrc_params->params.cl, 117 mrc_params->params.ras, mrc_params->params.wtr, 118 mrc_params->params.rrd, mrc_params->params.faw); 119 120 return 0; 121 } 122 123 int dram_init(void) 124 { 125 struct mrc_params mrc_params; 126 #ifdef CONFIG_ENABLE_MRC_CACHE 127 char *cache; 128 #endif 129 int ret; 130 131 memset(&mrc_params, 0, sizeof(struct mrc_params)); 132 ret = mrc_configure_params(&mrc_params); 133 if (ret) 134 return ret; 135 136 /* Set up the DRAM by calling the memory reference code */ 137 mrc_init(&mrc_params); 138 if (mrc_params.status) 139 return -EIO; 140 141 gd->ram_size = mrc_params.mem_size; 142 post_code(POST_DRAM); 143 144 /* variable range MTRR#2: RAM area */ 145 disable_caches(); 146 msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_RAM), 147 0 | MTRR_TYPE_WRBACK); 148 msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_RAM), 149 (~(gd->ram_size - 1)) | MTRR_PHYS_MASK_VALID); 150 enable_caches(); 151 152 #ifdef CONFIG_ENABLE_MRC_CACHE 153 cache = malloc(sizeof(struct mrc_timings)); 154 if (cache) { 155 memcpy(cache, &mrc_params.timings, sizeof(struct mrc_timings)); 156 gd->arch.mrc_output = cache; 157 gd->arch.mrc_output_len = sizeof(struct mrc_timings); 158 } 159 #endif 160 161 return 0; 162 } 163 164 int dram_init_banksize(void) 165 { 166 gd->bd->bi_dram[0].start = 0; 167 gd->bd->bi_dram[0].size = gd->ram_size; 168 169 return 0; 170 } 171 172 /* 173 * This function looks for the highest region of memory lower than 4GB which 174 * has enough space for U-Boot where U-Boot is aligned on a page boundary. 175 * It overrides the default implementation found elsewhere which simply 176 * picks the end of ram, wherever that may be. The location of the stack, 177 * the relocation address, and how far U-Boot is moved by relocation are 178 * set in the global data structure. 179 */ 180 ulong board_get_usable_ram_top(ulong total_size) 181 { 182 return gd->ram_size; 183 } 184