summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c2
-rw-r--r--arch/arm/cpu/armv7/sunxi/board.c8
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/sun8i-a33-q8-tablet.dts65
-rw-r--r--arch/arm/dts/sun8i-q8-common.dtsi84
-rw-r--r--arch/arm/imx-common/ddrmc-vf610.c193
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h54
-rw-r--r--arch/arm/include/asm/arch-vf610/ddrmc-vf610.h40
-rw-r--r--arch/arm/include/asm/arch-vf610/imx-regs.h6
-rw-r--r--arch/arm/mach-mvebu/cpu.c36
-rw-r--r--arch/arm/mach-mvebu/timer.c2
-rw-r--r--arch/x86/lib/fsp/fsp_dram.c3
13 files changed, 330 insertions, 169 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0b07e08..3a336e6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -538,6 +538,10 @@ config TARGET_COLIBRI_VF
bool "Support Colibri VF50/61"
select CPU_V7
+config TARGET_PCM052
+ bool "Support pcm-052"
+ select CPU_V7
+
config ARCH_ZYNQ
bool "Xilinx Zynq Platform"
select CPU_V7
@@ -753,6 +757,7 @@ source "board/maxbcm/Kconfig"
source "board/mpl/vcma9/Kconfig"
source "board/olimex/mx23_olinuxino/Kconfig"
source "board/phytec/pcm051/Kconfig"
+source "board/phytec/pcm052/Kconfig"
source "board/ppcag/bg0900/Kconfig"
source "board/samsung/smdk2410/Kconfig"
source "board/sandisk/sansa_fuze_plus/Kconfig"
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index ba6cc75..11efd12 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -535,6 +535,8 @@ int enable_fec_anatop_clock(int fec_id, enum enet_freq freq)
if (freq < ENET_25MHZ || freq > ENET_125MHZ)
return -EINVAL;
+ reg = readl(&anatop->pll_enet);
+
if (fec_id == 0) {
reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index b40198b..d11365b 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -21,6 +21,7 @@
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/spl.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
#include <asm/arch/tzpc.h>
@@ -152,7 +153,7 @@ u32 spl_boot_device(void)
* binary over USB. If it is found, it determines where SPL was
* read from.
*/
- if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */
+ if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
return BOOT_DEVICE_BOARD;
/* The BROM will try to boot from mmc0 first, so try that first. */
@@ -198,11 +199,6 @@ void board_init_f(ulong dummy)
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
sunxi_board_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- board_init_r(NULL, 0);
}
#endif
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 5f10243..6a11b12 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -158,6 +158,7 @@ dtb-$(CONFIG_MACH_SUN8I_A33) += \
sun8i-a33-et-q8-v1.6.dtb \
sun8i-a33-ga10h-v1.1.dtb \
sun8i-a33-ippo-q8h-v1.2.dtb \
+ sun8i-a33-q8-tablet.dtb \
sun8i-a33-sinlinx-sina33.dtb
dtb-$(CONFIG_MACH_SUN9I) += \
sun9i-a80-optimus.dtb \
diff --git a/arch/arm/dts/sun8i-a33-q8-tablet.dts b/arch/arm/dts/sun8i-a33-q8-tablet.dts
new file mode 100644
index 0000000..44b3229
--- /dev/null
+++ b/arch/arm/dts/sun8i-a33-q8-tablet.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-a33.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+ model = "Q8 A33 Tablet";
+ compatible = "allwinner,q8-a33", "allwinner,sun8i-a33";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-q8-common.dtsi b/arch/arm/dts/sun8i-q8-common.dtsi
new file mode 100644
index 0000000..07cd268
--- /dev/null
+++ b/arch/arm/dts/sun8i-q8-common.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "sunxi-q8-common.dtsi"
+
+/ {
+ aliases {
+ serial0 = &r_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+ cd-inverted;
+ status = "okay";
+};
+
+&pio {
+ bl_en_pin_q8: bl_en_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_q8: mmc0_cd_pin@0 {
+ allwinner,pins = "PB4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&r_uart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_uart_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/imx-common/ddrmc-vf610.c b/arch/arm/imx-common/ddrmc-vf610.c
index e462631..daf3c7e 100644
--- a/arch/arm/imx-common/ddrmc-vf610.c
+++ b/arch/arm/imx-common/ddrmc-vf610.c
@@ -12,9 +12,9 @@
#include <asm/arch/iomux-vf610.h>
#include <asm/arch/ddrmc-vf610.h>
-void ddrmc_setup_iomux(void)
+void ddrmc_setup_iomux(const iomux_v3_cfg_t *pads, int pads_count)
{
- static const iomux_v3_cfg_t ddr_pads[] = {
+ static const iomux_v3_cfg_t default_pads[] = {
VF610_PAD_DDR_A15__DDR_A_15,
VF610_PAD_DDR_A14__DDR_A_14,
VF610_PAD_DDR_A13__DDR_A_13,
@@ -65,76 +65,54 @@ void ddrmc_setup_iomux(void)
VF610_PAD_DDR_RESETB,
};
- imx_iomux_v3_setup_multiple_pads(ddr_pads, ARRAY_SIZE(ddr_pads));
-}
+ if ((pads == NULL) || (pads_count == 0)) {
+ pads = default_pads;
+ pads_count = ARRAY_SIZE(default_pads);
+ }
-void ddrmc_phy_init(void)
-{
- struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR;
+ imx_iomux_v3_setup_multiple_pads(pads, pads_count);
+}
- writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[0]);
- writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[16]);
- writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[32]);
+static struct ddrmc_phy_setting default_phy_settings[] = {
+ { DDRMC_PHY_DQ_TIMING, 0 },
+ { DDRMC_PHY_DQ_TIMING, 16 },
+ { DDRMC_PHY_DQ_TIMING, 32 },
- writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[1]);
- writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[17]);
+ { DDRMC_PHY_DQS_TIMING, 1 },
+ { DDRMC_PHY_DQS_TIMING, 17 },
- writel(DDRMC_PHY_CTRL, &ddrmr->phy[2]);
- writel(DDRMC_PHY_CTRL, &ddrmr->phy[18]);
- writel(DDRMC_PHY_CTRL, &ddrmr->phy[34]);
+ { DDRMC_PHY_CTRL, 2 },
+ { DDRMC_PHY_CTRL, 18 },
+ { DDRMC_PHY_CTRL, 34 },
- writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[3]);
- writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[19]);
- writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[35]);
+ { DDRMC_PHY_MASTER_CTRL, 3 },
+ { DDRMC_PHY_MASTER_CTRL, 19 },
+ { DDRMC_PHY_MASTER_CTRL, 35 },
- writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[4]);
- writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[20]);
- writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[36]);
+ { DDRMC_PHY_SLAVE_CTRL, 4 },
+ { DDRMC_PHY_SLAVE_CTRL, 20 },
+ { DDRMC_PHY_SLAVE_CTRL, 36 },
/* LPDDR2 only parameter */
- writel(DDRMC_PHY_OFF, &ddrmr->phy[49]);
+ { DDRMC_PHY_OFF, 49 },
- writel(DDRMC_PHY50_DDR3_MODE |
- DDRMC_PHY50_EN_SW_HALF_CYCLE, &ddrmr->phy[50]);
+ { DDRMC_PHY50_DDR3_MODE | DDRMC_PHY50_EN_SW_HALF_CYCLE, 50 },
/* Processor Pad ODT settings */
- writel(DDRMC_PHY_PROC_PAD_ODT, &ddrmr->phy[52]);
-}
-
-static void ddrmc_ctrl_lvl_init(struct ddrmc_lvl_info *lvl)
-{
- struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR;
- u32 cr102 = 0, cr105 = 0, cr106 = 0, cr110 = 0;
+ { DDRMC_PHY_PROC_PAD_ODT, 52 },
- if (lvl->wrlvl_reg_en) {
- writel(DDRMC_CR97_WRLVL_EN, &ddrmr->cr[97]);
- writel(DDRMC_CR98_WRLVL_DL_0(lvl->wrlvl_dl_0), &ddrmr->cr[98]);
- writel(DDRMC_CR99_WRLVL_DL_1(lvl->wrlvl_dl_1), &ddrmr->cr[99]);
- }
-
- if (lvl->rdlvl_reg_en) {
- cr102 |= DDRMC_CR102_RDLVL_REG_EN;
- cr105 |= DDRMC_CR105_RDLVL_DL_0(lvl->rdlvl_dl_0);
- cr110 |= DDRMC_CR110_RDLVL_DL_1(lvl->rdlvl_dl_1);
- }
-
- if (lvl->rdlvl_gt_reg_en) {
- cr102 |= DDRMC_CR102_RDLVL_GT_REGEN;
- cr106 |= DDRMC_CR106_RDLVL_GTDL_0(lvl->rdlvl_gt_dl_0);
- cr110 |= DDRMC_CR110_RDLVL_GTDL_1(lvl->rdlvl_gt_dl_1);
- }
-
- writel(cr102, &ddrmr->cr[102]);
- writel(cr105, &ddrmr->cr[105]);
- writel(cr106, &ddrmr->cr[106]);
- writel(cr110, &ddrmr->cr[110]);
-}
+ /* end marker */
+ { 0, -1 }
+};
void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
- struct ddrmc_lvl_info *lvl,
- int col_diff, int row_diff)
+ struct ddrmc_cr_setting *board_cr_settings,
+ struct ddrmc_phy_setting *board_phy_settings,
+ int col_diff, int row_diff)
{
struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR;
+ struct ddrmc_cr_setting *cr_setting;
+ struct ddrmc_phy_setting *phy_setting;
writel(DDRMC_CR00_DRAM_CLASS_DDR3, &ddrmr->cr[0]);
writel(DDRMC_CR02_DRAM_TINIT(timings->tinit), &ddrmr->cr[2]);
@@ -144,7 +122,9 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
writel(DDRMC_CR12_WRLAT(timings->wrlat) |
DDRMC_CR12_CASLAT_LIN(timings->caslat_lin), &ddrmr->cr[12]);
writel(DDRMC_CR13_TRC(timings->trc) | DDRMC_CR13_TRRD(timings->trrd) |
- DDRMC_CR13_TCCD(timings->tccd), &ddrmr->cr[13]);
+ DDRMC_CR13_TCCD(timings->tccd) |
+ DDRMC_CR13_TBST_INT_INTERVAL(timings->tbst_int_interval),
+ &ddrmr->cr[13]);
writel(DDRMC_CR14_TFAW(timings->tfaw) | DDRMC_CR14_TRP(timings->trp) |
DDRMC_CR14_TWTR(timings->twtr) |
DDRMC_CR14_TRAS_MIN(timings->tras_min), &ddrmr->cr[14]);
@@ -156,18 +136,19 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
DDRMC_CR18_TCKE(timings->tcke), &ddrmr->cr[18]);
writel(DDRMC_CR20_AP_EN, &ddrmr->cr[20]);
- writel(DDRMC_CR21_TRCD_INT(timings->trcd_int) |
- DDRMC_CR21_CCMAP_EN, &ddrmr->cr[21]);
+ writel(DDRMC_CR21_TRCD_INT(timings->trcd_int) | DDRMC_CR21_CCMAP_EN |
+ DDRMC_CR21_TRAS_LOCKOUT(timings->tras_lockout),
+ &ddrmr->cr[21]);
writel(DDRMC_CR22_TDAL(timings->tdal), &ddrmr->cr[22]);
- writel(DDRMC_CR23_BSTLEN(3) |
+ writel(DDRMC_CR23_BSTLEN(timings->bstlen) |
DDRMC_CR23_TDLL(timings->tdll), &ddrmr->cr[23]);
writel(DDRMC_CR24_TRP_AB(timings->trp_ab), &ddrmr->cr[24]);
writel(DDRMC_CR25_TREF_EN, &ddrmr->cr[25]);
writel(DDRMC_CR26_TREF(timings->tref) |
DDRMC_CR26_TRFC(timings->trfc), &ddrmr->cr[26]);
- writel(DDRMC_CR28_TREF_INT(0), &ddrmr->cr[28]);
+ writel(DDRMC_CR28_TREF_INT(timings->tref_int), &ddrmr->cr[28]);
writel(DDRMC_CR29_TPDEX(timings->tpdex), &ddrmr->cr[29]);
writel(DDRMC_CR30_TXPDLL(timings->txpdll), &ddrmr->cr[30]);
@@ -177,7 +158,7 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
writel(DDRMC_CR34_CKSRX(timings->cksrx) |
DDRMC_CR34_CKSRE(timings->cksre), &ddrmr->cr[34]);
- writel(DDRMC_CR38_FREQ_CHG_EN(0), &ddrmr->cr[38]);
+ writel(DDRMC_CR38_FREQ_CHG_EN(timings->freq_chg_en), &ddrmr->cr[38]);
writel(DDRMC_CR39_PHY_INI_COM(1024) | DDRMC_CR39_PHY_INI_STA(16) |
DDRMC_CR39_FRQ_CH_DLLOFF(2), &ddrmr->cr[39]);
@@ -191,13 +172,14 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
writel(DDRMC_CR69_ZQ_ON_SREF_EX(2), &ddrmr->cr[69]);
writel(DDRMC_CR70_REF_PER_ZQ(timings->ref_per_zq), &ddrmr->cr[70]);
- writel(DDRMC_CR72_ZQCS_ROTATE(0), &ddrmr->cr[72]);
+ writel(DDRMC_CR72_ZQCS_ROTATE(timings->zqcs_rotate), &ddrmr->cr[72]);
writel(DDRMC_CR73_APREBIT(timings->aprebit) |
DDRMC_CR73_COL_DIFF(col_diff) |
DDRMC_CR73_ROW_DIFF(row_diff), &ddrmr->cr[73]);
writel(DDRMC_CR74_BANKSPLT_EN | DDRMC_CR74_ADDR_CMP_EN |
- DDRMC_CR74_CMD_AGE_CNT(64) | DDRMC_CR74_AGE_CNT(64),
+ DDRMC_CR74_CMD_AGE_CNT(timings->cmd_age_cnt) |
+ DDRMC_CR74_AGE_CNT(timings->age_cnt),
&ddrmr->cr[74]);
writel(DDRMC_CR75_RW_PG_EN | DDRMC_CR75_RW_EN | DDRMC_CR75_PRI_EN |
DDRMC_CR75_PLEN, &ddrmr->cr[75]);
@@ -205,13 +187,15 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
DDRMC_CR76_W2R_SPLT_EN, &ddrmr->cr[76]);
writel(DDRMC_CR77_CS_MAP | DDRMC_CR77_DI_RD_INTLEAVE |
DDRMC_CR77_SWAP_EN, &ddrmr->cr[77]);
- writel(DDRMC_CR78_Q_FULLNESS(7) |
+ writel(DDRMC_CR78_Q_FULLNESS(timings->q_fullness) |
DDRMC_CR78_BUR_ON_FLY_BIT(12), &ddrmr->cr[78]);
writel(DDRMC_CR79_CTLUPD_AREF(0), &ddrmr->cr[79]);
writel(DDRMC_CR82_INT_MASK, &ddrmr->cr[82]);
- writel(DDRMC_CR87_ODT_WR_MAPCS0, &ddrmr->cr[87]);
+ writel(DDRMC_CR87_ODT_RD_MAPCS0(timings->odt_rd_mapcs0) |
+ DDRMC_CR87_ODT_WR_MAPCS0(timings->odt_wr_mapcs0),
+ &ddrmr->cr[87]);
writel(DDRMC_CR88_TODTL_CMD(4), &ddrmr->cr[88]);
writel(DDRMC_CR89_AODT_RWSMCS(2), &ddrmr->cr[89]);
@@ -219,58 +203,33 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
writel(DDRMC_CR96_WLMRD(timings->wlmrd) |
DDRMC_CR96_WLDQSEN(timings->wldqsen), &ddrmr->cr[96]);
- if (lvl != NULL)
- ddrmc_ctrl_lvl_init(lvl);
-
- writel(DDRMC_CR117_AXI0_W_PRI(0) |
- DDRMC_CR117_AXI0_R_PRI(0), &ddrmr->cr[117]);
- writel(DDRMC_CR118_AXI1_W_PRI(1) |
- DDRMC_CR118_AXI1_R_PRI(1), &ddrmr->cr[118]);
-
- writel(DDRMC_CR120_AXI0_PRI1_RPRI(2) |
- DDRMC_CR120_AXI0_PRI0_RPRI(2), &ddrmr->cr[120]);
- writel(DDRMC_CR121_AXI0_PRI3_RPRI(2) |
- DDRMC_CR121_AXI0_PRI2_RPRI(2), &ddrmr->cr[121]);
- writel(DDRMC_CR122_AXI1_PRI1_RPRI(1) | DDRMC_CR122_AXI1_PRI0_RPRI(1) |
- DDRMC_CR122_AXI0_PRIRLX(100), &ddrmr->cr[122]);
- writel(DDRMC_CR123_AXI1_P_ODR_EN | DDRMC_CR123_AXI1_PRI3_RPRI(1) |
- DDRMC_CR123_AXI1_PRI2_RPRI(1), &ddrmr->cr[123]);
- writel(DDRMC_CR124_AXI1_PRIRLX(100), &ddrmr->cr[124]);
-
- writel(DDRMC_CR126_PHY_RDLAT(8), &ddrmr->cr[126]);
- writel(DDRMC_CR132_WRLAT_ADJ(5) |
- DDRMC_CR132_RDLAT_ADJ(6), &ddrmr->cr[132]);
- writel(DDRMC_CR137_PHYCTL_DL(2), &ddrmr->cr[137]);
- writel(DDRMC_CR138_PHY_WRLV_MXDL(256) |
- DDRMC_CR138_PHYDRAM_CK_EN(1), &ddrmr->cr[138]);
- writel(DDRMC_CR139_PHY_WRLV_RESPLAT(4) | DDRMC_CR139_PHY_WRLV_LOAD(7) |
- DDRMC_CR139_PHY_WRLV_DLL(3) |
- DDRMC_CR139_PHY_WRLV_EN(3), &ddrmr->cr[139]);
- writel(DDRMC_CR140_PHY_WRLV_WW(64), &ddrmr->cr[140]);
- writel(DDRMC_CR143_RDLV_GAT_MXDL(1536) |
- DDRMC_CR143_RDLV_MXDL(128), &ddrmr->cr[143]);
- writel(DDRMC_CR144_PHY_RDLVL_RES(4) | DDRMC_CR144_PHY_RDLV_LOAD(7) |
- DDRMC_CR144_PHY_RDLV_DLL(3) |
- DDRMC_CR144_PHY_RDLV_EN(3), &ddrmr->cr[144]);
- writel(DDRMC_CR145_PHY_RDLV_RR(64), &ddrmr->cr[145]);
- writel(DDRMC_CR146_PHY_RDLVL_RESP(64), &ddrmr->cr[146]);
- writel(DDRMC_CR147_RDLV_RESP_MASK(983040), &ddrmr->cr[147]);
- writel(DDRMC_CR148_RDLV_GATE_RESP_MASK(983040), &ddrmr->cr[148]);
- writel(DDRMC_CR151_RDLV_GAT_DQ_ZERO_CNT(1) |
- DDRMC_CR151_RDLVL_DQ_ZERO_CNT(1), &ddrmr->cr[151]);
-
- writel(DDRMC_CR154_PAD_ZQ_EARLY_CMP_EN_TIMER(13) |
- DDRMC_CR154_PAD_ZQ_MODE(1) |
- DDRMC_CR154_DDR_SEL_PAD_CONTR(3) |
- DDRMC_CR154_PAD_ZQ_HW_FOR(1), &ddrmr->cr[154]);
- writel(DDRMC_CR155_PAD_ODT_BYTE1(2) |
- DDRMC_CR155_PAD_ODT_BYTE0(2), &ddrmr->cr[155]);
- writel(DDRMC_CR158_TWR(6), &ddrmr->cr[158]);
- writel(DDRMC_CR161_ODT_EN(1) | DDRMC_CR161_TODTH_RD(2) |
- DDRMC_CR161_TODTH_WR(2), &ddrmr->cr[161]);
-
- ddrmc_phy_init();
+ /* execute custom CR setting sequence (may be NULL) */
+ cr_setting = board_cr_settings;
+ if (cr_setting != NULL)
+ while (cr_setting->cr_rnum >= 0) {
+ writel(cr_setting->setting,
+ &ddrmr->cr[cr_setting->cr_rnum]);
+ cr_setting++;
+ }
+
+ /* perform default PHY settings (may be overriden by custom settings */
+ phy_setting = default_phy_settings;
+ while (phy_setting->phy_rnum >= 0) {
+ writel(phy_setting->setting,
+ &ddrmr->phy[phy_setting->phy_rnum]);
+ phy_setting++;
+ }
+
+ /* execute custom PHY setting sequence (may be NULL) */
+ phy_setting = board_phy_settings;
+ if (phy_setting != NULL)
+ while (phy_setting->phy_rnum >= 0) {
+ writel(phy_setting->setting,
+ &ddrmr->phy[phy_setting->phy_rnum]);
+ phy_setting++;
+ }
+ /* all inits done, start the DDR controller */
writel(DDRMC_CR00_DRAM_CLASS_DDR3 | DDRMC_CR00_START, &ddrmr->cr[0]);
while (!(readl(&ddrmr->cr[80]) && 0x100))
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index acbec46..a129dd4 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -1,20 +1,50 @@
/*
- * This is a copy of omap3/spl.h:
- *
- * (C) Copyright 2012
- * Texas Instruments, <www.ti.com>
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#define BOOT_DEVICE_NONE 0
-#define BOOT_DEVICE_XIP 1
-#define BOOT_DEVICE_NAND 2
-#define BOOT_DEVICE_ONE_NAND 3
-#define BOOT_DEVICE_MMC2 5 /*emmc*/
-#define BOOT_DEVICE_MMC1 6
-#define BOOT_DEVICE_XIPWAIT 7
-#define BOOT_DEVICE_MMC2_2 0xff
+#define BOOT0_MAGIC "eGON.BT0"
+#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */
+#define SPL_HEADER_VERSION 1
+
+/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */
+#define SPL_ADDR 0x0
+
+/* boot head definition from sun4i boot code */
+struct boot_file_head {
+ uint32_t b_instruction; /* one intruction jumping to real code */
+ uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
+ uint32_t check_sum; /* generated by PC */
+ uint32_t length; /* generated by PC */
+ /*
+ * We use a simplified header, only filling in what is needed
+ * by the boot ROM. To be compatible with Allwinner tools we
+ * would need to implement the proper fields here instead of
+ * padding.
+ *
+ * Actually we want the ability to recognize our "sunxi" variant
+ * of the SPL. To do so, let's place a special signature into the
+ * "pub_head_size" field. We can reasonably expect Allwinner's
+ * boot0 to always have the upper 16 bits of this set to 0 (after
+ * all the value shouldn't be larger than the limit imposed by
+ * SRAM size).
+ * If the signature is present (at 0x14), then we know it's safe
+ * to use the remaining 8 bytes (at 0x18) for our own purposes.
+ * (E.g. sunxi-tools "fel" utility can pass information there.)
+ */
+ union {
+ uint32_t pub_head_size;
+ uint8_t spl_signature[4];
+ };
+ uint32_t fel_script_address;
+ uint32_t reserved; /* padding, align to 32 bytes */
+};
+
+#define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
+
#endif
diff --git a/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h b/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h
index 6730cde..9022c46 100644
--- a/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h
+++ b/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h
@@ -11,18 +11,6 @@
#ifndef __ASM_ARCH_VF610_DDRMC_H
#define __ASM_ARCH_VF610_DDRMC_H
-struct ddrmc_lvl_info {
- u16 wrlvl_reg_en;
- u16 wrlvl_dl_0;
- u16 wrlvl_dl_1;
- u16 rdlvl_gt_reg_en;
- u16 rdlvl_gt_dl_0;
- u16 rdlvl_gt_dl_1;
- u16 rdlvl_reg_en;
- u16 rdlvl_dl_0;
- u16 rdlvl_dl_1;
-};
-
struct ddr3_jedec_timings {
u8 tinit;
u32 trst_pwron;
@@ -32,6 +20,7 @@ struct ddr3_jedec_timings {
u8 trc;
u8 trrd;
u8 tccd;
+ u8 tbst_int_interval;
u8 tfaw;
u8 trp;
u8 twtr;
@@ -43,30 +32,51 @@ struct ddr3_jedec_timings {
u8 tckesr;
u8 tcke;
u8 trcd_int;
+ u8 tras_lockout;
u8 tdal;
+ u8 bstlen;
u16 tdll;
u8 trp_ab;
u16 tref;
u8 trfc;
+ u16 tref_int;
u8 tpdex;
u8 txpdll;
u8 txsnr;
u16 txsr;
u8 cksrx;
u8 cksre;
+ u8 freq_chg_en;
u16 zqcl;
u16 zqinit;
u8 zqcs;
u8 ref_per_zq;
+ u8 zqcs_rotate;
u8 aprebit;
+ u8 cmd_age_cnt;
+ u8 age_cnt;
+ u8 q_fullness;
+ u8 odt_rd_mapcs0;
+ u8 odt_wr_mapcs0;
u8 wlmrd;
u8 wldqsen;
};
-void ddrmc_setup_iomux(void);
+struct ddrmc_cr_setting {
+ u32 setting;
+ int cr_rnum; /* CR register ; -1 for last entry */
+};
+
+struct ddrmc_phy_setting {
+ u32 setting;
+ int phy_rnum; /* PHY register ; -1 for last entry */
+};
+
+void ddrmc_setup_iomux(const iomux_v3_cfg_t *pads, int pads_count);
void ddrmc_phy_init(void);
void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
- struct ddrmc_lvl_info *lvl,
- int col_diff, int row_diff);
+ struct ddrmc_cr_setting *board_cr_settings,
+ struct ddrmc_phy_setting *board_phy_settings,
+ int col_diff, int row_diff);
#endif
diff --git a/arch/arm/include/asm/arch-vf610/imx-regs.h b/arch/arm/include/asm/arch-vf610/imx-regs.h
index 4366985..9758323 100644
--- a/arch/arm/include/asm/arch-vf610/imx-regs.h
+++ b/arch/arm/include/asm/arch-vf610/imx-regs.h
@@ -148,7 +148,7 @@
#define DDRMC_CR18_TCKE(v) ((v) & 0x7)
#define DDRMC_CR20_AP_EN (1 << 24)
#define DDRMC_CR21_TRCD_INT(v) (((v) & 0xff) << 16)
-#define DDRMC_CR21_TRAS_LOCKOUT (1 << 8)
+#define DDRMC_CR21_TRAS_LOCKOUT(v) ((v) << 8)
#define DDRMC_CR21_CCMAP_EN 1
#define DDRMC_CR22_TDAL(v) (((v) & 0x3f) << 16)
#define DDRMC_CR23_BSTLEN(v) (((v) & 0x7) << 24)
@@ -200,8 +200,8 @@
#define DDRMC_CR78_BUR_ON_FLY_BIT(v) ((v) & 0xf)
#define DDRMC_CR79_CTLUPD_AREF(v) (((v) & 0x1) << 24)
#define DDRMC_CR82_INT_MASK 0x10000000
-#define DDRMC_CR87_ODT_WR_MAPCS0 (1 << 24)
-#define DDRMC_CR87_ODT_RD_MAPCS0 (1 << 16)
+#define DDRMC_CR87_ODT_WR_MAPCS0(v) ((v) << 24)
+#define DDRMC_CR87_ODT_RD_MAPCS0(v) ((v) << 16)
#define DDRMC_CR88_TODTL_CMD(v) (((v) & 0x1f) << 16)
#define DDRMC_CR89_AODT_RWSMCS(v) ((v) & 0xf)
#define DDRMC_CR91_R2W_SMCSDL(v) (((v) & 0x7) << 16)
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index ea83e21..efd4d04 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -214,32 +214,40 @@ static void setup_usb_phys(void)
int arch_cpu_init(void)
{
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMADA_38X)
+ /*
+ * Only with disabled MMU its possible to switch the base
+ * register address on Armada 38x. Without this the SDRAM
+ * located at >= 0x4000.0000 is also not accessible, as its
+ * still locked to cache.
+ */
+ mmu_disable();
+#endif
+
+ /* Linux expects the internal registers to be at 0xf1000000 */
+ writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
+ set_cbar(SOC_REGS_PHY_BASE + 0xC000);
+
+#if !defined(CONFIG_SPL_BUILD)
+ /*
+ * From this stage on, the SoC detection is working. As we have
+ * configured the internal register base to the value used
+ * in the macros / defines in the U-Boot header (soc.h).
+ */
if (mvebu_soc_family() == MVEBU_SOC_A38X) {
struct pl310_regs *const pl310 =
(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
/*
- * Only with disabled MMU its possible to switch the base
- * register address on Armada 38x. Without this the SDRAM
- * located at >= 0x4000.0000 is also not accessible, as its
- * still locked to cache.
- *
- * So to fully release / unlock this area from cache, we need
- * to first flush all caches, then disable the MMU and
- * disable the L2 cache.
+ * To fully release / unlock this area from cache, we need
+ * to flush all caches and disable the L2 cache.
*/
icache_disable();
dcache_disable();
- mmu_disable();
clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
}
#endif
- /* Linux expects the internal registers to be at 0xf1000000 */
- writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
- set_cbar(SOC_REGS_PHY_BASE + 0xC000);
-
/*
* We need to call mvebu_mbus_probe() before calling
* update_sdram_window_sizes() as it disables all previously
diff --git a/arch/arm/mach-mvebu/timer.c b/arch/arm/mach-mvebu/timer.c
index c516c41..5449a89 100644
--- a/arch/arm/mach-mvebu/timer.c
+++ b/arch/arm/mach-mvebu/timer.c
@@ -41,7 +41,7 @@
#define timestamp gd->arch.tbl
#define lastdec gd->arch.lastinc
-static int init_done;
+static int init_done __attribute__((section(".data"))) = 0;
/* Timer reload and current value registers */
struct kwtmr_val {
diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c
index 28552fa..e51ca96 100644
--- a/arch/x86/lib/fsp/fsp_dram.c
+++ b/arch/x86/lib/fsp/fsp_dram.c
@@ -72,9 +72,10 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
entries[num_entries].type = E820_RAM;
else if (res_desc->type == RES_MEM_RESERVED)
entries[num_entries].type = E820_RESERVED;
+
+ num_entries++;
}
hdr = get_next_hob(hdr);
- num_entries++;
}
/* Mark PCIe ECAM address range as reserved */