1e34212c7SDmitry Osipenko // SPDX-License-Identifier: GPL-2.0+ 2e34212c7SDmitry Osipenko /* 3e34212c7SDmitry Osipenko * Tegra30 External Memory Controller driver 4e34212c7SDmitry Osipenko * 5e34212c7SDmitry Osipenko * Based on downstream driver from NVIDIA and tegra124-emc.c 6e34212c7SDmitry Osipenko * Copyright (C) 2011-2014 NVIDIA Corporation 7e34212c7SDmitry Osipenko * 8e34212c7SDmitry Osipenko * Author: Dmitry Osipenko <digetx@gmail.com> 9e34212c7SDmitry Osipenko * Copyright (C) 2019 GRATE-DRIVER project 10e34212c7SDmitry Osipenko */ 11e34212c7SDmitry Osipenko 12e3aabb3cSDmitry Osipenko #include <linux/bitfield.h> 13e34212c7SDmitry Osipenko #include <linux/clk.h> 14e34212c7SDmitry Osipenko #include <linux/clk/tegra.h> 158cee32b4SThierry Reding #include <linux/debugfs.h> 16e34212c7SDmitry Osipenko #include <linux/delay.h> 17e34212c7SDmitry Osipenko #include <linux/err.h> 18d76fa3f2SDmitry Osipenko #include <linux/interconnect-provider.h> 19e34212c7SDmitry Osipenko #include <linux/interrupt.h> 20e34212c7SDmitry Osipenko #include <linux/io.h> 21e34212c7SDmitry Osipenko #include <linux/iopoll.h> 22e34212c7SDmitry Osipenko #include <linux/kernel.h> 23e34212c7SDmitry Osipenko #include <linux/module.h> 24d76fa3f2SDmitry Osipenko #include <linux/mutex.h> 25e34212c7SDmitry Osipenko #include <linux/of_platform.h> 26e34212c7SDmitry Osipenko #include <linux/platform_device.h> 27d76fa3f2SDmitry Osipenko #include <linux/pm_opp.h> 28d76fa3f2SDmitry Osipenko #include <linux/slab.h> 29e34212c7SDmitry Osipenko #include <linux/sort.h> 30e34212c7SDmitry Osipenko #include <linux/types.h> 31e34212c7SDmitry Osipenko 32d76fa3f2SDmitry Osipenko #include <soc/tegra/common.h> 33e34212c7SDmitry Osipenko #include <soc/tegra/fuse.h> 34e34212c7SDmitry Osipenko 35e3aabb3cSDmitry Osipenko #include "../jedec_ddr.h" 36e3aabb3cSDmitry Osipenko #include "../of_memory.h" 37e3aabb3cSDmitry Osipenko 38e34212c7SDmitry Osipenko #include "mc.h" 39e34212c7SDmitry Osipenko 40e34212c7SDmitry Osipenko #define EMC_INTSTATUS 0x000 41e34212c7SDmitry Osipenko #define EMC_INTMASK 0x004 42e34212c7SDmitry Osipenko #define EMC_DBG 0x008 43e3aabb3cSDmitry Osipenko #define EMC_ADR_CFG 0x010 44e34212c7SDmitry Osipenko #define EMC_CFG 0x00c 45e34212c7SDmitry Osipenko #define EMC_REFCTRL 0x020 46e34212c7SDmitry Osipenko #define EMC_TIMING_CONTROL 0x028 47e34212c7SDmitry Osipenko #define EMC_RC 0x02c 48e34212c7SDmitry Osipenko #define EMC_RFC 0x030 49e34212c7SDmitry Osipenko #define EMC_RAS 0x034 50e34212c7SDmitry Osipenko #define EMC_RP 0x038 51e34212c7SDmitry Osipenko #define EMC_R2W 0x03c 52e34212c7SDmitry Osipenko #define EMC_W2R 0x040 53e34212c7SDmitry Osipenko #define EMC_R2P 0x044 54e34212c7SDmitry Osipenko #define EMC_W2P 0x048 55e34212c7SDmitry Osipenko #define EMC_RD_RCD 0x04c 56e34212c7SDmitry Osipenko #define EMC_WR_RCD 0x050 57e34212c7SDmitry Osipenko #define EMC_RRD 0x054 58e34212c7SDmitry Osipenko #define EMC_REXT 0x058 59e34212c7SDmitry Osipenko #define EMC_WDV 0x05c 60e34212c7SDmitry Osipenko #define EMC_QUSE 0x060 61e34212c7SDmitry Osipenko #define EMC_QRST 0x064 62e34212c7SDmitry Osipenko #define EMC_QSAFE 0x068 63e34212c7SDmitry Osipenko #define EMC_RDV 0x06c 64e34212c7SDmitry Osipenko #define EMC_REFRESH 0x070 65e34212c7SDmitry Osipenko #define EMC_BURST_REFRESH_NUM 0x074 66e34212c7SDmitry Osipenko #define EMC_PDEX2WR 0x078 67e34212c7SDmitry Osipenko #define EMC_PDEX2RD 0x07c 68e34212c7SDmitry Osipenko #define EMC_PCHG2PDEN 0x080 69e34212c7SDmitry Osipenko #define EMC_ACT2PDEN 0x084 70e34212c7SDmitry Osipenko #define EMC_AR2PDEN 0x088 71e34212c7SDmitry Osipenko #define EMC_RW2PDEN 0x08c 72e34212c7SDmitry Osipenko #define EMC_TXSR 0x090 73e34212c7SDmitry Osipenko #define EMC_TCKE 0x094 74e34212c7SDmitry Osipenko #define EMC_TFAW 0x098 75e34212c7SDmitry Osipenko #define EMC_TRPAB 0x09c 76e34212c7SDmitry Osipenko #define EMC_TCLKSTABLE 0x0a0 77e34212c7SDmitry Osipenko #define EMC_TCLKSTOP 0x0a4 78e34212c7SDmitry Osipenko #define EMC_TREFBW 0x0a8 79e34212c7SDmitry Osipenko #define EMC_QUSE_EXTRA 0x0ac 80e34212c7SDmitry Osipenko #define EMC_ODT_WRITE 0x0b0 81e34212c7SDmitry Osipenko #define EMC_ODT_READ 0x0b4 82e34212c7SDmitry Osipenko #define EMC_WEXT 0x0b8 83e34212c7SDmitry Osipenko #define EMC_CTT 0x0bc 84e34212c7SDmitry Osipenko #define EMC_MRS_WAIT_CNT 0x0c8 85e34212c7SDmitry Osipenko #define EMC_MRS 0x0cc 86e34212c7SDmitry Osipenko #define EMC_EMRS 0x0d0 87e34212c7SDmitry Osipenko #define EMC_SELF_REF 0x0e0 88e34212c7SDmitry Osipenko #define EMC_MRW 0x0e8 89e3aabb3cSDmitry Osipenko #define EMC_MRR 0x0ec 90e34212c7SDmitry Osipenko #define EMC_XM2DQSPADCTRL3 0x0f8 91e34212c7SDmitry Osipenko #define EMC_FBIO_SPARE 0x100 92e34212c7SDmitry Osipenko #define EMC_FBIO_CFG5 0x104 93e34212c7SDmitry Osipenko #define EMC_FBIO_CFG6 0x114 94e34212c7SDmitry Osipenko #define EMC_CFG_RSV 0x120 95e34212c7SDmitry Osipenko #define EMC_AUTO_CAL_CONFIG 0x2a4 96e34212c7SDmitry Osipenko #define EMC_AUTO_CAL_INTERVAL 0x2a8 97e34212c7SDmitry Osipenko #define EMC_AUTO_CAL_STATUS 0x2ac 98e34212c7SDmitry Osipenko #define EMC_STATUS 0x2b4 99e34212c7SDmitry Osipenko #define EMC_CFG_2 0x2b8 100e34212c7SDmitry Osipenko #define EMC_CFG_DIG_DLL 0x2bc 101e34212c7SDmitry Osipenko #define EMC_CFG_DIG_DLL_PERIOD 0x2c0 102e34212c7SDmitry Osipenko #define EMC_CTT_DURATION 0x2d8 103e34212c7SDmitry Osipenko #define EMC_CTT_TERM_CTRL 0x2dc 104e34212c7SDmitry Osipenko #define EMC_ZCAL_INTERVAL 0x2e0 105e34212c7SDmitry Osipenko #define EMC_ZCAL_WAIT_CNT 0x2e4 106e34212c7SDmitry Osipenko #define EMC_ZQ_CAL 0x2ec 107e34212c7SDmitry Osipenko #define EMC_XM2CMDPADCTRL 0x2f0 108e34212c7SDmitry Osipenko #define EMC_XM2DQSPADCTRL2 0x2fc 109e34212c7SDmitry Osipenko #define EMC_XM2DQPADCTRL2 0x304 110e34212c7SDmitry Osipenko #define EMC_XM2CLKPADCTRL 0x308 111e34212c7SDmitry Osipenko #define EMC_XM2COMPPADCTRL 0x30c 112e34212c7SDmitry Osipenko #define EMC_XM2VTTGENPADCTRL 0x310 113e34212c7SDmitry Osipenko #define EMC_XM2VTTGENPADCTRL2 0x314 114e34212c7SDmitry Osipenko #define EMC_XM2QUSEPADCTRL 0x318 115e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS0 0x328 116e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS1 0x32c 117e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS2 0x330 118e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS3 0x334 119e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS4 0x338 120e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS5 0x33c 121e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS6 0x340 122e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQS7 0x344 123e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE0 0x348 124e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE1 0x34c 125e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE2 0x350 126e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE3 0x354 127e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE4 0x358 128e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE5 0x35c 129e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE6 0x360 130e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_QUSE7 0x364 131e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQ0 0x368 132e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQ1 0x36c 133e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQ2 0x370 134e34212c7SDmitry Osipenko #define EMC_DLL_XFORM_DQ3 0x374 135e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS0 0x3a8 136e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS1 0x3ac 137e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS2 0x3b0 138e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS3 0x3b4 139e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS4 0x3b8 140e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS5 0x3bc 141e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS6 0x3c0 142e34212c7SDmitry Osipenko #define EMC_DLI_TRIM_TXDQS7 0x3c4 143e34212c7SDmitry Osipenko #define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8 144e34212c7SDmitry Osipenko #define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc 145e34212c7SDmitry Osipenko #define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0 146e34212c7SDmitry Osipenko #define EMC_SEL_DPD_CTRL 0x3d8 147e34212c7SDmitry Osipenko #define EMC_PRE_REFRESH_REQ_CNT 0x3dc 148e34212c7SDmitry Osipenko #define EMC_DYN_SELF_REF_CONTROL 0x3e0 149e34212c7SDmitry Osipenko #define EMC_TXSRDLL 0x3e4 150e34212c7SDmitry Osipenko 151e34212c7SDmitry Osipenko #define EMC_STATUS_TIMING_UPDATE_STALLED BIT(23) 152e34212c7SDmitry Osipenko 153e34212c7SDmitry Osipenko #define EMC_MODE_SET_DLL_RESET BIT(8) 154e34212c7SDmitry Osipenko #define EMC_MODE_SET_LONG_CNT BIT(26) 155e34212c7SDmitry Osipenko 156e34212c7SDmitry Osipenko #define EMC_SELF_REF_CMD_ENABLED BIT(0) 157e34212c7SDmitry Osipenko 158e34212c7SDmitry Osipenko #define DRAM_DEV_SEL_ALL (0 << 30) 159e0740fb8SDmitry Osipenko #define DRAM_DEV_SEL_0 BIT(31) 160e0740fb8SDmitry Osipenko #define DRAM_DEV_SEL_1 BIT(30) 161e34212c7SDmitry Osipenko #define DRAM_BROADCAST(num) \ 162e34212c7SDmitry Osipenko ((num) > 1 ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0) 163e34212c7SDmitry Osipenko 164e34212c7SDmitry Osipenko #define EMC_ZQ_CAL_CMD BIT(0) 165e34212c7SDmitry Osipenko #define EMC_ZQ_CAL_LONG BIT(4) 166e34212c7SDmitry Osipenko #define EMC_ZQ_CAL_LONG_CMD_DEV0 \ 167e34212c7SDmitry Osipenko (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) 168e34212c7SDmitry Osipenko #define EMC_ZQ_CAL_LONG_CMD_DEV1 \ 169e34212c7SDmitry Osipenko (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD) 170e34212c7SDmitry Osipenko 171e34212c7SDmitry Osipenko #define EMC_DBG_READ_MUX_ASSEMBLY BIT(0) 172e34212c7SDmitry Osipenko #define EMC_DBG_WRITE_MUX_ACTIVE BIT(1) 173e34212c7SDmitry Osipenko #define EMC_DBG_FORCE_UPDATE BIT(2) 174e34212c7SDmitry Osipenko #define EMC_DBG_CFG_PRIORITY BIT(24) 175e34212c7SDmitry Osipenko 176e34212c7SDmitry Osipenko #define EMC_CFG5_QUSE_MODE_SHIFT 13 177e34212c7SDmitry Osipenko #define EMC_CFG5_QUSE_MODE_MASK (7 << EMC_CFG5_QUSE_MODE_SHIFT) 178e34212c7SDmitry Osipenko 179e34212c7SDmitry Osipenko #define EMC_CFG5_QUSE_MODE_INTERNAL_LPBK 2 180e34212c7SDmitry Osipenko #define EMC_CFG5_QUSE_MODE_PULSE_INTERN 3 181e34212c7SDmitry Osipenko 182e34212c7SDmitry Osipenko #define EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE BIT(9) 183e34212c7SDmitry Osipenko 184e34212c7SDmitry Osipenko #define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE BIT(10) 185e34212c7SDmitry Osipenko 186e34212c7SDmitry Osipenko #define EMC_XM2QUSEPADCTRL_IVREF_ENABLE BIT(4) 187e34212c7SDmitry Osipenko 188e34212c7SDmitry Osipenko #define EMC_XM2DQSPADCTRL2_VREF_ENABLE BIT(5) 189e34212c7SDmitry Osipenko #define EMC_XM2DQSPADCTRL3_VREF_ENABLE BIT(5) 190e34212c7SDmitry Osipenko 191e34212c7SDmitry Osipenko #define EMC_AUTO_CAL_STATUS_ACTIVE BIT(31) 192e34212c7SDmitry Osipenko 193e34212c7SDmitry Osipenko #define EMC_FBIO_CFG5_DRAM_TYPE_MASK 0x3 194e34212c7SDmitry Osipenko 195e34212c7SDmitry Osipenko #define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK 0x3ff 196e34212c7SDmitry Osipenko #define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16 197e34212c7SDmitry Osipenko #define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \ 198e34212c7SDmitry Osipenko (0x3ff << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) 199e34212c7SDmitry Osipenko 200e34212c7SDmitry Osipenko #define EMC_REFCTRL_DEV_SEL_MASK 0x3 201e34212c7SDmitry Osipenko #define EMC_REFCTRL_ENABLE BIT(31) 202e34212c7SDmitry Osipenko #define EMC_REFCTRL_ENABLE_ALL(num) \ 203e34212c7SDmitry Osipenko (((num) > 1 ? 0 : 2) | EMC_REFCTRL_ENABLE) 204e34212c7SDmitry Osipenko #define EMC_REFCTRL_DISABLE_ALL(num) ((num) > 1 ? 0 : 2) 205e34212c7SDmitry Osipenko 206e34212c7SDmitry Osipenko #define EMC_CFG_PERIODIC_QRST BIT(21) 207e34212c7SDmitry Osipenko #define EMC_CFG_DYN_SREF_ENABLE BIT(28) 208e34212c7SDmitry Osipenko 209e34212c7SDmitry Osipenko #define EMC_CLKCHANGE_REQ_ENABLE BIT(0) 210e34212c7SDmitry Osipenko #define EMC_CLKCHANGE_PD_ENABLE BIT(1) 211e34212c7SDmitry Osipenko #define EMC_CLKCHANGE_SR_ENABLE BIT(2) 212e34212c7SDmitry Osipenko 213e34212c7SDmitry Osipenko #define EMC_TIMING_UPDATE BIT(0) 214e34212c7SDmitry Osipenko 215e34212c7SDmitry Osipenko #define EMC_REFRESH_OVERFLOW_INT BIT(3) 216e34212c7SDmitry Osipenko #define EMC_CLKCHANGE_COMPLETE_INT BIT(4) 217e3aabb3cSDmitry Osipenko #define EMC_MRR_DIVLD_INT BIT(5) 218e3aabb3cSDmitry Osipenko 219e3aabb3cSDmitry Osipenko #define EMC_MRR_DEV_SELECTN GENMASK(31, 30) 220e3aabb3cSDmitry Osipenko #define EMC_MRR_MRR_MA GENMASK(23, 16) 221e3aabb3cSDmitry Osipenko #define EMC_MRR_MRR_DATA GENMASK(15, 0) 222e3aabb3cSDmitry Osipenko 223e3aabb3cSDmitry Osipenko #define EMC_ADR_CFG_EMEM_NUMDEV BIT(0) 224e34212c7SDmitry Osipenko 225e34212c7SDmitry Osipenko enum emc_dram_type { 226e34212c7SDmitry Osipenko DRAM_TYPE_DDR3, 227e34212c7SDmitry Osipenko DRAM_TYPE_DDR1, 228e34212c7SDmitry Osipenko DRAM_TYPE_LPDDR2, 229e34212c7SDmitry Osipenko DRAM_TYPE_DDR2, 230e34212c7SDmitry Osipenko }; 231e34212c7SDmitry Osipenko 232e34212c7SDmitry Osipenko enum emc_dll_change { 233e34212c7SDmitry Osipenko DLL_CHANGE_NONE, 234e34212c7SDmitry Osipenko DLL_CHANGE_ON, 235e34212c7SDmitry Osipenko DLL_CHANGE_OFF 236e34212c7SDmitry Osipenko }; 237e34212c7SDmitry Osipenko 238e34212c7SDmitry Osipenko static const u16 emc_timing_registers[] = { 239e34212c7SDmitry Osipenko [0] = EMC_RC, 240e34212c7SDmitry Osipenko [1] = EMC_RFC, 241e34212c7SDmitry Osipenko [2] = EMC_RAS, 242e34212c7SDmitry Osipenko [3] = EMC_RP, 243e34212c7SDmitry Osipenko [4] = EMC_R2W, 244e34212c7SDmitry Osipenko [5] = EMC_W2R, 245e34212c7SDmitry Osipenko [6] = EMC_R2P, 246e34212c7SDmitry Osipenko [7] = EMC_W2P, 247e34212c7SDmitry Osipenko [8] = EMC_RD_RCD, 248e34212c7SDmitry Osipenko [9] = EMC_WR_RCD, 249e34212c7SDmitry Osipenko [10] = EMC_RRD, 250e34212c7SDmitry Osipenko [11] = EMC_REXT, 251e34212c7SDmitry Osipenko [12] = EMC_WEXT, 252e34212c7SDmitry Osipenko [13] = EMC_WDV, 253e34212c7SDmitry Osipenko [14] = EMC_QUSE, 254e34212c7SDmitry Osipenko [15] = EMC_QRST, 255e34212c7SDmitry Osipenko [16] = EMC_QSAFE, 256e34212c7SDmitry Osipenko [17] = EMC_RDV, 257e34212c7SDmitry Osipenko [18] = EMC_REFRESH, 258e34212c7SDmitry Osipenko [19] = EMC_BURST_REFRESH_NUM, 259e34212c7SDmitry Osipenko [20] = EMC_PRE_REFRESH_REQ_CNT, 260e34212c7SDmitry Osipenko [21] = EMC_PDEX2WR, 261e34212c7SDmitry Osipenko [22] = EMC_PDEX2RD, 262e34212c7SDmitry Osipenko [23] = EMC_PCHG2PDEN, 263e34212c7SDmitry Osipenko [24] = EMC_ACT2PDEN, 264e34212c7SDmitry Osipenko [25] = EMC_AR2PDEN, 265e34212c7SDmitry Osipenko [26] = EMC_RW2PDEN, 266e34212c7SDmitry Osipenko [27] = EMC_TXSR, 267e34212c7SDmitry Osipenko [28] = EMC_TXSRDLL, 268e34212c7SDmitry Osipenko [29] = EMC_TCKE, 269e34212c7SDmitry Osipenko [30] = EMC_TFAW, 270e34212c7SDmitry Osipenko [31] = EMC_TRPAB, 271e34212c7SDmitry Osipenko [32] = EMC_TCLKSTABLE, 272e34212c7SDmitry Osipenko [33] = EMC_TCLKSTOP, 273e34212c7SDmitry Osipenko [34] = EMC_TREFBW, 274e34212c7SDmitry Osipenko [35] = EMC_QUSE_EXTRA, 275e34212c7SDmitry Osipenko [36] = EMC_FBIO_CFG6, 276e34212c7SDmitry Osipenko [37] = EMC_ODT_WRITE, 277e34212c7SDmitry Osipenko [38] = EMC_ODT_READ, 278e34212c7SDmitry Osipenko [39] = EMC_FBIO_CFG5, 279e34212c7SDmitry Osipenko [40] = EMC_CFG_DIG_DLL, 280e34212c7SDmitry Osipenko [41] = EMC_CFG_DIG_DLL_PERIOD, 281e34212c7SDmitry Osipenko [42] = EMC_DLL_XFORM_DQS0, 282e34212c7SDmitry Osipenko [43] = EMC_DLL_XFORM_DQS1, 283e34212c7SDmitry Osipenko [44] = EMC_DLL_XFORM_DQS2, 284e34212c7SDmitry Osipenko [45] = EMC_DLL_XFORM_DQS3, 285e34212c7SDmitry Osipenko [46] = EMC_DLL_XFORM_DQS4, 286e34212c7SDmitry Osipenko [47] = EMC_DLL_XFORM_DQS5, 287e34212c7SDmitry Osipenko [48] = EMC_DLL_XFORM_DQS6, 288e34212c7SDmitry Osipenko [49] = EMC_DLL_XFORM_DQS7, 289e34212c7SDmitry Osipenko [50] = EMC_DLL_XFORM_QUSE0, 290e34212c7SDmitry Osipenko [51] = EMC_DLL_XFORM_QUSE1, 291e34212c7SDmitry Osipenko [52] = EMC_DLL_XFORM_QUSE2, 292e34212c7SDmitry Osipenko [53] = EMC_DLL_XFORM_QUSE3, 293e34212c7SDmitry Osipenko [54] = EMC_DLL_XFORM_QUSE4, 294e34212c7SDmitry Osipenko [55] = EMC_DLL_XFORM_QUSE5, 295e34212c7SDmitry Osipenko [56] = EMC_DLL_XFORM_QUSE6, 296e34212c7SDmitry Osipenko [57] = EMC_DLL_XFORM_QUSE7, 297e34212c7SDmitry Osipenko [58] = EMC_DLI_TRIM_TXDQS0, 298e34212c7SDmitry Osipenko [59] = EMC_DLI_TRIM_TXDQS1, 299e34212c7SDmitry Osipenko [60] = EMC_DLI_TRIM_TXDQS2, 300e34212c7SDmitry Osipenko [61] = EMC_DLI_TRIM_TXDQS3, 301e34212c7SDmitry Osipenko [62] = EMC_DLI_TRIM_TXDQS4, 302e34212c7SDmitry Osipenko [63] = EMC_DLI_TRIM_TXDQS5, 303e34212c7SDmitry Osipenko [64] = EMC_DLI_TRIM_TXDQS6, 304e34212c7SDmitry Osipenko [65] = EMC_DLI_TRIM_TXDQS7, 305e34212c7SDmitry Osipenko [66] = EMC_DLL_XFORM_DQ0, 306e34212c7SDmitry Osipenko [67] = EMC_DLL_XFORM_DQ1, 307e34212c7SDmitry Osipenko [68] = EMC_DLL_XFORM_DQ2, 308e34212c7SDmitry Osipenko [69] = EMC_DLL_XFORM_DQ3, 309e34212c7SDmitry Osipenko [70] = EMC_XM2CMDPADCTRL, 310e34212c7SDmitry Osipenko [71] = EMC_XM2DQSPADCTRL2, 311e34212c7SDmitry Osipenko [72] = EMC_XM2DQPADCTRL2, 312e34212c7SDmitry Osipenko [73] = EMC_XM2CLKPADCTRL, 313e34212c7SDmitry Osipenko [74] = EMC_XM2COMPPADCTRL, 314e34212c7SDmitry Osipenko [75] = EMC_XM2VTTGENPADCTRL, 315e34212c7SDmitry Osipenko [76] = EMC_XM2VTTGENPADCTRL2, 316e34212c7SDmitry Osipenko [77] = EMC_XM2QUSEPADCTRL, 317e34212c7SDmitry Osipenko [78] = EMC_XM2DQSPADCTRL3, 318e34212c7SDmitry Osipenko [79] = EMC_CTT_TERM_CTRL, 319e34212c7SDmitry Osipenko [80] = EMC_ZCAL_INTERVAL, 320e34212c7SDmitry Osipenko [81] = EMC_ZCAL_WAIT_CNT, 321e34212c7SDmitry Osipenko [82] = EMC_MRS_WAIT_CNT, 322e34212c7SDmitry Osipenko [83] = EMC_AUTO_CAL_CONFIG, 323e34212c7SDmitry Osipenko [84] = EMC_CTT, 324e34212c7SDmitry Osipenko [85] = EMC_CTT_DURATION, 325e34212c7SDmitry Osipenko [86] = EMC_DYN_SELF_REF_CONTROL, 326e34212c7SDmitry Osipenko [87] = EMC_FBIO_SPARE, 327e34212c7SDmitry Osipenko [88] = EMC_CFG_RSV, 328e34212c7SDmitry Osipenko }; 329e34212c7SDmitry Osipenko 330e34212c7SDmitry Osipenko struct emc_timing { 331e34212c7SDmitry Osipenko unsigned long rate; 332e34212c7SDmitry Osipenko 333e34212c7SDmitry Osipenko u32 data[ARRAY_SIZE(emc_timing_registers)]; 334e34212c7SDmitry Osipenko 335e34212c7SDmitry Osipenko u32 emc_auto_cal_interval; 336e34212c7SDmitry Osipenko u32 emc_mode_1; 337e34212c7SDmitry Osipenko u32 emc_mode_2; 338e34212c7SDmitry Osipenko u32 emc_mode_reset; 339e34212c7SDmitry Osipenko u32 emc_zcal_cnt_long; 340e34212c7SDmitry Osipenko bool emc_cfg_periodic_qrst; 341e34212c7SDmitry Osipenko bool emc_cfg_dyn_self_ref; 342e34212c7SDmitry Osipenko }; 343e34212c7SDmitry Osipenko 344d76fa3f2SDmitry Osipenko enum emc_rate_request_type { 345d76fa3f2SDmitry Osipenko EMC_RATE_DEBUG, 346d76fa3f2SDmitry Osipenko EMC_RATE_ICC, 347d76fa3f2SDmitry Osipenko EMC_RATE_TYPE_MAX, 348d76fa3f2SDmitry Osipenko }; 349d76fa3f2SDmitry Osipenko 350d76fa3f2SDmitry Osipenko struct emc_rate_request { 351d76fa3f2SDmitry Osipenko unsigned long min_rate; 352d76fa3f2SDmitry Osipenko unsigned long max_rate; 353d76fa3f2SDmitry Osipenko }; 354d76fa3f2SDmitry Osipenko 355e34212c7SDmitry Osipenko struct tegra_emc { 356e34212c7SDmitry Osipenko struct device *dev; 357e34212c7SDmitry Osipenko struct tegra_mc *mc; 358d76fa3f2SDmitry Osipenko struct icc_provider provider; 359e34212c7SDmitry Osipenko struct notifier_block clk_nb; 360e34212c7SDmitry Osipenko struct clk *clk; 361e34212c7SDmitry Osipenko void __iomem *regs; 362e34212c7SDmitry Osipenko unsigned int irq; 3630f8bb9daSDmitry Osipenko bool bad_state; 364e34212c7SDmitry Osipenko 3650f8bb9daSDmitry Osipenko struct emc_timing *new_timing; 366e34212c7SDmitry Osipenko struct emc_timing *timings; 367e34212c7SDmitry Osipenko unsigned int num_timings; 368e34212c7SDmitry Osipenko 369e34212c7SDmitry Osipenko u32 mc_override; 370e34212c7SDmitry Osipenko u32 emc_cfg; 371e34212c7SDmitry Osipenko 372e34212c7SDmitry Osipenko u32 emc_mode_1; 373e34212c7SDmitry Osipenko u32 emc_mode_2; 374e34212c7SDmitry Osipenko u32 emc_mode_reset; 375e34212c7SDmitry Osipenko 376e34212c7SDmitry Osipenko bool vref_cal_toggle : 1; 377e34212c7SDmitry Osipenko bool zcal_long : 1; 378e34212c7SDmitry Osipenko bool dll_on : 1; 3798cee32b4SThierry Reding 3808cee32b4SThierry Reding struct { 3818cee32b4SThierry Reding struct dentry *root; 3828cee32b4SThierry Reding unsigned long min_rate; 3838cee32b4SThierry Reding unsigned long max_rate; 3848cee32b4SThierry Reding } debugfs; 385d76fa3f2SDmitry Osipenko 386d76fa3f2SDmitry Osipenko /* 387d76fa3f2SDmitry Osipenko * There are multiple sources in the EMC driver which could request 388d76fa3f2SDmitry Osipenko * a min/max clock rate, these rates are contained in this array. 389d76fa3f2SDmitry Osipenko */ 390d76fa3f2SDmitry Osipenko struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX]; 391d76fa3f2SDmitry Osipenko 392d76fa3f2SDmitry Osipenko /* protect shared rate-change code path */ 393d76fa3f2SDmitry Osipenko struct mutex rate_lock; 394e3aabb3cSDmitry Osipenko 395e3aabb3cSDmitry Osipenko bool mrr_error; 396e34212c7SDmitry Osipenko }; 397e34212c7SDmitry Osipenko 3980f8bb9daSDmitry Osipenko static int emc_seq_update_timing(struct tegra_emc *emc) 3990f8bb9daSDmitry Osipenko { 4000f8bb9daSDmitry Osipenko u32 val; 4010f8bb9daSDmitry Osipenko int err; 4020f8bb9daSDmitry Osipenko 4030f8bb9daSDmitry Osipenko writel_relaxed(EMC_TIMING_UPDATE, emc->regs + EMC_TIMING_CONTROL); 4040f8bb9daSDmitry Osipenko 4050f8bb9daSDmitry Osipenko err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_STATUS, val, 4060f8bb9daSDmitry Osipenko !(val & EMC_STATUS_TIMING_UPDATE_STALLED), 4070f8bb9daSDmitry Osipenko 1, 200); 4080f8bb9daSDmitry Osipenko if (err) { 4090f8bb9daSDmitry Osipenko dev_err(emc->dev, "failed to update timing: %d\n", err); 4100f8bb9daSDmitry Osipenko return err; 4110f8bb9daSDmitry Osipenko } 4120f8bb9daSDmitry Osipenko 4130f8bb9daSDmitry Osipenko return 0; 4140f8bb9daSDmitry Osipenko } 4150f8bb9daSDmitry Osipenko 416e34212c7SDmitry Osipenko static irqreturn_t tegra_emc_isr(int irq, void *data) 417e34212c7SDmitry Osipenko { 418e34212c7SDmitry Osipenko struct tegra_emc *emc = data; 419930c6818SDmitry Osipenko u32 intmask = EMC_REFRESH_OVERFLOW_INT; 420e34212c7SDmitry Osipenko u32 status; 421e34212c7SDmitry Osipenko 422e34212c7SDmitry Osipenko status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask; 423e34212c7SDmitry Osipenko if (!status) 424e34212c7SDmitry Osipenko return IRQ_NONE; 425e34212c7SDmitry Osipenko 426e34212c7SDmitry Osipenko /* notify about HW problem */ 427e34212c7SDmitry Osipenko if (status & EMC_REFRESH_OVERFLOW_INT) 428e34212c7SDmitry Osipenko dev_err_ratelimited(emc->dev, 429e34212c7SDmitry Osipenko "refresh request overflow timeout\n"); 430e34212c7SDmitry Osipenko 431e34212c7SDmitry Osipenko /* clear interrupts */ 432e34212c7SDmitry Osipenko writel_relaxed(status, emc->regs + EMC_INTSTATUS); 433e34212c7SDmitry Osipenko 434e34212c7SDmitry Osipenko return IRQ_HANDLED; 435e34212c7SDmitry Osipenko } 436e34212c7SDmitry Osipenko 437e34212c7SDmitry Osipenko static struct emc_timing *emc_find_timing(struct tegra_emc *emc, 438e34212c7SDmitry Osipenko unsigned long rate) 439e34212c7SDmitry Osipenko { 440e34212c7SDmitry Osipenko struct emc_timing *timing = NULL; 441e34212c7SDmitry Osipenko unsigned int i; 442e34212c7SDmitry Osipenko 443e34212c7SDmitry Osipenko for (i = 0; i < emc->num_timings; i++) { 444e34212c7SDmitry Osipenko if (emc->timings[i].rate >= rate) { 445e34212c7SDmitry Osipenko timing = &emc->timings[i]; 446e34212c7SDmitry Osipenko break; 447e34212c7SDmitry Osipenko } 448e34212c7SDmitry Osipenko } 449e34212c7SDmitry Osipenko 450e34212c7SDmitry Osipenko if (!timing) { 451e34212c7SDmitry Osipenko dev_err(emc->dev, "no timing for rate %lu\n", rate); 452e34212c7SDmitry Osipenko return NULL; 453e34212c7SDmitry Osipenko } 454e34212c7SDmitry Osipenko 455e34212c7SDmitry Osipenko return timing; 456e34212c7SDmitry Osipenko } 457e34212c7SDmitry Osipenko 458e34212c7SDmitry Osipenko static bool emc_dqs_preset(struct tegra_emc *emc, struct emc_timing *timing, 459e34212c7SDmitry Osipenko bool *schmitt_to_vref) 460e34212c7SDmitry Osipenko { 461e34212c7SDmitry Osipenko bool preset = false; 462e34212c7SDmitry Osipenko u32 val; 463e34212c7SDmitry Osipenko 464e34212c7SDmitry Osipenko if (timing->data[71] & EMC_XM2DQSPADCTRL2_VREF_ENABLE) { 465e34212c7SDmitry Osipenko val = readl_relaxed(emc->regs + EMC_XM2DQSPADCTRL2); 466e34212c7SDmitry Osipenko 467e34212c7SDmitry Osipenko if (!(val & EMC_XM2DQSPADCTRL2_VREF_ENABLE)) { 468e34212c7SDmitry Osipenko val |= EMC_XM2DQSPADCTRL2_VREF_ENABLE; 469e34212c7SDmitry Osipenko writel_relaxed(val, emc->regs + EMC_XM2DQSPADCTRL2); 470e34212c7SDmitry Osipenko 471e34212c7SDmitry Osipenko preset = true; 472e34212c7SDmitry Osipenko } 473e34212c7SDmitry Osipenko } 474e34212c7SDmitry Osipenko 475e34212c7SDmitry Osipenko if (timing->data[78] & EMC_XM2DQSPADCTRL3_VREF_ENABLE) { 476e34212c7SDmitry Osipenko val = readl_relaxed(emc->regs + EMC_XM2DQSPADCTRL3); 477e34212c7SDmitry Osipenko 478e34212c7SDmitry Osipenko if (!(val & EMC_XM2DQSPADCTRL3_VREF_ENABLE)) { 479e34212c7SDmitry Osipenko val |= EMC_XM2DQSPADCTRL3_VREF_ENABLE; 480e34212c7SDmitry Osipenko writel_relaxed(val, emc->regs + EMC_XM2DQSPADCTRL3); 481e34212c7SDmitry Osipenko 482e34212c7SDmitry Osipenko preset = true; 483e34212c7SDmitry Osipenko } 484e34212c7SDmitry Osipenko } 485e34212c7SDmitry Osipenko 486e34212c7SDmitry Osipenko if (timing->data[77] & EMC_XM2QUSEPADCTRL_IVREF_ENABLE) { 487e34212c7SDmitry Osipenko val = readl_relaxed(emc->regs + EMC_XM2QUSEPADCTRL); 488e34212c7SDmitry Osipenko 489e34212c7SDmitry Osipenko if (!(val & EMC_XM2QUSEPADCTRL_IVREF_ENABLE)) { 490e34212c7SDmitry Osipenko val |= EMC_XM2QUSEPADCTRL_IVREF_ENABLE; 491e34212c7SDmitry Osipenko writel_relaxed(val, emc->regs + EMC_XM2QUSEPADCTRL); 492e34212c7SDmitry Osipenko 493e34212c7SDmitry Osipenko *schmitt_to_vref = true; 494e34212c7SDmitry Osipenko preset = true; 495e34212c7SDmitry Osipenko } 496e34212c7SDmitry Osipenko } 497e34212c7SDmitry Osipenko 498e34212c7SDmitry Osipenko return preset; 499e34212c7SDmitry Osipenko } 500e34212c7SDmitry Osipenko 501e34212c7SDmitry Osipenko static int emc_prepare_mc_clk_cfg(struct tegra_emc *emc, unsigned long rate) 502e34212c7SDmitry Osipenko { 503e34212c7SDmitry Osipenko struct tegra_mc *mc = emc->mc; 504e34212c7SDmitry Osipenko unsigned int misc0_index = 16; 505e34212c7SDmitry Osipenko unsigned int i; 506e34212c7SDmitry Osipenko bool same; 507e34212c7SDmitry Osipenko 508e34212c7SDmitry Osipenko for (i = 0; i < mc->num_timings; i++) { 509e34212c7SDmitry Osipenko if (mc->timings[i].rate != rate) 510e34212c7SDmitry Osipenko continue; 511e34212c7SDmitry Osipenko 512e34212c7SDmitry Osipenko if (mc->timings[i].emem_data[misc0_index] & BIT(27)) 513e34212c7SDmitry Osipenko same = true; 514e34212c7SDmitry Osipenko else 515e34212c7SDmitry Osipenko same = false; 516e34212c7SDmitry Osipenko 517e34212c7SDmitry Osipenko return tegra20_clk_prepare_emc_mc_same_freq(emc->clk, same); 518e34212c7SDmitry Osipenko } 519e34212c7SDmitry Osipenko 520e34212c7SDmitry Osipenko return -EINVAL; 521e34212c7SDmitry Osipenko } 522e34212c7SDmitry Osipenko 523e34212c7SDmitry Osipenko static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate) 524e34212c7SDmitry Osipenko { 525e34212c7SDmitry Osipenko struct emc_timing *timing = emc_find_timing(emc, rate); 526e34212c7SDmitry Osipenko enum emc_dll_change dll_change; 527e34212c7SDmitry Osipenko enum emc_dram_type dram_type; 528e34212c7SDmitry Osipenko bool schmitt_to_vref = false; 529e34212c7SDmitry Osipenko unsigned int pre_wait = 0; 530e34212c7SDmitry Osipenko bool qrst_used = false; 531e34212c7SDmitry Osipenko unsigned int dram_num; 532e34212c7SDmitry Osipenko unsigned int i; 533e34212c7SDmitry Osipenko u32 fbio_cfg5; 534e34212c7SDmitry Osipenko u32 emc_dbg; 535e34212c7SDmitry Osipenko u32 val; 536e34212c7SDmitry Osipenko int err; 537e34212c7SDmitry Osipenko 538e34212c7SDmitry Osipenko if (!timing || emc->bad_state) 539e34212c7SDmitry Osipenko return -EINVAL; 540e34212c7SDmitry Osipenko 541e34212c7SDmitry Osipenko dev_dbg(emc->dev, "%s: using timing rate %lu for requested rate %lu\n", 542e34212c7SDmitry Osipenko __func__, timing->rate, rate); 543e34212c7SDmitry Osipenko 544e34212c7SDmitry Osipenko emc->bad_state = true; 545e34212c7SDmitry Osipenko 546e34212c7SDmitry Osipenko err = emc_prepare_mc_clk_cfg(emc, rate); 547e34212c7SDmitry Osipenko if (err) { 548e34212c7SDmitry Osipenko dev_err(emc->dev, "mc clock preparation failed: %d\n", err); 549e34212c7SDmitry Osipenko return err; 550e34212c7SDmitry Osipenko } 551e34212c7SDmitry Osipenko 552e34212c7SDmitry Osipenko emc->vref_cal_toggle = false; 553e34212c7SDmitry Osipenko emc->mc_override = mc_readl(emc->mc, MC_EMEM_ARB_OVERRIDE); 554e34212c7SDmitry Osipenko emc->emc_cfg = readl_relaxed(emc->regs + EMC_CFG); 555e34212c7SDmitry Osipenko emc_dbg = readl_relaxed(emc->regs + EMC_DBG); 556e34212c7SDmitry Osipenko 557e34212c7SDmitry Osipenko if (emc->dll_on == !!(timing->emc_mode_1 & 0x1)) 558e34212c7SDmitry Osipenko dll_change = DLL_CHANGE_NONE; 559e34212c7SDmitry Osipenko else if (timing->emc_mode_1 & 0x1) 560e34212c7SDmitry Osipenko dll_change = DLL_CHANGE_ON; 561e34212c7SDmitry Osipenko else 562e34212c7SDmitry Osipenko dll_change = DLL_CHANGE_OFF; 563e34212c7SDmitry Osipenko 564e34212c7SDmitry Osipenko emc->dll_on = !!(timing->emc_mode_1 & 0x1); 565e34212c7SDmitry Osipenko 566e34212c7SDmitry Osipenko if (timing->data[80] && !readl_relaxed(emc->regs + EMC_ZCAL_INTERVAL)) 567e34212c7SDmitry Osipenko emc->zcal_long = true; 568e34212c7SDmitry Osipenko else 569e34212c7SDmitry Osipenko emc->zcal_long = false; 570e34212c7SDmitry Osipenko 571e34212c7SDmitry Osipenko fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5); 572e34212c7SDmitry Osipenko dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK; 573e34212c7SDmitry Osipenko 574e34212c7SDmitry Osipenko dram_num = tegra_mc_get_emem_device_count(emc->mc); 575e34212c7SDmitry Osipenko 576e34212c7SDmitry Osipenko /* disable dynamic self-refresh */ 577e34212c7SDmitry Osipenko if (emc->emc_cfg & EMC_CFG_DYN_SREF_ENABLE) { 578e34212c7SDmitry Osipenko emc->emc_cfg &= ~EMC_CFG_DYN_SREF_ENABLE; 579e34212c7SDmitry Osipenko writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG); 580e34212c7SDmitry Osipenko 581e34212c7SDmitry Osipenko pre_wait = 5; 582e34212c7SDmitry Osipenko } 583e34212c7SDmitry Osipenko 584e34212c7SDmitry Osipenko /* update MC arbiter settings */ 585e34212c7SDmitry Osipenko val = mc_readl(emc->mc, MC_EMEM_ARB_OUTSTANDING_REQ); 586e34212c7SDmitry Osipenko if (!(val & MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE) || 587e34212c7SDmitry Osipenko ((val & MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK) > 0x50)) { 588e34212c7SDmitry Osipenko 589e34212c7SDmitry Osipenko val = MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE | 590e34212c7SDmitry Osipenko MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE | 0x50; 591e34212c7SDmitry Osipenko mc_writel(emc->mc, val, MC_EMEM_ARB_OUTSTANDING_REQ); 592e34212c7SDmitry Osipenko mc_writel(emc->mc, MC_TIMING_UPDATE, MC_TIMING_CONTROL); 593e34212c7SDmitry Osipenko } 594e34212c7SDmitry Osipenko 595e34212c7SDmitry Osipenko if (emc->mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK) 596e34212c7SDmitry Osipenko mc_writel(emc->mc, 597e34212c7SDmitry Osipenko emc->mc_override & ~MC_EMEM_ARB_OVERRIDE_EACK_MASK, 598e34212c7SDmitry Osipenko MC_EMEM_ARB_OVERRIDE); 599e34212c7SDmitry Osipenko 600e34212c7SDmitry Osipenko /* check DQ/DQS VREF delay */ 601e34212c7SDmitry Osipenko if (emc_dqs_preset(emc, timing, &schmitt_to_vref)) { 602e34212c7SDmitry Osipenko if (pre_wait < 3) 603e34212c7SDmitry Osipenko pre_wait = 3; 604e34212c7SDmitry Osipenko } 605e34212c7SDmitry Osipenko 606e34212c7SDmitry Osipenko if (pre_wait) { 607e34212c7SDmitry Osipenko err = emc_seq_update_timing(emc); 608e34212c7SDmitry Osipenko if (err) 609e34212c7SDmitry Osipenko return err; 610e34212c7SDmitry Osipenko 611e34212c7SDmitry Osipenko udelay(pre_wait); 612e34212c7SDmitry Osipenko } 613e34212c7SDmitry Osipenko 614e34212c7SDmitry Osipenko /* disable auto-calibration if VREF mode is switching */ 615e34212c7SDmitry Osipenko if (timing->emc_auto_cal_interval) { 616e34212c7SDmitry Osipenko val = readl_relaxed(emc->regs + EMC_XM2COMPPADCTRL); 617e34212c7SDmitry Osipenko val ^= timing->data[74]; 618e34212c7SDmitry Osipenko 619e34212c7SDmitry Osipenko if (val & EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE) { 620e34212c7SDmitry Osipenko writel_relaxed(0, emc->regs + EMC_AUTO_CAL_INTERVAL); 621e34212c7SDmitry Osipenko 622e34212c7SDmitry Osipenko err = readl_relaxed_poll_timeout_atomic( 623e34212c7SDmitry Osipenko emc->regs + EMC_AUTO_CAL_STATUS, val, 624e34212c7SDmitry Osipenko !(val & EMC_AUTO_CAL_STATUS_ACTIVE), 1, 300); 625e34212c7SDmitry Osipenko if (err) { 626e34212c7SDmitry Osipenko dev_err(emc->dev, 6275e5eca66SDmitry Osipenko "auto-cal finish timeout: %d\n", err); 628e34212c7SDmitry Osipenko return err; 629e34212c7SDmitry Osipenko } 630e34212c7SDmitry Osipenko 631e34212c7SDmitry Osipenko emc->vref_cal_toggle = true; 632e34212c7SDmitry Osipenko } 633e34212c7SDmitry Osipenko } 634e34212c7SDmitry Osipenko 635e34212c7SDmitry Osipenko /* program shadow registers */ 636e34212c7SDmitry Osipenko for (i = 0; i < ARRAY_SIZE(timing->data); i++) { 637e34212c7SDmitry Osipenko /* EMC_XM2CLKPADCTRL should be programmed separately */ 638e34212c7SDmitry Osipenko if (i != 73) 639e34212c7SDmitry Osipenko writel_relaxed(timing->data[i], 640e34212c7SDmitry Osipenko emc->regs + emc_timing_registers[i]); 641e34212c7SDmitry Osipenko } 642e34212c7SDmitry Osipenko 643e34212c7SDmitry Osipenko err = tegra_mc_write_emem_configuration(emc->mc, timing->rate); 644e34212c7SDmitry Osipenko if (err) 645e34212c7SDmitry Osipenko return err; 646e34212c7SDmitry Osipenko 647e34212c7SDmitry Osipenko /* DDR3: predict MRS long wait count */ 648e34212c7SDmitry Osipenko if (dram_type == DRAM_TYPE_DDR3 && dll_change == DLL_CHANGE_ON) { 649e34212c7SDmitry Osipenko u32 cnt = 512; 650e34212c7SDmitry Osipenko 651e34212c7SDmitry Osipenko if (emc->zcal_long) 652e34212c7SDmitry Osipenko cnt -= dram_num * 256; 653e34212c7SDmitry Osipenko 654e34212c7SDmitry Osipenko val = timing->data[82] & EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK; 655e34212c7SDmitry Osipenko if (cnt < val) 656e34212c7SDmitry Osipenko cnt = val; 657e34212c7SDmitry Osipenko 658e34212c7SDmitry Osipenko val = timing->data[82] & ~EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; 659e34212c7SDmitry Osipenko val |= (cnt << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) & 660e34212c7SDmitry Osipenko EMC_MRS_WAIT_CNT_LONG_WAIT_MASK; 661e34212c7SDmitry Osipenko 662e34212c7SDmitry Osipenko writel_relaxed(val, emc->regs + EMC_MRS_WAIT_CNT); 663e34212c7SDmitry Osipenko } 664e34212c7SDmitry Osipenko 665e34212c7SDmitry Osipenko /* this read also completes the writes */ 666e34212c7SDmitry Osipenko val = readl_relaxed(emc->regs + EMC_SEL_DPD_CTRL); 667e34212c7SDmitry Osipenko 668e34212c7SDmitry Osipenko if (!(val & EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE) && schmitt_to_vref) { 669e34212c7SDmitry Osipenko u32 cur_mode, new_mode; 670e34212c7SDmitry Osipenko 671e34212c7SDmitry Osipenko cur_mode = fbio_cfg5 & EMC_CFG5_QUSE_MODE_MASK; 672e34212c7SDmitry Osipenko cur_mode >>= EMC_CFG5_QUSE_MODE_SHIFT; 673e34212c7SDmitry Osipenko 674e34212c7SDmitry Osipenko new_mode = timing->data[39] & EMC_CFG5_QUSE_MODE_MASK; 675e34212c7SDmitry Osipenko new_mode >>= EMC_CFG5_QUSE_MODE_SHIFT; 676e34212c7SDmitry Osipenko 677e34212c7SDmitry Osipenko if ((cur_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN && 678e34212c7SDmitry Osipenko cur_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK) || 679e34212c7SDmitry Osipenko (new_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN && 680e34212c7SDmitry Osipenko new_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK)) 681e34212c7SDmitry Osipenko qrst_used = true; 682e34212c7SDmitry Osipenko } 683e34212c7SDmitry Osipenko 684e34212c7SDmitry Osipenko /* flow control marker 1 */ 685e34212c7SDmitry Osipenko writel_relaxed(0x1, emc->regs + EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE); 686e34212c7SDmitry Osipenko 687e34212c7SDmitry Osipenko /* enable periodic reset */ 688e34212c7SDmitry Osipenko if (qrst_used) { 689e34212c7SDmitry Osipenko writel_relaxed(emc_dbg | EMC_DBG_WRITE_MUX_ACTIVE, 690e34212c7SDmitry Osipenko emc->regs + EMC_DBG); 691e34212c7SDmitry Osipenko writel_relaxed(emc->emc_cfg | EMC_CFG_PERIODIC_QRST, 692e34212c7SDmitry Osipenko emc->regs + EMC_CFG); 693e34212c7SDmitry Osipenko writel_relaxed(emc_dbg, emc->regs + EMC_DBG); 694e34212c7SDmitry Osipenko } 695e34212c7SDmitry Osipenko 696e34212c7SDmitry Osipenko /* disable auto-refresh to save time after clock change */ 697e34212c7SDmitry Osipenko writel_relaxed(EMC_REFCTRL_DISABLE_ALL(dram_num), 698e34212c7SDmitry Osipenko emc->regs + EMC_REFCTRL); 699e34212c7SDmitry Osipenko 700e34212c7SDmitry Osipenko /* turn off DLL and enter self-refresh on DDR3 */ 701e34212c7SDmitry Osipenko if (dram_type == DRAM_TYPE_DDR3) { 702e34212c7SDmitry Osipenko if (dll_change == DLL_CHANGE_OFF) 703e34212c7SDmitry Osipenko writel_relaxed(timing->emc_mode_1, 704e34212c7SDmitry Osipenko emc->regs + EMC_EMRS); 705e34212c7SDmitry Osipenko 706e34212c7SDmitry Osipenko writel_relaxed(DRAM_BROADCAST(dram_num) | 707e34212c7SDmitry Osipenko EMC_SELF_REF_CMD_ENABLED, 708e34212c7SDmitry Osipenko emc->regs + EMC_SELF_REF); 709e34212c7SDmitry Osipenko } 710e34212c7SDmitry Osipenko 711e34212c7SDmitry Osipenko /* flow control marker 2 */ 712e34212c7SDmitry Osipenko writel_relaxed(0x1, emc->regs + EMC_STALL_THEN_EXE_AFTER_CLKCHANGE); 713e34212c7SDmitry Osipenko 714e34212c7SDmitry Osipenko /* enable write-active MUX, update unshadowed pad control */ 715e34212c7SDmitry Osipenko writel_relaxed(emc_dbg | EMC_DBG_WRITE_MUX_ACTIVE, emc->regs + EMC_DBG); 716e34212c7SDmitry Osipenko writel_relaxed(timing->data[73], emc->regs + EMC_XM2CLKPADCTRL); 717e34212c7SDmitry Osipenko 718e34212c7SDmitry Osipenko /* restore periodic QRST and disable write-active MUX */ 719e34212c7SDmitry Osipenko val = !!(emc->emc_cfg & EMC_CFG_PERIODIC_QRST); 720e34212c7SDmitry Osipenko if (qrst_used || timing->emc_cfg_periodic_qrst != val) { 721e34212c7SDmitry Osipenko if (timing->emc_cfg_periodic_qrst) 722e34212c7SDmitry Osipenko emc->emc_cfg |= EMC_CFG_PERIODIC_QRST; 723e34212c7SDmitry Osipenko else 724e34212c7SDmitry Osipenko emc->emc_cfg &= ~EMC_CFG_PERIODIC_QRST; 725e34212c7SDmitry Osipenko 726e34212c7SDmitry Osipenko writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG); 727e34212c7SDmitry Osipenko } 728e34212c7SDmitry Osipenko writel_relaxed(emc_dbg, emc->regs + EMC_DBG); 729e34212c7SDmitry Osipenko 730e34212c7SDmitry Osipenko /* exit self-refresh on DDR3 */ 731e34212c7SDmitry Osipenko if (dram_type == DRAM_TYPE_DDR3) 732e34212c7SDmitry Osipenko writel_relaxed(DRAM_BROADCAST(dram_num), 733e34212c7SDmitry Osipenko emc->regs + EMC_SELF_REF); 734e34212c7SDmitry Osipenko 735e34212c7SDmitry Osipenko /* set DRAM-mode registers */ 736e34212c7SDmitry Osipenko if (dram_type == DRAM_TYPE_DDR3) { 737e34212c7SDmitry Osipenko if (timing->emc_mode_1 != emc->emc_mode_1) 738e34212c7SDmitry Osipenko writel_relaxed(timing->emc_mode_1, 739e34212c7SDmitry Osipenko emc->regs + EMC_EMRS); 740e34212c7SDmitry Osipenko 741e34212c7SDmitry Osipenko if (timing->emc_mode_2 != emc->emc_mode_2) 742e34212c7SDmitry Osipenko writel_relaxed(timing->emc_mode_2, 743e34212c7SDmitry Osipenko emc->regs + EMC_EMRS); 744e34212c7SDmitry Osipenko 745e34212c7SDmitry Osipenko if (timing->emc_mode_reset != emc->emc_mode_reset || 746e34212c7SDmitry Osipenko dll_change == DLL_CHANGE_ON) { 747e34212c7SDmitry Osipenko val = timing->emc_mode_reset; 748e34212c7SDmitry Osipenko if (dll_change == DLL_CHANGE_ON) { 749e34212c7SDmitry Osipenko val |= EMC_MODE_SET_DLL_RESET; 750e34212c7SDmitry Osipenko val |= EMC_MODE_SET_LONG_CNT; 751e34212c7SDmitry Osipenko } else { 752e34212c7SDmitry Osipenko val &= ~EMC_MODE_SET_DLL_RESET; 753e34212c7SDmitry Osipenko } 754e34212c7SDmitry Osipenko writel_relaxed(val, emc->regs + EMC_MRS); 755e34212c7SDmitry Osipenko } 756e34212c7SDmitry Osipenko } else { 757e34212c7SDmitry Osipenko if (timing->emc_mode_2 != emc->emc_mode_2) 758e34212c7SDmitry Osipenko writel_relaxed(timing->emc_mode_2, 759e34212c7SDmitry Osipenko emc->regs + EMC_MRW); 760e34212c7SDmitry Osipenko 761e34212c7SDmitry Osipenko if (timing->emc_mode_1 != emc->emc_mode_1) 762e34212c7SDmitry Osipenko writel_relaxed(timing->emc_mode_1, 763e34212c7SDmitry Osipenko emc->regs + EMC_MRW); 764e34212c7SDmitry Osipenko } 765e34212c7SDmitry Osipenko 766e34212c7SDmitry Osipenko emc->emc_mode_1 = timing->emc_mode_1; 767e34212c7SDmitry Osipenko emc->emc_mode_2 = timing->emc_mode_2; 768e34212c7SDmitry Osipenko emc->emc_mode_reset = timing->emc_mode_reset; 769e34212c7SDmitry Osipenko 770e34212c7SDmitry Osipenko /* issue ZCAL command if turning ZCAL on */ 771e34212c7SDmitry Osipenko if (emc->zcal_long) { 772e34212c7SDmitry Osipenko writel_relaxed(EMC_ZQ_CAL_LONG_CMD_DEV0, 773e34212c7SDmitry Osipenko emc->regs + EMC_ZQ_CAL); 774e34212c7SDmitry Osipenko 775e34212c7SDmitry Osipenko if (dram_num > 1) 776e34212c7SDmitry Osipenko writel_relaxed(EMC_ZQ_CAL_LONG_CMD_DEV1, 777e34212c7SDmitry Osipenko emc->regs + EMC_ZQ_CAL); 778e34212c7SDmitry Osipenko } 779e34212c7SDmitry Osipenko 780e34212c7SDmitry Osipenko /* flow control marker 3 */ 781e34212c7SDmitry Osipenko writel_relaxed(0x1, emc->regs + EMC_UNSTALL_RW_AFTER_CLKCHANGE); 782e34212c7SDmitry Osipenko 7830f8bb9daSDmitry Osipenko /* 7840f8bb9daSDmitry Osipenko * Read and discard an arbitrary MC register (Note: EMC registers 7850f8bb9daSDmitry Osipenko * can't be used) to ensure the register writes are completed. 7860f8bb9daSDmitry Osipenko */ 7870f8bb9daSDmitry Osipenko mc_readl(emc->mc, MC_EMEM_ARB_OVERRIDE); 7880f8bb9daSDmitry Osipenko 789e34212c7SDmitry Osipenko return 0; 790e34212c7SDmitry Osipenko } 791e34212c7SDmitry Osipenko 792e34212c7SDmitry Osipenko static int emc_complete_timing_change(struct tegra_emc *emc, 793e34212c7SDmitry Osipenko unsigned long rate) 794e34212c7SDmitry Osipenko { 795930c6818SDmitry Osipenko struct emc_timing *timing = emc_find_timing(emc, rate); 796930c6818SDmitry Osipenko unsigned int dram_num; 797930c6818SDmitry Osipenko int err; 798930c6818SDmitry Osipenko u32 v; 799e34212c7SDmitry Osipenko 800930c6818SDmitry Osipenko err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, v, 801930c6818SDmitry Osipenko v & EMC_CLKCHANGE_COMPLETE_INT, 802930c6818SDmitry Osipenko 1, 100); 803930c6818SDmitry Osipenko if (err) { 804930c6818SDmitry Osipenko dev_err(emc->dev, "emc-car handshake timeout: %d\n", err); 805930c6818SDmitry Osipenko return err; 806e34212c7SDmitry Osipenko } 807e34212c7SDmitry Osipenko 808930c6818SDmitry Osipenko /* re-enable auto-refresh */ 809930c6818SDmitry Osipenko dram_num = tegra_mc_get_emem_device_count(emc->mc); 810930c6818SDmitry Osipenko writel_relaxed(EMC_REFCTRL_ENABLE_ALL(dram_num), 811930c6818SDmitry Osipenko emc->regs + EMC_REFCTRL); 81251bb73f9SDmitry Osipenko 813930c6818SDmitry Osipenko /* restore auto-calibration */ 814930c6818SDmitry Osipenko if (emc->vref_cal_toggle) 815930c6818SDmitry Osipenko writel_relaxed(timing->emc_auto_cal_interval, 816930c6818SDmitry Osipenko emc->regs + EMC_AUTO_CAL_INTERVAL); 817930c6818SDmitry Osipenko 818930c6818SDmitry Osipenko /* restore dynamic self-refresh */ 819930c6818SDmitry Osipenko if (timing->emc_cfg_dyn_self_ref) { 820930c6818SDmitry Osipenko emc->emc_cfg |= EMC_CFG_DYN_SREF_ENABLE; 821930c6818SDmitry Osipenko writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG); 822930c6818SDmitry Osipenko } 823930c6818SDmitry Osipenko 824930c6818SDmitry Osipenko /* set number of clocks to wait after each ZQ command */ 825930c6818SDmitry Osipenko if (emc->zcal_long) 826930c6818SDmitry Osipenko writel_relaxed(timing->emc_zcal_cnt_long, 827930c6818SDmitry Osipenko emc->regs + EMC_ZCAL_WAIT_CNT); 828930c6818SDmitry Osipenko 829930c6818SDmitry Osipenko /* wait for writes to settle */ 830930c6818SDmitry Osipenko udelay(2); 831930c6818SDmitry Osipenko 832930c6818SDmitry Osipenko /* update restored timing */ 833930c6818SDmitry Osipenko err = emc_seq_update_timing(emc); 834930c6818SDmitry Osipenko if (!err) 835930c6818SDmitry Osipenko emc->bad_state = false; 836930c6818SDmitry Osipenko 837930c6818SDmitry Osipenko /* restore early ACK */ 838930c6818SDmitry Osipenko mc_writel(emc->mc, emc->mc_override, MC_EMEM_ARB_OVERRIDE); 839930c6818SDmitry Osipenko 840930c6818SDmitry Osipenko return err; 841e34212c7SDmitry Osipenko } 842e34212c7SDmitry Osipenko 843e34212c7SDmitry Osipenko static int emc_unprepare_timing_change(struct tegra_emc *emc, 844e34212c7SDmitry Osipenko unsigned long rate) 845e34212c7SDmitry Osipenko { 84651bb73f9SDmitry Osipenko if (!emc->bad_state) { 847e34212c7SDmitry Osipenko /* shouldn't ever happen in practice */ 848e34212c7SDmitry Osipenko dev_err(emc->dev, "timing configuration can't be reverted\n"); 849e34212c7SDmitry Osipenko emc->bad_state = true; 850e34212c7SDmitry Osipenko } 851e34212c7SDmitry Osipenko 852e34212c7SDmitry Osipenko return 0; 853e34212c7SDmitry Osipenko } 854e34212c7SDmitry Osipenko 855e34212c7SDmitry Osipenko static int emc_clk_change_notify(struct notifier_block *nb, 856e34212c7SDmitry Osipenko unsigned long msg, void *data) 857e34212c7SDmitry Osipenko { 858e34212c7SDmitry Osipenko struct tegra_emc *emc = container_of(nb, struct tegra_emc, clk_nb); 859e34212c7SDmitry Osipenko struct clk_notifier_data *cnd = data; 860e34212c7SDmitry Osipenko int err; 861e34212c7SDmitry Osipenko 862e34212c7SDmitry Osipenko switch (msg) { 863e34212c7SDmitry Osipenko case PRE_RATE_CHANGE: 8640f8bb9daSDmitry Osipenko /* 8650f8bb9daSDmitry Osipenko * Disable interrupt since read accesses are prohibited after 8660f8bb9daSDmitry Osipenko * stalling. 8670f8bb9daSDmitry Osipenko */ 8680f8bb9daSDmitry Osipenko disable_irq(emc->irq); 869e34212c7SDmitry Osipenko err = emc_prepare_timing_change(emc, cnd->new_rate); 8700f8bb9daSDmitry Osipenko enable_irq(emc->irq); 871e34212c7SDmitry Osipenko break; 872e34212c7SDmitry Osipenko 873e34212c7SDmitry Osipenko case ABORT_RATE_CHANGE: 874e34212c7SDmitry Osipenko err = emc_unprepare_timing_change(emc, cnd->old_rate); 875e34212c7SDmitry Osipenko break; 876e34212c7SDmitry Osipenko 877e34212c7SDmitry Osipenko case POST_RATE_CHANGE: 878e34212c7SDmitry Osipenko err = emc_complete_timing_change(emc, cnd->new_rate); 879e34212c7SDmitry Osipenko break; 880e34212c7SDmitry Osipenko 881e34212c7SDmitry Osipenko default: 882e34212c7SDmitry Osipenko return NOTIFY_DONE; 883e34212c7SDmitry Osipenko } 884e34212c7SDmitry Osipenko 885e34212c7SDmitry Osipenko return notifier_from_errno(err); 886e34212c7SDmitry Osipenko } 887e34212c7SDmitry Osipenko 888e34212c7SDmitry Osipenko static int load_one_timing_from_dt(struct tegra_emc *emc, 889e34212c7SDmitry Osipenko struct emc_timing *timing, 890e34212c7SDmitry Osipenko struct device_node *node) 891e34212c7SDmitry Osipenko { 892e34212c7SDmitry Osipenko u32 value; 893e34212c7SDmitry Osipenko int err; 894e34212c7SDmitry Osipenko 895e34212c7SDmitry Osipenko err = of_property_read_u32(node, "clock-frequency", &value); 896e34212c7SDmitry Osipenko if (err) { 897e34212c7SDmitry Osipenko dev_err(emc->dev, "timing %pOF: failed to read rate: %d\n", 898e34212c7SDmitry Osipenko node, err); 899e34212c7SDmitry Osipenko return err; 900e34212c7SDmitry Osipenko } 901e34212c7SDmitry Osipenko 902e34212c7SDmitry Osipenko timing->rate = value; 903e34212c7SDmitry Osipenko 904e34212c7SDmitry Osipenko err = of_property_read_u32_array(node, "nvidia,emc-configuration", 905e34212c7SDmitry Osipenko timing->data, 906e34212c7SDmitry Osipenko ARRAY_SIZE(emc_timing_registers)); 907e34212c7SDmitry Osipenko if (err) { 908e34212c7SDmitry Osipenko dev_err(emc->dev, 909e34212c7SDmitry Osipenko "timing %pOF: failed to read emc timing data: %d\n", 910e34212c7SDmitry Osipenko node, err); 911e34212c7SDmitry Osipenko return err; 912e34212c7SDmitry Osipenko } 913e34212c7SDmitry Osipenko 914e34212c7SDmitry Osipenko #define EMC_READ_BOOL(prop, dtprop) \ 915e34212c7SDmitry Osipenko timing->prop = of_property_read_bool(node, dtprop); 916e34212c7SDmitry Osipenko 917e34212c7SDmitry Osipenko #define EMC_READ_U32(prop, dtprop) \ 918e34212c7SDmitry Osipenko err = of_property_read_u32(node, dtprop, &timing->prop); \ 919e34212c7SDmitry Osipenko if (err) { \ 920e34212c7SDmitry Osipenko dev_err(emc->dev, \ 921e34212c7SDmitry Osipenko "timing %pOFn: failed to read " #prop ": %d\n", \ 922e34212c7SDmitry Osipenko node, err); \ 923e34212c7SDmitry Osipenko return err; \ 924e34212c7SDmitry Osipenko } 925e34212c7SDmitry Osipenko 926e34212c7SDmitry Osipenko EMC_READ_U32(emc_auto_cal_interval, "nvidia,emc-auto-cal-interval") 927e34212c7SDmitry Osipenko EMC_READ_U32(emc_mode_1, "nvidia,emc-mode-1") 928e34212c7SDmitry Osipenko EMC_READ_U32(emc_mode_2, "nvidia,emc-mode-2") 929e34212c7SDmitry Osipenko EMC_READ_U32(emc_mode_reset, "nvidia,emc-mode-reset") 930e34212c7SDmitry Osipenko EMC_READ_U32(emc_zcal_cnt_long, "nvidia,emc-zcal-cnt-long") 931e34212c7SDmitry Osipenko EMC_READ_BOOL(emc_cfg_dyn_self_ref, "nvidia,emc-cfg-dyn-self-ref") 932e34212c7SDmitry Osipenko EMC_READ_BOOL(emc_cfg_periodic_qrst, "nvidia,emc-cfg-periodic-qrst") 933e34212c7SDmitry Osipenko 934e34212c7SDmitry Osipenko #undef EMC_READ_U32 935e34212c7SDmitry Osipenko #undef EMC_READ_BOOL 936e34212c7SDmitry Osipenko 937e34212c7SDmitry Osipenko dev_dbg(emc->dev, "%s: %pOF: rate %lu\n", __func__, node, timing->rate); 938e34212c7SDmitry Osipenko 939e34212c7SDmitry Osipenko return 0; 940e34212c7SDmitry Osipenko } 941e34212c7SDmitry Osipenko 942e34212c7SDmitry Osipenko static int cmp_timings(const void *_a, const void *_b) 943e34212c7SDmitry Osipenko { 944e34212c7SDmitry Osipenko const struct emc_timing *a = _a; 945e34212c7SDmitry Osipenko const struct emc_timing *b = _b; 946e34212c7SDmitry Osipenko 947e34212c7SDmitry Osipenko if (a->rate < b->rate) 948e34212c7SDmitry Osipenko return -1; 949e34212c7SDmitry Osipenko 950e34212c7SDmitry Osipenko if (a->rate > b->rate) 951e34212c7SDmitry Osipenko return 1; 952e34212c7SDmitry Osipenko 953e34212c7SDmitry Osipenko return 0; 954e34212c7SDmitry Osipenko } 955e34212c7SDmitry Osipenko 956e34212c7SDmitry Osipenko static int emc_check_mc_timings(struct tegra_emc *emc) 957e34212c7SDmitry Osipenko { 958e34212c7SDmitry Osipenko struct tegra_mc *mc = emc->mc; 959e34212c7SDmitry Osipenko unsigned int i; 960e34212c7SDmitry Osipenko 961e34212c7SDmitry Osipenko if (emc->num_timings != mc->num_timings) { 962e34212c7SDmitry Osipenko dev_err(emc->dev, "emc/mc timings number mismatch: %u %u\n", 963e34212c7SDmitry Osipenko emc->num_timings, mc->num_timings); 964e34212c7SDmitry Osipenko return -EINVAL; 965e34212c7SDmitry Osipenko } 966e34212c7SDmitry Osipenko 967e34212c7SDmitry Osipenko for (i = 0; i < mc->num_timings; i++) { 968e34212c7SDmitry Osipenko if (emc->timings[i].rate != mc->timings[i].rate) { 969e34212c7SDmitry Osipenko dev_err(emc->dev, 970e34212c7SDmitry Osipenko "emc/mc timing rate mismatch: %lu %lu\n", 971e34212c7SDmitry Osipenko emc->timings[i].rate, mc->timings[i].rate); 972e34212c7SDmitry Osipenko return -EINVAL; 973e34212c7SDmitry Osipenko } 974e34212c7SDmitry Osipenko } 975e34212c7SDmitry Osipenko 976e34212c7SDmitry Osipenko return 0; 977e34212c7SDmitry Osipenko } 978e34212c7SDmitry Osipenko 979e34212c7SDmitry Osipenko static int emc_load_timings_from_dt(struct tegra_emc *emc, 980e34212c7SDmitry Osipenko struct device_node *node) 981e34212c7SDmitry Osipenko { 982e34212c7SDmitry Osipenko struct device_node *child; 983e34212c7SDmitry Osipenko struct emc_timing *timing; 984e34212c7SDmitry Osipenko int child_count; 985e34212c7SDmitry Osipenko int err; 986e34212c7SDmitry Osipenko 987e34212c7SDmitry Osipenko child_count = of_get_child_count(node); 988e34212c7SDmitry Osipenko if (!child_count) { 989e34212c7SDmitry Osipenko dev_err(emc->dev, "no memory timings in: %pOF\n", node); 990e34212c7SDmitry Osipenko return -EINVAL; 991e34212c7SDmitry Osipenko } 992e34212c7SDmitry Osipenko 993e34212c7SDmitry Osipenko emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing), 994e34212c7SDmitry Osipenko GFP_KERNEL); 995e34212c7SDmitry Osipenko if (!emc->timings) 996e34212c7SDmitry Osipenko return -ENOMEM; 997e34212c7SDmitry Osipenko 998e34212c7SDmitry Osipenko emc->num_timings = child_count; 999e34212c7SDmitry Osipenko timing = emc->timings; 1000e34212c7SDmitry Osipenko 1001e34212c7SDmitry Osipenko for_each_child_of_node(node, child) { 1002e34212c7SDmitry Osipenko err = load_one_timing_from_dt(emc, timing++, child); 1003e34212c7SDmitry Osipenko if (err) { 1004e34212c7SDmitry Osipenko of_node_put(child); 1005e34212c7SDmitry Osipenko return err; 1006e34212c7SDmitry Osipenko } 1007e34212c7SDmitry Osipenko } 1008e34212c7SDmitry Osipenko 1009e34212c7SDmitry Osipenko sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, 1010e34212c7SDmitry Osipenko NULL); 1011e34212c7SDmitry Osipenko 1012e34212c7SDmitry Osipenko err = emc_check_mc_timings(emc); 1013e34212c7SDmitry Osipenko if (err) 1014e34212c7SDmitry Osipenko return err; 1015e34212c7SDmitry Osipenko 1016f012ade8SDmitry Osipenko dev_info_once(emc->dev, 1017e34212c7SDmitry Osipenko "got %u timings for RAM code %u (min %luMHz max %luMHz)\n", 1018e34212c7SDmitry Osipenko emc->num_timings, 1019e34212c7SDmitry Osipenko tegra_read_ram_code(), 1020e34212c7SDmitry Osipenko emc->timings[0].rate / 1000000, 1021e34212c7SDmitry Osipenko emc->timings[emc->num_timings - 1].rate / 1000000); 1022e34212c7SDmitry Osipenko 1023e34212c7SDmitry Osipenko return 0; 1024e34212c7SDmitry Osipenko } 1025e34212c7SDmitry Osipenko 1026e3aabb3cSDmitry Osipenko static struct device_node *emc_find_node_by_ram_code(struct tegra_emc *emc) 1027e34212c7SDmitry Osipenko { 1028e3aabb3cSDmitry Osipenko struct device *dev = emc->dev; 1029e34212c7SDmitry Osipenko struct device_node *np; 1030e34212c7SDmitry Osipenko u32 value, ram_code; 1031e34212c7SDmitry Osipenko int err; 1032e34212c7SDmitry Osipenko 1033e3aabb3cSDmitry Osipenko if (emc->mrr_error) { 1034e3aabb3cSDmitry Osipenko dev_warn(dev, "memory timings skipped due to MRR error\n"); 1035e3aabb3cSDmitry Osipenko return NULL; 1036e3aabb3cSDmitry Osipenko } 1037e3aabb3cSDmitry Osipenko 1038bf25f3fcSDmitry Osipenko if (of_get_child_count(dev->of_node) == 0) { 1039f012ade8SDmitry Osipenko dev_info_once(dev, "device-tree doesn't have memory timings\n"); 1040bf25f3fcSDmitry Osipenko return NULL; 1041bf25f3fcSDmitry Osipenko } 1042bf25f3fcSDmitry Osipenko 1043e34212c7SDmitry Osipenko ram_code = tegra_read_ram_code(); 1044e34212c7SDmitry Osipenko 1045e34212c7SDmitry Osipenko for_each_child_of_node(dev->of_node, np) { 1046e34212c7SDmitry Osipenko err = of_property_read_u32(np, "nvidia,ram-code", &value); 1047e34212c7SDmitry Osipenko if (err || value != ram_code) 1048e34212c7SDmitry Osipenko continue; 1049e34212c7SDmitry Osipenko 1050e34212c7SDmitry Osipenko return np; 1051e34212c7SDmitry Osipenko } 1052e34212c7SDmitry Osipenko 1053e34212c7SDmitry Osipenko dev_err(dev, "no memory timings for RAM code %u found in device-tree\n", 1054e34212c7SDmitry Osipenko ram_code); 1055e34212c7SDmitry Osipenko 1056e34212c7SDmitry Osipenko return NULL; 1057e34212c7SDmitry Osipenko } 1058e34212c7SDmitry Osipenko 1059e3aabb3cSDmitry Osipenko static int emc_read_lpddr_mode_register(struct tegra_emc *emc, 1060e3aabb3cSDmitry Osipenko unsigned int emem_dev, 1061e3aabb3cSDmitry Osipenko unsigned int register_addr, 1062e3aabb3cSDmitry Osipenko unsigned int *register_data) 1063e3aabb3cSDmitry Osipenko { 1064e3aabb3cSDmitry Osipenko u32 memory_dev = emem_dev ? 1 : 2; 1065e3aabb3cSDmitry Osipenko u32 val, mr_mask = 0xff; 1066e3aabb3cSDmitry Osipenko int err; 1067e3aabb3cSDmitry Osipenko 1068e3aabb3cSDmitry Osipenko /* clear data-valid interrupt status */ 1069e3aabb3cSDmitry Osipenko writel_relaxed(EMC_MRR_DIVLD_INT, emc->regs + EMC_INTSTATUS); 1070e3aabb3cSDmitry Osipenko 1071e3aabb3cSDmitry Osipenko /* issue mode register read request */ 1072e3aabb3cSDmitry Osipenko val = FIELD_PREP(EMC_MRR_DEV_SELECTN, memory_dev); 1073e3aabb3cSDmitry Osipenko val |= FIELD_PREP(EMC_MRR_MRR_MA, register_addr); 1074e3aabb3cSDmitry Osipenko 1075e3aabb3cSDmitry Osipenko writel_relaxed(val, emc->regs + EMC_MRR); 1076e3aabb3cSDmitry Osipenko 1077e3aabb3cSDmitry Osipenko /* wait for the LPDDR2 data-valid interrupt */ 1078e3aabb3cSDmitry Osipenko err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, val, 1079e3aabb3cSDmitry Osipenko val & EMC_MRR_DIVLD_INT, 1080e3aabb3cSDmitry Osipenko 1, 100); 1081e3aabb3cSDmitry Osipenko if (err) { 1082e3aabb3cSDmitry Osipenko dev_err(emc->dev, "mode register %u read failed: %d\n", 1083e3aabb3cSDmitry Osipenko register_addr, err); 1084e3aabb3cSDmitry Osipenko emc->mrr_error = true; 1085e3aabb3cSDmitry Osipenko return err; 1086e3aabb3cSDmitry Osipenko } 1087e3aabb3cSDmitry Osipenko 1088e3aabb3cSDmitry Osipenko /* read out mode register data */ 1089e3aabb3cSDmitry Osipenko val = readl_relaxed(emc->regs + EMC_MRR); 1090e3aabb3cSDmitry Osipenko *register_data = FIELD_GET(EMC_MRR_MRR_DATA, val) & mr_mask; 1091e3aabb3cSDmitry Osipenko 1092e3aabb3cSDmitry Osipenko return 0; 1093e3aabb3cSDmitry Osipenko } 1094e3aabb3cSDmitry Osipenko 1095e3aabb3cSDmitry Osipenko static void emc_read_lpddr_sdram_info(struct tegra_emc *emc, 1096e3aabb3cSDmitry Osipenko unsigned int emem_dev) 1097e3aabb3cSDmitry Osipenko { 1098e3aabb3cSDmitry Osipenko union lpddr2_basic_config4 basic_conf4; 1099e3aabb3cSDmitry Osipenko unsigned int manufacturer_id; 1100e3aabb3cSDmitry Osipenko unsigned int revision_id1; 1101e3aabb3cSDmitry Osipenko unsigned int revision_id2; 1102e3aabb3cSDmitry Osipenko 1103e3aabb3cSDmitry Osipenko /* these registers are standard for all LPDDR JEDEC memory chips */ 1104e3aabb3cSDmitry Osipenko emc_read_lpddr_mode_register(emc, emem_dev, 5, &manufacturer_id); 1105e3aabb3cSDmitry Osipenko emc_read_lpddr_mode_register(emc, emem_dev, 6, &revision_id1); 1106e3aabb3cSDmitry Osipenko emc_read_lpddr_mode_register(emc, emem_dev, 7, &revision_id2); 1107e3aabb3cSDmitry Osipenko emc_read_lpddr_mode_register(emc, emem_dev, 8, &basic_conf4.value); 1108e3aabb3cSDmitry Osipenko 1109e3aabb3cSDmitry Osipenko dev_info(emc->dev, "SDRAM[dev%u]: manufacturer: 0x%x (%s) rev1: 0x%x rev2: 0x%x prefetch: S%u density: %uMbit iowidth: %ubit\n", 1110e3aabb3cSDmitry Osipenko emem_dev, manufacturer_id, 1111e3aabb3cSDmitry Osipenko lpddr2_jedec_manufacturer(manufacturer_id), 1112e3aabb3cSDmitry Osipenko revision_id1, revision_id2, 1113e3aabb3cSDmitry Osipenko 4 >> basic_conf4.arch_type, 1114e3aabb3cSDmitry Osipenko 64 << basic_conf4.density, 1115e3aabb3cSDmitry Osipenko 32 >> basic_conf4.io_width); 1116e3aabb3cSDmitry Osipenko } 1117e3aabb3cSDmitry Osipenko 1118e34212c7SDmitry Osipenko static int emc_setup_hw(struct tegra_emc *emc) 1119e34212c7SDmitry Osipenko { 1120e3aabb3cSDmitry Osipenko u32 fbio_cfg5, emc_cfg, emc_dbg, emc_adr_cfg; 1121930c6818SDmitry Osipenko u32 intmask = EMC_REFRESH_OVERFLOW_INT; 1122e3aabb3cSDmitry Osipenko static bool print_sdram_info_once; 1123e34212c7SDmitry Osipenko enum emc_dram_type dram_type; 1124e3aabb3cSDmitry Osipenko const char *dram_type_str; 1125e3aabb3cSDmitry Osipenko unsigned int emem_numdev; 1126e34212c7SDmitry Osipenko 1127e34212c7SDmitry Osipenko fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5); 1128e34212c7SDmitry Osipenko dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK; 1129e34212c7SDmitry Osipenko 1130e34212c7SDmitry Osipenko emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2); 1131e34212c7SDmitry Osipenko 1132e34212c7SDmitry Osipenko /* enable EMC and CAR to handshake on PLL divider/source changes */ 1133e34212c7SDmitry Osipenko emc_cfg |= EMC_CLKCHANGE_REQ_ENABLE; 1134e34212c7SDmitry Osipenko 1135e34212c7SDmitry Osipenko /* configure clock change mode accordingly to DRAM type */ 1136e34212c7SDmitry Osipenko switch (dram_type) { 1137e34212c7SDmitry Osipenko case DRAM_TYPE_LPDDR2: 1138e34212c7SDmitry Osipenko emc_cfg |= EMC_CLKCHANGE_PD_ENABLE; 1139e34212c7SDmitry Osipenko emc_cfg &= ~EMC_CLKCHANGE_SR_ENABLE; 1140e34212c7SDmitry Osipenko break; 1141e34212c7SDmitry Osipenko 1142e34212c7SDmitry Osipenko default: 1143e34212c7SDmitry Osipenko emc_cfg &= ~EMC_CLKCHANGE_SR_ENABLE; 1144e34212c7SDmitry Osipenko emc_cfg &= ~EMC_CLKCHANGE_PD_ENABLE; 1145e34212c7SDmitry Osipenko break; 1146e34212c7SDmitry Osipenko } 1147e34212c7SDmitry Osipenko 1148e34212c7SDmitry Osipenko writel_relaxed(emc_cfg, emc->regs + EMC_CFG_2); 1149e34212c7SDmitry Osipenko 1150e34212c7SDmitry Osipenko /* initialize interrupt */ 1151e34212c7SDmitry Osipenko writel_relaxed(intmask, emc->regs + EMC_INTMASK); 1152e34212c7SDmitry Osipenko writel_relaxed(0xffffffff, emc->regs + EMC_INTSTATUS); 1153e34212c7SDmitry Osipenko 1154e34212c7SDmitry Osipenko /* ensure that unwanted debug features are disabled */ 1155e34212c7SDmitry Osipenko emc_dbg = readl_relaxed(emc->regs + EMC_DBG); 1156e34212c7SDmitry Osipenko emc_dbg |= EMC_DBG_CFG_PRIORITY; 1157e34212c7SDmitry Osipenko emc_dbg &= ~EMC_DBG_READ_MUX_ASSEMBLY; 1158e34212c7SDmitry Osipenko emc_dbg &= ~EMC_DBG_WRITE_MUX_ACTIVE; 1159e34212c7SDmitry Osipenko emc_dbg &= ~EMC_DBG_FORCE_UPDATE; 1160e34212c7SDmitry Osipenko writel_relaxed(emc_dbg, emc->regs + EMC_DBG); 1161e34212c7SDmitry Osipenko 1162e3aabb3cSDmitry Osipenko switch (dram_type) { 1163e3aabb3cSDmitry Osipenko case DRAM_TYPE_DDR1: 1164e3aabb3cSDmitry Osipenko dram_type_str = "DDR1"; 1165e3aabb3cSDmitry Osipenko break; 1166e3aabb3cSDmitry Osipenko case DRAM_TYPE_LPDDR2: 1167e3aabb3cSDmitry Osipenko dram_type_str = "LPDDR2"; 1168e3aabb3cSDmitry Osipenko break; 1169e3aabb3cSDmitry Osipenko case DRAM_TYPE_DDR2: 1170e3aabb3cSDmitry Osipenko dram_type_str = "DDR2"; 1171e3aabb3cSDmitry Osipenko break; 1172e3aabb3cSDmitry Osipenko case DRAM_TYPE_DDR3: 1173e3aabb3cSDmitry Osipenko dram_type_str = "DDR3"; 1174e3aabb3cSDmitry Osipenko break; 1175e3aabb3cSDmitry Osipenko } 1176e3aabb3cSDmitry Osipenko 1177e3aabb3cSDmitry Osipenko emc_adr_cfg = readl_relaxed(emc->regs + EMC_ADR_CFG); 1178e3aabb3cSDmitry Osipenko emem_numdev = FIELD_GET(EMC_ADR_CFG_EMEM_NUMDEV, emc_adr_cfg) + 1; 1179e3aabb3cSDmitry Osipenko 1180e3aabb3cSDmitry Osipenko dev_info_once(emc->dev, "%u %s %s attached\n", emem_numdev, 1181e3aabb3cSDmitry Osipenko dram_type_str, emem_numdev == 2 ? "devices" : "device"); 1182e3aabb3cSDmitry Osipenko 1183e3aabb3cSDmitry Osipenko if (dram_type == DRAM_TYPE_LPDDR2 && !print_sdram_info_once) { 1184e3aabb3cSDmitry Osipenko while (emem_numdev--) 1185e3aabb3cSDmitry Osipenko emc_read_lpddr_sdram_info(emc, emem_numdev); 1186e3aabb3cSDmitry Osipenko 1187e3aabb3cSDmitry Osipenko print_sdram_info_once = true; 1188e3aabb3cSDmitry Osipenko } 1189e3aabb3cSDmitry Osipenko 1190e34212c7SDmitry Osipenko return 0; 1191e34212c7SDmitry Osipenko } 1192e34212c7SDmitry Osipenko 1193e34212c7SDmitry Osipenko static long emc_round_rate(unsigned long rate, 1194e34212c7SDmitry Osipenko unsigned long min_rate, 1195e34212c7SDmitry Osipenko unsigned long max_rate, 1196e34212c7SDmitry Osipenko void *arg) 1197e34212c7SDmitry Osipenko { 1198e34212c7SDmitry Osipenko struct emc_timing *timing = NULL; 1199e34212c7SDmitry Osipenko struct tegra_emc *emc = arg; 1200e34212c7SDmitry Osipenko unsigned int i; 1201e34212c7SDmitry Osipenko 1202bf25f3fcSDmitry Osipenko if (!emc->num_timings) 1203bf25f3fcSDmitry Osipenko return clk_get_rate(emc->clk); 1204bf25f3fcSDmitry Osipenko 1205e34212c7SDmitry Osipenko min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate); 1206e34212c7SDmitry Osipenko 1207e34212c7SDmitry Osipenko for (i = 0; i < emc->num_timings; i++) { 1208e34212c7SDmitry Osipenko if (emc->timings[i].rate < rate && i != emc->num_timings - 1) 1209e34212c7SDmitry Osipenko continue; 1210e34212c7SDmitry Osipenko 1211e34212c7SDmitry Osipenko if (emc->timings[i].rate > max_rate) { 1212e34212c7SDmitry Osipenko i = max(i, 1u) - 1; 1213e34212c7SDmitry Osipenko 1214e34212c7SDmitry Osipenko if (emc->timings[i].rate < min_rate) 1215e34212c7SDmitry Osipenko break; 1216e34212c7SDmitry Osipenko } 1217e34212c7SDmitry Osipenko 1218e34212c7SDmitry Osipenko if (emc->timings[i].rate < min_rate) 1219e34212c7SDmitry Osipenko continue; 1220e34212c7SDmitry Osipenko 1221e34212c7SDmitry Osipenko timing = &emc->timings[i]; 1222e34212c7SDmitry Osipenko break; 1223e34212c7SDmitry Osipenko } 1224e34212c7SDmitry Osipenko 1225e34212c7SDmitry Osipenko if (!timing) { 1226e34212c7SDmitry Osipenko dev_err(emc->dev, "no timing for rate %lu min %lu max %lu\n", 1227e34212c7SDmitry Osipenko rate, min_rate, max_rate); 1228e34212c7SDmitry Osipenko return -EINVAL; 1229e34212c7SDmitry Osipenko } 1230e34212c7SDmitry Osipenko 1231e34212c7SDmitry Osipenko return timing->rate; 1232e34212c7SDmitry Osipenko } 1233e34212c7SDmitry Osipenko 1234d76fa3f2SDmitry Osipenko static void tegra_emc_rate_requests_init(struct tegra_emc *emc) 1235d76fa3f2SDmitry Osipenko { 1236d76fa3f2SDmitry Osipenko unsigned int i; 1237d76fa3f2SDmitry Osipenko 1238d76fa3f2SDmitry Osipenko for (i = 0; i < EMC_RATE_TYPE_MAX; i++) { 1239d76fa3f2SDmitry Osipenko emc->requested_rate[i].min_rate = 0; 1240d76fa3f2SDmitry Osipenko emc->requested_rate[i].max_rate = ULONG_MAX; 1241d76fa3f2SDmitry Osipenko } 1242d76fa3f2SDmitry Osipenko } 1243d76fa3f2SDmitry Osipenko 1244d76fa3f2SDmitry Osipenko static int emc_request_rate(struct tegra_emc *emc, 1245d76fa3f2SDmitry Osipenko unsigned long new_min_rate, 1246d76fa3f2SDmitry Osipenko unsigned long new_max_rate, 1247d76fa3f2SDmitry Osipenko enum emc_rate_request_type type) 1248d76fa3f2SDmitry Osipenko { 1249d76fa3f2SDmitry Osipenko struct emc_rate_request *req = emc->requested_rate; 1250d76fa3f2SDmitry Osipenko unsigned long min_rate = 0, max_rate = ULONG_MAX; 1251d76fa3f2SDmitry Osipenko unsigned int i; 1252d76fa3f2SDmitry Osipenko int err; 1253d76fa3f2SDmitry Osipenko 1254d76fa3f2SDmitry Osipenko /* select minimum and maximum rates among the requested rates */ 1255d76fa3f2SDmitry Osipenko for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) { 1256d76fa3f2SDmitry Osipenko if (i == type) { 1257d76fa3f2SDmitry Osipenko min_rate = max(new_min_rate, min_rate); 1258d76fa3f2SDmitry Osipenko max_rate = min(new_max_rate, max_rate); 1259d76fa3f2SDmitry Osipenko } else { 1260d76fa3f2SDmitry Osipenko min_rate = max(req->min_rate, min_rate); 1261d76fa3f2SDmitry Osipenko max_rate = min(req->max_rate, max_rate); 1262d76fa3f2SDmitry Osipenko } 1263d76fa3f2SDmitry Osipenko } 1264d76fa3f2SDmitry Osipenko 1265d76fa3f2SDmitry Osipenko if (min_rate > max_rate) { 1266d76fa3f2SDmitry Osipenko dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n", 1267d76fa3f2SDmitry Osipenko __func__, type, min_rate, max_rate); 1268d76fa3f2SDmitry Osipenko return -ERANGE; 1269d76fa3f2SDmitry Osipenko } 1270d76fa3f2SDmitry Osipenko 1271d76fa3f2SDmitry Osipenko /* 1272d76fa3f2SDmitry Osipenko * EMC rate-changes should go via OPP API because it manages voltage 1273d76fa3f2SDmitry Osipenko * changes. 1274d76fa3f2SDmitry Osipenko */ 1275d76fa3f2SDmitry Osipenko err = dev_pm_opp_set_rate(emc->dev, min_rate); 1276d76fa3f2SDmitry Osipenko if (err) 1277d76fa3f2SDmitry Osipenko return err; 1278d76fa3f2SDmitry Osipenko 1279d76fa3f2SDmitry Osipenko emc->requested_rate[type].min_rate = new_min_rate; 1280d76fa3f2SDmitry Osipenko emc->requested_rate[type].max_rate = new_max_rate; 1281d76fa3f2SDmitry Osipenko 1282d76fa3f2SDmitry Osipenko return 0; 1283d76fa3f2SDmitry Osipenko } 1284d76fa3f2SDmitry Osipenko 1285d76fa3f2SDmitry Osipenko static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate, 1286d76fa3f2SDmitry Osipenko enum emc_rate_request_type type) 1287d76fa3f2SDmitry Osipenko { 1288d76fa3f2SDmitry Osipenko struct emc_rate_request *req = &emc->requested_rate[type]; 1289d76fa3f2SDmitry Osipenko int ret; 1290d76fa3f2SDmitry Osipenko 1291d76fa3f2SDmitry Osipenko mutex_lock(&emc->rate_lock); 1292d76fa3f2SDmitry Osipenko ret = emc_request_rate(emc, rate, req->max_rate, type); 1293d76fa3f2SDmitry Osipenko mutex_unlock(&emc->rate_lock); 1294d76fa3f2SDmitry Osipenko 1295d76fa3f2SDmitry Osipenko return ret; 1296d76fa3f2SDmitry Osipenko } 1297d76fa3f2SDmitry Osipenko 1298d76fa3f2SDmitry Osipenko static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate, 1299d76fa3f2SDmitry Osipenko enum emc_rate_request_type type) 1300d76fa3f2SDmitry Osipenko { 1301d76fa3f2SDmitry Osipenko struct emc_rate_request *req = &emc->requested_rate[type]; 1302d76fa3f2SDmitry Osipenko int ret; 1303d76fa3f2SDmitry Osipenko 1304d76fa3f2SDmitry Osipenko mutex_lock(&emc->rate_lock); 1305d76fa3f2SDmitry Osipenko ret = emc_request_rate(emc, req->min_rate, rate, type); 1306d76fa3f2SDmitry Osipenko mutex_unlock(&emc->rate_lock); 1307d76fa3f2SDmitry Osipenko 1308d76fa3f2SDmitry Osipenko return ret; 1309d76fa3f2SDmitry Osipenko } 1310d76fa3f2SDmitry Osipenko 13118cee32b4SThierry Reding /* 13128cee32b4SThierry Reding * debugfs interface 13138cee32b4SThierry Reding * 13148cee32b4SThierry Reding * The memory controller driver exposes some files in debugfs that can be used 13158cee32b4SThierry Reding * to control the EMC frequency. The top-level directory can be found here: 13168cee32b4SThierry Reding * 13178cee32b4SThierry Reding * /sys/kernel/debug/emc 13188cee32b4SThierry Reding * 13198cee32b4SThierry Reding * It contains the following files: 13208cee32b4SThierry Reding * 13218cee32b4SThierry Reding * - available_rates: This file contains a list of valid, space-separated 13228cee32b4SThierry Reding * EMC frequencies. 13238cee32b4SThierry Reding * 13248cee32b4SThierry Reding * - min_rate: Writing a value to this file sets the given frequency as the 13258cee32b4SThierry Reding * floor of the permitted range. If this is higher than the currently 13268cee32b4SThierry Reding * configured EMC frequency, this will cause the frequency to be 13278cee32b4SThierry Reding * increased so that it stays within the valid range. 13288cee32b4SThierry Reding * 13298cee32b4SThierry Reding * - max_rate: Similarily to the min_rate file, writing a value to this file 13308cee32b4SThierry Reding * sets the given frequency as the ceiling of the permitted range. If 13318cee32b4SThierry Reding * the value is lower than the currently configured EMC frequency, this 13328cee32b4SThierry Reding * will cause the frequency to be decreased so that it stays within the 13338cee32b4SThierry Reding * valid range. 13348cee32b4SThierry Reding */ 13358cee32b4SThierry Reding 13368cee32b4SThierry Reding static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) 13378cee32b4SThierry Reding { 13388cee32b4SThierry Reding unsigned int i; 13398cee32b4SThierry Reding 13408cee32b4SThierry Reding for (i = 0; i < emc->num_timings; i++) 13418cee32b4SThierry Reding if (rate == emc->timings[i].rate) 13428cee32b4SThierry Reding return true; 13438cee32b4SThierry Reding 13448cee32b4SThierry Reding return false; 13458cee32b4SThierry Reding } 13468cee32b4SThierry Reding 13478cee32b4SThierry Reding static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) 13488cee32b4SThierry Reding { 13498cee32b4SThierry Reding struct tegra_emc *emc = s->private; 13508cee32b4SThierry Reding const char *prefix = ""; 13518cee32b4SThierry Reding unsigned int i; 13528cee32b4SThierry Reding 13538cee32b4SThierry Reding for (i = 0; i < emc->num_timings; i++) { 13548cee32b4SThierry Reding seq_printf(s, "%s%lu", prefix, emc->timings[i].rate); 13558cee32b4SThierry Reding prefix = " "; 13568cee32b4SThierry Reding } 13578cee32b4SThierry Reding 13588cee32b4SThierry Reding seq_puts(s, "\n"); 13598cee32b4SThierry Reding 13608cee32b4SThierry Reding return 0; 13618cee32b4SThierry Reding } 136243fe67a3SLiu Shixin DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); 13638cee32b4SThierry Reding 13648cee32b4SThierry Reding static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) 13658cee32b4SThierry Reding { 13668cee32b4SThierry Reding struct tegra_emc *emc = data; 13678cee32b4SThierry Reding 13688cee32b4SThierry Reding *rate = emc->debugfs.min_rate; 13698cee32b4SThierry Reding 13708cee32b4SThierry Reding return 0; 13718cee32b4SThierry Reding } 13728cee32b4SThierry Reding 13738cee32b4SThierry Reding static int tegra_emc_debug_min_rate_set(void *data, u64 rate) 13748cee32b4SThierry Reding { 13758cee32b4SThierry Reding struct tegra_emc *emc = data; 13768cee32b4SThierry Reding int err; 13778cee32b4SThierry Reding 13788cee32b4SThierry Reding if (!tegra_emc_validate_rate(emc, rate)) 13798cee32b4SThierry Reding return -EINVAL; 13808cee32b4SThierry Reding 1381d76fa3f2SDmitry Osipenko err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG); 13828cee32b4SThierry Reding if (err < 0) 13838cee32b4SThierry Reding return err; 13848cee32b4SThierry Reding 13858cee32b4SThierry Reding emc->debugfs.min_rate = rate; 13868cee32b4SThierry Reding 13878cee32b4SThierry Reding return 0; 13888cee32b4SThierry Reding } 13898cee32b4SThierry Reding 1390e12bc354Sjing yangyang DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_min_rate_fops, 13918cee32b4SThierry Reding tegra_emc_debug_min_rate_get, 13928cee32b4SThierry Reding tegra_emc_debug_min_rate_set, "%llu\n"); 13938cee32b4SThierry Reding 13948cee32b4SThierry Reding static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) 13958cee32b4SThierry Reding { 13968cee32b4SThierry Reding struct tegra_emc *emc = data; 13978cee32b4SThierry Reding 13988cee32b4SThierry Reding *rate = emc->debugfs.max_rate; 13998cee32b4SThierry Reding 14008cee32b4SThierry Reding return 0; 14018cee32b4SThierry Reding } 14028cee32b4SThierry Reding 14038cee32b4SThierry Reding static int tegra_emc_debug_max_rate_set(void *data, u64 rate) 14048cee32b4SThierry Reding { 14058cee32b4SThierry Reding struct tegra_emc *emc = data; 14068cee32b4SThierry Reding int err; 14078cee32b4SThierry Reding 14088cee32b4SThierry Reding if (!tegra_emc_validate_rate(emc, rate)) 14098cee32b4SThierry Reding return -EINVAL; 14108cee32b4SThierry Reding 1411d76fa3f2SDmitry Osipenko err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG); 14128cee32b4SThierry Reding if (err < 0) 14138cee32b4SThierry Reding return err; 14148cee32b4SThierry Reding 14158cee32b4SThierry Reding emc->debugfs.max_rate = rate; 14168cee32b4SThierry Reding 14178cee32b4SThierry Reding return 0; 14188cee32b4SThierry Reding } 14198cee32b4SThierry Reding 1420e12bc354Sjing yangyang DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_max_rate_fops, 14218cee32b4SThierry Reding tegra_emc_debug_max_rate_get, 14228cee32b4SThierry Reding tegra_emc_debug_max_rate_set, "%llu\n"); 14238cee32b4SThierry Reding 14248cee32b4SThierry Reding static void tegra_emc_debugfs_init(struct tegra_emc *emc) 14258cee32b4SThierry Reding { 14268cee32b4SThierry Reding struct device *dev = emc->dev; 14278cee32b4SThierry Reding unsigned int i; 14288cee32b4SThierry Reding int err; 14298cee32b4SThierry Reding 14308cee32b4SThierry Reding emc->debugfs.min_rate = ULONG_MAX; 14318cee32b4SThierry Reding emc->debugfs.max_rate = 0; 14328cee32b4SThierry Reding 14338cee32b4SThierry Reding for (i = 0; i < emc->num_timings; i++) { 14348cee32b4SThierry Reding if (emc->timings[i].rate < emc->debugfs.min_rate) 14358cee32b4SThierry Reding emc->debugfs.min_rate = emc->timings[i].rate; 14368cee32b4SThierry Reding 14378cee32b4SThierry Reding if (emc->timings[i].rate > emc->debugfs.max_rate) 14388cee32b4SThierry Reding emc->debugfs.max_rate = emc->timings[i].rate; 14398cee32b4SThierry Reding } 14408cee32b4SThierry Reding 1441a53670e1SDmitry Osipenko if (!emc->num_timings) { 1442a53670e1SDmitry Osipenko emc->debugfs.min_rate = clk_get_rate(emc->clk); 1443a53670e1SDmitry Osipenko emc->debugfs.max_rate = emc->debugfs.min_rate; 1444a53670e1SDmitry Osipenko } 1445a53670e1SDmitry Osipenko 14468cee32b4SThierry Reding err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, 14478cee32b4SThierry Reding emc->debugfs.max_rate); 14488cee32b4SThierry Reding if (err < 0) { 14498cee32b4SThierry Reding dev_err(dev, "failed to set rate range [%lu-%lu] for %pC\n", 14508cee32b4SThierry Reding emc->debugfs.min_rate, emc->debugfs.max_rate, 14518cee32b4SThierry Reding emc->clk); 14528cee32b4SThierry Reding } 14538cee32b4SThierry Reding 14548cee32b4SThierry Reding emc->debugfs.root = debugfs_create_dir("emc", NULL); 14558cee32b4SThierry Reding 14566cc8823aSDmitry Osipenko debugfs_create_file("available_rates", 0444, emc->debugfs.root, 14578cee32b4SThierry Reding emc, &tegra_emc_debug_available_rates_fops); 14586cc8823aSDmitry Osipenko debugfs_create_file("min_rate", 0644, emc->debugfs.root, 14598cee32b4SThierry Reding emc, &tegra_emc_debug_min_rate_fops); 14606cc8823aSDmitry Osipenko debugfs_create_file("max_rate", 0644, emc->debugfs.root, 14618cee32b4SThierry Reding emc, &tegra_emc_debug_max_rate_fops); 14628cee32b4SThierry Reding } 14638cee32b4SThierry Reding 1464d76fa3f2SDmitry Osipenko static inline struct tegra_emc * 1465d76fa3f2SDmitry Osipenko to_tegra_emc_provider(struct icc_provider *provider) 1466d76fa3f2SDmitry Osipenko { 1467d76fa3f2SDmitry Osipenko return container_of(provider, struct tegra_emc, provider); 1468d76fa3f2SDmitry Osipenko } 1469d76fa3f2SDmitry Osipenko 1470d76fa3f2SDmitry Osipenko static struct icc_node_data * 1471d76fa3f2SDmitry Osipenko emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) 1472d76fa3f2SDmitry Osipenko { 1473d76fa3f2SDmitry Osipenko struct icc_provider *provider = data; 1474d76fa3f2SDmitry Osipenko struct icc_node_data *ndata; 1475d76fa3f2SDmitry Osipenko struct icc_node *node; 1476d76fa3f2SDmitry Osipenko 1477d76fa3f2SDmitry Osipenko /* External Memory is the only possible ICC route */ 1478d76fa3f2SDmitry Osipenko list_for_each_entry(node, &provider->nodes, node_list) { 1479d76fa3f2SDmitry Osipenko if (node->id != TEGRA_ICC_EMEM) 1480d76fa3f2SDmitry Osipenko continue; 1481d76fa3f2SDmitry Osipenko 1482d76fa3f2SDmitry Osipenko ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); 1483d76fa3f2SDmitry Osipenko if (!ndata) 1484d76fa3f2SDmitry Osipenko return ERR_PTR(-ENOMEM); 1485d76fa3f2SDmitry Osipenko 1486d76fa3f2SDmitry Osipenko /* 1487d76fa3f2SDmitry Osipenko * SRC and DST nodes should have matching TAG in order to have 1488d76fa3f2SDmitry Osipenko * it set by default for a requested path. 1489d76fa3f2SDmitry Osipenko */ 1490d76fa3f2SDmitry Osipenko ndata->tag = TEGRA_MC_ICC_TAG_ISO; 1491d76fa3f2SDmitry Osipenko ndata->node = node; 1492d76fa3f2SDmitry Osipenko 1493d76fa3f2SDmitry Osipenko return ndata; 1494d76fa3f2SDmitry Osipenko } 1495d76fa3f2SDmitry Osipenko 1496d76fa3f2SDmitry Osipenko return ERR_PTR(-EPROBE_DEFER); 1497d76fa3f2SDmitry Osipenko } 1498d76fa3f2SDmitry Osipenko 1499d76fa3f2SDmitry Osipenko static int emc_icc_set(struct icc_node *src, struct icc_node *dst) 1500d76fa3f2SDmitry Osipenko { 1501d76fa3f2SDmitry Osipenko struct tegra_emc *emc = to_tegra_emc_provider(dst->provider); 1502d76fa3f2SDmitry Osipenko unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw); 1503d76fa3f2SDmitry Osipenko unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw); 1504d76fa3f2SDmitry Osipenko unsigned long long rate = max(avg_bw, peak_bw); 1505d76fa3f2SDmitry Osipenko const unsigned int dram_data_bus_width_bytes = 4; 1506d76fa3f2SDmitry Osipenko const unsigned int ddr = 2; 1507d76fa3f2SDmitry Osipenko int err; 1508d76fa3f2SDmitry Osipenko 1509d76fa3f2SDmitry Osipenko /* 1510d76fa3f2SDmitry Osipenko * Tegra30 EMC runs on a clock rate of SDRAM bus. This means that 1511d76fa3f2SDmitry Osipenko * EMC clock rate is twice smaller than the peak data rate because 1512d76fa3f2SDmitry Osipenko * data is sampled on both EMC clock edges. 1513d76fa3f2SDmitry Osipenko */ 1514d76fa3f2SDmitry Osipenko do_div(rate, ddr * dram_data_bus_width_bytes); 1515d76fa3f2SDmitry Osipenko rate = min_t(u64, rate, U32_MAX); 1516d76fa3f2SDmitry Osipenko 1517d76fa3f2SDmitry Osipenko err = emc_set_min_rate(emc, rate, EMC_RATE_ICC); 1518d76fa3f2SDmitry Osipenko if (err) 1519d76fa3f2SDmitry Osipenko return err; 1520d76fa3f2SDmitry Osipenko 1521d76fa3f2SDmitry Osipenko return 0; 1522d76fa3f2SDmitry Osipenko } 1523d76fa3f2SDmitry Osipenko 1524d76fa3f2SDmitry Osipenko static int tegra_emc_interconnect_init(struct tegra_emc *emc) 1525d76fa3f2SDmitry Osipenko { 1526d76fa3f2SDmitry Osipenko const struct tegra_mc_soc *soc = emc->mc->soc; 1527d76fa3f2SDmitry Osipenko struct icc_node *node; 1528d76fa3f2SDmitry Osipenko int err; 1529d76fa3f2SDmitry Osipenko 1530d76fa3f2SDmitry Osipenko emc->provider.dev = emc->dev; 1531d76fa3f2SDmitry Osipenko emc->provider.set = emc_icc_set; 1532d76fa3f2SDmitry Osipenko emc->provider.data = &emc->provider; 1533d76fa3f2SDmitry Osipenko emc->provider.aggregate = soc->icc_ops->aggregate; 1534d76fa3f2SDmitry Osipenko emc->provider.xlate_extended = emc_of_icc_xlate_extended; 1535d76fa3f2SDmitry Osipenko 1536*9db481c9SJohan Hovold icc_provider_init(&emc->provider); 1537d76fa3f2SDmitry Osipenko 1538d76fa3f2SDmitry Osipenko /* create External Memory Controller node */ 1539d76fa3f2SDmitry Osipenko node = icc_node_create(TEGRA_ICC_EMC); 1540d76fa3f2SDmitry Osipenko if (IS_ERR(node)) { 1541d76fa3f2SDmitry Osipenko err = PTR_ERR(node); 1542*9db481c9SJohan Hovold goto err_msg; 1543d76fa3f2SDmitry Osipenko } 1544d76fa3f2SDmitry Osipenko 1545d76fa3f2SDmitry Osipenko node->name = "External Memory Controller"; 1546d76fa3f2SDmitry Osipenko icc_node_add(node, &emc->provider); 1547d76fa3f2SDmitry Osipenko 1548d76fa3f2SDmitry Osipenko /* link External Memory Controller to External Memory (DRAM) */ 1549d76fa3f2SDmitry Osipenko err = icc_link_create(node, TEGRA_ICC_EMEM); 1550d76fa3f2SDmitry Osipenko if (err) 1551d76fa3f2SDmitry Osipenko goto remove_nodes; 1552d76fa3f2SDmitry Osipenko 1553d76fa3f2SDmitry Osipenko /* create External Memory node */ 1554d76fa3f2SDmitry Osipenko node = icc_node_create(TEGRA_ICC_EMEM); 1555d76fa3f2SDmitry Osipenko if (IS_ERR(node)) { 1556d76fa3f2SDmitry Osipenko err = PTR_ERR(node); 1557d76fa3f2SDmitry Osipenko goto remove_nodes; 1558d76fa3f2SDmitry Osipenko } 1559d76fa3f2SDmitry Osipenko 1560d76fa3f2SDmitry Osipenko node->name = "External Memory (DRAM)"; 1561d76fa3f2SDmitry Osipenko icc_node_add(node, &emc->provider); 1562d76fa3f2SDmitry Osipenko 1563*9db481c9SJohan Hovold err = icc_provider_register(&emc->provider); 1564*9db481c9SJohan Hovold if (err) 1565*9db481c9SJohan Hovold goto remove_nodes; 1566*9db481c9SJohan Hovold 1567d76fa3f2SDmitry Osipenko return 0; 1568d76fa3f2SDmitry Osipenko 1569d76fa3f2SDmitry Osipenko remove_nodes: 1570d76fa3f2SDmitry Osipenko icc_nodes_remove(&emc->provider); 1571d76fa3f2SDmitry Osipenko err_msg: 1572d76fa3f2SDmitry Osipenko dev_err(emc->dev, "failed to initialize ICC: %d\n", err); 1573d76fa3f2SDmitry Osipenko 1574d76fa3f2SDmitry Osipenko return err; 1575d76fa3f2SDmitry Osipenko } 1576d76fa3f2SDmitry Osipenko 1577d76fa3f2SDmitry Osipenko static void devm_tegra_emc_unset_callback(void *data) 1578d76fa3f2SDmitry Osipenko { 1579d76fa3f2SDmitry Osipenko tegra20_clk_set_emc_round_callback(NULL, NULL); 1580d76fa3f2SDmitry Osipenko } 1581d76fa3f2SDmitry Osipenko 1582d76fa3f2SDmitry Osipenko static void devm_tegra_emc_unreg_clk_notifier(void *data) 1583d76fa3f2SDmitry Osipenko { 1584d76fa3f2SDmitry Osipenko struct tegra_emc *emc = data; 1585d76fa3f2SDmitry Osipenko 1586d76fa3f2SDmitry Osipenko clk_notifier_unregister(emc->clk, &emc->clk_nb); 1587d76fa3f2SDmitry Osipenko } 1588d76fa3f2SDmitry Osipenko 1589d76fa3f2SDmitry Osipenko static int tegra_emc_init_clk(struct tegra_emc *emc) 1590d76fa3f2SDmitry Osipenko { 1591d76fa3f2SDmitry Osipenko int err; 1592d76fa3f2SDmitry Osipenko 1593d76fa3f2SDmitry Osipenko tegra20_clk_set_emc_round_callback(emc_round_rate, emc); 1594d76fa3f2SDmitry Osipenko 1595d76fa3f2SDmitry Osipenko err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unset_callback, 1596d76fa3f2SDmitry Osipenko NULL); 1597d76fa3f2SDmitry Osipenko if (err) 1598d76fa3f2SDmitry Osipenko return err; 1599d76fa3f2SDmitry Osipenko 1600d76fa3f2SDmitry Osipenko emc->clk = devm_clk_get(emc->dev, NULL); 1601d76fa3f2SDmitry Osipenko if (IS_ERR(emc->clk)) { 1602d76fa3f2SDmitry Osipenko dev_err(emc->dev, "failed to get EMC clock: %pe\n", emc->clk); 1603d76fa3f2SDmitry Osipenko return PTR_ERR(emc->clk); 1604d76fa3f2SDmitry Osipenko } 1605d76fa3f2SDmitry Osipenko 1606d76fa3f2SDmitry Osipenko err = clk_notifier_register(emc->clk, &emc->clk_nb); 1607d76fa3f2SDmitry Osipenko if (err) { 1608d76fa3f2SDmitry Osipenko dev_err(emc->dev, "failed to register clk notifier: %d\n", err); 1609d76fa3f2SDmitry Osipenko return err; 1610d76fa3f2SDmitry Osipenko } 1611d76fa3f2SDmitry Osipenko 1612d76fa3f2SDmitry Osipenko err = devm_add_action_or_reset(emc->dev, 1613d76fa3f2SDmitry Osipenko devm_tegra_emc_unreg_clk_notifier, emc); 1614d76fa3f2SDmitry Osipenko if (err) 1615d76fa3f2SDmitry Osipenko return err; 1616d76fa3f2SDmitry Osipenko 1617d76fa3f2SDmitry Osipenko return 0; 1618d76fa3f2SDmitry Osipenko } 1619d76fa3f2SDmitry Osipenko 1620e34212c7SDmitry Osipenko static int tegra_emc_probe(struct platform_device *pdev) 1621e34212c7SDmitry Osipenko { 1622b4f74b59SDmitry Osipenko struct tegra_core_opp_params opp_params = {}; 1623e34212c7SDmitry Osipenko struct device_node *np; 1624e34212c7SDmitry Osipenko struct tegra_emc *emc; 1625e34212c7SDmitry Osipenko int err; 1626e34212c7SDmitry Osipenko 1627e34212c7SDmitry Osipenko emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); 16280e1bcf2cSNathan Chancellor if (!emc) 1629e34212c7SDmitry Osipenko return -ENOMEM; 1630e34212c7SDmitry Osipenko 16316c6bd207SDmitry Osipenko emc->mc = devm_tegra_memory_controller_get(&pdev->dev); 16326c6bd207SDmitry Osipenko if (IS_ERR(emc->mc)) 16336c6bd207SDmitry Osipenko return PTR_ERR(emc->mc); 1634e34212c7SDmitry Osipenko 1635d76fa3f2SDmitry Osipenko mutex_init(&emc->rate_lock); 1636e34212c7SDmitry Osipenko emc->clk_nb.notifier_call = emc_clk_change_notify; 1637e34212c7SDmitry Osipenko emc->dev = &pdev->dev; 1638e34212c7SDmitry Osipenko 1639e34212c7SDmitry Osipenko emc->regs = devm_platform_ioremap_resource(pdev, 0); 1640e34212c7SDmitry Osipenko if (IS_ERR(emc->regs)) 1641e34212c7SDmitry Osipenko return PTR_ERR(emc->regs); 1642e34212c7SDmitry Osipenko 1643e34212c7SDmitry Osipenko err = emc_setup_hw(emc); 1644e34212c7SDmitry Osipenko if (err) 1645e34212c7SDmitry Osipenko return err; 1646e34212c7SDmitry Osipenko 1647e3aabb3cSDmitry Osipenko np = emc_find_node_by_ram_code(emc); 1648e3aabb3cSDmitry Osipenko if (np) { 1649e3aabb3cSDmitry Osipenko err = emc_load_timings_from_dt(emc, np); 1650e3aabb3cSDmitry Osipenko of_node_put(np); 1651e3aabb3cSDmitry Osipenko if (err) 1652e3aabb3cSDmitry Osipenko return err; 1653e3aabb3cSDmitry Osipenko } 1654e3aabb3cSDmitry Osipenko 1655e34212c7SDmitry Osipenko err = platform_get_irq(pdev, 0); 1656162641a6SDmitry Osipenko if (err < 0) 1657e34212c7SDmitry Osipenko return err; 1658162641a6SDmitry Osipenko 1659e34212c7SDmitry Osipenko emc->irq = err; 1660e34212c7SDmitry Osipenko 1661e34212c7SDmitry Osipenko err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0, 1662e34212c7SDmitry Osipenko dev_name(&pdev->dev), emc); 1663e34212c7SDmitry Osipenko if (err) { 1664e34212c7SDmitry Osipenko dev_err(&pdev->dev, "failed to request irq: %d\n", err); 1665e34212c7SDmitry Osipenko return err; 1666e34212c7SDmitry Osipenko } 1667e34212c7SDmitry Osipenko 1668d76fa3f2SDmitry Osipenko err = tegra_emc_init_clk(emc); 1669d76fa3f2SDmitry Osipenko if (err) 1670d76fa3f2SDmitry Osipenko return err; 1671e34212c7SDmitry Osipenko 1672b4f74b59SDmitry Osipenko opp_params.init_state = true; 1673b4f74b59SDmitry Osipenko 1674b4f74b59SDmitry Osipenko err = devm_tegra_core_dev_init_opp_table(&pdev->dev, &opp_params); 1675d76fa3f2SDmitry Osipenko if (err) 1676d76fa3f2SDmitry Osipenko return err; 1677e34212c7SDmitry Osipenko 1678e34212c7SDmitry Osipenko platform_set_drvdata(pdev, emc); 1679d76fa3f2SDmitry Osipenko tegra_emc_rate_requests_init(emc); 16808cee32b4SThierry Reding tegra_emc_debugfs_init(emc); 1681d76fa3f2SDmitry Osipenko tegra_emc_interconnect_init(emc); 1682e34212c7SDmitry Osipenko 16830c56eda8SDmitry Osipenko /* 16840c56eda8SDmitry Osipenko * Don't allow the kernel module to be unloaded. Unloading adds some 16850c56eda8SDmitry Osipenko * extra complexity which doesn't really worth the effort in a case of 16860c56eda8SDmitry Osipenko * this driver. 16870c56eda8SDmitry Osipenko */ 16880c56eda8SDmitry Osipenko try_module_get(THIS_MODULE); 16890c56eda8SDmitry Osipenko 1690e34212c7SDmitry Osipenko return 0; 1691e34212c7SDmitry Osipenko } 1692e34212c7SDmitry Osipenko 1693e34212c7SDmitry Osipenko static int tegra_emc_suspend(struct device *dev) 1694e34212c7SDmitry Osipenko { 1695e34212c7SDmitry Osipenko struct tegra_emc *emc = dev_get_drvdata(dev); 169651bb73f9SDmitry Osipenko int err; 1697e34212c7SDmitry Osipenko 169851bb73f9SDmitry Osipenko /* take exclusive control over the clock's rate */ 169951bb73f9SDmitry Osipenko err = clk_rate_exclusive_get(emc->clk); 170051bb73f9SDmitry Osipenko if (err) { 170151bb73f9SDmitry Osipenko dev_err(emc->dev, "failed to acquire clk: %d\n", err); 170251bb73f9SDmitry Osipenko return err; 170351bb73f9SDmitry Osipenko } 170451bb73f9SDmitry Osipenko 170551bb73f9SDmitry Osipenko /* suspending in a bad state will hang machine */ 170651bb73f9SDmitry Osipenko if (WARN(emc->bad_state, "hardware in a bad state\n")) 1707e34212c7SDmitry Osipenko return -EINVAL; 1708e34212c7SDmitry Osipenko 1709e34212c7SDmitry Osipenko emc->bad_state = true; 1710e34212c7SDmitry Osipenko 1711e34212c7SDmitry Osipenko return 0; 1712e34212c7SDmitry Osipenko } 1713e34212c7SDmitry Osipenko 1714e34212c7SDmitry Osipenko static int tegra_emc_resume(struct device *dev) 1715e34212c7SDmitry Osipenko { 1716e34212c7SDmitry Osipenko struct tegra_emc *emc = dev_get_drvdata(dev); 1717e34212c7SDmitry Osipenko 1718e34212c7SDmitry Osipenko emc_setup_hw(emc); 1719e34212c7SDmitry Osipenko emc->bad_state = false; 1720e34212c7SDmitry Osipenko 172151bb73f9SDmitry Osipenko clk_rate_exclusive_put(emc->clk); 172251bb73f9SDmitry Osipenko 1723e34212c7SDmitry Osipenko return 0; 1724e34212c7SDmitry Osipenko } 1725e34212c7SDmitry Osipenko 1726e34212c7SDmitry Osipenko static const struct dev_pm_ops tegra_emc_pm_ops = { 1727e34212c7SDmitry Osipenko .suspend = tegra_emc_suspend, 1728e34212c7SDmitry Osipenko .resume = tegra_emc_resume, 1729e34212c7SDmitry Osipenko }; 1730e34212c7SDmitry Osipenko 1731e34212c7SDmitry Osipenko static const struct of_device_id tegra_emc_of_match[] = { 1732e34212c7SDmitry Osipenko { .compatible = "nvidia,tegra30-emc", }, 1733e34212c7SDmitry Osipenko {}, 1734e34212c7SDmitry Osipenko }; 17350c56eda8SDmitry Osipenko MODULE_DEVICE_TABLE(of, tegra_emc_of_match); 1736e34212c7SDmitry Osipenko 1737e34212c7SDmitry Osipenko static struct platform_driver tegra_emc_driver = { 1738e34212c7SDmitry Osipenko .probe = tegra_emc_probe, 1739e34212c7SDmitry Osipenko .driver = { 1740e34212c7SDmitry Osipenko .name = "tegra30-emc", 1741e34212c7SDmitry Osipenko .of_match_table = tegra_emc_of_match, 1742e34212c7SDmitry Osipenko .pm = &tegra_emc_pm_ops, 1743e34212c7SDmitry Osipenko .suppress_bind_attrs = true, 1744d76fa3f2SDmitry Osipenko .sync_state = icc_sync_state, 1745e34212c7SDmitry Osipenko }, 1746e34212c7SDmitry Osipenko }; 17470c56eda8SDmitry Osipenko module_platform_driver(tegra_emc_driver); 1748e34212c7SDmitry Osipenko 17490c56eda8SDmitry Osipenko MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>"); 17500c56eda8SDmitry Osipenko MODULE_DESCRIPTION("NVIDIA Tegra30 EMC driver"); 17510c56eda8SDmitry Osipenko MODULE_LICENSE("GPL v2"); 1752