/* * arch/arm/mach-tegra/board-colibri_t20-memory.c * * Copyright (C) 2012 Toradex, Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include #include #include "board-colibri_t20.h" #include "board.h" #include "tegra2_emc.h" /* Optimised timings for Colibri T20 256 MB */ static const struct tegra_emc_table colibri_t20_emc_tables_nanya_333Mhz[] = { { .rate = 83250, /* SDRAM frequency */ .regs = { 0x00000005, /* RC */ 0x00000011, /* RFC */ 0x00000004, /* RAS */ 0x00000002, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000001, /* R2P */ 0x0000000a, /* W2P */ 0x00000002, /* RD_RCD */ 0x00000002, /* WR_RCD */ 0x00000001, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x0000025f, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000002, /* PCHG2PDEN */ 0x00000002, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000008, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000005, /* TFAW */ 0x00000003, /* TRPAB */ 0x00000006, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00520006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 125000, /* SDRAM frequency */ .regs = { 0x00000008, /* RC */ 0x00000010, /* RFC */ 0x00000006, /* RAS */ 0x00000002, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000001, /* R2P */ 0x0000000a, /* W2P */ 0x00000002, /* RD_RCD */ 0x00000002, /* WR_RCD */ 0x00000002, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x0000039f, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000002, /* PCHG2PDEN */ 0x00000002, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000008, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000007, /* TFAW */ 0x00000003, /* TRPAB */ 0x00000006, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00510006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 166500, /* SDRAM frequency */ .regs = { 0x0000000a, /* RC */ 0x00000016, /* RFC */ 0x00000008, /* RAS */ 0x00000003, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000002, /* R2P */ 0x0000000a, /* W2P */ 0x00000003, /* RD_RCD */ 0x00000003, /* WR_RCD */ 0x00000002, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x000004df, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000003, /* PCHG2PDEN */ 0x00000003, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000009, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000009, /* TFAW */ 0x00000004, /* TRPAB */ 0x00000006, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x004f0006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 333000, /* SDRAM frequency */ .regs = { 0x00000014, /* RC */ 0x0000002b, /* RFC */ 0x0000000f, /* RAS */ 0x00000005, /* RP */ 0x00000004, /* R2W */ 0x00000005, /* W2R */ 0x00000003, /* R2P */ 0x0000000a, /* W2P */ 0x00000005, /* RD_RCD */ 0x00000005, /* WR_RCD */ 0x00000004, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x000009ff, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000005, /* PCHG2PDEN */ 0x00000005, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x0000000e, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000011, /* TFAW */ 0x00000006, /* TRPAB */ 0x00000006, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00380006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, }; /* Standard timings for Colibri T20 512 MB */ static const struct tegra_emc_table colibri_t20_emc_tables_memphis_333Mhz[] = { { .rate = 83250, /* SDRAM frequency */ .regs = { 0x00000005, /* RC */ 0x00000011, /* RFC */ 0x00000004, /* RAS */ 0x00000002, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000001, /* R2P */ 0x0000000a, /* W2P */ 0x00000002, /* RD_RCD */ 0x00000002, /* WR_RCD */ 0x00000001, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x0000025f, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000002, /* PCHG2PDEN */ 0x00000002, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000008, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000005, /* TFAW */ 0x00000003, /* TRPAB */ 0x0000000c, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00520006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 125000, /* SDRAM frequency */ .regs = { 0x00000008, /* RC */ 0x00000019, /* RFC */ 0x00000006, /* RAS */ 0x00000002, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000001, /* R2P */ 0x0000000a, /* W2P */ 0x00000002, /* RD_RCD */ 0x00000002, /* WR_RCD */ 0x00000002, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x0000039f, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000002, /* PCHG2PDEN */ 0x00000002, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000008, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000007, /* TFAW */ 0x00000003, /* TRPAB */ 0x0000000c, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00510006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 166500, /* SDRAM frequency */ .regs = { 0x0000000a, /* RC */ 0x00000021, /* RFC */ 0x00000008, /* RAS */ 0x00000003, /* RP */ 0x00000004, /* R2W */ 0x00000004, /* W2R */ 0x00000002, /* R2P */ 0x0000000a, /* W2P */ 0x00000003, /* RD_RCD */ 0x00000003, /* WR_RCD */ 0x00000002, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x000004df, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000003, /* PCHG2PDEN */ 0x00000003, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x00000009, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000009, /* TFAW */ 0x00000004, /* TRPAB */ 0x0000000c, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x004f0006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, { .rate = 333000, /* SDRAM frequency */ .regs = { 0x00000014, /* RC */ 0x00000041, /* RFC */ 0x0000000f, /* RAS */ 0x00000005, /* RP */ 0x00000004, /* R2W */ 0x00000005, /* W2R */ 0x00000003, /* R2P */ 0x0000000a, /* W2P */ 0x00000005, /* RD_RCD */ 0x00000005, /* WR_RCD */ 0x00000004, /* RRD */ 0x00000001, /* REXT */ 0x00000003, /* WDV */ 0x00000004, /* QUSE */ 0x00000003, /* QRST */ 0x00000009, /* QSAFE */ 0x0000000c, /* RDV */ 0x000009ff, /* REFRESH */ 0x00000000, /* BURST_REFRESH_NUM */ 0x00000003, /* PDEX2WR */ 0x00000003, /* PDEX2RD */ 0x00000005, /* PCHG2PDEN */ 0x00000005, /* ACT2PDEN */ 0x00000001, /* AR2PDEN */ 0x0000000e, /* RW2PDEN */ 0x000000c8, /* TXSR */ 0x00000003, /* TCKE */ 0x00000011, /* TFAW */ 0x00000006, /* TRPAB */ 0x0000000c, /* TCLKSTABLE */ 0x00000002, /* TCLKSTOP */ 0x00000000, /* TREFBW */ 0x00000000, /* QUSE_EXTRA */ 0x00000002, /* FBIO_CFG6 */ 0x00000000, /* ODT_WRITE */ 0x00000000, /* ODT_READ */ 0x00000083, /* FBIO_CFG5 */ 0x00380006, /* CFG_DIG_DLL */ 0x00000010, /* DLL_XFORM_DQS */ 0x00000008, /* DLL_XFORM_QUSE */ 0x00000000, /* ZCAL_REF_CNT */ 0x00000000, /* ZCAL_WAIT_CNT */ 0x00000000, /* AUTO_CAL_INTERVAL */ 0x00000000, /* CFG_CLKTRIM_0 */ 0x00000000, /* CFG_CLKTRIM_1 */ 0x00000000, /* CFG_CLKTRIM_2 */ } }, }; static const struct tegra_emc_chip colibri_t20_emc_chips[] = { { .description = "Nanya NT5TU64M16GG 333MHz", .table = colibri_t20_emc_tables_nanya_333Mhz, .table_size = ARRAY_SIZE(colibri_t20_emc_tables_nanya_333Mhz) }, { .description = "MEMPHIS MEM2G16D2DABG 333MHz", .table = colibri_t20_emc_tables_memphis_333Mhz, .table_size = ARRAY_SIZE(colibri_t20_emc_tables_memphis_333Mhz) }, }; int colibri_t20_emc_init(void) { /* Assume less than 256 MB of kernel memory (e.g. physical memory minus carveout and framebuffers) means we are running on a 256 MB module */ if (memblock_end_of_DRAM() < 256 * 1024 * 1024) tegra_init_emc(&colibri_t20_emc_chips[0], 1); else tegra_init_emc(&colibri_t20_emc_chips[1], 1); return 0; }