| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * MediaTek DDR3 driver for MT7629 SoC |
| * |
| * Copyright (C) 2018 MediaTek Inc. |
| * Author: Wu Zou <wu.zou@mediatek.com> |
| * Ryder Lee <ryder.lee@mediatek.com> |
| */ |
| |
| #include <clk.h> |
| #include <common.h> |
| #include <dm.h> |
| #include <ram.h> |
| #include <asm/io.h> |
| #include <linux/bitops.h> |
| #include <linux/delay.h> |
| |
| /* EMI */ |
| #define EMI_CONA 0x000 |
| #define EMI_CONF 0x028 |
| #define EMI_CONM 0x060 |
| |
| /* DDR PHY */ |
| #define DDRPHY_PLL1 0x0000 |
| #define DDRPHY_PLL2 0x0004 |
| #define DDRPHY_PLL3 0x0008 |
| #define DDRPHY_PLL4 0x000c |
| #define DDRPHY_PLL5 0x0010 |
| #define DDRPHY_PLL7 0x0018 |
| #define DDRPHY_B0_DLL_ARPI0 0x0080 |
| #define DDRPHY_B0_DLL_ARPI1 0x0084 |
| #define DDRPHY_B0_DLL_ARPI2 0x0088 |
| #define DDRPHY_B0_DLL_ARPI3 0x008c |
| #define DDRPHY_B0_DLL_ARPI4 0x0090 |
| #define DDRPHY_B0_DLL_ARPI5 0x0094 |
| #define DDRPHY_B0_DQ2 0x00a0 |
| #define DDRPHY_B0_DQ3 0x00a4 |
| #define DDRPHY_B0_DQ4 0x00a8 |
| #define DDRPHY_B0_DQ5 0x00ac |
| #define DDRPHY_B0_DQ6 0x00b0 |
| #define DDRPHY_B0_DQ7 0x00b4 |
| #define DDRPHY_B0_DQ8 0x00b8 |
| #define DDRPHY_B1_DLL_ARPI0 0x0100 |
| #define DDRPHY_B1_DLL_ARPI1 0x0104 |
| #define DDRPHY_B1_DLL_ARPI2 0x0108 |
| #define DDRPHY_B1_DLL_ARPI3 0x010c |
| #define DDRPHY_B1_DLL_ARPI4 0x0110 |
| #define DDRPHY_B1_DLL_ARPI5 0x0114 |
| #define DDRPHY_B1_DQ2 0x0120 |
| #define DDRPHY_B1_DQ3 0x0124 |
| #define DDRPHY_B1_DQ4 0x0128 |
| #define DDRPHY_B1_DQ5 0x012c |
| #define DDRPHY_B1_DQ6 0x0130 |
| #define DDRPHY_B1_DQ7 0x0134 |
| #define DDRPHY_B1_DQ8 0x0138 |
| #define DDRPHY_CA_DLL_ARPI0 0x0180 |
| #define DDRPHY_CA_DLL_ARPI1 0x0184 |
| #define DDRPHY_CA_DLL_ARPI2 0x0188 |
| #define DDRPHY_CA_DLL_ARPI3 0x018c |
| #define DDRPHY_CA_DLL_ARPI4 0x0190 |
| #define DDRPHY_CA_DLL_ARPI5 0x0194 |
| #define DDRPHY_CA_CMD2 0x01a0 |
| #define DDRPHY_CA_CMD3 0x01a4 |
| #define DDRPHY_CA_CMD5 0x01ac |
| #define DDRPHY_CA_CMD6 0x01b0 |
| #define DDRPHY_CA_CMD7 0x01b4 |
| #define DDRPHY_CA_CMD8 0x01b8 |
| #define DDRPHY_MISC_VREF_CTRL 0x0264 |
| #define DDRPHY_MISC_IMP_CTRL0 0x0268 |
| #define DDRPHY_MISC_IMP_CTRL1 0x026c |
| #define DDRPHY_MISC_SHU_OPT 0x0270 |
| #define DDRPHY_MISC_SPM_CTRL0 0x0274 |
| #define DDRPHY_MISC_SPM_CTRL1 0x0278 |
| #define DDRPHY_MISC_SPM_CTRL2 0x027c |
| #define DDRPHY_MISC_CG_CTRL0 0x0284 |
| #define DDRPHY_MISC_CG_CTRL1 0x0288 |
| #define DDRPHY_MISC_CG_CTRL2 0x028c |
| #define DDRPHY_MISC_CG_CTRL4 0x0294 |
| #define DDRPHY_MISC_CTRL0 0x029c |
| #define DDRPHY_MISC_CTRL1 0x02a0 |
| #define DDRPHY_MISC_CTRL3 0x02a8 |
| #define DDRPHY_MISC_RXDVS1 0x05e4 |
| #define DDRPHY_SHU1_B0_DQ4 0x0c10 |
| #define DDRPHY_SHU1_B0_DQ5 0x0c14 |
| #define DDRPHY_SHU1_B0_DQ6 0x0c18 |
| #define DDRPHY_SHU1_B0_DQ7 0x0c1c |
| #define DDRPHY_SHU1_B1_DQ4 0x0c90 |
| #define DDRPHY_SHU1_B1_DQ5 0x0c94 |
| #define DDRPHY_SHU1_B1_DQ6 0x0c98 |
| #define DDRPHY_SHU1_B1_DQ7 0x0c9c |
| #define DDRPHY_SHU1_CA_CMD2 0x0d08 |
| #define DDRPHY_SHU1_CA_CMD4 0x0d10 |
| #define DDRPHY_SHU1_CA_CMD5 0x0d14 |
| #define DDRPHY_SHU1_CA_CMD6 0x0d18 |
| #define DDRPHY_SHU1_CA_CMD7 0x0d1c |
| #define DDRPHY_SHU1_PLL0 0x0d80 |
| #define DDRPHY_SHU1_PLL1 0x0d84 |
| #define DDRPHY_SHU1_PLL4 0x0d90 |
| #define DDRPHY_SHU1_PLL5 0x0d94 |
| #define DDRPHY_SHU1_PLL6 0x0d98 |
| #define DDRPHY_SHU1_PLL7 0x0d9C |
| #define DDRPHY_SHU1_PLL8 0x0da0 |
| #define DDRPHY_SHU1_PLL9 0x0da4 |
| #define DDRPHY_SHU1_PLL10 0x0da8 |
| #define DDRPHY_SHU1_PLL11 0x0dac |
| #define DDRPHY_SHU1_R0_B0_DQ2 0x0e08 |
| #define DDRPHY_SHU1_R0_B0_DQ3 0x0e0c |
| #define DDRPHY_SHU1_R0_B0_DQ4 0x0e10 |
| #define DDRPHY_SHU1_R0_B0_DQ5 0x0e14 |
| #define DDRPHY_SHU1_R0_B0_DQ6 0x0e18 |
| #define DDRPHY_SHU1_R0_B0_DQ7 0x0e1c |
| #define DDRPHY_SHU1_R0_B1_DQ2 0x0e58 |
| #define DDRPHY_SHU1_R0_B1_DQ3 0x0e5c |
| #define DDRPHY_SHU1_R0_B1_DQ4 0x0e60 |
| #define DDRPHY_SHU1_R0_B1_DQ5 0x0e64 |
| #define DDRPHY_SHU1_R0_B1_DQ6 0x0e68 |
| #define DDRPHY_SHU1_R0_B1_DQ7 0x0e6c |
| #define DDRPHY_SHU1_R0_CA_CMD9 0x0ec4 |
| #define DDRPHY_SHU1_R1_B0_DQ2 0x0f08 |
| #define DDRPHY_SHU1_R1_B0_DQ3 0x0f0c |
| #define DDRPHY_SHU1_R1_B0_DQ4 0x0f10 |
| #define DDRPHY_SHU1_R1_B0_DQ5 0x0f14 |
| #define DDRPHY_SHU1_R1_B0_DQ6 0x0f18 |
| #define DDRPHY_SHU1_R1_B0_DQ7 0x0f1c |
| #define DDRPHY_SHU1_R1_B1_DQ2 0x0f58 |
| #define DDRPHY_SHU1_R1_B1_DQ3 0x0f5c |
| #define DDRPHY_SHU1_R1_B1_DQ4 0x0f60 |
| #define DDRPHY_SHU1_R1_B1_DQ5 0x0f64 |
| #define DDRPHY_SHU1_R1_B1_DQ6 0x0f68 |
| #define DDRPHY_SHU1_R1_B1_DQ7 0x0f6c |
| #define DDRPHY_SHU1_R1_CA_CMD9 0x0fc4 |
| |
| /* DRAMC */ |
| #define DRAMC_DDRCONF0 0x0000 |
| #define DRAMC_DRAMCTRL 0x0004 |
| #define DRAMC_MISCTL0 0x0008 |
| #define DRAMC_PERFCTL0 0x000c |
| #define DRAMC_ARBCTL 0x0010 |
| #define DRAMC_RSTMASK 0x001c |
| #define DRAMC_PADCTRL 0x0020 |
| #define DRAMC_CKECTRL 0x0024 |
| #define DRAMC_RKCFG 0x0034 |
| #define DRAMC_DRAMC_PD_CTRL 0x0038 |
| #define DRAMC_CLKAR 0x003c |
| #define DRAMC_CLKCTRL 0x0040 |
| #define DRAMC_SREFCTRL 0x0048 |
| #define DRAMC_REFCTRL0 0x004c |
| #define DRAMC_REFCTRL1 0x0050 |
| #define DRAMC_REFRATRE_FILTER 0x0054 |
| #define DRAMC_ZQCS 0x0058 |
| #define DRAMC_MRS 0x005c |
| #define DRAMC_SPCMD 0x0060 |
| #define DRAMC_SPCMDCTRL 0x0064 |
| #define DRAMC_HW_MRR_FUN 0x0074 |
| #define DRAMC_TEST2_1 0x0094 |
| #define DRAMC_TEST2_2 0x0098 |
| #define DRAMC_TEST2_3 0x009c |
| #define DRAMC_TEST2_4 0x00a0 |
| #define DRAMC_CATRAINING1 0x00b0 |
| #define DRAMC_DUMMY_RD 0x00d0 |
| #define DRAMC_SHUCTRL 0x00d4 |
| #define DRAMC_SHUCTRL2 0x00dc |
| #define DRAMC_STBCAL 0x0200 |
| #define DRAMC_STBCAL1 0x0204 |
| #define DRAMC_EYESCAN 0x020c |
| #define DRAMC_DVFSDLL 0x0210 |
| #define DRAMC_SHU_ACTIM0 0x0800 |
| #define DRAMC_SHU_ACTIM1 0x0804 |
| #define DRAMC_SHU_ACTIM2 0x0808 |
| #define DRAMC_SHU_ACTIM3 0x080c |
| #define DRAMC_SHU_ACTIM4 0x0810 |
| #define DRAMC_SHU_ACTIM5 0x0814 |
| #define DRAMC_SHU_ACTIM_XRT 0x081c |
| #define DRAMC_SHU_AC_TIME_05T 0x0820 |
| #define DRAMC_SHU_CONF0 0x0840 |
| #define DRAMC_SHU_CONF1 0x0844 |
| #define DRAMC_SHU_CONF2 0x0848 |
| #define DRAMC_SHU_CONF3 0x084c |
| #define DRAMC_SHU_RANKCTL 0x0858 |
| #define DRAMC_SHU_CKECTRL 0x085c |
| #define DRAMC_SHU_ODTCTRL 0x0860 |
| #define DRAMC_SHU_PIPE 0x0878 |
| #define DRAMC_SHU_SELPH_CA1 0x0880 |
| #define DRAMC_SHU_SELPH_CA2 0x0884 |
| #define DRAMC_SHU_SELPH_CA3 0x0888 |
| #define DRAMC_SHU_SELPH_CA4 0x088c |
| #define DRAMC_SHU_SELPH_CA5 0x0890 |
| #define DRAMC_SHU_SELPH_CA6 0x0894 |
| #define DRAMC_SHU_SELPH_CA7 0x0898 |
| #define DRAMC_SHU_SELPH_CA8 0x089c |
| #define DRAMC_SHU_SELPH_DQS0 0x08a0 |
| #define DRAMC_SHU_SELPH_DQS1 0x08a4 |
| #define DRAMC_SHU1_DRVING1 0x08a8 |
| #define DRAMC_SHU1_DRVING2 0x08ac |
| #define DRAMC_SHU1_WODT 0x08c0 |
| #define DRAMC_SHU_SCINTV 0x08c8 |
| #define DRAMC_SHURK0_DQSCTL 0x0a00 |
| #define DRAMC_SHURK0_DQSIEN 0x0a04 |
| #define DRAMC_SHURK0_SELPH_ODTEN0 0x0a1c |
| #define DRAMC_SHURK0_SELPH_ODTEN1 0x0a20 |
| #define DRAMC_SHURK0_SELPH_DQSG0 0x0a24 |
| #define DRAMC_SHURK0_SELPH_DQSG1 0x0a28 |
| #define DRAMC_SHURK0_SELPH_DQ0 0x0a2c |
| #define DRAMC_SHURK0_SELPH_DQ1 0x0a30 |
| #define DRAMC_SHURK0_SELPH_DQ2 0x0a34 |
| #define DRAMC_SHURK0_SELPH_DQ3 0x0a38 |
| #define DRAMC_SHURK1_DQSCTL 0x0b00 |
| #define DRAMC_SHURK1_SELPH_ODTEN0 0x0b1c |
| #define DRAMC_SHURK1_SELPH_ODTEN1 0x0b20 |
| #define DRAMC_SHURK1_SELPH_DQSG0 0x0b24 |
| #define DRAMC_SHURK1_SELPH_DQSG1 0x0b28 |
| #define DRAMC_SHURK1_SELPH_DQ0 0x0b2c |
| #define DRAMC_SHURK1_SELPH_DQ1 0x0b30 |
| #define DRAMC_SHURK1_SELPH_DQ2 0x0b34 |
| #define DRAMC_SHURK1_SELPH_DQ3 0x0b38 |
| #define DRAMC_SHURK2_SELPH_ODTEN0 0x0c1c |
| #define DRAMC_SHURK2_SELPH_ODTEN1 0x0c20 |
| #define DRAMC_SHU_DQSG_RETRY 0x0c54 |
| |
| #define EMI_COL_ADDR_MASK GENMASK(13, 12) |
| #define EMI_COL_ADDR_SHIFT 12 |
| #define WALKING_PATTERN 0x12345678 |
| #define WALKING_STEP 0x4000000 |
| |
| struct mtk_ddr3_priv { |
| fdt_addr_t emi; |
| fdt_addr_t ddrphy; |
| fdt_addr_t dramc_ao; |
| struct clk phy; |
| struct clk phy_mux; |
| struct clk mem; |
| struct clk mem_mux; |
| }; |
| |
| #ifdef CONFIG_SPL_BUILD |
| static int mtk_ddr3_rank_size_detect(struct udevice *dev) |
| { |
| struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| int step; |
| u32 start, test; |
| |
| /* To detect size, we have to make sure it's single rank |
| * and it has maximum addressing region |
| */ |
| |
| writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE); |
| |
| if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN) |
| return -EINVAL; |
| |
| for (step = 0; step < 5; step++) { |
| writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE + |
| (WALKING_STEP << step)); |
| |
| start = readl(CONFIG_SYS_SDRAM_BASE); |
| test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step)); |
| if ((test != ~WALKING_PATTERN) || test == start) |
| break; |
| } |
| |
| step = step ? step - 1 : 3; |
| clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK, |
| step << EMI_COL_ADDR_SHIFT); |
| |
| return 0; |
| } |
| |
| static int mtk_ddr3_init(struct udevice *dev) |
| { |
| struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| int ret; |
| |
| ret = clk_set_parent(&priv->phy, &priv->phy_mux); |
| if (ret) |
| return ret; |
| |
| /* EMI Setting */ |
| writel(0x00003010, priv->emi + EMI_CONA); |
| writel(0x00000000, priv->emi + EMI_CONF); |
| writel(0x000006b8, priv->emi + EMI_CONM); |
| /* DQS */ |
| writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1); |
| /* Clock */ |
| writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2); |
| |
| /* DDRPHY setting */ |
| writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL); |
| writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5); |
| writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5); |
| writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1); |
| writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0); |
| writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2); |
| writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2); |
| writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4); |
| |
| writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7); |
| writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7); |
| writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7); |
| writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2); |
| writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2); |
| writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1); |
| writel(0x10, priv->ddrphy + DDRPHY_PLL3); |
| writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL); |
| writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0); |
| writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5); |
| writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5); |
| udelay(1); |
| |
| writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3); |
| writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3); |
| writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1); |
| writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4); |
| writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6); |
| writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4); |
| writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6); |
| writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3); |
| writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6); |
| writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2); |
| writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3); |
| writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3); |
| writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8); |
| writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1); |
| writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4); |
| writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT); |
| writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0); |
| |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| writel(0x40000, priv->ddrphy + DDRPHY_PLL4); |
| writel(0x0, priv->ddrphy + DDRPHY_PLL1); |
| writel(0x0, priv->ddrphy + DDRPHY_PLL2); |
| writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2); |
| writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2); |
| writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11); |
| writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0); |
| writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8); |
| writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10); |
| writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4); |
| writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6); |
| |
| writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5); |
| writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7); |
| |
| writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5); |
| writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7); |
| writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8); |
| writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10); |
| writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1); |
| writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4); |
| writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4); |
| writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1); |
| writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1); |
| writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1); |
| writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3); |
| writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3); |
| writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4); |
| writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| writel(0x80010000, priv->ddrphy + DDRPHY_PLL1); |
| writel(0x80000000, priv->ddrphy + DDRPHY_PLL2); |
| udelay(100); |
| |
| writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| writel(0xd0000, priv->ddrphy + DDRPHY_PLL4); |
| udelay(1); |
| |
| writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0); |
| writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| udelay(1); |
| |
| writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2); |
| writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2); |
| writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0); |
| writel(0x80000000, priv->ddrphy + DDRPHY_PLL1); |
| udelay(1); |
| |
| writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| udelay(1); |
| |
| writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| udelay(1); |
| |
| writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| udelay(1); |
| |
| ret = clk_set_parent(&priv->mem, &priv->mem_mux); |
| if (ret) |
| return ret; |
| |
| /* DDR PHY PLL setting */ |
| writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3); |
| writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3); |
| writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8); |
| writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7); |
| writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7); |
| writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7); |
| writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3); |
| writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2); |
| writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2); |
| |
| /* Update initial setting */ |
| writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3); |
| writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3); |
| writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6); |
| writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6); |
| writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6); |
| writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2); |
| writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2); |
| writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8); |
| writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8); |
| writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5); |
| writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5); |
| writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR); |
| writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0); |
| writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0); |
| |
| /* Dramc setting PC3 */ |
| writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| |
| writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3); |
| writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY); |
| writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2); |
| writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL); |
| writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0); |
| writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0); |
| writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0); |
| writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL); |
| writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0); |
| writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL); |
| writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL); |
| writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE); |
| writel(0x731004, priv->dramc_ao + DRAMC_RKCFG); |
| writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2); |
| writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL); |
| writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1); |
| writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER); |
| |
| /* Update PCDDR3 default setting */ |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1); |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2); |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3); |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4); |
| writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5); |
| writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6); |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7); |
| writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0); |
| writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1); |
| writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2); |
| writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1); |
| writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2); |
| writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3); |
| writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7); |
| writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7); |
| writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0); |
| writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1); |
| writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0); |
| writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1); |
| writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0); |
| writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1); |
| writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1); |
| writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0); |
| writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1); |
| writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0); |
| writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4); |
| writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5); |
| writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6); |
| writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL); |
| writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL); |
| writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL); |
| writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0); |
| writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1); |
| writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2); |
| writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3); |
| writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4); |
| writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5); |
| writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT); |
| writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T); |
| writel(0x80010000, priv->ddrphy + DDRPHY_PLL2); |
| udelay(500); |
| |
| writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0); |
| writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0); |
| writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0); |
| writel(0x80, priv->dramc_ao + DRAMC_ARBCTL); |
| writel(0x9, priv->dramc_ao + DRAMC_PADCTRL); |
| writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL); |
| writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1); |
| writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| writel(0x731414, priv->dramc_ao + DRAMC_RKCFG); |
| writel(0x733414, priv->dramc_ao + DRAMC_RKCFG); |
| udelay(20); |
| |
| writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL); |
| udelay(100); |
| |
| writel(0x400000, priv->dramc_ao + DRAMC_MRS); |
| writel(0x401800, priv->dramc_ao + DRAMC_MRS); |
| writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| udelay(100); |
| |
| writel(0x601800, priv->dramc_ao + DRAMC_MRS); |
| writel(0x600000, priv->dramc_ao + DRAMC_MRS); |
| writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| udelay(100); |
| |
| writel(0x200000, priv->dramc_ao + DRAMC_MRS); |
| writel(0x200400, priv->dramc_ao + DRAMC_MRS); |
| writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| udelay(100); |
| |
| writel(0x400, priv->dramc_ao + DRAMC_MRS); |
| writel(0x1d7000, priv->dramc_ao + DRAMC_MRS); |
| writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| udelay(100); |
| |
| writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0x10, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x20, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN); |
| writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0xa56, priv->dramc_ao + DRAMC_ZQCS); |
| writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3); |
| writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1); |
| writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL); |
| writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN); |
| writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1); |
| writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1); |
| writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2); |
| writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3); |
| writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2); |
| writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL); |
| writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD); |
| writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4); |
| writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1); |
| writel(0x0, priv->dramc_ao + DRAMC_RSTMASK); |
| writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL); |
| writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| |
| /* Apply config before calibration */ |
| writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3); |
| writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0); |
| writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3); |
| writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL); |
| writel(0xa56, priv->dramc_ao + DRAMC_ZQCS); |
| writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT); |
| writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7); |
| writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7); |
| writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN); |
| writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| |
| /* Write leveling */ |
| writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0); |
| |
| /* RX dqs gating cal */ |
| writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0); |
| writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1); |
| writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN); |
| |
| /* RX window per-bit cal */ |
| writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2); |
| writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3); |
| writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4); |
| writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5); |
| writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2); |
| writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3); |
| writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4); |
| writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5); |
| |
| /* RX datlat cal */ |
| writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1); |
| |
| /* TX window per-byte with 2UI cal */ |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0); |
| writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2); |
| writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1); |
| writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3); |
| writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| |
| return mtk_ddr3_rank_size_detect(dev); |
| } |
| #endif |
| |
| static int mtk_ddr3_probe(struct udevice *dev) |
| { |
| struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| |
| priv->emi = dev_read_addr_index(dev, 0); |
| if (priv->emi == FDT_ADDR_T_NONE) |
| return -EINVAL; |
| |
| priv->ddrphy = dev_read_addr_index(dev, 1); |
| if (priv->ddrphy == FDT_ADDR_T_NONE) |
| return -EINVAL; |
| |
| priv->dramc_ao = dev_read_addr_index(dev, 2); |
| if (priv->dramc_ao == FDT_ADDR_T_NONE) |
| return -EINVAL; |
| |
| #ifdef CONFIG_SPL_BUILD |
| int ret; |
| |
| ret = clk_get_by_index(dev, 0, &priv->phy); |
| if (ret) |
| return ret; |
| |
| ret = clk_get_by_index(dev, 1, &priv->phy_mux); |
| if (ret) |
| return ret; |
| |
| ret = clk_get_by_index(dev, 2, &priv->mem); |
| if (ret) |
| return ret; |
| |
| ret = clk_get_by_index(dev, 3, &priv->mem_mux); |
| if (ret) |
| return ret; |
| |
| ret = mtk_ddr3_init(dev); |
| if (ret) |
| return ret; |
| #endif |
| return 0; |
| } |
| |
| static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info) |
| { |
| struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| u32 val = readl(priv->emi + EMI_CONA); |
| |
| info->base = CONFIG_SYS_SDRAM_BASE; |
| |
| switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) { |
| case 0: |
| info->size = SZ_128M; |
| break; |
| case 1: |
| info->size = SZ_256M; |
| break; |
| case 2: |
| info->size = SZ_512M; |
| break; |
| case 3: |
| info->size = SZ_1G; |
| break; |
| default: |
| return -EINVAL; |
| } |
| |
| return 0; |
| } |
| |
| static struct ram_ops mtk_ddr3_ops = { |
| .get_info = mtk_ddr3_get_info, |
| }; |
| |
| static const struct udevice_id mtk_ddr3_ids[] = { |
| { .compatible = "mediatek,mt7629-dramc" }, |
| { } |
| }; |
| |
| U_BOOT_DRIVER(mediatek_ddr3) = { |
| .name = "mediatek_ddr3", |
| .id = UCLASS_RAM, |
| .of_match = mtk_ddr3_ids, |
| .ops = &mtk_ddr3_ops, |
| .probe = mtk_ddr3_probe, |
| .priv_auto = sizeof(struct mtk_ddr3_priv), |
| }; |