summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorJimmy Zhang <jimmzhang@nvidia.com>2011-06-09 18:17:33 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:39:24 -0700
commitef64b9587648bde33dfa3405bc5dc742ee5ccf66 (patch)
tree26d691b53add5e8f8bd51c294f8a505e1a0b396c /board
parentc944c37cff2243782786352d67e3756e4bbd383e (diff)
arm: Tegra2: Set emc to performance configuration
BUG=none TEST=unit test done on t20 and t25 seaboard. Need to be test out on Kaen and Aebl. Change-Id: I72707a880b52f58a558098fa8740bd3dff991337 Reviewed-on: http://gerrit.chromium.org/gerrit/2424 Reviewed-by: Jimmy Zhang <jimmzhang@nvidia.com> Tested-by: Jimmy Zhang <jimmzhang@nvidia.com>
Diffstat (limited to 'board')
-rw-r--r--board/nvidia/common/Makefile1
-rw-r--r--board/nvidia/common/board.c3
-rw-r--r--board/nvidia/common/emc.c1001
3 files changed, 1005 insertions, 0 deletions
diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile
index 5d40bd73e5..7c0585eb74 100644
--- a/board/nvidia/common/Makefile
+++ b/board/nvidia/common/Makefile
@@ -30,6 +30,7 @@ COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
COBJS-$(CONFIG_SPI_UART_SWITCH) += uart-spi-fix.o
COBJS-$(CONFIG_TEGRA2_KEYBOARD) += generic_kbc.o
COBJS-$(CONFIG_TEGRA2_I2C) += pmu.o
+COBJS-$(CONFIG_TEGRA2_I2C) += emc.o
COBJS-$(CONFIG_TEGRA2_LP0) += crypto/aes_ref.o
COBJS-$(CONFIG_TEGRA2_LP0) += crypto/crypto.o
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 1e2ff3e788..93bf4f4d41 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -36,6 +36,7 @@
#include <asm/arch/usb.h>
#include <asm/arch/pmc.h>
#include <asm/arch/fuse.h>
+#include <asm/arch/emc.h>
#include <spi.h>
#include <fdt_decode.h>
#include <i2c.h>
@@ -215,6 +216,8 @@ int board_init(void)
i2c_init_board();
pmu_set_nominal();
+
+ board_emc_init();
#endif
return 0;
diff --git a/board/nvidia/common/emc.c b/board/nvidia/common/emc.c
new file mode 100644
index 0000000000..648ec8cd8a
--- /dev/null
+++ b/board/nvidia/common/emc.c
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/bitfield.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pmu.h>
+#include <asm/arch/emc.h>
+#include "board.h"
+
+static const struct tegra_emc_table *tegra_emc_table;
+static int tegra_emc_table_size;
+
+static inline void emc_writel(u32 val, unsigned long addr)
+{
+ writel(val, (NV_PA_EMC_BASE + addr));
+}
+
+static inline u32 emc_readl(unsigned long addr)
+{
+ return readl((NV_PA_EMC_BASE + addr));
+}
+
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+ 0x2c, /* RC */
+ 0x30, /* RFC */
+ 0x34, /* RAS */
+ 0x38, /* RP */
+ 0x3c, /* R2W */
+ 0x40, /* W2R */
+ 0x44, /* R2P */
+ 0x48, /* W2P */
+ 0x4c, /* RD_RCD */
+ 0x50, /* WR_RCD */
+ 0x54, /* RRD */
+ 0x58, /* REXT */
+ 0x5c, /* WDV */
+ 0x60, /* QUSE */
+ 0x64, /* QRST */
+ 0x68, /* QSAFE */
+ 0x6c, /* RDV */
+ 0x70, /* REFRESH */
+ 0x74, /* BURST_REFRESH_NUM */
+ 0x78, /* PDEX2WR */
+ 0x7c, /* PDEX2RD */
+ 0x80, /* PCHG2PDEN */
+ 0x84, /* ACT2PDEN */
+ 0x88, /* AR2PDEN */
+ 0x8c, /* RW2PDEN */
+ 0x90, /* TXSR */
+ 0x94, /* TCKE */
+ 0x98, /* TFAW */
+ 0x9c, /* TRPAB */
+ 0xa0, /* TCLKSTABLE */
+ 0xa4, /* TCLKSTOP */
+ 0xa8, /* TREFBW */
+ 0xac, /* QUSE_EXTRA */
+ 0x114, /* FBIO_CFG6 */
+ 0xb0, /* ODT_WRITE */
+ 0xb4, /* ODT_READ */
+ 0x104, /* FBIO_CFG5 */
+ 0x2bc, /* CFG_DIG_DLL */
+ 0x2c0, /* DLL_XFORM_DQS */
+ 0x2c4, /* DLL_XFORM_QUSE */
+ 0x2e0, /* ZCAL_REF_CNT */
+ 0x2e4, /* ZCAL_WAIT_CNT */
+ 0x2a8, /* AUTO_CAL_INTERVAL */
+ 0x2d0, /* CFG_CLKTRIM_0 */
+ 0x2d4, /* CFG_CLKTRIM_1 */
+ 0x2d8, /* CFG_CLKTRIM_2 */
+};
+
+/* The EMC registers have shadow registers. When the EMC clock is updated
+ * in the clock controller, the shadow registers are copied to the active
+ * registers, allowing glitchless memory bus frequency changes.
+ * This function updates the shadow registers for a new clock frequency,
+ * and relies on the clock lock on the emc clock to avoid races between
+ * multiple frequency changes */
+#define EMC_SDRAM_RATE_T20 (333000*2*1000)
+#define EMC_SDRAM_RATE_T25 (380000*2*1000)
+
+static int tegra_emc_set_rate(unsigned long rate)
+{
+ int i;
+ int j;
+
+ if (!tegra_emc_table)
+ return -1;
+
+ /* The EMC clock rate is twice the bus rate, and the bus rate is
+ * measured in kHz */
+ rate = rate / 2 / 1000;
+
+ for (i = 0; i < tegra_emc_table_size; i++)
+ if (tegra_emc_table[i].rate == rate)
+ break;
+
+ if (i >= tegra_emc_table_size)
+ return -1;
+
+ for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
+ emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+
+ /*
+ * trigger emc with new settings by updating clk_rst's source EMC
+ * Set PLLM_OUT0 (bits: 31:30= 0) and divisor bits 7:0 = 0 (ie 1)
+ */
+ clock_ll_set_source_divisor(PERIPH_ID_EMC, 0, 0);
+ udelay(1);
+ return 0;
+}
+
+static int tegra_set_emc(const struct tegra_emc_table *table, int table_size)
+{
+ unsigned long rate;
+
+ if (!table) {
+ tegra_emc_table = NULL;
+ tegra_emc_table_size = 0;
+ return -1;
+ }
+
+ tegra_emc_table = table;
+ tegra_emc_table_size = table_size;
+
+ switch (tegra_get_chip_type()) {
+ case TEGRA_SOC_T20:
+ rate = EMC_SDRAM_RATE_T20;
+ break;
+ case TEGRA_SOC_T25:
+ rate = EMC_SDRAM_RATE_T25;
+ break;
+ default:
+ /* unknown chip type, no clk change*/
+ return -1;
+ }
+
+ tegra_emc_set_rate(rate);
+
+ return 0;
+}
+
+struct tegra_board_emc_table {
+ int id; /* Boot strap ID */
+ const struct tegra_emc_table *table;
+ const int table_size;
+ const char *name;
+};
+
+
+static const struct tegra_emc_table seaboard_emc_tables_hynix_333Mhz[] = {
+ {
+ .rate = 166500, /* SDRAM frequency */
+ .regs = {
+ 0x0000000a, /* RC */
+ 0x00000021, /* RFC */
+ 0x00000008, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x000004df, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000a, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000006, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa04004ae, /* CFG_DIG_DLL */
+ 0x007fd010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 */
+ 0x0000000c, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x000009ff, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000005, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000f, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000c, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe034048b, /* CFG_DIG_DLL */
+ 0x007e8010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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_table seaboard_emc_tables_hynix_380Mhz[] = {
+ {
+ .rate = 190000, /* SDRAM frequency */
+ .regs = {
+ 0x0000000c, /* RC */
+ 0x00000026, /* RFC */
+ 0x00000009, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x0000059f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000b, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000007, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06204ae, /* CFG_DIG_DLL */
+ 0x007dc010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 = 380000, /* SDRAM frequency */
+ .regs = {
+ 0x00000017, /* RC */
+ 0x0000004b, /* RFC */
+ 0x00000012, /* RAS */
+ 0x00000006, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000006, /* RD_RCD */
+ 0x00000006, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x00000b5f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000006, /* PCHG2PDEN */
+ 0x00000006, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x00000011, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000e, /* TFAW */
+ 0x00000007, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe044048b, /* CFG_DIG_DLL */
+ 0x007d8010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 */
+ }
+ }
+};
+
+void seaboard_emc_init(void)
+{
+ switch (tegra_get_chip_type()) {
+ case TEGRA_SOC_T20:
+ tegra_set_emc(seaboard_emc_tables_hynix_333Mhz,
+ ARRAY_SIZE(seaboard_emc_tables_hynix_333Mhz));
+ break;
+ case TEGRA_SOC_T25:
+ tegra_set_emc(seaboard_emc_tables_hynix_380Mhz,
+ ARRAY_SIZE(seaboard_emc_tables_hynix_380Mhz));
+ break;
+ default:
+ /* unknown chip type, no clk change*/
+ tegra_set_emc(NULL, 0);
+ break;
+ }
+}
+
+static const struct tegra_emc_table kaen_emc_tables_Nanya_333Mhz[] = {
+ {
+ .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 */
+ 0x00000007, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000006, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06e04ae, /* CFG_DIG_DLL */
+ 0x007e2010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 */
+ 0x00000003, /* 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 */
+ 0x0000000d, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x00000006, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe04e048b, /* CFG_DIG_DLL */
+ 0x007e2010, /* DLL_XFORM_DQS */
+ 0x007f8417, /* 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_table kaen_emc_tables_Nanya_380Mhz[] = {
+ {
+ .rate = 190000, /* SDRAM frequency */
+ .regs = {
+ 0x0000000b, /* RC */
+ 0x00000019, /* RFC */
+ 0x00000009, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000b, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000004, /* QUSE */
+ 0x00000003, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000c, /* RDV */
+ 0x0000059f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000a, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000007, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06204ae, /* CFG_DIG_DLL */
+ 0x007fd010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 = 380000, /* SDRAM frequency */
+ .regs = {
+ 0x00000016, /* RC */
+ 0x00000031, /* RFC */
+ 0x00000012, /* RAS */
+ 0x00000006, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000b, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000004, /* QUSE */
+ 0x00000003, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000c, /* RDV */
+ 0x00000b5f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000006, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x00000010, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000e, /* TFAW */
+ 0x00000007, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000004, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe044048b, /* CFG_DIG_DLL */
+ 0x007e4010, /* DLL_XFORM_DQS */
+ 0x00016617, /* 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_table kaen_emc_tables_Samsung_333Mhz[] = {
+ {
+ .rate = 166500, /* SDRAM frequency */
+ .regs = {
+ 0x0000000a, /* RC */
+ 0x00000016, /* RFC */
+ 0x00000008, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x000004df, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000a, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000006, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06e04ae, /* CFG_DIG_DLL */
+ 0x007e2010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 */
+ 0x0000000c, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x000009ff, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000005, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000f, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000c, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe04e048b, /* CFG_DIG_DLL */
+ 0x007de010, /* DLL_XFORM_DQS */
+ 0x00022015, /* 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_table kaen_emc_tables_Samsung_380Mhz[] = {
+ {
+ .rate = 190000, /* SDRAM frequency */
+ .regs = {
+ 0x0000000c, /* RC */
+ 0x00000019, /* RFC */
+ 0x00000009, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x0000059f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000b, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000007, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06204ae, /* CFG_DIG_DLL */
+ 0x007e0010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 = 380000, /* SDRAM frequency */
+ .regs = {
+ 0x00000017, /* RC */
+ 0x00000031, /* RFC */
+ 0x00000012, /* RAS */
+ 0x00000006, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000c, /* W2P */
+ 0x00000006, /* RD_RCD */
+ 0x00000006, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000d, /* RDV */
+ 0x00000b5f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000006, /* PCHG2PDEN */
+ 0x00000006, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x00000011, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000e, /* TFAW */
+ 0x00000007, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe044048b, /* CFG_DIG_DLL */
+ 0x007e0010, /* DLL_XFORM_DQS */
+ 0x00023215, /* 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 */
+ }
+ }
+};
+
+struct tegra_board_emc_table kaen_emc[] = {
+ {
+ .table = kaen_emc_tables_Samsung_333Mhz,
+ .table_size = ARRAY_SIZE(kaen_emc_tables_Samsung_333Mhz),
+ .name = "Samsung 333MHz",
+ },
+ {
+ .table = kaen_emc_tables_Nanya_333Mhz,
+ .table_size = ARRAY_SIZE(kaen_emc_tables_Nanya_333Mhz),
+ .name = "Nanya 333MHz",
+ },
+ {
+ .table = kaen_emc_tables_Samsung_380Mhz,
+ .table_size = ARRAY_SIZE(kaen_emc_tables_Samsung_380Mhz),
+ .name = "Samsung 380MHz",
+ },
+ {
+ .table = kaen_emc_tables_Nanya_380Mhz,
+ .table_size = ARRAY_SIZE(kaen_emc_tables_Nanya_380Mhz),
+ .name = "Nanya 380MHz",
+ },
+};
+
+#define STRAP_OPT 0x008
+#define GMI_AD0 (1 << 4)
+#define GMI_AD1 (1 << 5)
+#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
+#define RAM_CODE_SHIFT 4
+
+void kaen_emc_init(void)
+{
+ u32 reg;
+ int ram_id;
+
+ reg = readl(NV_PA_APB_MISC_BASE + STRAP_OPT);
+ ram_id = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
+
+ if (ram_id >= ARRAY_SIZE(kaen_emc) || !kaen_emc[ram_id].table) {
+ tegra_set_emc(NULL, 0);
+ } else {
+ tegra_set_emc(kaen_emc[ram_id].table,
+ kaen_emc[ram_id].table_size);
+ }
+}
+
+static const struct tegra_emc_table aebl_emc_tables[] = {
+ {
+ .rate = 190000, /* SDRAM frequency */
+ .regs = {
+ 0x0000000b, /* RC */
+ 0x00000026, /* RFC */
+ 0x00000008, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000b, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000004, /* QUSE */
+ 0x00000005, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000c, /* RDV */
+ 0x0000059f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000a, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000007, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xa06204ae, /* CFG_DIG_DLL */
+ 0x007e8010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 = 380000, /* SDRAM frequency */
+ .regs = {
+ 0x00000015, /* RC */
+ 0x0000004c, /* RFC */
+ 0x00000010, /* RAS */
+ 0x00000005, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000b, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000004, /* QUSE */
+ 0x00000003, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000c, /* RDV */
+ 0x00000b5f, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000005, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000f, /* RW2PDEN */
+ 0x000000c8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000e, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x0000000f, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xe044048b, /* CFG_DIG_DLL */
+ 0x007e0010, /* DLL_XFORM_DQS */
+ 0x00000000, /* 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 */
+ }
+ }
+};
+
+void aebl_emc_init(void)
+{
+ tegra_set_emc(aebl_emc_tables, ARRAY_SIZE(aebl_emc_tables));
+}
+
+struct emc_init {
+ unsigned int id; /* board id */
+ void (*init)(void);
+};
+
+static struct emc_init board_table[] = {
+ {
+ .id = MACH_TYPE_AEBL,
+ .init = aebl_emc_init,
+ },
+ {
+ .id = MACH_TYPE_HARMONY,
+ .init = NULL,
+ },
+ {
+ .id = MACH_TYPE_KAEN,
+ .init = kaen_emc_init,
+ },
+ {
+ .id = MACH_TYPE_SEABOARD,
+ .init = seaboard_emc_init,
+ },
+ {
+ .id = MACH_TYPE_WARIO,
+ .init = NULL,
+ },
+};
+
+int board_emc_init(void)
+{
+ int i;
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* if voltage has not been set properly, return */
+ if (!tegra2_pmu_is_voltage_nominal())
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(board_table); i++) {
+ if (board_table[i].id == gd->bd->bi_arch_number) {
+ if (board_table[i].init) {
+ board_table[i].init();
+ return 0;
+ } else
+ return -1;
+ }
+ }
+ return -1;
+}