Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memory: tegra: Add EMC (external memory controller) driver

Implements functionality needed to change the rate of the memory bus
clock.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Mikko Perttunen and committed by
Thierry Reding
73a7f0a9 3d9dd6fd

+1123
+10
drivers/memory/tegra/Kconfig
··· 5 5 help 6 6 This driver supports the Memory Controller (MC) hardware found on 7 7 NVIDIA Tegra SoCs. 8 + 9 + config TEGRA124_EMC 10 + bool "NVIDIA Tegra124 External Memory Controller driver" 11 + default y 12 + depends on TEGRA_MC && ARCH_TEGRA_124_SOC 13 + help 14 + This driver is for the External Memory Controller (EMC) found on 15 + Tegra124 chips. The EMC controls the external DRAM on the board. 16 + This driver is required to change memory timings / clock rate for 17 + external memory.
+2
drivers/memory/tegra/Makefile
··· 5 5 tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o 6 6 7 7 obj-$(CONFIG_TEGRA_MC) += tegra-mc.o 8 + 9 + obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
+1092
drivers/memory/tegra/tegra124-emc.c
··· 1 + /* 2 + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * Author: 5 + * Mikko Perttunen <mperttunen@nvidia.com> 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #include <linux/clk-provider.h> 19 + #include <linux/clk.h> 20 + #include <linux/clkdev.h> 21 + #include <linux/delay.h> 22 + #include <linux/of_address.h> 23 + #include <linux/of_platform.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/sort.h> 26 + #include <linux/string.h> 27 + 28 + #include <soc/tegra/emc.h> 29 + #include <soc/tegra/fuse.h> 30 + #include <soc/tegra/mc.h> 31 + 32 + #define EMC_FBIO_CFG5 0x104 33 + #define EMC_FBIO_CFG5_DRAM_TYPE_MASK 0x3 34 + #define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT 0 35 + 36 + #define EMC_INTSTATUS 0x0 37 + #define EMC_INTSTATUS_CLKCHANGE_COMPLETE BIT(4) 38 + 39 + #define EMC_CFG 0xc 40 + #define EMC_CFG_DRAM_CLKSTOP_PD BIT(31) 41 + #define EMC_CFG_DRAM_CLKSTOP_SR BIT(30) 42 + #define EMC_CFG_DRAM_ACPD BIT(29) 43 + #define EMC_CFG_DYN_SREF BIT(28) 44 + #define EMC_CFG_PWR_MASK ((0xF << 28) | BIT(18)) 45 + #define EMC_CFG_DSR_VTTGEN_DRV_EN BIT(18) 46 + 47 + #define EMC_REFCTRL 0x20 48 + #define EMC_REFCTRL_DEV_SEL_SHIFT 0 49 + #define EMC_REFCTRL_ENABLE BIT(31) 50 + 51 + #define EMC_TIMING_CONTROL 0x28 52 + #define EMC_RC 0x2c 53 + #define EMC_RFC 0x30 54 + #define EMC_RAS 0x34 55 + #define EMC_RP 0x38 56 + #define EMC_R2W 0x3c 57 + #define EMC_W2R 0x40 58 + #define EMC_R2P 0x44 59 + #define EMC_W2P 0x48 60 + #define EMC_RD_RCD 0x4c 61 + #define EMC_WR_RCD 0x50 62 + #define EMC_RRD 0x54 63 + #define EMC_REXT 0x58 64 + #define EMC_WDV 0x5c 65 + #define EMC_QUSE 0x60 66 + #define EMC_QRST 0x64 67 + #define EMC_QSAFE 0x68 68 + #define EMC_RDV 0x6c 69 + #define EMC_REFRESH 0x70 70 + #define EMC_BURST_REFRESH_NUM 0x74 71 + #define EMC_PDEX2WR 0x78 72 + #define EMC_PDEX2RD 0x7c 73 + #define EMC_PCHG2PDEN 0x80 74 + #define EMC_ACT2PDEN 0x84 75 + #define EMC_AR2PDEN 0x88 76 + #define EMC_RW2PDEN 0x8c 77 + #define EMC_TXSR 0x90 78 + #define EMC_TCKE 0x94 79 + #define EMC_TFAW 0x98 80 + #define EMC_TRPAB 0x9c 81 + #define EMC_TCLKSTABLE 0xa0 82 + #define EMC_TCLKSTOP 0xa4 83 + #define EMC_TREFBW 0xa8 84 + #define EMC_ODT_WRITE 0xb0 85 + #define EMC_ODT_READ 0xb4 86 + #define EMC_WEXT 0xb8 87 + #define EMC_CTT 0xbc 88 + #define EMC_RFC_SLR 0xc0 89 + #define EMC_MRS_WAIT_CNT2 0xc4 90 + 91 + #define EMC_MRS_WAIT_CNT 0xc8 92 + #define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0 93 + #define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \ 94 + (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT) 95 + #define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16 96 + #define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \ 97 + (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) 98 + 99 + #define EMC_MRS 0xcc 100 + #define EMC_MODE_SET_DLL_RESET BIT(8) 101 + #define EMC_MODE_SET_LONG_CNT BIT(26) 102 + #define EMC_EMRS 0xd0 103 + #define EMC_REF 0xd4 104 + #define EMC_PRE 0xd8 105 + 106 + #define EMC_SELF_REF 0xe0 107 + #define EMC_SELF_REF_CMD_ENABLED BIT(0) 108 + #define EMC_SELF_REF_DEV_SEL_SHIFT 30 109 + 110 + #define EMC_MRW 0xe8 111 + 112 + #define EMC_MRR 0xec 113 + #define EMC_MRR_MA_SHIFT 16 114 + #define LPDDR2_MR4_TEMP_SHIFT 0 115 + 116 + #define EMC_XM2DQSPADCTRL3 0xf8 117 + #define EMC_FBIO_SPARE 0x100 118 + 119 + #define EMC_FBIO_CFG6 0x114 120 + #define EMC_EMRS2 0x12c 121 + #define EMC_MRW2 0x134 122 + #define EMC_MRW4 0x13c 123 + #define EMC_EINPUT 0x14c 124 + #define EMC_EINPUT_DURATION 0x150 125 + #define EMC_PUTERM_EXTRA 0x154 126 + #define EMC_TCKESR 0x158 127 + #define EMC_TPD 0x15c 128 + 129 + #define EMC_AUTO_CAL_CONFIG 0x2a4 130 + #define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START BIT(31) 131 + #define EMC_AUTO_CAL_INTERVAL 0x2a8 132 + #define EMC_AUTO_CAL_STATUS 0x2ac 133 + #define EMC_AUTO_CAL_STATUS_ACTIVE BIT(31) 134 + #define EMC_STATUS 0x2b4 135 + #define EMC_STATUS_TIMING_UPDATE_STALLED BIT(23) 136 + 137 + #define EMC_CFG_2 0x2b8 138 + #define EMC_CFG_2_MODE_SHIFT 0 139 + #define EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR BIT(6) 140 + 141 + #define EMC_CFG_DIG_DLL 0x2bc 142 + #define EMC_CFG_DIG_DLL_PERIOD 0x2c0 143 + #define EMC_RDV_MASK 0x2cc 144 + #define EMC_WDV_MASK 0x2d0 145 + #define EMC_CTT_DURATION 0x2d8 146 + #define EMC_CTT_TERM_CTRL 0x2dc 147 + #define EMC_ZCAL_INTERVAL 0x2e0 148 + #define EMC_ZCAL_WAIT_CNT 0x2e4 149 + 150 + #define EMC_ZQ_CAL 0x2ec 151 + #define EMC_ZQ_CAL_CMD BIT(0) 152 + #define EMC_ZQ_CAL_LONG BIT(4) 153 + #define EMC_ZQ_CAL_LONG_CMD_DEV0 \ 154 + (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) 155 + #define EMC_ZQ_CAL_LONG_CMD_DEV1 \ 156 + (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) 157 + 158 + #define EMC_XM2CMDPADCTRL 0x2f0 159 + #define EMC_XM2DQSPADCTRL 0x2f8 160 + #define EMC_XM2DQSPADCTRL2 0x2fc 161 + #define EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE BIT(0) 162 + #define EMC_XM2DQSPADCTRL2_VREF_ENABLE BIT(5) 163 + #define EMC_XM2DQPADCTRL 0x300 164 + #define EMC_XM2DQPADCTRL2 0x304 165 + #define EMC_XM2CLKPADCTRL 0x308 166 + #define EMC_XM2COMPPADCTRL 0x30c 167 + #define EMC_XM2VTTGENPADCTRL 0x310 168 + #define EMC_XM2VTTGENPADCTRL2 0x314 169 + #define EMC_XM2VTTGENPADCTRL3 0x318 170 + #define EMC_XM2DQSPADCTRL4 0x320 171 + #define EMC_DLL_XFORM_DQS0 0x328 172 + #define EMC_DLL_XFORM_DQS1 0x32c 173 + #define EMC_DLL_XFORM_DQS2 0x330 174 + #define EMC_DLL_XFORM_DQS3 0x334 175 + #define EMC_DLL_XFORM_DQS4 0x338 176 + #define EMC_DLL_XFORM_DQS5 0x33c 177 + #define EMC_DLL_XFORM_DQS6 0x340 178 + #define EMC_DLL_XFORM_DQS7 0x344 179 + #define EMC_DLL_XFORM_QUSE0 0x348 180 + #define EMC_DLL_XFORM_QUSE1 0x34c 181 + #define EMC_DLL_XFORM_QUSE2 0x350 182 + #define EMC_DLL_XFORM_QUSE3 0x354 183 + #define EMC_DLL_XFORM_QUSE4 0x358 184 + #define EMC_DLL_XFORM_QUSE5 0x35c 185 + #define EMC_DLL_XFORM_QUSE6 0x360 186 + #define EMC_DLL_XFORM_QUSE7 0x364 187 + #define EMC_DLL_XFORM_DQ0 0x368 188 + #define EMC_DLL_XFORM_DQ1 0x36c 189 + #define EMC_DLL_XFORM_DQ2 0x370 190 + #define EMC_DLL_XFORM_DQ3 0x374 191 + #define EMC_DLI_TRIM_TXDQS0 0x3a8 192 + #define EMC_DLI_TRIM_TXDQS1 0x3ac 193 + #define EMC_DLI_TRIM_TXDQS2 0x3b0 194 + #define EMC_DLI_TRIM_TXDQS3 0x3b4 195 + #define EMC_DLI_TRIM_TXDQS4 0x3b8 196 + #define EMC_DLI_TRIM_TXDQS5 0x3bc 197 + #define EMC_DLI_TRIM_TXDQS6 0x3c0 198 + #define EMC_DLI_TRIM_TXDQS7 0x3c4 199 + #define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc 200 + #define EMC_SEL_DPD_CTRL 0x3d8 201 + #define EMC_SEL_DPD_CTRL_DATA_SEL_DPD BIT(8) 202 + #define EMC_SEL_DPD_CTRL_ODT_SEL_DPD BIT(5) 203 + #define EMC_SEL_DPD_CTRL_RESET_SEL_DPD BIT(4) 204 + #define EMC_SEL_DPD_CTRL_CA_SEL_DPD BIT(3) 205 + #define EMC_SEL_DPD_CTRL_CLK_SEL_DPD BIT(2) 206 + #define EMC_SEL_DPD_CTRL_DDR3_MASK \ 207 + ((0xf << 2) | BIT(8)) 208 + #define EMC_SEL_DPD_CTRL_MASK \ 209 + ((0x3 << 2) | BIT(5) | BIT(8)) 210 + #define EMC_PRE_REFRESH_REQ_CNT 0x3dc 211 + #define EMC_DYN_SELF_REF_CONTROL 0x3e0 212 + #define EMC_TXSRDLL 0x3e4 213 + #define EMC_CCFIFO_ADDR 0x3e8 214 + #define EMC_CCFIFO_DATA 0x3ec 215 + #define EMC_CCFIFO_STATUS 0x3f0 216 + #define EMC_CDB_CNTL_1 0x3f4 217 + #define EMC_CDB_CNTL_2 0x3f8 218 + #define EMC_XM2CLKPADCTRL2 0x3fc 219 + #define EMC_AUTO_CAL_CONFIG2 0x458 220 + #define EMC_AUTO_CAL_CONFIG3 0x45c 221 + #define EMC_IBDLY 0x468 222 + #define EMC_DLL_XFORM_ADDR0 0x46c 223 + #define EMC_DLL_XFORM_ADDR1 0x470 224 + #define EMC_DLL_XFORM_ADDR2 0x474 225 + #define EMC_DSR_VTTGEN_DRV 0x47c 226 + #define EMC_TXDSRVTTGEN 0x480 227 + #define EMC_XM2CMDPADCTRL4 0x484 228 + #define EMC_XM2CMDPADCTRL5 0x488 229 + #define EMC_DLL_XFORM_DQS8 0x4a0 230 + #define EMC_DLL_XFORM_DQS9 0x4a4 231 + #define EMC_DLL_XFORM_DQS10 0x4a8 232 + #define EMC_DLL_XFORM_DQS11 0x4ac 233 + #define EMC_DLL_XFORM_DQS12 0x4b0 234 + #define EMC_DLL_XFORM_DQS13 0x4b4 235 + #define EMC_DLL_XFORM_DQS14 0x4b8 236 + #define EMC_DLL_XFORM_DQS15 0x4bc 237 + #define EMC_DLL_XFORM_QUSE8 0x4c0 238 + #define EMC_DLL_XFORM_QUSE9 0x4c4 239 + #define EMC_DLL_XFORM_QUSE10 0x4c8 240 + #define EMC_DLL_XFORM_QUSE11 0x4cc 241 + #define EMC_DLL_XFORM_QUSE12 0x4d0 242 + #define EMC_DLL_XFORM_QUSE13 0x4d4 243 + #define EMC_DLL_XFORM_QUSE14 0x4d8 244 + #define EMC_DLL_XFORM_QUSE15 0x4dc 245 + #define EMC_DLL_XFORM_DQ4 0x4e0 246 + #define EMC_DLL_XFORM_DQ5 0x4e4 247 + #define EMC_DLL_XFORM_DQ6 0x4e8 248 + #define EMC_DLL_XFORM_DQ7 0x4ec 249 + #define EMC_DLI_TRIM_TXDQS8 0x520 250 + #define EMC_DLI_TRIM_TXDQS9 0x524 251 + #define EMC_DLI_TRIM_TXDQS10 0x528 252 + #define EMC_DLI_TRIM_TXDQS11 0x52c 253 + #define EMC_DLI_TRIM_TXDQS12 0x530 254 + #define EMC_DLI_TRIM_TXDQS13 0x534 255 + #define EMC_DLI_TRIM_TXDQS14 0x538 256 + #define EMC_DLI_TRIM_TXDQS15 0x53c 257 + #define EMC_CDB_CNTL_3 0x540 258 + #define EMC_XM2DQSPADCTRL5 0x544 259 + #define EMC_XM2DQSPADCTRL6 0x548 260 + #define EMC_XM2DQPADCTRL3 0x54c 261 + #define EMC_DLL_XFORM_ADDR3 0x550 262 + #define EMC_DLL_XFORM_ADDR4 0x554 263 + #define EMC_DLL_XFORM_ADDR5 0x558 264 + #define EMC_CFG_PIPE 0x560 265 + #define EMC_QPOP 0x564 266 + #define EMC_QUSE_WIDTH 0x568 267 + #define EMC_PUTERM_WIDTH 0x56c 268 + #define EMC_BGBIAS_CTL0 0x570 269 + #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX BIT(3) 270 + #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN BIT(2) 271 + #define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD BIT(1) 272 + #define EMC_PUTERM_ADJ 0x574 273 + 274 + #define DRAM_DEV_SEL_ALL 0 275 + #define DRAM_DEV_SEL_0 (2 << 30) 276 + #define DRAM_DEV_SEL_1 (1 << 30) 277 + 278 + #define EMC_CFG_POWER_FEATURES_MASK \ 279 + (EMC_CFG_DYN_SREF | EMC_CFG_DRAM_ACPD | EMC_CFG_DRAM_CLKSTOP_SR | \ 280 + EMC_CFG_DRAM_CLKSTOP_PD | EMC_CFG_DSR_VTTGEN_DRV_EN) 281 + #define EMC_REFCTRL_DEV_SEL(n) (((n > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) 282 + #define EMC_DRAM_DEV_SEL(n) ((n > 1) ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0) 283 + 284 + /* Maximum amount of time in us. to wait for changes to become effective */ 285 + #define EMC_STATUS_UPDATE_TIMEOUT 1000 286 + 287 + enum emc_dram_type { 288 + DRAM_TYPE_DDR3 = 0, 289 + DRAM_TYPE_DDR1 = 1, 290 + DRAM_TYPE_LPDDR3 = 2, 291 + DRAM_TYPE_DDR2 = 3 292 + }; 293 + 294 + enum emc_dll_change { 295 + DLL_CHANGE_NONE, 296 + DLL_CHANGE_ON, 297 + DLL_CHANGE_OFF 298 + }; 299 + 300 + static const unsigned long emc_burst_regs[] = { 301 + EMC_RC, 302 + EMC_RFC, 303 + EMC_RFC_SLR, 304 + EMC_RAS, 305 + EMC_RP, 306 + EMC_R2W, 307 + EMC_W2R, 308 + EMC_R2P, 309 + EMC_W2P, 310 + EMC_RD_RCD, 311 + EMC_WR_RCD, 312 + EMC_RRD, 313 + EMC_REXT, 314 + EMC_WEXT, 315 + EMC_WDV, 316 + EMC_WDV_MASK, 317 + EMC_QUSE, 318 + EMC_QUSE_WIDTH, 319 + EMC_IBDLY, 320 + EMC_EINPUT, 321 + EMC_EINPUT_DURATION, 322 + EMC_PUTERM_EXTRA, 323 + EMC_PUTERM_WIDTH, 324 + EMC_PUTERM_ADJ, 325 + EMC_CDB_CNTL_1, 326 + EMC_CDB_CNTL_2, 327 + EMC_CDB_CNTL_3, 328 + EMC_QRST, 329 + EMC_QSAFE, 330 + EMC_RDV, 331 + EMC_RDV_MASK, 332 + EMC_REFRESH, 333 + EMC_BURST_REFRESH_NUM, 334 + EMC_PRE_REFRESH_REQ_CNT, 335 + EMC_PDEX2WR, 336 + EMC_PDEX2RD, 337 + EMC_PCHG2PDEN, 338 + EMC_ACT2PDEN, 339 + EMC_AR2PDEN, 340 + EMC_RW2PDEN, 341 + EMC_TXSR, 342 + EMC_TXSRDLL, 343 + EMC_TCKE, 344 + EMC_TCKESR, 345 + EMC_TPD, 346 + EMC_TFAW, 347 + EMC_TRPAB, 348 + EMC_TCLKSTABLE, 349 + EMC_TCLKSTOP, 350 + EMC_TREFBW, 351 + EMC_FBIO_CFG6, 352 + EMC_ODT_WRITE, 353 + EMC_ODT_READ, 354 + EMC_FBIO_CFG5, 355 + EMC_CFG_DIG_DLL, 356 + EMC_CFG_DIG_DLL_PERIOD, 357 + EMC_DLL_XFORM_DQS0, 358 + EMC_DLL_XFORM_DQS1, 359 + EMC_DLL_XFORM_DQS2, 360 + EMC_DLL_XFORM_DQS3, 361 + EMC_DLL_XFORM_DQS4, 362 + EMC_DLL_XFORM_DQS5, 363 + EMC_DLL_XFORM_DQS6, 364 + EMC_DLL_XFORM_DQS7, 365 + EMC_DLL_XFORM_DQS8, 366 + EMC_DLL_XFORM_DQS9, 367 + EMC_DLL_XFORM_DQS10, 368 + EMC_DLL_XFORM_DQS11, 369 + EMC_DLL_XFORM_DQS12, 370 + EMC_DLL_XFORM_DQS13, 371 + EMC_DLL_XFORM_DQS14, 372 + EMC_DLL_XFORM_DQS15, 373 + EMC_DLL_XFORM_QUSE0, 374 + EMC_DLL_XFORM_QUSE1, 375 + EMC_DLL_XFORM_QUSE2, 376 + EMC_DLL_XFORM_QUSE3, 377 + EMC_DLL_XFORM_QUSE4, 378 + EMC_DLL_XFORM_QUSE5, 379 + EMC_DLL_XFORM_QUSE6, 380 + EMC_DLL_XFORM_QUSE7, 381 + EMC_DLL_XFORM_ADDR0, 382 + EMC_DLL_XFORM_ADDR1, 383 + EMC_DLL_XFORM_ADDR2, 384 + EMC_DLL_XFORM_ADDR3, 385 + EMC_DLL_XFORM_ADDR4, 386 + EMC_DLL_XFORM_ADDR5, 387 + EMC_DLL_XFORM_QUSE8, 388 + EMC_DLL_XFORM_QUSE9, 389 + EMC_DLL_XFORM_QUSE10, 390 + EMC_DLL_XFORM_QUSE11, 391 + EMC_DLL_XFORM_QUSE12, 392 + EMC_DLL_XFORM_QUSE13, 393 + EMC_DLL_XFORM_QUSE14, 394 + EMC_DLL_XFORM_QUSE15, 395 + EMC_DLI_TRIM_TXDQS0, 396 + EMC_DLI_TRIM_TXDQS1, 397 + EMC_DLI_TRIM_TXDQS2, 398 + EMC_DLI_TRIM_TXDQS3, 399 + EMC_DLI_TRIM_TXDQS4, 400 + EMC_DLI_TRIM_TXDQS5, 401 + EMC_DLI_TRIM_TXDQS6, 402 + EMC_DLI_TRIM_TXDQS7, 403 + EMC_DLI_TRIM_TXDQS8, 404 + EMC_DLI_TRIM_TXDQS9, 405 + EMC_DLI_TRIM_TXDQS10, 406 + EMC_DLI_TRIM_TXDQS11, 407 + EMC_DLI_TRIM_TXDQS12, 408 + EMC_DLI_TRIM_TXDQS13, 409 + EMC_DLI_TRIM_TXDQS14, 410 + EMC_DLI_TRIM_TXDQS15, 411 + EMC_DLL_XFORM_DQ0, 412 + EMC_DLL_XFORM_DQ1, 413 + EMC_DLL_XFORM_DQ2, 414 + EMC_DLL_XFORM_DQ3, 415 + EMC_DLL_XFORM_DQ4, 416 + EMC_DLL_XFORM_DQ5, 417 + EMC_DLL_XFORM_DQ6, 418 + EMC_DLL_XFORM_DQ7, 419 + EMC_XM2CMDPADCTRL, 420 + EMC_XM2CMDPADCTRL4, 421 + EMC_XM2CMDPADCTRL5, 422 + EMC_XM2DQPADCTRL2, 423 + EMC_XM2DQPADCTRL3, 424 + EMC_XM2CLKPADCTRL, 425 + EMC_XM2CLKPADCTRL2, 426 + EMC_XM2COMPPADCTRL, 427 + EMC_XM2VTTGENPADCTRL, 428 + EMC_XM2VTTGENPADCTRL2, 429 + EMC_XM2VTTGENPADCTRL3, 430 + EMC_XM2DQSPADCTRL3, 431 + EMC_XM2DQSPADCTRL4, 432 + EMC_XM2DQSPADCTRL5, 433 + EMC_XM2DQSPADCTRL6, 434 + EMC_DSR_VTTGEN_DRV, 435 + EMC_TXDSRVTTGEN, 436 + EMC_FBIO_SPARE, 437 + EMC_ZCAL_WAIT_CNT, 438 + EMC_MRS_WAIT_CNT2, 439 + EMC_CTT, 440 + EMC_CTT_DURATION, 441 + EMC_CFG_PIPE, 442 + EMC_DYN_SELF_REF_CONTROL, 443 + EMC_QPOP 444 + }; 445 + 446 + struct emc_timing { 447 + unsigned long rate; 448 + 449 + u32 emc_burst_data[ARRAY_SIZE(emc_burst_regs)]; 450 + 451 + u32 emc_auto_cal_config; 452 + u32 emc_auto_cal_config2; 453 + u32 emc_auto_cal_config3; 454 + u32 emc_auto_cal_interval; 455 + u32 emc_bgbias_ctl0; 456 + u32 emc_cfg; 457 + u32 emc_cfg_2; 458 + u32 emc_ctt_term_ctrl; 459 + u32 emc_mode_1; 460 + u32 emc_mode_2; 461 + u32 emc_mode_4; 462 + u32 emc_mode_reset; 463 + u32 emc_mrs_wait_cnt; 464 + u32 emc_sel_dpd_ctrl; 465 + u32 emc_xm2dqspadctrl2; 466 + u32 emc_zcal_cnt_long; 467 + u32 emc_zcal_interval; 468 + }; 469 + 470 + struct tegra_emc { 471 + struct device *dev; 472 + 473 + struct tegra_mc *mc; 474 + 475 + void __iomem *regs; 476 + 477 + enum emc_dram_type dram_type; 478 + unsigned int dram_num; 479 + 480 + struct emc_timing last_timing; 481 + struct emc_timing *timings; 482 + unsigned int num_timings; 483 + }; 484 + 485 + /* Timing change sequence functions */ 486 + 487 + static void emc_ccfifo_writel(struct tegra_emc *emc, u32 value, 488 + unsigned long offset) 489 + { 490 + writel(value, emc->regs + EMC_CCFIFO_DATA); 491 + writel(offset, emc->regs + EMC_CCFIFO_ADDR); 492 + } 493 + 494 + static void emc_seq_update_timing(struct tegra_emc *emc) 495 + { 496 + unsigned int i; 497 + u32 value; 498 + 499 + writel(1, emc->regs + EMC_TIMING_CONTROL); 500 + 501 + for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { 502 + value = readl(emc->regs + EMC_STATUS); 503 + if ((value & EMC_STATUS_TIMING_UPDATE_STALLED) == 0) 504 + return; 505 + udelay(1); 506 + } 507 + 508 + dev_err(emc->dev, "timing update timed out\n"); 509 + } 510 + 511 + static void emc_seq_disable_auto_cal(struct tegra_emc *emc) 512 + { 513 + unsigned int i; 514 + u32 value; 515 + 516 + writel(0, emc->regs + EMC_AUTO_CAL_INTERVAL); 517 + 518 + for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { 519 + value = readl(emc->regs + EMC_AUTO_CAL_STATUS); 520 + if ((value & EMC_AUTO_CAL_STATUS_ACTIVE) == 0) 521 + return; 522 + udelay(1); 523 + } 524 + 525 + dev_err(emc->dev, "auto cal disable timed out\n"); 526 + } 527 + 528 + static void emc_seq_wait_clkchange(struct tegra_emc *emc) 529 + { 530 + unsigned int i; 531 + u32 value; 532 + 533 + for (i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; ++i) { 534 + value = readl(emc->regs + EMC_INTSTATUS); 535 + if (value & EMC_INTSTATUS_CLKCHANGE_COMPLETE) 536 + return; 537 + udelay(1); 538 + } 539 + 540 + dev_err(emc->dev, "clock change timed out\n"); 541 + } 542 + 543 + static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, 544 + unsigned long rate) 545 + { 546 + struct emc_timing *timing = NULL; 547 + unsigned int i; 548 + 549 + for (i = 0; i < emc->num_timings; i++) { 550 + if (emc->timings[i].rate == rate) { 551 + timing = &emc->timings[i]; 552 + break; 553 + } 554 + } 555 + 556 + if (!timing) { 557 + dev_err(emc->dev, "no timing for rate %lu\n", rate); 558 + return NULL; 559 + } 560 + 561 + return timing; 562 + } 563 + 564 + int tegra_emc_prepare_timing_change(struct tegra_emc *emc, 565 + unsigned long rate) 566 + { 567 + struct emc_timing *timing = tegra_emc_find_timing(emc, rate); 568 + struct emc_timing *last = &emc->last_timing; 569 + enum emc_dll_change dll_change; 570 + unsigned int pre_wait = 0; 571 + u32 val, val2, mask; 572 + bool update = false; 573 + unsigned int i; 574 + 575 + if (!timing) 576 + return -ENOENT; 577 + 578 + if ((last->emc_mode_1 & 0x1) == (timing->emc_mode_1 & 0x1)) 579 + dll_change = DLL_CHANGE_NONE; 580 + else if (timing->emc_mode_1 & 0x1) 581 + dll_change = DLL_CHANGE_ON; 582 + else 583 + dll_change = DLL_CHANGE_OFF; 584 + 585 + /* Clear CLKCHANGE_COMPLETE interrupts */ 586 + writel(EMC_INTSTATUS_CLKCHANGE_COMPLETE, emc->regs + EMC_INTSTATUS); 587 + 588 + /* Disable dynamic self-refresh */ 589 + val = readl(emc->regs + EMC_CFG); 590 + if (val & EMC_CFG_PWR_MASK) { 591 + val &= ~EMC_CFG_POWER_FEATURES_MASK; 592 + writel(val, emc->regs + EMC_CFG); 593 + 594 + pre_wait = 5; 595 + } 596 + 597 + /* Disable SEL_DPD_CTRL for clock change */ 598 + if (emc->dram_type == DRAM_TYPE_DDR3) 599 + mask = EMC_SEL_DPD_CTRL_DDR3_MASK; 600 + else 601 + mask = EMC_SEL_DPD_CTRL_MASK; 602 + 603 + val = readl(emc->regs + EMC_SEL_DPD_CTRL); 604 + if (val & mask) { 605 + val &= ~mask; 606 + writel(val, emc->regs + EMC_SEL_DPD_CTRL); 607 + } 608 + 609 + /* Prepare DQ/DQS for clock change */ 610 + val = readl(emc->regs + EMC_BGBIAS_CTL0); 611 + val2 = last->emc_bgbias_ctl0; 612 + if (!(timing->emc_bgbias_ctl0 & 613 + EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX) && 614 + (val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX)) { 615 + val2 &= ~EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX; 616 + update = true; 617 + } 618 + 619 + if ((val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD) || 620 + (val & EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN)) { 621 + update = true; 622 + } 623 + 624 + if (update) { 625 + writel(val2, emc->regs + EMC_BGBIAS_CTL0); 626 + if (pre_wait < 5) 627 + pre_wait = 5; 628 + } 629 + 630 + update = false; 631 + val = readl(emc->regs + EMC_XM2DQSPADCTRL2); 632 + if (timing->emc_xm2dqspadctrl2 & EMC_XM2DQSPADCTRL2_VREF_ENABLE && 633 + !(val & EMC_XM2DQSPADCTRL2_VREF_ENABLE)) { 634 + val |= EMC_XM2DQSPADCTRL2_VREF_ENABLE; 635 + update = true; 636 + } 637 + 638 + if (timing->emc_xm2dqspadctrl2 & EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE && 639 + !(val & EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE)) { 640 + val |= EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE; 641 + update = true; 642 + } 643 + 644 + if (update) { 645 + writel(val, emc->regs + EMC_XM2DQSPADCTRL2); 646 + if (pre_wait < 30) 647 + pre_wait = 30; 648 + } 649 + 650 + /* Wait to settle */ 651 + if (pre_wait) { 652 + emc_seq_update_timing(emc); 653 + udelay(pre_wait); 654 + } 655 + 656 + /* Program CTT_TERM control */ 657 + if (last->emc_ctt_term_ctrl != timing->emc_ctt_term_ctrl) { 658 + emc_seq_disable_auto_cal(emc); 659 + writel(timing->emc_ctt_term_ctrl, 660 + emc->regs + EMC_CTT_TERM_CTRL); 661 + emc_seq_update_timing(emc); 662 + } 663 + 664 + /* Program burst shadow registers */ 665 + for (i = 0; i < ARRAY_SIZE(timing->emc_burst_data); ++i) 666 + writel(timing->emc_burst_data[i], 667 + emc->regs + emc_burst_regs[i]); 668 + 669 + writel(timing->emc_xm2dqspadctrl2, emc->regs + EMC_XM2DQSPADCTRL2); 670 + writel(timing->emc_zcal_interval, emc->regs + EMC_ZCAL_INTERVAL); 671 + 672 + tegra_mc_write_emem_configuration(emc->mc, timing->rate); 673 + 674 + val = timing->emc_cfg & ~EMC_CFG_POWER_FEATURES_MASK; 675 + emc_ccfifo_writel(emc, val, EMC_CFG); 676 + 677 + /* Program AUTO_CAL_CONFIG */ 678 + if (timing->emc_auto_cal_config2 != last->emc_auto_cal_config2) 679 + emc_ccfifo_writel(emc, timing->emc_auto_cal_config2, 680 + EMC_AUTO_CAL_CONFIG2); 681 + 682 + if (timing->emc_auto_cal_config3 != last->emc_auto_cal_config3) 683 + emc_ccfifo_writel(emc, timing->emc_auto_cal_config3, 684 + EMC_AUTO_CAL_CONFIG3); 685 + 686 + if (timing->emc_auto_cal_config != last->emc_auto_cal_config) { 687 + val = timing->emc_auto_cal_config; 688 + val &= EMC_AUTO_CAL_CONFIG_AUTO_CAL_START; 689 + emc_ccfifo_writel(emc, val, EMC_AUTO_CAL_CONFIG); 690 + } 691 + 692 + /* DDR3: predict MRS long wait count */ 693 + if (emc->dram_type == DRAM_TYPE_DDR3 && 694 + dll_change == DLL_CHANGE_ON) { 695 + u32 cnt = 512; 696 + 697 + if (timing->emc_zcal_interval != 0 && 698 + last->emc_zcal_interval == 0) 699 + cnt -= emc->dram_num * 256; 700 + 701 + val = (timing->emc_mrs_wait_cnt 702 + & EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK) 703 + >> EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT; 704 + if (cnt < val) 705 + cnt = val; 706 + 707 + val = timing->emc_mrs_wait_cnt 708 + & ~EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; 709 + val |= (cnt << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) 710 + & EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; 711 + 712 + writel(val, emc->regs + EMC_MRS_WAIT_CNT); 713 + } 714 + 715 + val = timing->emc_cfg_2; 716 + val &= ~EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR; 717 + emc_ccfifo_writel(emc, val, EMC_CFG_2); 718 + 719 + /* DDR3: Turn off DLL and enter self-refresh */ 720 + if (emc->dram_type == DRAM_TYPE_DDR3 && dll_change == DLL_CHANGE_OFF) 721 + emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_EMRS); 722 + 723 + /* Disable refresh controller */ 724 + emc_ccfifo_writel(emc, EMC_REFCTRL_DEV_SEL(emc->dram_num), 725 + EMC_REFCTRL); 726 + if (emc->dram_type == DRAM_TYPE_DDR3) 727 + emc_ccfifo_writel(emc, EMC_DRAM_DEV_SEL(emc->dram_num) | 728 + EMC_SELF_REF_CMD_ENABLED, 729 + EMC_SELF_REF); 730 + 731 + /* Flow control marker */ 732 + emc_ccfifo_writel(emc, 1, EMC_STALL_THEN_EXE_AFTER_CLKCHANGE); 733 + 734 + /* DDR3: Exit self-refresh */ 735 + if (emc->dram_type == DRAM_TYPE_DDR3) 736 + emc_ccfifo_writel(emc, EMC_DRAM_DEV_SEL(emc->dram_num), 737 + EMC_SELF_REF); 738 + emc_ccfifo_writel(emc, EMC_REFCTRL_DEV_SEL(emc->dram_num) | 739 + EMC_REFCTRL_ENABLE, 740 + EMC_REFCTRL); 741 + 742 + /* Set DRAM mode registers */ 743 + if (emc->dram_type == DRAM_TYPE_DDR3) { 744 + if (timing->emc_mode_1 != last->emc_mode_1) 745 + emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_EMRS); 746 + if (timing->emc_mode_2 != last->emc_mode_2) 747 + emc_ccfifo_writel(emc, timing->emc_mode_2, EMC_EMRS2); 748 + 749 + if ((timing->emc_mode_reset != last->emc_mode_reset) || 750 + dll_change == DLL_CHANGE_ON) { 751 + val = timing->emc_mode_reset; 752 + if (dll_change == DLL_CHANGE_ON) { 753 + val |= EMC_MODE_SET_DLL_RESET; 754 + val |= EMC_MODE_SET_LONG_CNT; 755 + } else { 756 + val &= ~EMC_MODE_SET_DLL_RESET; 757 + } 758 + emc_ccfifo_writel(emc, val, EMC_MRS); 759 + } 760 + } else { 761 + if (timing->emc_mode_2 != last->emc_mode_2) 762 + emc_ccfifo_writel(emc, timing->emc_mode_2, EMC_MRW2); 763 + if (timing->emc_mode_1 != last->emc_mode_1) 764 + emc_ccfifo_writel(emc, timing->emc_mode_1, EMC_MRW); 765 + if (timing->emc_mode_4 != last->emc_mode_4) 766 + emc_ccfifo_writel(emc, timing->emc_mode_4, EMC_MRW4); 767 + } 768 + 769 + /* Issue ZCAL command if turning ZCAL on */ 770 + if (timing->emc_zcal_interval != 0 && last->emc_zcal_interval == 0) { 771 + emc_ccfifo_writel(emc, EMC_ZQ_CAL_LONG_CMD_DEV0, EMC_ZQ_CAL); 772 + if (emc->dram_num > 1) 773 + emc_ccfifo_writel(emc, EMC_ZQ_CAL_LONG_CMD_DEV1, 774 + EMC_ZQ_CAL); 775 + } 776 + 777 + /* Write to RO register to remove stall after change */ 778 + emc_ccfifo_writel(emc, 0, EMC_CCFIFO_STATUS); 779 + 780 + if (timing->emc_cfg_2 & EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR) 781 + emc_ccfifo_writel(emc, timing->emc_cfg_2, EMC_CFG_2); 782 + 783 + /* Disable AUTO_CAL for clock change */ 784 + emc_seq_disable_auto_cal(emc); 785 + 786 + /* Read register to wait until programming has settled */ 787 + readl(emc->regs + EMC_INTSTATUS); 788 + 789 + return 0; 790 + } 791 + 792 + void tegra_emc_complete_timing_change(struct tegra_emc *emc, 793 + unsigned long rate) 794 + { 795 + struct emc_timing *timing = tegra_emc_find_timing(emc, rate); 796 + struct emc_timing *last = &emc->last_timing; 797 + u32 val; 798 + 799 + if (!timing) 800 + return; 801 + 802 + /* Wait until the state machine has settled */ 803 + emc_seq_wait_clkchange(emc); 804 + 805 + /* Restore AUTO_CAL */ 806 + if (timing->emc_ctt_term_ctrl != last->emc_ctt_term_ctrl) 807 + writel(timing->emc_auto_cal_interval, 808 + emc->regs + EMC_AUTO_CAL_INTERVAL); 809 + 810 + /* Restore dynamic self-refresh */ 811 + if (timing->emc_cfg & EMC_CFG_PWR_MASK) 812 + writel(timing->emc_cfg, emc->regs + EMC_CFG); 813 + 814 + /* Set ZCAL wait count */ 815 + writel(timing->emc_zcal_cnt_long, emc->regs + EMC_ZCAL_WAIT_CNT); 816 + 817 + /* LPDDR3: Turn off BGBIAS if low frequency */ 818 + if (emc->dram_type == DRAM_TYPE_LPDDR3 && 819 + timing->emc_bgbias_ctl0 & 820 + EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX) { 821 + val = timing->emc_bgbias_ctl0; 822 + val |= EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN; 823 + val |= EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD; 824 + writel(val, emc->regs + EMC_BGBIAS_CTL0); 825 + } else { 826 + if (emc->dram_type == DRAM_TYPE_DDR3 && 827 + readl(emc->regs + EMC_BGBIAS_CTL0) != 828 + timing->emc_bgbias_ctl0) { 829 + writel(timing->emc_bgbias_ctl0, 830 + emc->regs + EMC_BGBIAS_CTL0); 831 + } 832 + 833 + writel(timing->emc_auto_cal_interval, 834 + emc->regs + EMC_AUTO_CAL_INTERVAL); 835 + } 836 + 837 + /* Wait for timing to settle */ 838 + udelay(2); 839 + 840 + /* Reprogram SEL_DPD_CTRL */ 841 + writel(timing->emc_sel_dpd_ctrl, emc->regs + EMC_SEL_DPD_CTRL); 842 + emc_seq_update_timing(emc); 843 + 844 + emc->last_timing = *timing; 845 + } 846 + 847 + /* Initialization and deinitialization */ 848 + 849 + static void emc_read_current_timing(struct tegra_emc *emc, 850 + struct emc_timing *timing) 851 + { 852 + unsigned int i; 853 + 854 + for (i = 0; i < ARRAY_SIZE(emc_burst_regs); ++i) 855 + timing->emc_burst_data[i] = 856 + readl(emc->regs + emc_burst_regs[i]); 857 + 858 + timing->emc_cfg = readl(emc->regs + EMC_CFG); 859 + 860 + timing->emc_auto_cal_interval = 0; 861 + timing->emc_zcal_cnt_long = 0; 862 + timing->emc_mode_1 = 0; 863 + timing->emc_mode_2 = 0; 864 + timing->emc_mode_4 = 0; 865 + timing->emc_mode_reset = 0; 866 + } 867 + 868 + static int emc_init(struct tegra_emc *emc) 869 + { 870 + emc->dram_type = readl(emc->regs + EMC_FBIO_CFG5); 871 + emc->dram_type &= EMC_FBIO_CFG5_DRAM_TYPE_MASK; 872 + emc->dram_type >>= EMC_FBIO_CFG5_DRAM_TYPE_SHIFT; 873 + 874 + emc->dram_num = tegra_mc_get_emem_device_count(emc->mc); 875 + 876 + emc_read_current_timing(emc, &emc->last_timing); 877 + 878 + return 0; 879 + } 880 + 881 + static int load_one_timing_from_dt(struct tegra_emc *emc, 882 + struct emc_timing *timing, 883 + struct device_node *node) 884 + { 885 + u32 value; 886 + int err; 887 + 888 + err = of_property_read_u32(node, "clock-frequency", &value); 889 + if (err) { 890 + dev_err(emc->dev, "timing %s: failed to read rate: %d\n", 891 + node->name, err); 892 + return err; 893 + } 894 + 895 + timing->rate = value; 896 + 897 + err = of_property_read_u32_array(node, "nvidia,emc-configuration", 898 + timing->emc_burst_data, 899 + ARRAY_SIZE(timing->emc_burst_data)); 900 + if (err) { 901 + dev_err(emc->dev, 902 + "timing %s: failed to read emc burst data: %d\n", 903 + node->name, err); 904 + return err; 905 + } 906 + 907 + #define EMC_READ_PROP(prop, dtprop) { \ 908 + err = of_property_read_u32(node, dtprop, &timing->prop); \ 909 + if (err) { \ 910 + dev_err(emc->dev, "timing %s: failed to read " #prop ": %d\n", \ 911 + node->name, err); \ 912 + return err; \ 913 + } \ 914 + } 915 + 916 + EMC_READ_PROP(emc_auto_cal_config, "nvidia,emc-auto-cal-config") 917 + EMC_READ_PROP(emc_auto_cal_config2, "nvidia,emc-auto-cal-config2") 918 + EMC_READ_PROP(emc_auto_cal_config3, "nvidia,emc-auto-cal-config3") 919 + EMC_READ_PROP(emc_auto_cal_interval, "nvidia,emc-auto-cal-interval") 920 + EMC_READ_PROP(emc_bgbias_ctl0, "nvidia,emc-bgbias-ctl0") 921 + EMC_READ_PROP(emc_cfg, "nvidia,emc-cfg") 922 + EMC_READ_PROP(emc_cfg_2, "nvidia,emc-cfg-2") 923 + EMC_READ_PROP(emc_ctt_term_ctrl, "nvidia,emc-ctt-term-ctrl") 924 + EMC_READ_PROP(emc_mode_1, "nvidia,emc-mode-1") 925 + EMC_READ_PROP(emc_mode_2, "nvidia,emc-mode-2") 926 + EMC_READ_PROP(emc_mode_4, "nvidia,emc-mode-4") 927 + EMC_READ_PROP(emc_mode_reset, "nvidia,emc-mode-reset") 928 + EMC_READ_PROP(emc_mrs_wait_cnt, "nvidia,emc-mrs-wait-cnt") 929 + EMC_READ_PROP(emc_sel_dpd_ctrl, "nvidia,emc-sel-dpd-ctrl") 930 + EMC_READ_PROP(emc_xm2dqspadctrl2, "nvidia,emc-xm2dqspadctrl2") 931 + EMC_READ_PROP(emc_zcal_cnt_long, "nvidia,emc-zcal-cnt-long") 932 + EMC_READ_PROP(emc_zcal_interval, "nvidia,emc-zcal-interval") 933 + 934 + #undef EMC_READ_PROP 935 + 936 + return 0; 937 + } 938 + 939 + static int cmp_timings(const void *_a, const void *_b) 940 + { 941 + const struct emc_timing *a = _a; 942 + const struct emc_timing *b = _b; 943 + 944 + if (a->rate < b->rate) 945 + return -1; 946 + else if (a->rate == b->rate) 947 + return 0; 948 + else 949 + return 1; 950 + } 951 + 952 + static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, 953 + struct device_node *node) 954 + { 955 + int child_count = of_get_child_count(node); 956 + struct device_node *child; 957 + struct emc_timing *timing; 958 + unsigned int i = 0; 959 + int err; 960 + 961 + emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing), 962 + GFP_KERNEL); 963 + if (!emc->timings) 964 + return -ENOMEM; 965 + 966 + emc->num_timings = child_count; 967 + 968 + for_each_child_of_node(node, child) { 969 + timing = &emc->timings[i++]; 970 + 971 + err = load_one_timing_from_dt(emc, timing, child); 972 + if (err) 973 + return err; 974 + } 975 + 976 + sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, 977 + NULL); 978 + 979 + return 0; 980 + } 981 + 982 + static const struct of_device_id tegra_emc_of_match[] = { 983 + { .compatible = "nvidia,tegra124-emc" }, 984 + {} 985 + }; 986 + 987 + static struct device_node * 988 + tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) 989 + { 990 + struct device_node *np; 991 + int err; 992 + 993 + for_each_child_of_node(node, np) { 994 + u32 value; 995 + 996 + err = of_property_read_u32(np, "nvidia,ram-code", &value); 997 + if (err || (value != ram_code)) { 998 + of_node_put(np); 999 + continue; 1000 + } 1001 + 1002 + return np; 1003 + } 1004 + 1005 + return NULL; 1006 + } 1007 + 1008 + static int tegra_emc_probe(struct platform_device *pdev) 1009 + { 1010 + struct platform_device *mc; 1011 + struct device_node *np; 1012 + struct tegra_emc *emc; 1013 + struct resource *res; 1014 + u32 ram_code; 1015 + int err; 1016 + 1017 + emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); 1018 + if (!emc) 1019 + return -ENOMEM; 1020 + 1021 + emc->dev = &pdev->dev; 1022 + 1023 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1024 + emc->regs = devm_ioremap_resource(&pdev->dev, res); 1025 + if (IS_ERR(emc->regs)) 1026 + return PTR_ERR(emc->regs); 1027 + 1028 + np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0); 1029 + if (!np) { 1030 + dev_err(&pdev->dev, "could not get memory controller\n"); 1031 + return -ENOENT; 1032 + } 1033 + 1034 + mc = of_find_device_by_node(np); 1035 + if (!mc) 1036 + return -ENOENT; 1037 + 1038 + of_node_put(np); 1039 + 1040 + emc->mc = platform_get_drvdata(mc); 1041 + if (!emc->mc) 1042 + return -EPROBE_DEFER; 1043 + 1044 + ram_code = tegra_read_ram_code(); 1045 + 1046 + np = tegra_emc_find_node_by_ram_code(pdev->dev.of_node, ram_code); 1047 + if (!np) { 1048 + dev_err(&pdev->dev, 1049 + "no memory timings for RAM code %u found in DT\n", 1050 + ram_code); 1051 + return -ENOENT; 1052 + } 1053 + 1054 + err = tegra_emc_load_timings_from_dt(emc, np); 1055 + 1056 + of_node_put(np); 1057 + 1058 + if (err) 1059 + return err; 1060 + 1061 + if (emc->num_timings == 0) { 1062 + dev_err(&pdev->dev, 1063 + "no memory timings for RAM code %u registered\n", 1064 + ram_code); 1065 + return -ENOENT; 1066 + } 1067 + 1068 + err = emc_init(emc); 1069 + if (err) { 1070 + dev_err(&pdev->dev, "EMC initialization failed: %d\n", err); 1071 + return err; 1072 + } 1073 + 1074 + platform_set_drvdata(pdev, emc); 1075 + 1076 + return 0; 1077 + }; 1078 + 1079 + static struct platform_driver tegra_emc_driver = { 1080 + .probe = tegra_emc_probe, 1081 + .driver = { 1082 + .name = "tegra-emc", 1083 + .of_match_table = tegra_emc_of_match, 1084 + .suppress_bind_attrs = true, 1085 + }, 1086 + }; 1087 + 1088 + static int tegra_emc_init(void) 1089 + { 1090 + return platform_driver_register(&tegra_emc_driver); 1091 + } 1092 + subsys_initcall(tegra_emc_init);
+19
include/soc/tegra/emc.h
··· 1 + /* 2 + * Copyright (c) 2014 NVIDIA Corporation. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __SOC_TEGRA_EMC_H__ 10 + #define __SOC_TEGRA_EMC_H__ 11 + 12 + struct tegra_emc; 13 + 14 + int tegra_emc_prepare_timing_change(struct tegra_emc *emc, 15 + unsigned long rate); 16 + void tegra_emc_complete_timing_change(struct tegra_emc *emc, 17 + unsigned long rate); 18 + 19 + #endif /* __SOC_TEGRA_EMC_H__ */