1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2011 The Chromium OS Authors. 4 */ 5 6 #include <common.h> 7 #include <fdtdec.h> 8 #include <asm/io.h> 9 #include <asm/arch-tegra/ap.h> 10 #include <asm/arch-tegra/apb_misc.h> 11 #include <asm/arch/clock.h> 12 #include <asm/arch/emc.h> 13 #include <asm/arch/tegra.h> 14 15 /* 16 * The EMC registers have shadow registers. When the EMC clock is updated 17 * in the clock controller, the shadow registers are copied to the active 18 * registers, allowing glitchless memory bus frequency changes. 19 * This function updates the shadow registers for a new clock frequency, 20 * and relies on the clock lock on the emc clock to avoid races between 21 * multiple frequency changes 22 */ 23 24 /* 25 * This table defines the ordering of the registers provided to 26 * tegra_set_mmc() 27 * TODO: Convert to fdt version once available 28 */ 29 static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { 30 0x2c, /* RC */ 31 0x30, /* RFC */ 32 0x34, /* RAS */ 33 0x38, /* RP */ 34 0x3c, /* R2W */ 35 0x40, /* W2R */ 36 0x44, /* R2P */ 37 0x48, /* W2P */ 38 0x4c, /* RD_RCD */ 39 0x50, /* WR_RCD */ 40 0x54, /* RRD */ 41 0x58, /* REXT */ 42 0x5c, /* WDV */ 43 0x60, /* QUSE */ 44 0x64, /* QRST */ 45 0x68, /* QSAFE */ 46 0x6c, /* RDV */ 47 0x70, /* REFRESH */ 48 0x74, /* BURST_REFRESH_NUM */ 49 0x78, /* PDEX2WR */ 50 0x7c, /* PDEX2RD */ 51 0x80, /* PCHG2PDEN */ 52 0x84, /* ACT2PDEN */ 53 0x88, /* AR2PDEN */ 54 0x8c, /* RW2PDEN */ 55 0x90, /* TXSR */ 56 0x94, /* TCKE */ 57 0x98, /* TFAW */ 58 0x9c, /* TRPAB */ 59 0xa0, /* TCLKSTABLE */ 60 0xa4, /* TCLKSTOP */ 61 0xa8, /* TREFBW */ 62 0xac, /* QUSE_EXTRA */ 63 0x114, /* FBIO_CFG6 */ 64 0xb0, /* ODT_WRITE */ 65 0xb4, /* ODT_READ */ 66 0x104, /* FBIO_CFG5 */ 67 0x2bc, /* CFG_DIG_DLL */ 68 0x2c0, /* DLL_XFORM_DQS */ 69 0x2c4, /* DLL_XFORM_QUSE */ 70 0x2e0, /* ZCAL_REF_CNT */ 71 0x2e4, /* ZCAL_WAIT_CNT */ 72 0x2a8, /* AUTO_CAL_INTERVAL */ 73 0x2d0, /* CFG_CLKTRIM_0 */ 74 0x2d4, /* CFG_CLKTRIM_1 */ 75 0x2d8, /* CFG_CLKTRIM_2 */ 76 }; 77 78 struct emc_ctlr *emc_get_controller(const void *blob) 79 { 80 fdt_addr_t addr; 81 int node; 82 83 node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); 84 if (node > 0) { 85 addr = fdtdec_get_addr(blob, node, "reg"); 86 if (addr != FDT_ADDR_T_NONE) 87 return (struct emc_ctlr *)addr; 88 } 89 return NULL; 90 } 91 92 /* Error codes we use */ 93 enum { 94 ERR_NO_EMC_NODE = -10, 95 ERR_NO_EMC_REG, 96 ERR_NO_FREQ, 97 ERR_FREQ_NOT_FOUND, 98 ERR_BAD_REGS, 99 ERR_NO_RAM_CODE, 100 ERR_RAM_CODE_NOT_FOUND, 101 }; 102 103 /** 104 * Find EMC tables for the given ram code. 105 * 106 * The tegra EMC binding has two options, one using the ram code and one not. 107 * We detect which is in use by looking for the nvidia,use-ram-code property. 108 * If this is not present, then the EMC tables are directly below 'node', 109 * otherwise we select the correct emc-tables subnode based on the 'ram_code' 110 * value. 111 * 112 * @param blob Device tree blob 113 * @param node EMC node (nvidia,tegra20-emc compatible string) 114 * @param ram_code RAM code to select (0-3, or -1 if unknown) 115 * @return 0 if ok, otherwise a -ve ERR_ code (see enum above) 116 */ 117 static int find_emc_tables(const void *blob, int node, int ram_code) 118 { 119 int need_ram_code; 120 int depth; 121 int offset; 122 123 /* If we are using RAM codes, scan through the tables for our code */ 124 need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code"); 125 if (!need_ram_code) 126 return node; 127 if (ram_code == -1) { 128 debug("%s: RAM code required but not supplied\n", __func__); 129 return ERR_NO_RAM_CODE; 130 } 131 132 offset = node; 133 depth = 0; 134 do { 135 /* 136 * Sadly there is no compatible string so we cannot use 137 * fdtdec_next_compatible_subnode(). 138 */ 139 offset = fdt_next_node(blob, offset, &depth); 140 if (depth <= 0) 141 break; 142 143 /* Make sure this is a direct subnode */ 144 if (depth != 1) 145 continue; 146 if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL))) 147 continue; 148 149 if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1) 150 == ram_code) 151 return offset; 152 } while (1); 153 154 debug("%s: Could not find tables for RAM code %d\n", __func__, 155 ram_code); 156 return ERR_RAM_CODE_NOT_FOUND; 157 } 158 159 /** 160 * Decode the EMC node of the device tree, returning a pointer to the emc 161 * controller and the table to be used for the given rate. 162 * 163 * @param blob Device tree blob 164 * @param rate Clock speed of memory controller in Hz (=2x memory bus rate) 165 * @param emcp Returns address of EMC controller registers 166 * @param tablep Returns pointer to table to program into EMC. There are 167 * TEGRA_EMC_NUM_REGS entries, destined for offsets as per the 168 * emc_reg_addr array. 169 * @return 0 if ok, otherwise a -ve error code which will allow someone to 170 * figure out roughly what went wrong by looking at this code. 171 */ 172 static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp, 173 const u32 **tablep) 174 { 175 struct apb_misc_pp_ctlr *pp = 176 (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; 177 int ram_code; 178 int depth; 179 int node; 180 181 ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK) 182 >> RAM_CODE_SHIFT; 183 /* 184 * The EMC clock rate is twice the bus rate, and the bus rate is 185 * measured in kHz 186 */ 187 rate = rate / 2 / 1000; 188 189 node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); 190 if (node < 0) { 191 debug("%s: No EMC node found in FDT\n", __func__); 192 return ERR_NO_EMC_NODE; 193 } 194 *emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg"); 195 if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) { 196 debug("%s: No EMC node reg property\n", __func__); 197 return ERR_NO_EMC_REG; 198 } 199 200 /* Work out the parent node which contains our EMC tables */ 201 node = find_emc_tables(blob, node, ram_code & 3); 202 if (node < 0) 203 return node; 204 205 depth = 0; 206 for (;;) { 207 int node_rate; 208 209 node = fdtdec_next_compatible_subnode(blob, node, 210 COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth); 211 if (node < 0) 212 break; 213 node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1); 214 if (node_rate == -1) { 215 debug("%s: Missing clock-frequency\n", __func__); 216 return ERR_NO_FREQ; /* we expect this property */ 217 } 218 219 if (node_rate == rate) 220 break; 221 } 222 if (node < 0) { 223 debug("%s: No node found for clock frequency %d\n", __func__, 224 rate); 225 return ERR_FREQ_NOT_FOUND; 226 } 227 228 *tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers", 229 TEGRA_EMC_NUM_REGS); 230 if (!*tablep) { 231 debug("%s: node '%s' array missing / wrong size\n", __func__, 232 fdt_get_name(blob, node, NULL)); 233 return ERR_BAD_REGS; 234 } 235 236 /* All seems well */ 237 return 0; 238 } 239 240 int tegra_set_emc(const void *blob, unsigned rate) 241 { 242 struct emc_ctlr *emc; 243 const u32 *table = NULL; 244 int err, i; 245 246 err = decode_emc(blob, rate, &emc, &table); 247 if (err) { 248 debug("Warning: no valid EMC (%d), memory timings unset\n", 249 err); 250 return err; 251 } 252 253 debug("%s: Table found, setting EMC values as follows:\n", __func__); 254 for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) { 255 u32 value = fdt32_to_cpu(table[i]); 256 u32 addr = (uintptr_t)emc + emc_reg_addr[i]; 257 258 debug(" %#x: %#x\n", addr, value); 259 writel(value, addr); 260 } 261 262 /* trigger emc with new settings */ 263 clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY, 264 clock_get_rate(CLOCK_ID_MEMORY), NULL); 265 debug("EMC clock set to %lu\n", 266 clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY)); 267 268 return 0; 269 } 270