summaryrefslogtreecommitdiff
path: root/src/soc/mediatek/mt8173/include
diff options
context:
space:
mode:
authorPeter Kao <peter.kao@mediatek.com>2015-07-31 17:11:14 +0800
committerPatrick Georgi <pgeorgi@google.com>2016-03-12 09:00:21 +0100
commitda1e02a3a0cd8de244a03cc84d5ecc9663e5e694 (patch)
tree561d900efe1632f802de2eee84ff11d6f4465ed5 /src/soc/mediatek/mt8173/include
parentb74a2eca80deed3e7d21ba1123c2b986abcfcc10 (diff)
mediatek/mt8173: Add EMI driver, DRAM initialization
BUG=none TEST=emerge-oak coreboot BRANCH=none Change-Id: I6b05898de2d0022e0de7b18f1db3c3e9c06d8135 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: b614eeb1bba5660438c214e82225832809caca8e Original-Change-Id: I0f7b0a426dae1548b34114a024c92befdf6002f6 Original-Signed-off-by: Peter Kao <peter.kao@mediatek.com> Original-Reviewed-on: https://chromium-review.googlesource.com/292692 Original-Commit-Ready: Yidi Lin <yidi.lin@mediatek.com> Original-Tested-by: Yidi Lin <yidi.lin@mediatek.com> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/13105 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/mediatek/mt8173/include')
-rw-r--r--src/soc/mediatek/mt8173/include/soc/dramc_common.h42
-rw-r--r--src/soc/mediatek/mt8173/include/soc/dramc_pi_api.h187
-rw-r--r--src/soc/mediatek/mt8173/include/soc/dramc_register.h522
-rw-r--r--src/soc/mediatek/mt8173/include/soc/emi.h140
-rw-r--r--src/soc/mediatek/mt8173/include/soc/pll.h5
5 files changed, 896 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8173/include/soc/dramc_common.h b/src/soc/mediatek/mt8173/include/soc/dramc_common.h
new file mode 100644
index 0000000000..084e7de555
--- /dev/null
+++ b/src/soc/mediatek/mt8173/include/soc/dramc_common.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef _DRAMC_COMMON_H_
+#define _DRAMC_COMMON_H_
+
+enum {
+ CHANNEL_A = 0,
+ CHANNEL_B,
+ CHANNEL_NUM
+};
+
+enum {
+ GW_PARAM_COARSE = 0,
+ GW_PARAM_FINE,
+ GW_PARAM_NUM
+};
+
+enum {
+ DUAL_RANKS = 2,
+ CATRAINING_NUM = 10
+};
+
+enum {
+ DQ_DATA_WIDTH = 32,
+ DQS_BIT_NUMBER = 8,
+ DQS_NUMBER = (DQ_DATA_WIDTH / DQS_BIT_NUMBER)
+};
+
+#endif /* _DRAMC_COMMON_H_ */
diff --git a/src/soc/mediatek/mt8173/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8173/include/soc/dramc_pi_api.h
new file mode 100644
index 0000000000..1411d39f48
--- /dev/null
+++ b/src/soc/mediatek/mt8173/include/soc/dramc_pi_api.h
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef _DRAMC_PI_API_H
+#define _DRAMC_PI_API_H
+
+#include <soc/emi.h>
+#include <console/console.h>
+
+enum {
+ MAX_CLKO_DELAY = 15
+};
+
+enum {
+ /* jitter meter for PLL phase calibration */
+ JMETER_COUNT = 1024,
+ JMETER_COUNT_N = JMETER_COUNT/10,
+ /* 10us for more margin, Fin = 52 */
+ JMETER_WAIT_DONE_US = (JMETER_COUNT/52 + 10)
+};
+
+enum {
+ DLE_TEST_NUM = 4
+};
+
+enum {
+ /* window type: tx/rx */
+ RX_WIN = 0,
+ TX_WIN = 1,
+ /* stage type: setup/hold time */
+ STAGE_SETUP = 0,
+ STAGE_HOLD = 1,
+ /* combinational flags of stage and window type */
+ STAGE_SETUP_RX_WIN = STAGE_SETUP | RX_WIN << 1,
+ STAGE_SETUP_TX_WIN = STAGE_SETUP | TX_WIN << 1,
+ STAGE_HOLD_RX_WIN = STAGE_HOLD | RX_WIN << 1,
+ STAGE_HOLD_TX_WIN = STAGE_HOLD | TX_WIN << 1
+};
+
+enum {
+ RX_DQ = 0,
+ RX_DQS,
+ TX_DQ,
+ TX_DQS,
+ TX_DQM
+};
+
+enum {
+ AUDIO = 1,
+ XTALK,
+ ISI
+};
+
+enum {
+ MEMPLL_INIT = 0,
+ MEMPLL_REF_LAG,
+ MEMPLL_REF_LEAD
+};
+
+enum {
+ FIRST_DQ_DELAY = 0, /* first DQ delay taps */
+ FIRST_DQS_DELAY = 0, /* first DQS delay taps */
+ MAX_DQDLY_TAPS = 16, /* max DQ delay taps */
+ MAX_TX_DQSDLY_TAPS = 16, /* max TX DQS delay taps */
+ MAX_RX_DQSDLY_TAPS = 64 /* max RX DQS delay taps */
+};
+
+enum {
+ DRAMK_READ = 0,
+ DRAMK_WRITE = 1
+};
+
+enum {
+ ENABLE = 1,
+ DISABLE = 0
+};
+
+enum {
+ DATA_WIDTH_16BIT = 16,
+ DATA_WIDTH_32BIT = 32
+};
+
+enum dram_tw_op {
+ TE_OP_WRITE_READ_CHECK = 0,
+ TE_OP_READ_CHECK
+};
+
+enum {
+ DQS_GW_TE_OFFSET = 0x10,
+ DQS_GW_GOLD_COUNTER_32BIT = 0x20202020,
+ DQS_GW_PATTERN1 = 0xaa000000,
+ DQS_GW_PATTERN2 = 0x55000000
+};
+
+enum {
+ /* pattern0 and base address for test engine when we do calibration */
+ DEFAULT_TEST2_1_CAL = 0x55000000,
+ /* for testing, to separate TA4-3 address for running simultaneously */
+ /* pattern1 and offset address for test engine when we do calibraion */
+ DEFAULT_TEST2_2_CAL = 0xaa000400,
+ /* pattern0 and base addr. for test engine when doing dqs GW */
+ DEFAULT_TEST2_1_DQSIEN = 0x55000000,
+ /* pattern1 and offset addr. for test engine when doing dqs GW */
+ DEFAULT_TEST2_2_DQSIEN = 0xaa000010,
+ /* gold pattern */
+ DEFAULT_GOLD_DQSIEN = 0x20202020
+};
+
+enum {
+ TEST_ISI_PATTERN = 0,
+ TEST_AUDIO_PATTERN,
+ TEST_TA1_SIMPLE,
+ TEST_TESTPAT4,
+ TEST_TESTPAT4_3,
+ TEST_XTALK_PATTERN,
+ TEST_MIX_PATTERN
+};
+
+struct dqs_perbit_dly {
+ s8 first_dqdly_pass;
+ s8 last_dqdly_pass;
+ s8 first_dqsdly_pass;
+ s8 last_dqsdly_pass;
+ s8 best_first_dqdly_pass;
+ s8 best_last_dqdly_pass;
+ s8 best_first_dqsdly_pass;
+ s8 best_last_dqsdly_pass;
+ u8 best_dqdly;
+ u8 best_dqsdly;
+};
+
+void transfer_to_spm_control(void);
+void transfer_to_reg_control(void);
+void dramc_phy_reset(u32 channel);
+void clk_duty_cal(u32 channel);
+void div2_phase_sync(void);
+void dramc_runtime_config(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void dramc_rankinctl_config(u32 channel, const struct mt8173_sdram_params *sdram_params);
+
+/* dramc init prototypes */
+void mem_pll_init(const struct mt8173_sdram_params *sdram_params);
+void dramc_init(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void dramc_pre_init(u32 channel, const struct mt8173_sdram_params *sdram_params);
+
+/* mandatory calibration function prototypes */
+void tx_window_perbit_cal(u32 channel);
+void rx_window_perbit_cal(u32 channel);
+void perbit_window_cal(u32 channel, u8 type);
+void sw_impedance_cal(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void ca_training(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void rx_dqs_gating_cal(u32 channel, u8 rank, const struct mt8173_sdram_params *sdram_params);
+void dual_rank_rx_datlat_cal(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void dual_rank_rx_dqs_gating_cal(u32 channel, const struct mt8173_sdram_params *sdram_params);
+void write_leveling(u32 channel, const struct mt8173_sdram_params *sdram_params);
+
+u8 dramk_calcu_best_dly(u8 bit, struct dqs_perbit_dly *p, u8 *p_max_byte);
+u8 is_dual_rank(u32 channel, const struct mt8173_sdram_params *sdram_params);
+u8 rx_datlat_cal(u32 channel, u8 rank, const struct mt8173_sdram_params *sdram_params);
+u32 dram_k_perbit(u32 channel);
+u32 dramc_engine2(u32 channel, enum dram_tw_op wr, u32 test2_1, u32 test2_2,
+ u8 testaudpat, u8 log2loopcount);
+
+void dramk_check_dqs_win(struct dqs_perbit_dly *p, u8 dly_step, u8 last_step, u32 fail_bit);
+void dramk_check_dq_win(struct dqs_perbit_dly *p, u8 dly_step, u8 last_step, u32 fail_bit);
+
+void tx_delay_for_wrleveling(u32 channel, struct dqs_perbit_dly *dqdqs_perbit_dly,
+ u8 *ave_dqdly_byte, u8 *max_dqsdly_byte);
+
+#if CONFIG_DEBUG_DRAM
+#define dramc_dbg_msg(_x_...) printk(BIOS_DEBUG, _x_)
+#else
+#define dramc_dbg_msg(_x_...)
+#endif
+
+#endif /* _PI_API_H */
diff --git a/src/soc/mediatek/mt8173/include/soc/dramc_register.h b/src/soc/mediatek/mt8173/include/soc/dramc_register.h
new file mode 100644
index 0000000000..ce6517376f
--- /dev/null
+++ b/src/soc/mediatek/mt8173/include/soc/dramc_register.h
@@ -0,0 +1,522 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef _DRAMC_REGISTER_H_
+#define _DRAMC_REGISTER_H_
+
+#include <stddef.h>
+#include <types.h>
+
+#define DRIVING_DS2_0 7 /* DS[2:0] 7->6 */
+#define DEFAULT_DRIVING 0x99009900
+
+enum {
+ /* CONF2 = 0x008 */
+ CONF2_TEST1_EN = BIT(29),
+ CONF2_TEST2R_EN = BIT(30),
+ CONF2_TEST2W_EN = BIT(31),
+ /* PADCTL1 = 0x00c */
+ PADCTL1_CLK_SHIFT = 24,
+ PADCTL1_CS1_SHIFT = 28,
+ /* PADCTL2 = 0x010 */
+ MASK_PADCTL2_16BIT = 0x000000ff,
+ MASK_PADCTL2_32BIT = 0x0000ffff,
+ MASK_PADCTL2 = 0xffff0000,
+ PADCTL2_SHIFT = 0,
+ /* TEST2_3 = 0x044 */
+ TEST2_3_TESTCNT_SHIFT = 0,
+ TEST2_3_TESTCNT_MASK = (0xful << TEST2_3_TESTCNT_SHIFT),
+ TEST2_3_TESTAUDPAT_EN = BIT(7),
+ TEST2_3_ADVREFEN_EN = BIT(30),
+ /* TEST2_4 = 0x048 */
+ TEST2_4_TESTAUDINC_SHIFT = 0,
+ TEST2_4_TESTAUDINC_MASK = (0x1ful << TEST2_4_TESTAUDINC_SHIFT),
+ TEST2_4_TESTAUDINIT_SHIFT = 8,
+ TEST2_4_TESTAUDINIT_MASK = (0x1ful << TEST2_4_TESTAUDINIT_SHIFT),
+ TEST2_4_TESTAUDBITINV_EN = BIT(14),
+ TEST2_4_TESTAUDMODE_EN = BIT(15),
+ TEST2_4_TESTXTALKPAT_EN = BIT(16),
+ /* DDR2CTL = 0x07c */
+ DDR2CTL_WOEN_SHIFT = 3,
+ DDR2CTL_DATLAT_SHIFT = 4,
+ /* MISC = 0x80 */
+ MISC_LATNORMP_SHIFT = 0,
+ MISC_DATLAT_DSEL_SHIFT = 8,
+ /* MRS = 0x088 */
+ MASK_MR2_OP = 0x00800000,
+ /* R0 R1 DQSIEN = 0x094 */
+ DQSIEN_DQS0IEN_SHIFT = 0,
+ DQSIEN_DQS1IEN_SHIFT = 8,
+ DQSIEN_DQS2IEN_SHIFT = 16,
+ DQSIEN_DQS3IEN_SHIFT = 24,
+ /* MCKDLY = 0x0d8 */
+ MCKDLY_DQIENLAT_SHIFT = 4,
+ MCKDLY_DQIENQKEND_SHIFT = 10,
+ MCKDLY_FIXDQIEN_SHIFT = 12,
+ MCKDLY_FIXODT_SHIFT = 23,
+ /* DQSCTL1 = 0x0e0 */
+ DQSCTL1_DQSINCTL_SHIFT = 24,
+ DQSCTL1_DQSIENMODE_SHIFT = 28,
+ /* PADCTL4 = 0x0e4 */
+ PADCTL4_CKEFIXON_SHIFT = 2,
+ PADCTL4_DATLAT3_SHIFT = 4,
+ /* PHYCTL1 = 0x0f0 */
+ PHYCTL1_DATLAT4_SHIFT = 25,
+ PHYCTL1_PHYRST_SHIFT = 28,
+ /* GDDR3CTL1 = 0x0f4 */
+ GDDR3CTL1_BKSWAP_SHIFT = 20,
+ GDDR3CTL1_RDATRST_SHIFT = 25,
+ GDDR3CTL1_DQMSWAP_SHIFT = 31,
+ /* RKCFG = 0x110 */
+ MASK_RKCFG_RKSWAP_EN = 0x08,
+ RKCFG_PBREF_DISBYRATE_SHIFT = 6,
+ RKCFG_WDATKEY64_SHIFT = 29,
+ /* DQSCTL2 = 0x118 */
+ DQSCTL2_DQSINCTL_SHIFT = 0,
+ /* DQSGCTL = 0x124 */
+ DQSGCTL_DQSGDUALP_SHIFT = 30,
+ /* PHYCLKDUTY = 0x148 */
+ PHYCLKDUTY_CMDCLKP0DUTYN_SHIFT = 16,
+ PHYCLKDUTY_CMDCLKP0DUTYP_SHIFT = 18,
+ PHYCLKDUTY_CMDCLKP0DUTYSEL_SHIFT = 28,
+ /* CMDDLY0 = 0x1a8 */
+ CMDDLY0_RA0_SHIFT = 0,
+ CMDDLY0_RA1_SHIFT = 8,
+ CMDDLY0_RA2_SHIFT = 16,
+ CMDDLY0_RA3_SHIFT = 24,
+ /* CMDDLY1 = 0x1ac */
+ CMDDLY1_RA7_SHIFT = 24,
+ /* CMDDLY3 = 0x1b4 */
+ CMDDLY3_BA0_SHIFT = 8,
+ CMDDLY3_BA1_SHIFT = 16,
+ CMDDLY3_BA2_SHIFT = 24,
+ /* CMDDLY4 = 0x1b8 */
+ CMDDLY4_CS_SHIFT = 0,
+ CMDDLY4_CKE_SHIFT = 8,
+ CMDDLY4_RAS_SHIFT = 16,
+ CMDDLY4_CAS_SHIFT = 24,
+ /* CMDDLY5 = 0x1bc */
+ CMDDLY5_WE_SHIFT = 8,
+ CMDDLY5_RA13_SHIFT = 16,
+ /* DQSCAL0 = 0x1c0 */
+ DQSCAL0_RA14_SHIFT = 24,
+ DQSCAL0_STBCALEN_SHIFT = 31,
+ /* DQSCAL1 = 0x1c4 */
+ DQSCAL1_CKE1_SHIFT = 24,
+ /* IMPCAL = 0x1c8 */
+ IMP_CALI_EN_SHIFT = 0,
+ IMP_CALI_HW_SHIFT = 1,
+ IMP_CALI_ENN_SHIFT = 4,
+ IMP_CALI_ENP_SHIFT = 5,
+ IMP_CALI_PDN_SHIFT = 6,
+ IMP_CALI_PDP_SHIFT = 7,
+ IMP_CALI_DRVP_SHIFT = 8,
+ IMP_CALI_DRVN_SHIFT = 12,
+ /* JMETER for PLL2, PLL3, PLL4 */
+ JMETER_EN_BIT= BIT(0),
+ JMETER_COUNTER_SHIFT = 16,
+ JMETER_COUNTER_MASK = (0xffff << JMETER_COUNTER_SHIFT),
+ /* SPCMD = 0x1e4 */
+ SPCMD_MRWEN_SHIFT = 0,
+ SPCMD_DQSGCNTEN_SHIFT = 8,
+ SPCMD_DQSGCNTRST_SHIFT = 9,
+ /* JMETER for PLL2/3/4 ST */
+ JMETER_PLL_ZERO_SHIFT = 0,
+ JMETER_PLL_ONE_SHIFT = 16,
+ /* TESTRPT = 0x3fc */
+ TESTRPT_DM_CMP_CPT_SHIFT = 10,
+ TESTRPT_DM_CMP_ERR_SHIFT = 14,
+ /* SELPH2 = 0x404 */
+ SELPH2_TXDLY_DQSGATE_SHIFT = 12,
+ SELPH2_TXDLY_DQSGATE_P1_SHIFT = 20,
+ /* SELPH5 = 0x410 */
+ SELPH5_DLY_DQSGATE_SHIFT = 22,
+ SELPH5_DLY_DQSGATE_P1_SHIFT = 24,
+ /* SELPH6_1 = 0x418 */
+ SELPH6_1_DLY_R1DQSGATE_SHIFT = 0,
+ SELPH6_1_DLY_R1DQSGATE_P1_SHIFT = 2,
+ SELPH6_1_TXDLY_R1DQSGATE_SHIFT = 4,
+ SELPH6_1_TXDLY_R1DQSGATE_P1_SHIFT = 8,
+ /* MEMPLL_S14 = 0x638 */
+ MASK_MEMPLL_DL = 0xc0ffffff,
+ MEMPLL_FB_DL_SHIFT = 0,
+ MEMPLL_REF_DL_SHIFT = 8,
+ MEMPLL_DL_SHIFT = 24,
+ MEMPLL_MODE_SHIFT = 29,
+ /* MEMPLL_DIVIDER = 0x640 */
+ MEMCLKENB_SHIFT = 5
+};
+
+struct dramc_ao_regs {
+ uint32_t actim0; /* 0x0 */
+ uint32_t conf1; /* 0x4 */
+ uint32_t conf2; /* 0x8 */
+ uint32_t rsvd_ao1[3]; /* 0xc */
+ uint32_t r0deldly; /* 0x18 */
+ uint32_t r1deldly; /* 0x1c */
+ uint32_t r0difdly; /* 0x20 */
+ uint32_t r1difdly; /* 0x24 */
+ uint32_t dllconf; /* 0x28 */
+ uint32_t rsvd_ao2[6]; /* 0x2c */
+ uint32_t test2_3; /* 0x44 */
+ uint32_t test2_4; /* 0x48 */
+ uint32_t catraining; /* 0x4c */
+ uint32_t catraining2; /* 0x50 */
+ uint32_t wodt; /* 0x54 */
+ uint32_t rsvd_ao3[9]; /* 0x58 */
+ uint32_t ddr2ctl; /* 0x7c */
+ uint32_t misc; /* 0x80 */
+ uint32_t zqcs; /* 0x84 */
+ uint32_t mrs; /* 0x88 */
+ uint32_t clk1delay; /* 0x8c */
+ uint32_t rsvd_ao4[1]; /* 0x90 */
+ uint32_t dqsien[2]; /* 0x94 */
+ uint32_t rsvd_ao5[2]; /* 0x9c */
+ uint32_t iodrv1; /* 0xa4 */
+ uint32_t iodrv2; /* 0xa8 */
+ uint32_t iodrv3; /* 0xac */
+ uint32_t iodrv4; /* 0xb0 */
+ uint32_t iodrv5; /* 0xb4 */
+ uint32_t iodrv6; /* 0xb8 */
+ uint32_t drvctl1; /* 0xbc */
+ uint32_t dllsel; /* 0xc0 */
+ uint32_t rsvd_ao7[5]; /* 0xc4 */
+ uint32_t mckdly; /* 0xd8 */
+ uint32_t rsvd_ao8[1]; /* 0xdc */
+ uint32_t dqsctl1; /* 0xe0 */
+ uint32_t padctl4; /* 0xe4 */
+ uint32_t rsvd_ao9[2]; /* 0xe8 */
+ uint32_t phyctl1; /* 0xf0 */
+ uint32_t gddr3ctl1; /* 0xf4 */
+ uint32_t padctl7; /* 0xf8 */
+ uint32_t misctl0; /* 0xfc */
+ uint32_t ocdk; /* 0x100 */
+ uint32_t rsvd_ao10[3]; /* 0x104 */
+ uint32_t rkcfg; /* 0x110 */
+ uint32_t ckphdet; /* 0x114 */
+ uint32_t dqsctl2; /* 0x118 */
+ uint32_t rsvd_ao11[5]; /* 0x11c */
+ uint32_t clkctl; /* 0x130 */
+ uint32_t rsvd_ao12[1]; /* 0x134 */
+ uint32_t dummy; /* 0x138 */
+ uint32_t write_leveling; /* 0x13c */
+ uint32_t rsvd_ao13[10]; /* 0x140 */
+ uint32_t arbctl0; /* 0x168 */
+ uint32_t rsvd_ao14[21]; /* 0x16c */
+ uint32_t dqscal0; /* 0x1c0 */
+ uint32_t dqscal1; /* 0x1c4 */
+ uint32_t impcal; /* 0x1c8 */
+ uint32_t rsvd_ao15[4]; /* 0x1cc */
+ uint32_t dramc_pd_ctrl; /* 0x1dc */
+ uint32_t lpddr2_3; /* 0x1e0 */
+ uint32_t spcmd; /* 0x1e4 */
+ uint32_t actim1; /* 0x1e8 */
+ uint32_t perfctl0; /* 0x1ec */
+ uint32_t ac_derating; /* 0x1f0 */
+ uint32_t rrrate_ctl; /* 0x1f4 */
+ uint32_t ac_time_05t; /* 0x1f8 */
+ uint32_t mrr_ctl; /* 0x1fc */
+ uint32_t rsvd_ao16[4]; /* 0x200 */
+ uint32_t dqidly[9]; /* 0x210 */
+ uint32_t rsvd_ao17[115]; /* 0x234 */
+ uint32_t selph1; /* 0x400 */
+ uint32_t selph2; /* 0x404 */
+ uint32_t selph3; /* 0x408 */
+ uint32_t selph4; /* 0x40c */
+ uint32_t selph5; /* 0x410 */
+ uint32_t selph6; /* 0x414 */
+ uint32_t selph6_1; /* 0x418 */
+ uint32_t selph7; /* 0x41c */
+ uint32_t selph8; /* 0x420 */
+ uint32_t selph9; /* 0x424 */
+ uint32_t selph10; /* 0x428 */
+ uint32_t selph11; /* 0x42c */
+};
+
+check_member(dramc_ao_regs, selph11, 0x42c);
+
+struct dramc_nao_regs {
+ uint32_t rsvd_nao1[11]; /* 0x0 */
+ uint32_t test_mode; /* 0x2c */
+ uint32_t rsvd_nao2[3]; /* 0x30 */
+ uint32_t test2_1; /* 0x3c */
+ uint32_t test2_2; /* 0x40 */
+ uint32_t rsvd_nao3[48]; /* 0x44 */
+ uint32_t lbwdat0; /* 0x104 */
+ uint32_t lbwdat1; /* 0x108 */
+ uint32_t lbwdat2; /* 0x10c */
+ uint32_t rsvd_nao4[1]; /* 0x110 */
+ uint32_t ckphdet; /* 0x114 */
+ uint32_t rsvd_nao5[48]; /* 0x118 */
+ uint32_t dmmonitor; /* 0x1d8 */
+ uint32_t rsvd_nao6[41]; /* 0x1dc */
+ uint32_t r2r_page_hit_counter; /* 0x280 */
+ uint32_t r2r_page_miss_counter; /* 0x284 */
+ uint32_t r2r_interbank_counter; /* 0x288 */
+ uint32_t r2w_page_hit_counter; /* 0x28c */
+ uint32_t r2w_page_miss_counter; /* 0x290 */
+ uint32_t r2w_interbank_counter; /* 0x294 */
+ uint32_t w2r_page_hit_counter; /* 0x298 */
+ uint32_t w2r_page_miss_counter; /* 0x29c */
+ uint32_t w2r_page_interbank_counter; /* 0x2a0 */
+ uint32_t w2w_page_hit_counter; /* 0x2a4 */
+ uint32_t w2w_page_miss_counter; /* 0x2a8 */
+ uint32_t w2w_page_interbank_counter; /* 0x2ac */
+ uint32_t dramc_idle_counter; /* 0x2b0 */
+ uint32_t freerun_26m_counter; /* 0x2b4 */
+ uint32_t refresh_pop_counter; /* 0x2b8 */
+ uint32_t jmeter_st; /* 0x2bc */
+ uint32_t dq_cal_max[8]; /* 0x2c0 */
+ uint32_t dqs_cal_min[8]; /* 0x2e0 */
+ uint32_t dqs_cal_max[8]; /* 0x300 */
+ uint32_t rsvd_nao7[4]; /* 0x320 */
+ uint32_t read_bytes_counter; /* 0x330 */
+ uint32_t write_bytes_counter; /* 0x334 */
+ uint32_t rsvd_nao8[6]; /* 0x338 */
+ uint32_t dqical[4]; /* 0x350 */
+ uint32_t rsvd_nao9[4]; /* 0x360 */
+ uint32_t cmp_err; /* 0x370 */
+ uint32_t r0dqsiendly; /* 0x374 */
+ uint32_t r1dqsiendly; /* 0x378 */
+ uint32_t rsvd_nao10[9]; /* 0x37c */
+ uint32_t dqsdly0; /* 0x3a0 */
+ uint32_t rsvd_nao11[4]; /* 0x3a4 */
+ uint32_t mrrdata; /* 0x3b4 */
+ uint32_t spcmdresp; /* 0x3b8 */
+ uint32_t iorgcnt; /* 0x3bc */
+ uint32_t dqsgnwcnt[6]; /* 0x3c0 */
+ uint32_t rsvd_nao12[4]; /* 0x3d8 */
+ uint32_t ckphcnt; /* 0x3e8 */
+ uint32_t rsvd_nao13[4]; /* 0x3ec */
+ uint32_t testrpt; /* 0x3fc */
+};
+
+check_member(dramc_nao_regs, testrpt, 0x3fc);
+
+struct dramc_ddrphy_regs {
+ uint32_t rsvd_phy1[3]; /* 0x0 */
+ uint32_t padctl1; /* 0xc */
+ uint32_t padctl2; /* 0x10 */
+ uint32_t padctl3; /* 0x14 */
+ uint32_t rsvd_phy2[25]; /* 0x18 */
+ uint32_t ddr2ctl; /* 0x7c */
+ uint32_t rsvd_phy3[3]; /* 0x80 */
+ uint32_t clk1delay; /* 0x8c */
+ uint32_t ioctl; /* 0x90 */
+ uint32_t rsvd_phy4[7]; /* 0x94 */
+ uint32_t iodrv4; /* 0xb0 */
+ uint32_t iodrv5; /* 0xb4 */
+ uint32_t iodrv6; /* 0xb8 */
+ uint32_t drvctl1; /* 0xbc */
+ uint32_t dllsel; /* 0xc0 */
+ uint32_t rsvd_phy5[2]; /* 0xc4 */
+ uint32_t tdsel[3]; /* 0xcc */
+ uint32_t mckdly; /* 0xd8 */
+ uint32_t dqsctl0; /* 0xdc */
+ uint32_t dqsctl1; /* 0xe0 */
+ uint32_t dqsctl4; /* 0xe4 */
+ uint32_t dqsctl5; /* 0xe8 */
+ uint32_t dqsctl6; /* 0xec */
+ uint32_t phyctl1; /* 0xf0 */
+ uint32_t gddr3ctl1; /* 0xf4 */
+ uint32_t rsvd_phy6[1]; /* 0xf8 */
+ uint32_t misctl0; /* 0xfc */
+ uint32_t ocdk; /* 0x100 */
+ uint32_t rsvd_phy7[8]; /* 0x104 */
+ uint32_t dqsgctl; /* 0x124 */
+ uint32_t rsvd_phy8[6]; /* 0x128 */
+ uint32_t ddrphydqsgctl; /* 0x140 */
+ uint32_t dqsgct2; /* 0x144 */
+ uint32_t phyclkduty; /* 0x148 */
+ uint32_t rsvd_phy9[3]; /* 0x14c */
+ uint32_t dqsisel; /* 0x158 */
+ uint32_t dqmdqs_sel; /* 0x15c */
+ uint32_t rsvd_phy10[10]; /* 0x160 */
+ uint32_t jmeterpop1; /* 0x188 */
+ uint32_t jmeterpop2; /* 0x18c */
+ uint32_t jmeterpop3; /* 0x190 */
+ uint32_t jmeterpop4; /* 0x194 */
+ uint32_t rsvd_phy11[4]; /* 0x198 */
+ uint32_t cmddly[6]; /* 0x1a8 */
+ uint32_t dqscal0; /* 0x1c0 */
+ uint32_t rsvd_phy12[2]; /* 0x1c4 */
+ uint32_t jmeter[3]; /* 0x1cc */
+ uint32_t rsvd_phy13[2]; /* 0x1d8 */
+ uint32_t lpddr2_3; /* 0x1e0 */
+ uint32_t spcmd; /* 0x1e4 */
+ uint32_t rsvd_phy14[6]; /* 0x1e8 */
+ uint32_t dqodly[4]; /* 0x200 */
+ uint32_t rsvd_phy15[11]; /* 0x210 */
+ uint32_t lpddr2_4; /* 0x23c */
+ uint32_t rsvd_phy16[56]; /* 0x240 */
+ uint32_t jmeter_pll_st[3]; /* 0x320 */
+ uint32_t jmeter_done_st; /* 0x32c */
+ uint32_t rsvd_phy17[2]; /* 0x330 */
+ uint32_t jmeter_pll1_st; /* 0x338 */
+ uint32_t jmeter_pop_pll2_st; /* 0x33c */
+ uint32_t jmeter_pop_pll3_st; /* 0x340 */
+ uint32_t jmeter_pop_pll4_st; /* 0x344 */
+ uint32_t jmeter_pop_pll1_st; /* 0x348 */
+ uint32_t rsvd_phy18[13]; /* 0x34c */
+ uint32_t dq_o1; /* 0x380 */
+ uint32_t rsvd_phy19[2]; /* 0x384 */
+ uint32_t stben[4]; /* 0x38c */
+ uint32_t rsvd_phy20[16]; /* 0x39c */
+ uint32_t dllcnt0; /* 0x3dc */
+ uint32_t pllautok; /* 0x3e0 */
+ uint32_t poppllautok; /* 0x3e4 */
+ uint32_t rsvd_phy21[18]; /* 0x3e8 */
+ uint32_t selph12; /* 0x430 */
+ uint32_t selph13; /* 0x434 */
+ uint32_t selph14; /* 0x438 */
+ uint32_t selph15; /* 0x43c */
+ uint32_t selph16; /* 0x440 */
+ uint32_t selph17; /* 0x444 */
+ uint32_t selph18; /* 0x448 */
+ uint32_t selph19; /* 0x44c */
+ uint32_t selph20; /* 0x450 */
+ uint32_t rsvd_phy22[91]; /* 0x454 */
+ uint32_t peri[4]; /* 0x5c0 */
+ uint32_t rsvd_phy23[12]; /* 0x5d0 */
+ uint32_t mempll[15]; /* 0x600 */
+ uint32_t ddrphy_cg_ctrl; /* 0x63c */
+ uint32_t mempll_divider; /* 0x640 */
+ uint32_t vrefctl0; /* 0x644 */
+ uint32_t rsvd_phy24[18]; /* 0x648 */
+ uint32_t mempll05_divider; /* 0x690 */
+};
+
+check_member(dramc_ddrphy_regs, mempll05_divider, 0x690);
+
+struct emi_regs {
+ uint32_t emi_cona; /* 0x0 */
+ uint32_t rsvd_emi1; /* 0x4 */
+ uint32_t emi_conb; /* 0x08 */
+ uint32_t rsvd_emi2; /* 0x0c */
+ uint32_t emi_conc; /* 0x10 */
+ uint32_t rsvd_emi3; /* 0x14 */
+ uint32_t emi_cond; /* 0x18 */
+ uint32_t rsvd_emi4; /* 0x1c */
+ uint32_t emi_cone; /* 0x20 */
+ uint32_t rsvd_emi5; /* 0x24 */
+ uint32_t emi_conf; /* 0x28 */
+ uint32_t rsvd_emi6; /* 0x2c */
+ uint32_t emi_cong; /* 0x30 */
+ uint32_t rsvd_emi7; /* 0x34 */
+ uint32_t emi_conh; /* 0x38 */
+ uint32_t rsvd_emi8[9]; /* 0x3c */
+ uint32_t emi_conm; /* 0x60 */
+ uint32_t rsvd_emi9[5]; /* 0x64 */
+ uint32_t emi_mdct; /* 0x78 */
+ uint32_t rsvd_emi10[21]; /* 0x7c */
+ uint32_t emi_test0; /* 0xd0 */
+ uint32_t rsvd_emi11; /* 0xd4 */
+ uint32_t emi_test1; /* 0xd8 */
+ uint32_t rsvd_emi12; /* 0xdc */
+ uint32_t emi_testa; /* 0xe0 */
+ uint32_t rsvd_emi13; /* 0xe4 */
+ uint32_t emi_testb; /* 0xe8 */
+ uint32_t rsvd_emi14; /* 0xec */
+ uint32_t emi_testc; /* 0xf0 */
+ uint32_t rsvd_emi15; /* 0xf4 */
+ uint32_t emi_testd; /* 0xf8 */
+ uint32_t rsvd_emi16; /* 0xfc */
+ uint32_t emi_arba; /* 0x100 */
+ uint32_t rsvd_emi17[3]; /* 0x104 */
+ uint32_t emi_arbc; /* 0x110 */
+ uint32_t rsvd_emi18; /* 0x114 */
+ uint32_t emi_arbd; /* 0x118 */
+ uint32_t rsvd_emi19; /* 0x11c */
+ uint32_t emi_arbe; /* 0x120 */
+ uint32_t rsvd_emi20; /* 0x124 */
+ uint32_t emi_arbf; /* 0x128 */
+ uint32_t rsvd_emi21; /* 0x12c */
+ uint32_t emi_arbg; /* 0x130 */
+ uint32_t rsvd_emi22; /* 0x134 */
+ uint32_t emi_arbh; /* 0x138 */
+ uint32_t rsvd_emi23; /* 0x13c */
+ uint32_t emi_arbi; /* 0x140 */
+ uint32_t emi_arbi_2nd; /* 0x144 */
+ uint32_t emi_arbj; /* 0x148 */
+ uint32_t emi_arbj_2nd; /* 0x14c */
+ uint32_t emi_arbk; /* 0x150 */
+ uint32_t emi_arbk_2nd; /* 0x154 */
+ uint32_t emi_slct; /* 0x158 */
+ uint32_t rsvd_emi24; /* 0x15C */
+ uint32_t emi_mpua; /* 0x160 */
+ uint32_t rsvd_emi25; /* 0x164 */
+ uint32_t emi_mpub; /* 0x168 */
+ uint32_t rsvd_emi26; /* 0x16c */
+ uint32_t emi_mpuc; /* 0x170 */
+ uint32_t rsvd_emi27; /* 0x174 */
+ uint32_t emi_mpud; /* 0x178 */
+ uint32_t rsvd_emi28; /* 0x17C */
+ uint32_t emi_mpue; /* 0x180 */
+ uint32_t rsvd_emi29; /* 0x184 */
+ uint32_t emi_mpuf; /* 0x188 */
+ uint32_t rsvd_emi30; /* 0x18C */
+ uint32_t emi_mpug; /* 0x190 */
+ uint32_t rsvd_emi31; /* 0x194 */
+ uint32_t emi_mpuh; /* 0x198 */
+ uint32_t rsvd_emi32; /* 0x19C */
+ uint32_t emi_mpui; /* 0x1A0 */
+ uint32_t rsvd_emi33; /* 0x1A4 */
+ uint32_t emi_mpuj; /* 0x1A8 */
+ uint32_t rsvd_emi34; /* 0x1AC */
+ uint32_t emi_mpuk; /* 0x1B0 */
+ uint32_t rsvd_emi35; /* 0x1B4 */
+ uint32_t emi_mpul; /* 0x1B8 */
+ uint32_t rsvd_emi36; /* 0x1BC */
+ uint32_t emi_mpum; /* 0x1C0 */
+ uint32_t rsvd_emi37; /* 0x1C4 */
+ uint32_t emi_mpun; /* 0x1C8 */
+ uint32_t rsvd_emi38; /* 0x1CC */
+ uint32_t emi_mpuo; /* 0x1D0 */
+ uint32_t rsvd_emi39; /* 0x1D4 */
+ uint32_t emi_mpup; /* 0x1D8 */
+ uint32_t rsvd_emi40; /* 0x1DC */
+ uint32_t emi_mpuq; /* 0x1E0 */
+ uint32_t rsvd_emi41; /* 0x1E4 */
+ uint32_t emi_mpur; /* 0x1E8 */
+ uint32_t rsvd_emi42; /* 0x1EC */
+ uint32_t emi_mpus; /* 0x1F0 */
+ uint32_t rsvd_emi43; /* 0x1F4 */
+ uint32_t emi_mput; /* 0x1F8 */
+ uint32_t rsvd_emi44; /* 0x1FC */
+ uint32_t emi_mpuu; /* 0x200 */
+ uint32_t rsvd_emi45[7]; /* 0x204 */
+ uint32_t emi_mpuy; /* 0x220 */
+ uint32_t rsvd_emi46[119]; /* 0x224 */
+ uint32_t emi_bmen; /* 0x400 */
+};
+
+check_member(emi_regs, emi_bmen, 0x400);
+
+extern struct dramc_ao_regs *ao_regs;
+extern struct dramc_nao_regs *nao_regs;
+extern struct dramc_ddrphy_regs *ddrphy_regs;
+
+struct dramc_channel {
+ struct dramc_ao_regs *ao_regs;
+ struct dramc_nao_regs *nao_regs;
+ struct dramc_ddrphy_regs *ddrphy_regs;
+};
+
+static struct dramc_channel const ch[2] = {
+ {(void *)CHA_DRAMCAO_BASE, (void *)CHA_DRAMCNAO_BASE, (void *)CHA_DDRPHY_BASE},
+ {(void *)CHB_DRAMCAO_BASE, (void *)CHB_DRAMCNAO_BASE, (void *)CHB_DDRPHY_BASE}
+};
+
+#endif /* _DRAMC_REGISTER_H_ */
diff --git a/src/soc/mediatek/mt8173/include/soc/emi.h b/src/soc/mediatek/mt8173/include/soc/emi.h
new file mode 100644
index 0000000000..d3a2aeec9c
--- /dev/null
+++ b/src/soc/mediatek/mt8173/include/soc/emi.h
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef SOC_MEDIATEK_MT8173_EMI_H
+#define SOC_MEDIATEK_MT8173_EMI_H
+
+#include <soc/dramc_common.h>
+#include <stdint.h>
+
+/* DDR type */
+enum ram_type {
+ TYPE_INVALID,
+ TYPE_DDR1,
+ TYPE_LPDDR2,
+ TYPE_LPDDR3,
+ TYPE_PCDDR3
+};
+
+enum {
+ /*
+ * Vmem voltage adjustment:
+ * 1) HV: high voltage
+ * 2) NV: normal voltage
+ * 3) LV: low voltage
+ */
+ Vmem_HV_LPDDR3 = 0x50, /* 1.300V */
+ Vmem_NV_LPDDR3 = 0x44, /* 1.225V */
+ Vmem_LV_LPDDR3 = 0x36 /* 1.138V */
+};
+
+enum {
+ /*
+ * Vcore voltage adjustment:
+ * 1) HHV: extra high voltage
+ * 2) HV: high voltage
+ * 3) NV: normal voltage
+ * 4) LV: low voltage
+ * 5) LLV: extra low voltage
+ */
+ Vcore_HHV_LPPDR3 = 0x60, /* 1.300V */
+ Vcore_HV_LPPDR3 = 0x48, /* 1.150V */
+ Vcore_NV_LPPDR3 = 0x44, /* 1.125V */
+ Vcore_LV_LPPDR3 = 0x34, /* 1.025V */
+ Vcore_LLV_LPPDR3 = 0x25 /* 0.931V */
+};
+
+struct mt8173_calib_params {
+ u8 impedance_drvp;
+ u8 impedance_drvn;
+ u8 datlat_ucfirst;
+ s8 ca_train[CHANNEL_NUM][CATRAINING_NUM];
+ s8 ca_train_center[CHANNEL_NUM];
+ s8 wr_level[CHANNEL_NUM][DQS_NUMBER];
+ u8 gating_win[CHANNEL_NUM][DUAL_RANKS][GW_PARAM_NUM];
+ u32 rx_dqs_dly[CHANNEL_NUM];
+ u32 rx_dq_dly[CHANNEL_NUM][DQS_BIT_NUMBER];
+};
+
+struct mt8173_timing_params {
+ u32 actim;
+ u32 actim1;
+ u32 actim05t;
+ u32 conf1;
+ u32 conf2;
+ u32 ddr2ctl;
+ u32 gddr3ctl1;
+ u32 misctl0;
+ u32 pd_ctrl;
+ u32 rkcfg;
+ u32 test2_4;
+ u32 test2_3;
+};
+
+struct mt8173_emi_params {
+ u32 cona;
+ u32 conb;
+ u32 conc;
+ u32 cond;
+ u32 cone;
+ u32 conf;
+ u32 cong;
+ u32 conh;
+ u32 conm_1;
+ u32 conm_2;
+ u32 mdct_1;
+ u32 mdct_2;
+ u32 test0;
+ u32 test1;
+ u32 testb;
+ u32 testc;
+ u32 testd;
+ u32 arba;
+ u32 arbc;
+ u32 arbd;
+ u32 arbe;
+ u32 arbf;
+ u32 arbg;
+ u32 arbi;
+ u32 arbj;
+ u32 arbk;
+ u32 slct_1;
+ u32 slct_2;
+ u32 bmen;
+};
+
+struct mt8173_mrs_params {
+ u32 mrs_1;
+ u32 mrs_2;
+ u32 mrs_3;
+ u32 mrs_10;
+ u32 mrs_11;
+ u32 mrs_63;
+};
+
+struct mt8173_sdram_params {
+ struct mt8173_calib_params calib_params;
+ struct mt8173_timing_params ac_timing;
+ struct mt8173_emi_params emi_set;
+ struct mt8173_mrs_params mrs_set;
+ enum ram_type type;
+ unsigned int dram_freq;
+};
+
+void mt_set_emi(const struct mt8173_sdram_params *sdram_params);
+void mt_mem_init(const struct mt8173_sdram_params *sdram_params);
+const struct mt8173_sdram_params *get_sdram_config(void);
+
+#endif
diff --git a/src/soc/mediatek/mt8173/include/soc/pll.h b/src/soc/mediatek/mt8173/include/soc/pll.h
index 1eab709462..6d38bb3447 100644
--- a/src/soc/mediatek/mt8173/include/soc/pll.h
+++ b/src/soc/mediatek/mt8173/include/soc/pll.h
@@ -16,6 +16,7 @@
#ifndef SOC_MEDIATEK_MT8173_PLL_H
#define SOC_MEDIATEK_MT8173_PLL_H
+#include <soc/emi.h>
#include <soc/addressmap.h>
struct mt8173_topckgen_regs {
@@ -285,5 +286,9 @@ void mt_pll_post_init(void);
void mt_pll_init(void);
void mt_pll_set_aud_div(u32 rate);
void mt_pll_enable_ssusb_clk(void);
+void mt_mem_pll_set_clk_cfg(void);
+void mt_mem_pll_config_pre(const struct mt8173_sdram_params *sdram_params);
+void mt_mem_pll_config_post(void);
+void mt_mem_pll_mux(void);
#endif /* SOC_MEDIATEK_MT8173_PLL_H */