summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/at91/Makefile52
-rw-r--r--arch/arm/cpu/armv7/at91/clock.c125
-rw-r--r--arch/arm/cpu/armv7/at91/cpu.c90
-rw-r--r--arch/arm/cpu/armv7/at91/reset.c47
-rw-r--r--arch/arm/cpu/armv7/at91/sama5d3_devices.c196
-rw-r--r--arch/arm/cpu/armv7/at91/timer.c139
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap-common/abb.c137
-rw-r--r--arch/arm/cpu/armv7/omap-common/boot-common.c39
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c101
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c28
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c40
-rw-r--r--arch/arm/cpu/armv7/omap-common/timer.c1
-rw-r--r--arch/arm/cpu/armv7/omap-common/vc.c14
-rw-r--r--arch/arm/cpu/armv7/omap3/clock.c2
-rw-r--r--arch/arm/cpu/armv7/omap4/hw_data.c13
-rw-r--r--arch/arm/cpu/armv7/omap4/prcm-regs.c3
-rw-r--r--arch/arm/cpu/armv7/omap5/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap5/abb.c67
-rw-r--r--arch/arm/cpu/armv7/omap5/hw_data.c167
-rw-r--r--arch/arm/cpu/armv7/omap5/hwinit.c24
-rw-r--r--arch/arm/cpu/armv7/omap5/prcm-regs.c20
-rw-r--r--arch/arm/cpu/armv7/omap5/sdram.c170
-rw-r--r--arch/arm/cpu/armv7/start.S78
-rw-r--r--arch/arm/cpu/armv7/vf610/Makefile42
-rw-r--r--arch/arm/cpu/armv7/vf610/generic.c324
-rw-r--r--arch/arm/cpu/armv7/vf610/timer.c103
27 files changed, 1816 insertions, 208 deletions
diff --git a/arch/arm/cpu/armv7/at91/Makefile b/arch/arm/cpu/armv7/at91/Makefile
new file mode 100644
index 0000000000..040c67d511
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2013
+# Bo Shen <voice.shen@atmel.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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; either version 2 of
+# the License, or (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).o
+
+COBJS-$(CONFIG_SAMA5D3) += sama5d3_devices.o
+COBJS-y += clock.o
+COBJS-y += cpu.o
+COBJS-y += reset.o
+COBJS-y += timer.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c
new file mode 100644
index 0000000000..624b52cc31
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/clock.c
@@ -0,0 +1,125 @@
+/*
+ * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
+ *
+ * Copyright (C) 2005 David Brownell
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+
+#if !defined(CONFIG_AT91FAMILY)
+# error You need to define CONFIG_AT91FAMILY in your board config!
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned long at91_css_to_rate(unsigned long css)
+{
+ switch (css) {
+ case AT91_PMC_MCKR_CSS_SLOW:
+ return CONFIG_SYS_AT91_SLOW_CLOCK;
+ case AT91_PMC_MCKR_CSS_MAIN:
+ return gd->arch.main_clk_rate_hz;
+ case AT91_PMC_MCKR_CSS_PLLA:
+ return gd->arch.plla_rate_hz;
+ }
+
+ return 0;
+}
+
+static u32 at91_pll_rate(u32 freq, u32 reg)
+{
+ unsigned mul, div;
+
+ div = reg & 0xff;
+ mul = (reg >> 18) & 0x7f;
+ if (div && mul) {
+ freq /= div;
+ freq *= mul + 1;
+ } else {
+ freq = 0;
+ }
+
+ return freq;
+}
+
+int at91_clock_init(unsigned long main_clock)
+{
+ unsigned freq, mckr;
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
+ unsigned tmp;
+ /*
+ * When the bootloader initialized the main oscillator correctly,
+ * there's no problem using the cycle counter. But if it didn't,
+ * or when using oscillator bypass mode, we must be told the speed
+ * of the main clock.
+ */
+ if (!main_clock) {
+ do {
+ tmp = readl(&pmc->mcfr);
+ } while (!(tmp & AT91_PMC_MCFR_MAINRDY));
+ tmp &= AT91_PMC_MCFR_MAINF_MASK;
+ main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
+ }
+#endif
+ gd->arch.main_clk_rate_hz = main_clock;
+
+ /* report if PLLA is more than mildly overclocked */
+ gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
+
+ /*
+ * MCK and CPU derive from one of those primary clocks.
+ * For now, assume this parentage won't change.
+ */
+ mckr = readl(&pmc->mckr);
+
+ /* plla divisor by 2 */
+ if (mckr & (1 << 12))
+ gd->arch.plla_rate_hz >>= 1;
+
+ gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
+ freq = gd->arch.mck_rate_hz;
+
+ /* prescale */
+ freq >>= mckr & AT91_PMC_MCKR_PRES_MASK;
+
+ switch (mckr & AT91_PMC_MCKR_MDIV_MASK) {
+ case AT91_PMC_MCKR_MDIV_2:
+ gd->arch.mck_rate_hz = freq / 2;
+ break;
+ case AT91_PMC_MCKR_MDIV_3:
+ gd->arch.mck_rate_hz = freq / 3;
+ break;
+ case AT91_PMC_MCKR_MDIV_4:
+ gd->arch.mck_rate_hz = freq / 4;
+ break;
+ default:
+ break;
+ }
+
+ gd->arch.cpu_clk_rate_hz = freq;
+
+ return 0;
+}
+
+void at91_periph_clk_enable(int id)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ if (id > 31)
+ writel(1 << (id - 32), &pmc->pcer1);
+ else
+ writel(1 << id, &pmc->pcer);
+}
diff --git a/arch/arm/cpu/armv7/at91/cpu.c b/arch/arm/cpu/armv7/at91/cpu.c
new file mode 100644
index 0000000000..3df6143d74
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/cpu.c
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ * (C) Copyright 2009
+ * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * (C) Copyright 2013
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_dbu.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_pit.h>
+#include <asm/arch/at91_gpbr.h>
+#include <asm/arch/clk.h>
+
+#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
+#define CONFIG_SYS_AT91_MAIN_CLOCK 0
+#endif
+
+int arch_cpu_init(void)
+{
+ return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
+}
+
+void arch_preboot_os(void)
+{
+ ulong cpiv;
+ at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
+
+ cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir));
+
+ /*
+ * Disable PITC
+ * Add 0x1000 to current counter to stop it faster
+ * without waiting for wrapping back to 0
+ */
+ writel(cpiv + 0x1000, &pit->mr);
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ char buf[32];
+
+ printf("CPU: %s\n", get_cpu_name());
+ printf("Crystal frequency: %8s MHz\n",
+ strmhz(buf, get_main_clk_rate()));
+ printf("CPU clock : %8s MHz\n",
+ strmhz(buf, get_cpu_clk_rate()));
+ printf("Master clock : %8s MHz\n",
+ strmhz(buf, get_mck_clk_rate()));
+
+ return 0;
+}
+#endif
+
+void enable_caches(void)
+{
+}
+
+unsigned int get_chip_id(void)
+{
+ return readl(ATMEL_BASE_DBGU + AT91_DBU_CIDR) & ~AT91_DBU_CIDR_MASK;
+}
+
+unsigned int get_extension_chip_id(void)
+{
+ return readl(ATMEL_BASE_DBGU + AT91_DBU_EXID);
+}
diff --git a/arch/arm/cpu/armv7/at91/reset.c b/arch/arm/cpu/armv7/at91/reset.c
new file mode 100644
index 0000000000..b9f83d91b9
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/reset.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian@popies.net>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * (C) Copyright 2013
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_rstc.h>
+
+/* Reset the cpu by telling the reset controller to do so */
+void reset_cpu(ulong ignored)
+{
+ at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC;
+
+ writel(AT91_RSTC_KEY
+ | AT91_RSTC_CR_PROCRST /* Processor Reset */
+ | AT91_RSTC_CR_PERRST /* Peripheral Reset */
+#ifdef CONFIG_AT91RESET_EXTRST
+ | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */
+#endif
+ , &rstc->cr);
+ /* never reached */
+ do { } while (1);
+}
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
new file mode 100644
index 0000000000..acf8b43ee6
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012-2013 Atmel Corporation
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/sama5d3.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+
+unsigned int has_emac()
+{
+ return cpu_is_sama5d31() || cpu_is_sama5d35();
+}
+
+unsigned int has_gmac()
+{
+ return !cpu_is_sama5d31();
+}
+
+unsigned int has_lcdc()
+{
+ return !cpu_is_sama5d35();
+}
+
+char *get_cpu_name()
+{
+ unsigned int extension_id = get_extension_chip_id();
+
+ if (cpu_is_sama5d3())
+ switch (extension_id) {
+ case ARCH_EXID_SAMA5D31:
+ return "SAMA5D31";
+ case ARCH_EXID_SAMA5D33:
+ return "SAMA5D33";
+ case ARCH_EXID_SAMA5D34:
+ return "SAMA5D34";
+ case ARCH_EXID_SAMA5D35:
+ return "SAMA5D35";
+ default:
+ return "Unknown CPU type";
+ }
+ else
+ return "Unknown CPU type";
+}
+
+void at91_serial0_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTD, 18, 1); /* TXD0 */
+ at91_set_a_periph(AT91_PIO_PORTD, 17, 0); /* RXD0 */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_USART0);
+}
+
+void at91_serial1_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTB, 29, 1); /* TXD1 */
+ at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* RXD1 */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_USART1);
+}
+
+void at91_serial2_hw_init(void)
+{
+ at91_set_b_periph(AT91_PIO_PORTE, 26, 1); /* TXD2 */
+ at91_set_b_periph(AT91_PIO_PORTE, 25, 0); /* RXD2 */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_USART2);
+}
+
+void at91_seriald_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTB, 31, 1); /* DTXD */
+ at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_SYS);
+}
+
+#if defined(CONFIG_ATMEL_SPI)
+void at91_spi0_hw_init(unsigned long cs_mask)
+{
+ at91_set_a_periph(AT91_PIO_PORTD, 10, 0); /* SPI0_MISO */
+ at91_set_a_periph(AT91_PIO_PORTD, 11, 0); /* SPI0_MOSI */
+ at91_set_a_periph(AT91_PIO_PORTD, 12, 0); /* SPI0_SPCK */
+
+ if (cs_mask & (1 << 0))
+ at91_set_pio_output(AT91_PIO_PORTD, 13, 1);
+ if (cs_mask & (1 << 1))
+ at91_set_pio_output(AT91_PIO_PORTD, 14, 1);
+ if (cs_mask & (1 << 2))
+ at91_set_pio_output(AT91_PIO_PORTD, 15, 1);
+ if (cs_mask & (1 << 3))
+ at91_set_pio_output(AT91_PIO_PORTD, 16, 1);
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_SPI0);
+}
+#endif
+
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+void at91_mci_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTD, 0, 0); /* MCI0 CMD */
+ at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* MCI0 DA0 */
+ at91_set_a_periph(AT91_PIO_PORTD, 2, 0); /* MCI0 DA1 */
+ at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* MCI0 DA2 */
+ at91_set_a_periph(AT91_PIO_PORTD, 4, 0); /* MCI0 DA3 */
+#ifdef CONFIG_ATMEL_MCI_8BIT
+ at91_set_a_periph(AT91_PIO_PORTD, 5, 0); /* MCI0 DA4 */
+ at91_set_a_periph(AT91_PIO_PORTD, 6, 0); /* MCI0 DA5 */
+ at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* MCI0 DA6 */
+ at91_set_a_periph(AT91_PIO_PORTD, 8, 0); /* MCI0 DA7 */
+#endif
+ at91_set_a_periph(AT91_PIO_PORTD, 9, 0); /* MCI0 CLK */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_MCI0);
+}
+#endif
+
+#ifdef CONFIG_MACB
+void at91_macb_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* ETXCK_EREFCK */
+ at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* ERXDV */
+ at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* ERX0 */
+ at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* ERX1 */
+ at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* ERXER */
+ at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* ETXEN */
+ at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* ETX0 */
+ at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* ETX1 */
+ at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* EMDIO */
+ at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* EMDC */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_EMAC);
+}
+#endif
+
+#ifdef CONFIG_LCD
+void at91_lcd_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */
+ at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */
+ at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */
+ at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */
+ at91_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */
+ at91_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */
+
+ /* The lower 16-bit of LCD only available on Port A */
+ at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */
+ at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */
+ at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */
+ at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */
+ at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */
+ at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */
+ at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */
+ at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */
+ at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD8 */
+ at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD9 */
+ at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */
+ at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */
+ at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */
+ at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */
+ at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */
+ at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */
+
+ /* Enable clock */
+ at91_periph_clk_enable(ATMEL_ID_LCDC);
+}
+#endif
diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c
new file mode 100644
index 0000000000..b3a450fb31
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/timer.c
@@ -0,0 +1,139 @@
+/*
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian@popies.net>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * (C) Copyright 2013
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pit.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+#include <div64.h>
+
+#if !defined(CONFIG_AT91FAMILY)
+# error You need to define CONFIG_AT91FAMILY in your board config!
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * We're using the SAMA5D3x PITC in 32 bit mode, by
+ * setting the 20 bit counter period to its maximum (0xfffff).
+ * (See the relevant data sheets to understand that this really works)
+ *
+ * We do also mimic the typical powerpc way of incrementing
+ * two 32 bit registers called tbl and tbu.
+ *
+ * Those registers increment at 1/16 the main clock rate.
+ */
+
+#define TIMER_LOAD_VAL 0xfffff
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, gd->arch.timer_rate_hz);
+
+ return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+ usec *= gd->arch.timer_rate_hz;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
+/*
+ * Use the PITC in full 32 bit incrementing mode
+ */
+int timer_init(void)
+{
+ at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
+
+ /* Enable PITC Clock */
+ at91_periph_clk_enable(ATMEL_ID_SYS);
+
+ /* Enable PITC */
+ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
+
+ gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16;
+ gd->arch.tbu = 0;
+ gd->arch.tbl = 0;
+
+ return 0;
+}
+
+/*
+ * Get the current 64 bit timer tick count
+ */
+unsigned long long get_ticks(void)
+{
+ at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
+
+ ulong now = readl(&pit->piir);
+
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long long start;
+ ulong tmo;
+
+ start = get_ticks(); /* get current timestamp */
+ tmo = usec_to_tick(usec); /* convert usecs to ticks */
+ while ((get_ticks() - start) < tmo)
+ ; /* loop till time has passed */
+}
+
+/*
+ * get_timer(base) can be used to check for timeouts or
+ * to measure elasped time relative to an event:
+ *
+ * ulong start_time = get_timer(0) sets start_time to the current
+ * time value.
+ * get_timer(start_time) returns the time elapsed since then.
+ *
+ * The time is used in CONFIG_SYS_HZ units!
+ */
+ulong get_timer(ulong base)
+{
+ return tick_to_time(get_ticks()) - base;
+}
+
+/*
+ * Return the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 55e82ba369..c4b9809ad0 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -34,6 +34,7 @@ COBJS += hwinit-common.o
COBJS += clocks-common.o
COBJS += emif-common.o
COBJS += vc.o
+COBJS += abb.o
endif
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
diff --git a/arch/arm/cpu/armv7/omap-common/abb.c b/arch/arm/cpu/armv7/omap-common/abb.c
new file mode 100644
index 0000000000..87d1fb82eb
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/abb.c
@@ -0,0 +1,137 @@
+/*
+ *
+ * Adaptive Body Bias programming sequence for OMAP family
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+
+__weak s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
+{
+ return -1;
+}
+
+static void abb_setup_timings(u32 setup)
+{
+ u32 sys_rate, sr2_cnt, clk_cycles;
+
+ /*
+ * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a
+ * transition and must be programmed with the correct time at boot.
+ * The value programmed into the register is the number of SYS_CLK
+ * clock cycles that match a given wall time profiled for the ldo.
+ * This value depends on:
+ * settling time of ldo in micro-seconds (varies per OMAP family),
+ * of clock cycles per SYS_CLK period (varies per OMAP family),
+ * the SYS_CLK frequency in MHz (varies per board)
+ * The formula is:
+ *
+ * ldo settling time (in micro-seconds)
+ * SR2_WTCNT_VALUE = ------------------------------------------
+ * (# system clock cycles) * (sys_clk period)
+ *
+ * Put another way:
+ *
+ * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate))
+ *
+ * To avoid dividing by zero multiply both "# clock cycles" and
+ * "settling time" by 10 such that the final result is the one we want.
+ */
+
+ /* calculate SR2_WTCNT_VALUE */
+ sys_rate = DIV_ROUND(V_OSCK, 1000000);
+ clk_cycles = DIV_ROUND(OMAP_ABB_CLOCK_CYCLES * 10, sys_rate);
+ sr2_cnt = DIV_ROUND(OMAP_ABB_SETTLING_TIME * 10, clk_cycles);
+
+ setbits_le32(setup,
+ sr2_cnt << (ffs(OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK) - 1));
+}
+
+void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control,
+ u32 txdone, u32 txdone_mask, u32 opp)
+{
+ u32 abb_type_mask, opp_sel_mask;
+
+ /* sanity check */
+ if (!setup || !control || !txdone)
+ return;
+
+ /* setup ABB only in case of Fast or Slow OPP */
+ switch (opp) {
+ case OMAP_ABB_FAST_OPP:
+ abb_type_mask = OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK;
+ opp_sel_mask = OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK;
+ break;
+ case OMAP_ABB_SLOW_OPP:
+ abb_type_mask = OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK;
+ opp_sel_mask = OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK;
+ break;
+ default:
+ return;
+ }
+
+ /*
+ * For some OMAP silicons additional setup for LDOVBB register is
+ * required. This is determined by data retrieved from corresponding
+ * OPP EFUSE register. Data, which is retrieved from EFUSE - is
+ * ABB enable/disable flag and VSET value, which must be copied
+ * to LDOVBB register. If function call fails - return quietly,
+ * it means no ABB is required for such silicon.
+ *
+ * For silicons, which don't require LDOVBB setup "fuse" and
+ * "ldovbb" offsets are not defined. ABB will be initialized in
+ * the common way for them.
+ */
+ if (fuse && ldovbb) {
+ if (abb_setup_ldovbb(fuse, ldovbb))
+ return;
+ }
+
+ /* clear ABB registers */
+ writel(0, setup);
+ writel(0, control);
+
+ /* configure timings, based on oscillator value */
+ abb_setup_timings(setup);
+
+ /* clear pending interrupts before setup */
+ setbits_le32(txdone, txdone_mask);
+
+ /* select ABB type */
+ setbits_le32(setup, abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK);
+
+ /* initiate ABB ldo change */
+ setbits_le32(control, opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK);
+
+ /* wait until transition complete */
+ if (!wait_on_value(txdone_mask, txdone_mask, (void *)txdone, LDELAY))
+ puts("Error: ABB txdone is not set\n");
+
+ /* clear ABB tranxdone */
+ setbits_le32(txdone, txdone_mask);
+}
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index bff7e9c82a..76ae1b675f 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -25,6 +25,45 @@
DECLARE_GLOBAL_DATA_PTR;
+void save_omap_boot_params(void)
+{
+ u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+ u8 boot_device;
+ u32 dev_desc, dev_data;
+
+ if ((rom_params < NON_SECURE_SRAM_START) ||
+ (rom_params > NON_SECURE_SRAM_END))
+ return;
+
+ /*
+ * rom_params can be type casted to omap_boot_parameters and
+ * used. But it not correct to assume that romcode structure
+ * encoding would be same as u-boot. So use the defined offsets.
+ */
+ gd->arch.omap_boot_params.omap_bootdevice = boot_device =
+ *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
+
+ gd->arch.omap_boot_params.ch_flags =
+ *((u8 *)(rom_params + CH_FLAGS_OFFSET));
+
+ if ((boot_device >= MMC_BOOT_DEVICES_START) &&
+ (boot_device <= MMC_BOOT_DEVICES_END)) {
+#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX)
+ if ((omap_hw_init_context() ==
+ OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
+ gd->arch.omap_boot_params.omap_bootmode =
+ *((u8 *)(rom_params + BOOT_MODE_OFFSET));
+ } else
+#endif
+ {
+ dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET));
+ dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET));
+ gd->arch.omap_boot_params.omap_bootmode =
+ *((u32 *)(dev_data + BOOT_MODE_OFFSET));
+ }
+ }
+}
+
#ifdef CONFIG_SPL_BUILD
u32 spl_boot_device(void)
{
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 99910cdcb0..ef23127bb6 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -30,9 +30,10 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <i2c.h>
#include <asm/omap_common.h>
#include <asm/gpio.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/utils.h>
#include <asm/omap_gpio.h>
@@ -49,13 +50,12 @@
const u32 sys_clk_array[8] = {
12000000, /* 12 MHz */
- 13000000, /* 13 MHz */
+ 20000000, /* 20 MHz */
16800000, /* 16.8 MHz */
19200000, /* 19.2 MHz */
26000000, /* 26 MHz */
27000000, /* 27 MHz */
38400000, /* 38.4 MHz */
- 20000000, /* 20 MHz */
};
static inline u32 __get_sys_clk_index(void)
@@ -74,13 +74,6 @@ static inline u32 __get_sys_clk_index(void)
/* SYS_CLKSEL - 1 to match the dpll param array indices */
ind = (readl((*prcm)->cm_sys_clksel) &
CM_SYS_CLKSEL_SYS_CLKSEL_MASK) - 1;
- /*
- * SYS_CLKSEL value for 20MHz is 0. This is introduced newly
- * in DRA7XX socs. SYS_CLKSEL -1 will be greater than
- * NUM_SYS_CLK. So considering the last 3 bits as the index
- * for the dpll param array.
- */
- ind &= CM_SYS_CLKSEL_SYS_CLKSEL_MASK;
}
return ind;
}
@@ -440,6 +433,12 @@ static void setup_non_essential_dplls(void)
params = get_abe_dpll_params(*dplls_data);
#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_SYSCLK;
+
+ if (omap_revision() == DRA752_ES1_0)
+ /* Select the sys clk for dpll_abe */
+ clrsetbits_le32((*prcm)->cm_abe_pll_sys_clksel,
+ CM_CLKSEL_ABE_PLL_SYS_CLKSEL_MASK,
+ CM_ABE_PLL_SYS_CLKSEL_SYSCLK2);
#else
abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_32KCLK;
/*
@@ -487,6 +486,10 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
u32 offset = volt_mv;
int ret = 0;
+ if (!volt_mv)
+ return;
+
+ pmic->pmic_bus_init();
/* See if we can first get the GPIO if needed */
if (pmic->gpio_en)
ret = gpio_request(pmic->gpio, "PMIC_GPIO");
@@ -509,14 +512,45 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv,
offset_code);
- if (omap_vc_bypass_send_value(SMPS_I2C_SLAVE_ADDR,
- vcore_reg, offset_code))
+ if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code))
printf("Scaling voltage failed for 0x%x\n", vcore_reg);
if (pmic->gpio_en)
gpio_direction_output(pmic->gpio, 1);
}
+static u32 optimize_vcore_voltage(struct volts const *v)
+{
+ u32 val;
+ if (!v->value)
+ return 0;
+ if (!v->efuse.reg)
+ return v->value;
+
+ switch (v->efuse.reg_bits) {
+ case 16:
+ val = readw(v->efuse.reg);
+ break;
+ case 32:
+ val = readl(v->efuse.reg);
+ break;
+ default:
+ printf("Error: efuse 0x%08x bits=%d unknown\n",
+ v->efuse.reg, v->efuse.reg_bits);
+ return v->value;
+ }
+
+ if (!val) {
+ printf("Error: efuse 0x%08x bits=%d val=0, using %d\n",
+ v->efuse.reg, v->efuse.reg_bits, v->value);
+ return v->value;
+ }
+
+ debug("%s:efuse 0x%08x bits=%d Vnom=%d, using efuse value %d\n",
+ __func__, v->efuse.reg, v->efuse.reg_bits, v->value, val);
+ return val;
+}
+
/*
* Setup the voltages for vdd_mpu, vdd_core, and vdd_iva
* We set the maximum voltages allowed here because Smart-Reflex is not
@@ -525,16 +559,34 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
*/
void scale_vcores(struct vcores_data const *vcores)
{
- omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ);
+ u32 val;
+
+ val = optimize_vcore_voltage(&vcores->core);
+ do_scale_vcore(vcores->core.addr, val, vcores->core.pmic);
+
+ val = optimize_vcore_voltage(&vcores->mpu);
+ do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic);
+
+ /* Configure MPU ABB LDO after scale */
+ abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2,
+ (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl,
+ (*prcm)->prm_abbldo_mpu_setup,
+ (*prcm)->prm_abbldo_mpu_ctrl,
+ (*prcm)->prm_irqstatus_mpu_2,
+ OMAP_ABB_MPU_TXDONE_MASK,
+ OMAP_ABB_FAST_OPP);
- do_scale_vcore(vcores->core.addr, vcores->core.value,
- vcores->core.pmic);
+ val = optimize_vcore_voltage(&vcores->mm);
+ do_scale_vcore(vcores->mm.addr, val, vcores->mm.pmic);
- do_scale_vcore(vcores->mpu.addr, vcores->mpu.value,
- vcores->mpu.pmic);
+ val = optimize_vcore_voltage(&vcores->gpu);
+ do_scale_vcore(vcores->gpu.addr, val, vcores->gpu.pmic);
- do_scale_vcore(vcores->mm.addr, vcores->mm.value,
- vcores->mm.pmic);
+ val = optimize_vcore_voltage(&vcores->eve);
+ do_scale_vcore(vcores->eve.addr, val, vcores->eve.pmic);
+
+ val = optimize_vcore_voltage(&vcores->iva);
+ do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic);
if (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3) {
/* Configure LDO SRAM "magic" bits */
@@ -710,6 +762,7 @@ void prcm_init(void)
case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
enable_basic_clocks();
+ timer_init();
scale_vcores(*omap_vcores);
setup_dplls();
#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
@@ -725,3 +778,13 @@ void prcm_init(void)
if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context())
enable_basic_uboot_clocks();
}
+
+void gpi2c_init(void)
+{
+ static int gpi2c = 1;
+
+ if (gpi2c) {
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ gpi2c = 0;
+ }
+}
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 11e830a533..652e5a71b3 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -27,7 +27,7 @@
#include <common.h>
#include <asm/emif.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/omap_common.h>
#include <asm/utils.h>
@@ -209,7 +209,8 @@ void emif_update_timings(u32 base, const struct emif_regs *regs)
writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
- if (omap_revision() >= OMAP5430_ES1_0) {
+ if ((omap_revision() >= OMAP5430_ES1_0) ||
+ (omap_revision() == DRA752_ES1_0)) {
writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0,
&emif->emif_l3_config);
} else if (omap_revision() >= OMAP4460_ES1_0) {
@@ -263,6 +264,18 @@ static void ddr3_leveling(u32 base, const struct emif_regs *regs)
__udelay(130);
}
+static void ddr3_sw_leveling(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
+ config_data_eye_leveling_samples(base);
+
+ writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
+ writel(regs->sdram_config, &emif->emif_sdram_config);
+}
+
static void ddr3_init(u32 base, const struct emif_regs *regs)
{
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
@@ -273,6 +286,7 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
* defined, contents of mode Registers must be fully initialized.
* H/W takes care of this initialization
*/
+ writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
writel(regs->sdram_config_init, &emif->emif_sdram_config);
writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
@@ -290,7 +304,10 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
/* enable leveling */
writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
- ddr3_leveling(base, regs);
+ if (omap_revision() == DRA752_ES1_0)
+ ddr3_sw_leveling(base, regs);
+ else
+ ddr3_leveling(base, regs);
}
#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
@@ -1078,7 +1095,10 @@ static void do_sdram_init(u32 base)
if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) {
set_lpmode_selfrefresh(base);
emif_reset_phy(base);
- ddr3_leveling(base, regs);
+ if (omap_revision() == DRA752_ES1_0)
+ ddr3_sw_leveling(base, regs);
+ else
+ ddr3_leveling(base, regs);
}
/* Write to the shadow registers */
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 1645120de7..5df116edbe 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -84,7 +84,7 @@ u32 cortex_rev(void)
return rev;
}
-void omap_rev_string(void)
+static void omap_rev_string(void)
{
u32 omap_rev = omap_revision();
u32 soc_variant = (omap_rev & 0xF0000000) >> 28;
@@ -111,42 +111,6 @@ void __weak srcomp_enable(void)
{
}
-static void save_omap_boot_params(void)
-{
- u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
- u8 boot_device;
- u32 dev_desc, dev_data;
-
- if ((rom_params < NON_SECURE_SRAM_START) ||
- (rom_params > NON_SECURE_SRAM_END))
- return;
-
- /*
- * rom_params can be type casted to omap_boot_parameters and
- * used. But it not correct to assume that romcode structure
- * encoding would be same as u-boot. So use the defined offsets.
- */
- gd->arch.omap_boot_params.omap_bootdevice = boot_device =
- *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
-
- gd->arch.omap_boot_params.ch_flags =
- *((u8 *)(rom_params + CH_FLAGS_OFFSET));
-
- if ((boot_device >= MMC_BOOT_DEVICES_START) &&
- (boot_device <= MMC_BOOT_DEVICES_END)) {
- if ((omap_hw_init_context() ==
- OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
- gd->arch.omap_boot_params.omap_bootmode =
- *((u8 *)(rom_params + BOOT_MODE_OFFSET));
- } else {
- dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET));
- dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET));
- gd->arch.omap_boot_params.omap_bootmode =
- *((u32 *)(dev_data + BOOT_MODE_OFFSET));
- }
- }
-}
-
#ifdef CONFIG_ARCH_CPU_INIT
/*
* SOC specific cpu init
@@ -202,8 +166,6 @@ void s_init(void)
#endif
prcm_init();
#ifdef CONFIG_SPL_BUILD
- timer_init();
-
/* For regular u-boot sdram_init() is called from dram_init() */
sdram_init();
#endif
diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c
index 507f6873e9..5926a5a810 100644
--- a/arch/arm/cpu/armv7/omap-common/timer.c
+++ b/arch/arm/cpu/armv7/omap-common/timer.c
@@ -35,6 +35,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/arm/cpu/armv7/omap-common/vc.c b/arch/arm/cpu/armv7/omap-common/vc.c
index e6e5f7893c..a68f1d145d 100644
--- a/arch/arm/cpu/armv7/omap-common/vc.c
+++ b/arch/arm/cpu/armv7/omap-common/vc.c
@@ -17,6 +17,7 @@
#include <common.h>
#include <asm/omap_common.h>
#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
/*
* Define Master code if there are multiple masters on the I2C_SR bus.
@@ -57,7 +58,7 @@
* omap_vc_init() - Initialization for Voltage controller
* @speed_khz: I2C buspeed in KHz
*/
-void omap_vc_init(u16 speed_khz)
+static void omap_vc_init(u16 speed_khz)
{
u32 val;
u32 sys_clk_khz, cycles_hi, cycles_low;
@@ -137,3 +138,14 @@ int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data)
/* All good.. */
return 0;
}
+
+void sri2c_init(void)
+{
+ static int sri2c = 1;
+
+ if (sri2c) {
+ omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ);
+ sri2c = 0;
+ }
+ return;
+}
diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c
index 09c51f62aa..81cc859780 100644
--- a/arch/arm/cpu/armv7/omap3/clock.c
+++ b/arch/arm/cpu/armv7/omap3/clock.c
@@ -27,7 +27,7 @@
#include <common.h>
#include <asm/io.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/arch/clocks_omap3.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
diff --git a/arch/arm/cpu/armv7/omap4/hw_data.c b/arch/arm/cpu/armv7/omap4/hw_data.c
index 06a2fc8c2f..b97cad4364 100644
--- a/arch/arm/cpu/armv7/omap4/hw_data.c
+++ b/arch/arm/cpu/armv7/omap4/hw_data.c
@@ -29,7 +29,7 @@
#include <asm/arch/omap.h>
#include <asm/arch/sys_proto.h>
#include <asm/omap_common.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/omap_gpio.h>
#include <asm/io.h>
@@ -219,6 +219,9 @@ struct pmic_data twl6030_4430es1 = {
.step = 12660, /* 12.66 mV represented in uV */
/* The code starts at 1 not 0 */
.start_code = 1,
+ .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR,
+ .pmic_bus_init = sri2c_init,
+ .pmic_write = omap_vc_bypass_send_value,
};
struct pmic_data twl6030 = {
@@ -226,6 +229,9 @@ struct pmic_data twl6030 = {
.step = 12660, /* 12.66 mV represented in uV */
/* The code starts at 1 not 0 */
.start_code = 1,
+ .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR,
+ .pmic_bus_init = sri2c_init,
+ .pmic_write = omap_vc_bypass_send_value,
};
struct pmic_data tps62361 = {
@@ -233,7 +239,10 @@ struct pmic_data tps62361 = {
.step = 10000, /* 10 mV represented in uV */
.start_code = 0,
.gpio = TPS62361_VSEL0_GPIO,
- .gpio_en = 1
+ .gpio_en = 1,
+ .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR,
+ .pmic_bus_init = sri2c_init,
+ .pmic_write = omap_vc_bypass_send_value,
};
struct vcores_data omap4430_volts_es1 = {
diff --git a/arch/arm/cpu/armv7/omap4/prcm-regs.c b/arch/arm/cpu/armv7/omap4/prcm-regs.c
index 7225a301b1..7e71ca0a26 100644
--- a/arch/arm/cpu/armv7/omap4/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap4/prcm-regs.c
@@ -301,6 +301,8 @@ struct omap_sys_ctrl_regs const omap4_ctrl = {
.control_ldosram_iva_voltage_ctrl = 0x4A002320,
.control_ldosram_mpu_voltage_ctrl = 0x4A002324,
.control_ldosram_core_voltage_ctrl = 0x4A002328,
+ .control_usbotghs_ctrl = 0x4A00233C,
+ .control_padconf_core_base = 0x4A100000,
.control_pbiaslite = 0x4A100600,
.control_lpddr2io1_0 = 0x4A100638,
.control_lpddr2io1_1 = 0x4A10063C,
@@ -312,4 +314,5 @@ struct omap_sys_ctrl_regs const omap4_ctrl = {
.control_lpddr2io2_3 = 0x4A100654,
.control_efuse_1 = 0x4A100700,
.control_efuse_2 = 0x4A100704,
+ .control_padconf_wkup_base = 0x4A31E000,
};
diff --git a/arch/arm/cpu/armv7/omap5/Makefile b/arch/arm/cpu/armv7/omap5/Makefile
index ce00e2c3c5..6ff8dbb4eb 100644
--- a/arch/arm/cpu/armv7/omap5/Makefile
+++ b/arch/arm/cpu/armv7/omap5/Makefile
@@ -30,6 +30,7 @@ COBJS += emif.o
COBJS += sdram.o
COBJS += prcm-regs.o
COBJS += hw_data.o
+COBJS += abb.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/omap5/abb.c b/arch/arm/cpu/armv7/omap5/abb.c
new file mode 100644
index 0000000000..92470becc0
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap5/abb.c
@@ -0,0 +1,67 @@
+/*
+ *
+ * Adaptive Body Bias programming sequence for OMAP5 family
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/io.h>
+
+/*
+ * Setup LDOVBB for OMAP5.
+ * On OMAP5+ some ABB settings are fused. They are handled
+ * in the following way:
+ *
+ * 1. corresponding EFUSE register contains ABB enable bit
+ * and VSET value
+ * 2. If ABB enable bit is set to 1, than ABB should be
+ * enabled, otherwise ABB should be disabled
+ * 3. If ABB is enabled, than VSET value should be copied
+ * to corresponding MUX control register
+ */
+s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
+{
+ u32 vset;
+
+ /*
+ * ABB parameters must be properly fused
+ * otherwise ABB should be disabled
+ */
+ vset = readl(fuse);
+ if (!(vset & OMAP5_ABB_FUSE_ENABLE_MASK))
+ return -1;
+
+ /* prepare VSET value for LDOVBB mux register */
+ vset &= OMAP5_ABB_FUSE_VSET_MASK;
+ vset >>= ffs(OMAP5_ABB_FUSE_VSET_MASK) - 1;
+ vset <<= ffs(OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK) - 1;
+ vset |= OMAP5_ABB_LDOVBBMPU_MUX_CTRL_MASK;
+
+ /* setup LDOVBB using fused value */
+ clrsetbits_le32(ldovbb, OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK, vset);
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index 604fa42b1b..56cf1f8c60 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -26,10 +26,11 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <palmas.h>
#include <asm/arch/omap.h>
#include <asm/arch/sys_proto.h>
#include <asm/omap_common.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/omap_gpio.h>
#include <asm/io.h>
#include <asm/emif.h>
@@ -99,14 +100,13 @@ static const struct dpll_params mpu_dpll_params_499mhz[NUM_SYS_CLKS] = {
};
static const struct dpll_params mpu_dpll_params_1ghz[NUM_SYS_CLKS] = {
- {250, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */
- {119, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
- {625, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
- {500, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
+ {250, 2, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
+ {500, 9, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */
+ {119, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
+ {625, 11, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
+ {500, 12, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
- {625, 23, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
- {50, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 20 MHz */
+ {625, 23, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
};
static const struct dpll_params
@@ -132,15 +132,14 @@ static const struct dpll_params
};
static const struct dpll_params
- core_dpll_params_2128mhz_ddr532_dra7xx[NUM_SYS_CLKS] = {
- {266, 2, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6}, /* 12 MHz */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */
- {443, 6, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6}, /* 16.8 MHz */
- {277, 4, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6}, /* 19.2 MHz */
- {368, 8, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6}, /* 26 MHz */
+ core_dpll_params_2128mhz_dra7xx[NUM_SYS_CLKS] = {
+ {266, 2, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 12 MHz */
+ {266, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 20 MHz */
+ {443, 6, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 16.8 MHz */
+ {277, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 19.2 MHz */
+ {368, 8, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 26 MHz */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
- {277, 9, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6}, /* 38.4 MHz */
- {266, 4, 2, -1, -1, 4, 62, 5, -1, 5, 7, 6} /* 20 MHz */
+ {277, 9, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 38.4 MHz */
};
static const struct dpll_params
@@ -186,14 +185,13 @@ static const struct dpll_params per_dpll_params_768mhz_es2[NUM_SYS_CLKS] = {
};
static const struct dpll_params per_dpll_params_768mhz_dra7xx[NUM_SYS_CLKS] = {
- {32, 0, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 12 MHz */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */
- {160, 6, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 16.8 MHz */
- {20, 0, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 19.2 MHz */
- {192, 12, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 26 MHz */
+ {32, 0, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 12 MHz */
+ {96, 4, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 20 MHz */
+ {160, 6, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 16.8 MHz */
+ {20, 0, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 19.2 MHz */
+ {192, 12, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 26 MHz */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
- {10, 0, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 38.4 MHz */
- {96, 4, 4, -1, 3, 4, 10, 2, -1, -1, -1, -1} /* 20 MHz */
+ {10, 0, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 38.4 MHz */
};
static const struct dpll_params iva_dpll_params_2330mhz[NUM_SYS_CLKS] = {
@@ -206,6 +204,16 @@ static const struct dpll_params iva_dpll_params_2330mhz[NUM_SYS_CLKS] = {
{91, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */
};
+static const struct dpll_params iva_dpll_params_2330mhz_dra7xx[NUM_SYS_CLKS] = {
+ {1165, 11, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
+ {233, 3, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */
+ {208, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
+ {182, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
+ {224, 4, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
+ {91, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
+};
+
/* ABE M & N values with sys_clk as source */
static const struct dpll_params
abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = {
@@ -223,26 +231,36 @@ static const struct dpll_params abe_dpll_params_32k_196608khz = {
750, 0, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1
};
+/* ABE M & N values with sysclk2(22.5792 MHz) as input */
+static const struct dpll_params
+ abe_dpll_params_sysclk2_361267khz[NUM_SYS_CLKS] = {
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
+ {16, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
+};
+
static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = {
{400, 4, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */
+ {480, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */
{400, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
{400, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
{480, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
{400, 15, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
- {48, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 20 MHz */
};
-static const struct dpll_params ddr_dpll_params_1066mhz[NUM_SYS_CLKS] = {
- {533, 11, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */
- {222, 6, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
- {111, 3, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
- {41, 1, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
+static const struct dpll_params ddr_dpll_params_2128mhz[NUM_SYS_CLKS] = {
+ {266, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */
+ {266, 4, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */
+ {190, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */
+ {665, 11, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
+ {532, 12, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */
- {347, 24, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
- {533, 19, 1, 1, 4, -1, -1, -1, -1, -1, -1, -1} /* 20 MHz */
+ {665, 23, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */
};
struct dplls omap5_dplls_es1 = {
@@ -275,10 +293,12 @@ struct dplls omap5_dplls_es2 = {
struct dplls dra7xx_dplls = {
.mpu = mpu_dpll_params_1ghz,
- .core = core_dpll_params_2128mhz_ddr532_dra7xx,
+ .core = core_dpll_params_2128mhz_dra7xx,
.per = per_dpll_params_768mhz_dra7xx,
+ .abe = abe_dpll_params_sysclk2_361267khz,
+ .iva = iva_dpll_params_2330mhz_dra7xx,
.usb = usb_dpll_params_1920mhz,
- .ddr = ddr_dpll_params_1066mhz,
+ .ddr = ddr_dpll_params_2128mhz,
};
struct pmic_data palmas = {
@@ -289,6 +309,22 @@ struct pmic_data palmas = {
* Offset code 0 switches OFF the SMPS
*/
.start_code = 6,
+ .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR,
+ .pmic_bus_init = sri2c_init,
+ .pmic_write = omap_vc_bypass_send_value,
+};
+
+struct pmic_data tps659038 = {
+ .base_offset = PALMAS_SMPS_BASE_VOLT_UV,
+ .step = 10000, /* 10 mV represented in uV */
+ /*
+ * Offset codes 1-6 all give the base voltage in Palmas
+ * Offset code 0 switches OFF the SMPS
+ */
+ .start_code = 6,
+ .i2c_slave_addr = TPS659038_I2C_SLAVE_ADDR,
+ .pmic_bus_init = gpi2c_init,
+ .pmic_write = palmas_i2c_write_u8,
};
struct vcores_data omap5430_volts = {
@@ -319,6 +355,38 @@ struct vcores_data omap5430_volts_es2 = {
.mm.pmic = &palmas,
};
+struct vcores_data dra752_volts = {
+ .mpu.value = VDD_MPU_DRA752,
+ .mpu.efuse.reg = STD_FUSE_OPP_VMIN_MPU_NOM,
+ .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+ .mpu.addr = TPS659038_REG_ADDR_SMPS12_MPU,
+ .mpu.pmic = &tps659038,
+
+ .eve.value = VDD_EVE_DRA752,
+ .eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+ .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+ .eve.addr = TPS659038_REG_ADDR_SMPS45_EVE,
+ .eve.pmic = &tps659038,
+
+ .gpu.value = VDD_GPU_DRA752,
+ .gpu.efuse.reg = STD_FUSE_OPP_VMIN_GPU_NOM,
+ .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+ .gpu.addr = TPS659038_REG_ADDR_SMPS6_GPU,
+ .gpu.pmic = &tps659038,
+
+ .core.value = VDD_CORE_DRA752,
+ .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM,
+ .core.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+ .core.addr = TPS659038_REG_ADDR_SMPS7_CORE,
+ .core.pmic = &tps659038,
+
+ .iva.value = VDD_IVA_DRA752,
+ .iva.efuse.reg = STD_FUSE_OPP_VMIN_IVA_NOM,
+ .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+ .iva.addr = TPS659038_REG_ADDR_SMPS8_IVA,
+ .iva.pmic = &tps659038,
+};
+
/*
* Enable essential clock domains, modules and
* do some additional special settings needed
@@ -383,12 +451,6 @@ void enable_basic_clocks(void)
clk_modules_explicit_en_essential,
1);
- /* Select 384Mhz for GPU as its the POR for ES1.0 */
- setbits_le32((*prcm)->cm_sgx_sgx_clkctrl,
- CLKSEL_GPU_HYD_GCLK_MASK);
- setbits_le32((*prcm)->cm_sgx_sgx_clkctrl,
- CLKSEL_GPU_CORE_GCLK_MASK);
-
/* Enable SCRM OPT clocks for PER and CORE dpll */
setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl,
OPTFCLKEN_SCRM_PER_MASK);
@@ -540,6 +602,17 @@ const struct ctrl_ioregs ioregs_omap5432_es2 = {
.ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES,
};
+const struct ctrl_ioregs ioregs_dra7xx_es1 = {
+ .ctrl_ddrch = 0x40404040,
+ .ctrl_lpddr2ch = 0x40404040,
+ .ctrl_ddr3ch = 0x80808080,
+ .ctrl_ddrio_0 = 0xbae8c631,
+ .ctrl_ddrio_1 = 0xb46318d8,
+ .ctrl_ddrio_2 = 0x84210000,
+ .ctrl_emif_sdram_config_ext = 0xb2c00000,
+ .ctrl_ddr_ctrl_ext_0 = 0xA2000000,
+};
+
void hw_data_init(void)
{
u32 omap_rev = omap_revision();
@@ -565,7 +638,7 @@ void hw_data_init(void)
case DRA752_ES1_0:
*prcm = &dra7xx_prcm;
*dplls_data = &dra7xx_dplls;
- *omap_vcores = &omap5430_volts_es2;
+ *omap_vcores = &dra752_volts;
*ctrl = &dra7xx_ctrl;
break;
@@ -582,14 +655,16 @@ void get_ioregs(const struct ctrl_ioregs **regs)
case OMAP5430_ES1_0:
case OMAP5430_ES2_0:
*regs = &ioregs_omap5430;
- break;
+ break;
case OMAP5432_ES1_0:
*regs = &ioregs_omap5432_es1;
- break;
+ break;
case OMAP5432_ES2_0:
- case DRA752_ES1_0:
*regs = &ioregs_omap5432_es2;
- break;
+ break;
+ case DRA752_ES1_0:
+ *regs = &ioregs_dra7xx_es1;
+ break;
default:
printf("\n INVALID OMAP REVISION ");
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index e192fea0eb..daf124e99c 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -32,7 +32,7 @@
#include <asm/armv7.h>
#include <asm/arch/cpu.h>
#include <asm/arch/sys_proto.h>
-#include <asm/arch/clocks.h>
+#include <asm/arch/clock.h>
#include <asm/sizes.h>
#include <asm/utils.h>
#include <asm/arch/gpio.h>
@@ -100,16 +100,21 @@ static void io_settings_ddr3(void)
writel(ioregs->ctrl_emif_sdram_config_ext,
(*ctrl)->control_emif2_sdram_config_ext);
- /* Disable DLL select */
- io_settings = (readl((*ctrl)->control_port_emif1_sdram_config)
+ if (is_omap54xx()) {
+ /* Disable DLL select */
+ io_settings = (readl((*ctrl)->control_port_emif1_sdram_config)
& 0xFFEFFFFF);
- writel(io_settings,
- (*ctrl)->control_port_emif1_sdram_config);
+ writel(io_settings,
+ (*ctrl)->control_port_emif1_sdram_config);
- io_settings = (readl((*ctrl)->control_port_emif2_sdram_config)
+ io_settings = (readl((*ctrl)->control_port_emif2_sdram_config)
& 0xFFEFFFFF);
- writel(io_settings,
- (*ctrl)->control_port_emif2_sdram_config);
+ writel(io_settings,
+ (*ctrl)->control_port_emif2_sdram_config);
+ } else {
+ writel(ioregs->ctrl_ddr_ctrl_ext_0,
+ (*ctrl)->control_ddr_control_ext_0);
+ }
}
/*
@@ -201,6 +206,9 @@ void srcomp_enable(void)
u32 sysclk_ind = get_sys_clk_index();
u32 omap_rev = omap_revision();
+ if (!is_omap54xx())
+ return;
+
mul_factor = srcomp_parameters[sysclk_ind].multiply_factor;
div_factor = srcomp_parameters[sysclk_ind].divide_factor;
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c
index e9f6a32653..e839ff5fe5 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -298,6 +298,7 @@ struct prcm_regs const omap5_es1_prcm = {
.cm_wkupaon_io_srcomp_clkctrl = 0x4ae07898,
.prm_rstctrl = 0x4ae07b00,
.prm_rstst = 0x4ae07b04,
+ .prm_rsttime = 0x4ae07b08,
.prm_vc_val_bypass = 0x4ae07ba0,
.prm_vc_cfg_i2c_mode = 0x4ae07bb4,
.prm_vc_cfg_i2c_clk = 0x4ae07bb8,
@@ -307,10 +308,16 @@ struct prcm_regs const omap5_es1_prcm = {
.prm_sldo_mpu_ctrl = 0x4ae07bd0,
.prm_sldo_mm_setup = 0x4ae07bd4,
.prm_sldo_mm_ctrl = 0x4ae07bd8,
+
+ /* SCRM stuff, used by some boards */
+ .scrm_auxclk0 = 0x4ae0a310,
+ .scrm_auxclk1 = 0x4ae0a314,
};
struct omap_sys_ctrl_regs const omap5_ctrl = {
.control_status = 0x4A002134,
+ .control_std_fuse_opp_vdd_mpu_2 = 0x4A0021B4,
+ .control_padconf_core_base = 0x4A002800,
.control_paconf_global = 0x4A002DA0,
.control_paconf_mode = 0x4A002DA4,
.control_smart1io_padconf_0 = 0x4A002DA8,
@@ -358,6 +365,8 @@ struct omap_sys_ctrl_regs const omap5_ctrl = {
.control_port_emif2_sdram_config = 0x4AE0C118,
.control_emif1_sdram_config_ext = 0x4AE0C144,
.control_emif2_sdram_config_ext = 0x4AE0C148,
+ .control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C318,
+ .control_padconf_wkup_base = 0x4AE0C800,
.control_smart1nopmio_padconf_0 = 0x4AE0CDA0,
.control_smart1nopmio_padconf_1 = 0x4AE0CDA4,
.control_padconf_mode = 0x4AE0CDA8,
@@ -434,6 +443,7 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = {
.control_srcomp_east_side = 0x4A002E7C,
.control_srcomp_west_side = 0x4A002E80,
.control_srcomp_code_latch = 0x4A002E84,
+ .control_ddr_control_ext_0 = 0x4A002E88,
.control_padconf_core_base = 0x4A003400,
.control_port_emif1_sdram_config = 0x4AE0C110,
.control_port_emif1_lpddr2_nvm_config = 0x4AE0C114,
@@ -709,6 +719,9 @@ struct prcm_regs const omap5_es2_prcm = {
.cm_l3init_fsusb_clkctrl = 0x4a0096d0,
.cm_l3init_ocp2scp1_clkctrl = 0x4a0096e0,
+ /* prm irqstatus regs */
+ .prm_irqstatus_mpu_2 = 0x4ae06014,
+
/* l4 wkup regs */
.cm_abe_pll_ref_clksel = 0x4ae0610c,
.cm_sys_clksel = 0x4ae06110,
@@ -740,6 +753,12 @@ struct prcm_regs const omap5_es2_prcm = {
.prm_sldo_mpu_ctrl = 0x4ae07cd0,
.prm_sldo_mm_setup = 0x4ae07cd4,
.prm_sldo_mm_ctrl = 0x4ae07cd8,
+ .prm_abbldo_mpu_setup = 0x4ae07cdc,
+ .prm_abbldo_mpu_ctrl = 0x4ae07ce0,
+
+ /* SCRM stuff, used by some boards */
+ .scrm_auxclk0 = 0x4ae0a310,
+ .scrm_auxclk1 = 0x4ae0a314,
};
struct prcm_regs const dra7xx_prcm = {
@@ -941,6 +960,7 @@ struct prcm_regs const dra7xx_prcm = {
/* l4 wkup regs */
.cm_abe_pll_ref_clksel = 0x4ae0610c,
.cm_sys_clksel = 0x4ae06110,
+ .cm_abe_pll_sys_clksel = 0x4ae06118,
.cm_wkup_clkstctrl = 0x4ae07800,
.cm_wkup_l4wkup_clkctrl = 0x4ae07820,
.cm_wkup_wdtimer1_clkctrl = 0x4ae07828,
diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c
index 6b461e4846..1b445a61eb 100644
--- a/arch/arm/cpu/armv7/omap5/sdram.c
+++ b/arch/arm/cpu/armv7/omap5/sdram.c
@@ -108,6 +108,7 @@ const struct emif_regs emif_regs_266_mhz_2cs = {
const struct emif_regs emif_regs_ddr3_532_mhz_1cs = {
.sdram_config_init = 0x61851B32,
.sdram_config = 0x61851B32,
+ .sdram_config2 = 0x0,
.ref_ctrl = 0x00001035,
.sdram_tim1 = 0xCCCF36B3,
.sdram_tim2 = 0x308F7FDA,
@@ -131,6 +132,7 @@ const struct emif_regs emif_regs_ddr3_532_mhz_1cs = {
const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = {
.sdram_config_init = 0x61851B32,
.sdram_config = 0x61851B32,
+ .sdram_config2 = 0x0,
.ref_ctrl = 0x00001035,
.sdram_tim1 = 0xCCCF36B3,
.sdram_tim2 = 0x308F7FDA,
@@ -151,6 +153,54 @@ const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = {
.emif_rd_wr_exec_thresh = 0x40000305
};
+const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = {
+ .sdram_config_init = 0x61851ab2,
+ .sdram_config = 0x61851ab2,
+ .sdram_config2 = 0x08000000,
+ .ref_ctrl = 0x00001035,
+ .sdram_tim1 = 0xCCCF36B3,
+ .sdram_tim2 = 0x308F7FDA,
+ .sdram_tim3 = 0x027F88A8,
+ .read_idle_ctrl = 0x00050000,
+ .zq_config = 0x0007190B,
+ .temp_alert_config = 0x00000000,
+ .emif_ddr_phy_ctlr_1_init = 0x0E20400A,
+ .emif_ddr_phy_ctlr_1 = 0x0E24400A,
+ .emif_ddr_ext_phy_ctrl_1 = 0x04040100,
+ .emif_ddr_ext_phy_ctrl_2 = 0x009E009E,
+ .emif_ddr_ext_phy_ctrl_3 = 0x009E009E,
+ .emif_ddr_ext_phy_ctrl_4 = 0x009E009E,
+ .emif_ddr_ext_phy_ctrl_5 = 0x009E009E,
+ .emif_rd_wr_lvl_rmp_win = 0x00000000,
+ .emif_rd_wr_lvl_rmp_ctl = 0x80000000,
+ .emif_rd_wr_lvl_ctl = 0x00000000,
+ .emif_rd_wr_exec_thresh = 0x00000305
+};
+
+const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = {
+ .sdram_config_init = 0x61851B32,
+ .sdram_config = 0x61851B32,
+ .sdram_config2 = 0x08000000,
+ .ref_ctrl = 0x00001035,
+ .sdram_tim1 = 0xCCCF36B3,
+ .sdram_tim2 = 0x308F7FDA,
+ .sdram_tim3 = 0x027F88A8,
+ .read_idle_ctrl = 0x00050000,
+ .zq_config = 0x0007190B,
+ .temp_alert_config = 0x00000000,
+ .emif_ddr_phy_ctlr_1_init = 0x0020400A,
+ .emif_ddr_phy_ctlr_1 = 0x0E24400A,
+ .emif_ddr_ext_phy_ctrl_1 = 0x04040100,
+ .emif_ddr_ext_phy_ctrl_2 = 0x009D009D,
+ .emif_ddr_ext_phy_ctrl_3 = 0x009D009D,
+ .emif_ddr_ext_phy_ctrl_4 = 0x009D009D,
+ .emif_ddr_ext_phy_ctrl_5 = 0x009D009D,
+ .emif_rd_wr_lvl_rmp_win = 0x00000000,
+ .emif_rd_wr_lvl_rmp_ctl = 0x80000000,
+ .emif_rd_wr_lvl_ctl = 0x00000000,
+ .emif_rd_wr_exec_thresh = 0x00000305
+};
+
const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = {
.dmm_lisa_map_0 = 0x0,
.dmm_lisa_map_1 = 0x0,
@@ -159,11 +209,39 @@ const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = {
.is_ma_present = 0x1
};
-const struct dmm_lisa_map_regs lisa_map_512M_x_1 = {
+/*
+ * DRA752 EVM board has 1.5 GB of memory
+ * EMIF1 --> 2Gb * 2 = 512MB
+ * EMIF2 --> 2Gb * 4 = 1GB
+ * so mapping 1GB interleaved and 512MB non-interleaved
+ */
+const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2_2G_x_1_x_2 = {
+ .dmm_lisa_map_0 = 0x0,
+ .dmm_lisa_map_1 = 0x80640300,
+ .dmm_lisa_map_2 = 0xC0500220,
+ .dmm_lisa_map_3 = 0xFF020100,
+ .is_ma_present = 0x1
+};
+
+/*
+ * DRA752 EVM EMIF1 ONLY CONFIGURATION
+ */
+const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = {
.dmm_lisa_map_0 = 0x0,
.dmm_lisa_map_1 = 0x0,
- .dmm_lisa_map_2 = 0x0,
- .dmm_lisa_map_3 = 0x80500100,
+ .dmm_lisa_map_2 = 0x80500100,
+ .dmm_lisa_map_3 = 0xFF020100,
+ .is_ma_present = 0x1
+};
+
+/*
+ * DRA752 EVM EMIF2 ONLY CONFIGURATION
+ */
+const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = {
+ .dmm_lisa_map_0 = 0x0,
+ .dmm_lisa_map_1 = 0x0,
+ .dmm_lisa_map_2 = 0x80600200,
+ .dmm_lisa_map_3 = 0xFF020100,
.is_ma_present = 0x1
};
@@ -180,9 +258,20 @@ static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
*regs = &emif_regs_532_mhz_2cs_es2;
break;
case OMAP5432_ES2_0:
+ *regs = &emif_regs_ddr3_532_mhz_1cs_es2;
+ break;
case DRA752_ES1_0:
+ switch (emif_nr) {
+ case 1:
+ *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1;
+ break;
+ case 2:
+ *regs = &emif_2_regs_ddr3_532_mhz_1cs_dra_es1;
+ break;
+ }
+ break;
default:
- *regs = &emif_regs_ddr3_532_mhz_1cs_es2;
+ *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1;
}
}
@@ -201,7 +290,7 @@ static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
break;
case DRA752_ES1_0:
default:
- *dmm_lisa_regs = &lisa_map_512M_x_1;
+ *dmm_lisa_regs = &lisa_map_2G_x_2_x_2_2G_x_1_x_2;
}
}
@@ -252,7 +341,8 @@ const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = {
0x00000000,
0x00000000,
0x00000000,
- 0x00000077
+ 0x00000077,
+ 0x0
};
const u32 ddr3_ext_phy_ctrl_const_base_es1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
@@ -274,7 +364,8 @@ const u32 ddr3_ext_phy_ctrl_const_base_es1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
0x00000000,
0x00000000,
0x00000000,
- 0x00000057
+ 0x00000057,
+ 0x0
};
const u32 ddr3_ext_phy_ctrl_const_base_es2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
@@ -296,7 +387,56 @@ const u32 ddr3_ext_phy_ctrl_const_base_es2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
0x00000000,
0x00000000,
0x00000000,
- 0x00000057
+ 0x00000057,
+ 0x0
+};
+
+const u32
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+ 0x009E009E,
+ 0x002E002E,
+ 0x002E002E,
+ 0x002E002E,
+ 0x002E002E,
+ 0x002E002E,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x004D004D,
+ 0x0,
+ 0x600020,
+ 0x40010080,
+ 0x8102040
+};
+
+const u32
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+ 0x009D009D,
+ 0x002D002D,
+ 0x002D002D,
+ 0x002D002D,
+ 0x002D002D,
+ 0x002D002D,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x00570057,
+ 0x0,
+ 0x600020,
+ 0x40010080,
+ 0x8102040
};
const struct lpddr2_mr_regs mr_regs = {
@@ -307,7 +447,7 @@ const struct lpddr2_mr_regs mr_regs = {
.mr16 = MR16_REF_FULL_ARRAY
};
-static void emif_get_ext_phy_ctrl_const_regs(const u32 **regs)
+static void emif_get_ext_phy_ctrl_const_regs(u32 emif_nr, const u32 **regs)
{
switch (omap_revision()) {
case OMAP5430_ES1_0:
@@ -318,7 +458,14 @@ static void emif_get_ext_phy_ctrl_const_regs(const u32 **regs)
*regs = ddr3_ext_phy_ctrl_const_base_es1;
break;
case OMAP5432_ES2_0:
+ *regs = ddr3_ext_phy_ctrl_const_base_es2;
+ break;
case DRA752_ES1_0:
+ if (emif_nr == 1)
+ *regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif1;
+ else
+ *regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif2;
+ break;
default:
*regs = ddr3_ext_phy_ctrl_const_base_es2;
@@ -334,9 +481,12 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
{
u32 *ext_phy_ctrl_base = 0;
u32 *emif_ext_phy_ctrl_base = 0;
+ u32 emif_nr;
const u32 *ext_phy_ctrl_const_regs;
u32 i = 0;
+ emif_nr = (base == EMIF1_BASE) ? 1 : 2;
+
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
@@ -353,7 +503,7 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
* external phy 6-24 registers do not change with
* ddr frequency
*/
- emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs);
+ emif_get_ext_phy_ctrl_const_regs(emif_nr, &ext_phy_ctrl_const_regs);
for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) {
writel(ext_phy_ctrl_const_regs[i],
emif_ext_phy_ctrl_base++);
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index e9e57e6450..8e9cb19119 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -94,10 +94,6 @@ _TEXT_BASE:
_bss_start_ofs:
.word __bss_start - _start
-.globl _image_copy_end_ofs
-_image_copy_end_ofs:
- .word __image_copy_end - _start
-
.globl _bss_end_ofs
_bss_end_ofs:
.word __bss_end - _start
@@ -167,80 +163,6 @@ reset:
/*------------------------------------------------------------------------------*/
-#ifndef CONFIG_SPL_BUILD
-/*
- * void relocate_code(addr_moni)
- *
- * This function relocates the monitor code.
- */
-ENTRY(relocate_code)
- mov r6, r0 /* save addr of destination */
-
- adr r0, _start
- subs r9, r6, r0 /* r9 <- relocation offset */
- beq relocate_done /* skip relocation */
- mov r1, r6 /* r1 <- scratch for copy_loop */
- ldr r3, _image_copy_end_ofs
- add r2, r0, r3 /* r2 <- source end address */
-
-copy_loop:
- ldmia r0!, {r10-r11} /* copy from source address [r0] */
- stmia r1!, {r10-r11} /* copy to target address [r1] */
- cmp r0, r2 /* until source end address [r2] */
- blo copy_loop
-
- /*
- * fix .rel.dyn relocations
- */
- ldr r0, _TEXT_BASE /* r0 <- Text base */
- ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
- add r10, r10, r0 /* r10 <- sym table in FLASH */
- ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
- add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
- ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
- add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
-fixloop:
- ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
- add r0, r0, r9 /* r0 <- location to fix up in RAM */
- ldr r1, [r2, #4]
- and r7, r1, #0xff
- cmp r7, #23 /* relative fixup? */
- beq fixrel
- cmp r7, #2 /* absolute fixup? */
- beq fixabs
- /* ignore unknown type of fixup */
- b fixnext
-fixabs:
- /* absolute fix: set location to (offset) symbol value */
- mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
- add r1, r10, r1 /* r1 <- address of symbol in table */
- ldr r1, [r1, #4] /* r1 <- symbol value */
- add r1, r1, r9 /* r1 <- relocated sym addr */
- b fixnext
-fixrel:
- /* relative fix: increase location by offset */
- ldr r1, [r0]
- add r1, r1, r9
-fixnext:
- str r1, [r0]
- add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
- cmp r2, r3
- blo fixloop
-
-relocate_done:
-
- bx lr
-
-_rel_dyn_start_ofs:
- .word __rel_dyn_start - _start
-_rel_dyn_end_ofs:
- .word __rel_dyn_end - _start
-_dynsym_start_ofs:
- .word __dynsym_start - _start
-ENDPROC(relocate_code)
-
-#endif
-
ENTRY(c_runtime_cpu_setup)
/*
* If I-cache is enabled invalidate it
diff --git a/arch/arm/cpu/armv7/vf610/Makefile b/arch/arm/cpu/armv7/vf610/Makefile
new file mode 100644
index 0000000000..9232cd4276
--- /dev/null
+++ b/arch/arm/cpu/armv7/vf610/Makefile
@@ -0,0 +1,42 @@
+#
+# Copyright 2013 Freescale Semiconductor, 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; either version 2 of
+# the License, or (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).o
+
+COBJS += generic.o
+COBJS += timer.o
+
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c
new file mode 100644
index 0000000000..87f2a8642d
--- /dev/null
+++ b/arch/arm/cpu/armv7/vf610/generic.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <netdev.h>
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+#ifdef CONFIG_MXC_OCOTP
+void enable_ocotp_clk(unsigned char enable)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 reg;
+
+ reg = readl(&ccm->ccgr6);
+ if (enable)
+ reg |= CCM_CCGR6_OCOTP_CTRL_MASK;
+ else
+ reg &= ~CCM_CCGR6_OCOTP_CTRL_MASK;
+ writel(reg, &ccm->ccgr6);
+}
+#endif
+
+static u32 get_mcu_main_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_ccsr, ccm_cacrr, armclk_div;
+ u32 sysclk_sel, pll_pfd_sel = 0;
+ u32 freq = 0;
+
+ ccm_ccsr = readl(&ccm->ccsr);
+ sysclk_sel = ccm_ccsr & CCM_CCSR_SYS_CLK_SEL_MASK;
+ sysclk_sel >>= CCM_CCSR_SYS_CLK_SEL_OFFSET;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+ armclk_div = ccm_cacrr & CCM_CACRR_ARM_CLK_DIV_MASK;
+ armclk_div >>= CCM_CACRR_ARM_CLK_DIV_OFFSET;
+ armclk_div += 1;
+
+ switch (sysclk_sel) {
+ case 0:
+ freq = FASE_CLK_FREQ;
+ break;
+ case 1:
+ freq = SLOW_CLK_FREQ;
+ break;
+ case 2:
+ pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK;
+ pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET;
+ if (pll_pfd_sel == 0)
+ freq = PLL2_MAIN_FREQ;
+ else if (pll_pfd_sel == 1)
+ freq = PLL2_PFD1_FREQ;
+ else if (pll_pfd_sel == 2)
+ freq = PLL2_PFD2_FREQ;
+ else if (pll_pfd_sel == 3)
+ freq = PLL2_PFD3_FREQ;
+ else if (pll_pfd_sel == 4)
+ freq = PLL2_PFD4_FREQ;
+ break;
+ case 3:
+ freq = PLL2_MAIN_FREQ;
+ break;
+ case 4:
+ pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK;
+ pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET;
+ if (pll_pfd_sel == 0)
+ freq = PLL1_MAIN_FREQ;
+ else if (pll_pfd_sel == 1)
+ freq = PLL1_PFD1_FREQ;
+ else if (pll_pfd_sel == 2)
+ freq = PLL1_PFD2_FREQ;
+ else if (pll_pfd_sel == 3)
+ freq = PLL1_PFD3_FREQ;
+ else if (pll_pfd_sel == 4)
+ freq = PLL1_PFD4_FREQ;
+ break;
+ case 5:
+ freq = PLL3_MAIN_FREQ;
+ break;
+ default:
+ printf("unsupported system clock select\n");
+ }
+
+ return freq / armclk_div;
+}
+
+static u32 get_bus_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cacrr, busclk_div;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+
+ busclk_div = ccm_cacrr & CCM_CACRR_BUS_CLK_DIV_MASK;
+ busclk_div >>= CCM_CACRR_BUS_CLK_DIV_OFFSET;
+ busclk_div += 1;
+
+ return get_mcu_main_clk() / busclk_div;
+}
+
+static u32 get_ipg_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cacrr, ipgclk_div;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+
+ ipgclk_div = ccm_cacrr & CCM_CACRR_IPG_CLK_DIV_MASK;
+ ipgclk_div >>= CCM_CACRR_IPG_CLK_DIV_OFFSET;
+ ipgclk_div += 1;
+
+ return get_bus_clk() / ipgclk_div;
+}
+
+static u32 get_uart_clk(void)
+{
+ return get_ipg_clk();
+}
+
+static u32 get_sdhc_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cscmr1, ccm_cscdr2, sdhc_clk_sel, sdhc_clk_div;
+ u32 freq = 0;
+
+ ccm_cscmr1 = readl(&ccm->cscmr1);
+ sdhc_clk_sel = ccm_cscmr1 & CCM_CSCMR1_ESDHC1_CLK_SEL_MASK;
+ sdhc_clk_sel >>= CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
+
+ ccm_cscdr2 = readl(&ccm->cscdr2);
+ sdhc_clk_div = ccm_cscdr2 & CCM_CSCDR2_ESDHC1_CLK_DIV_MASK;
+ sdhc_clk_div >>= CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET;
+ sdhc_clk_div += 1;
+
+ switch (sdhc_clk_sel) {
+ case 0:
+ freq = PLL3_MAIN_FREQ;
+ break;
+ case 1:
+ freq = PLL3_PFD3_FREQ;
+ break;
+ case 2:
+ freq = PLL1_PFD3_FREQ;
+ break;
+ case 3:
+ freq = get_bus_clk();
+ break;
+ }
+
+ return freq / sdhc_clk_div;
+}
+
+u32 get_fec_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cscmr2, rmii_clk_sel;
+ u32 freq = 0;
+
+ ccm_cscmr2 = readl(&ccm->cscmr2);
+ rmii_clk_sel = ccm_cscmr2 & CCM_CSCMR2_RMII_CLK_SEL_MASK;
+ rmii_clk_sel >>= CCM_CSCMR2_RMII_CLK_SEL_OFFSET;
+
+ switch (rmii_clk_sel) {
+ case 0:
+ freq = ENET_EXTERNAL_CLK;
+ break;
+ case 1:
+ freq = AUDIO_EXTERNAL_CLK;
+ break;
+ case 2:
+ freq = PLL5_MAIN_FREQ;
+ break;
+ case 3:
+ freq = PLL5_MAIN_FREQ / 2;
+ break;
+ }
+
+ return freq;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return get_mcu_main_clk();
+ case MXC_BUS_CLK:
+ return get_bus_clk();
+ case MXC_IPG_CLK:
+ return get_ipg_clk();
+ case MXC_UART_CLK:
+ return get_uart_clk();
+ case MXC_ESDHC_CLK:
+ return get_sdhc_clk();
+ case MXC_FEC_CLK:
+ return get_fec_clk();
+ default:
+ break;
+ }
+ return -1;
+}
+
+/* Dump some core clocks */
+int do_vf610_showclocks(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ printf("\n");
+ printf("cpu clock : %8d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("bus clock : %8d MHz\n", mxc_get_clock(MXC_BUS_CLK) / 1000000);
+ printf("ipg clock : %8d MHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000000);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clocks, CONFIG_SYS_MAXARGS, 1, do_vf610_showclocks,
+ "display clocks",
+ ""
+);
+
+#ifdef CONFIG_FEC_MXC
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[4];
+ struct fuse_bank4_regs *fuse =
+ (struct fuse_bank4_regs *)bank->fuse_regs;
+
+ u32 value = readl(&fuse->mac_addr0);
+ mac[0] = (value >> 8);
+ mac[1] = value;
+
+ value = readl(&fuse->mac_addr1);
+ mac[2] = value >> 24;
+ mac[3] = value >> 16;
+ mac[4] = value >> 8;
+ mac[5] = value;
+}
+#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+static char *get_reset_cause(void)
+{
+ u32 cause;
+ struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+
+ cause = readl(&src_regs->srsr);
+ writel(cause, &src_regs->srsr);
+ cause &= 0xff;
+
+ switch (cause) {
+ case 0x08:
+ return "WDOG";
+ case 0x20:
+ return "JTAG HIGH-Z";
+ case 0x80:
+ return "EXTERNAL RESET";
+ case 0xfd:
+ return "POR";
+ default:
+ return "unknown reset";
+ }
+}
+
+int print_cpuinfo(void)
+{
+ printf("CPU: Freescale Vybrid VF610 at %d MHz\n",
+ mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("Reset cause: %s\n", get_reset_cause());
+
+ return 0;
+}
+#endif
+
+int cpu_eth_init(bd_t *bis)
+{
+ int rc = -ENODEV;
+
+#if defined(CONFIG_FEC_MXC)
+ rc = fecmxc_initialize(bis);
+#endif
+
+ return rc;
+}
+
+#ifdef CONFIG_FSL_ESDHC
+int cpu_mmc_init(bd_t *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/vf610/timer.c b/arch/arm/cpu/armv7/vf610/timer.c
new file mode 100644
index 0000000000..f8fbed7864
--- /dev/null
+++ b/arch/arm/cpu/armv7/vf610/timer.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+static struct pit_reg *cur_pit = (struct pit_reg *)PIT_BASE_ADDR;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, mxc_get_clock(MXC_IPG_CLK));
+
+ return tick;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long usec)
+{
+ usec = usec * mxc_get_clock(MXC_IPG_CLK) + 999999;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
+int timer_init(void)
+{
+ __raw_writel(0, &cur_pit->mcr);
+
+ __raw_writel(TIMER_LOAD_VAL, &cur_pit->ldval1);
+ __raw_writel(0, &cur_pit->tctrl1);
+ __raw_writel(1, &cur_pit->tctrl1);
+
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong now = TIMER_LOAD_VAL - __raw_readl(&cur_pit->cval1);
+
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+ulong get_timer_masked(void)
+{
+ return tick_to_time(get_ticks());
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/* delay x useconds AND preserve advance timstamp value */
+void __udelay(unsigned long usec)
+{
+ unsigned long long start;
+ ulong tmo;
+
+ start = get_ticks(); /* get current timestamp */
+ tmo = us_to_tick(usec); /* convert usecs to ticks */
+ while ((get_ticks() - start) < tmo)
+ ; /* loop till time has passed */
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return mxc_get_clock(MXC_IPG_CLK);
+}