summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/at32ap/Makefile3
-rw-r--r--cpu/at32ap/at32ap700x/Makefile2
-rw-r--r--cpu/at32ap/at32ap700x/clk.c25
-rw-r--r--cpu/at32ap/at32ap700x/gpio.c199
-rw-r--r--cpu/at32ap/at32ap700x/portmux.c204
-rw-r--r--cpu/at32ap/cache.c2
-rw-r--r--cpu/at32ap/cpu.c3
-rw-r--r--cpu/at32ap/pio.c116
-rw-r--r--cpu/at32ap/portmux-gpio.c107
-rw-r--r--cpu/at32ap/portmux-pio.c92
-rw-r--r--cpu/blackfin/cpu.c8
-rw-r--r--cpu/blackfin/initcode.c255
-rw-r--r--cpu/blackfin/jtag-console.c15
-rw-r--r--cpu/blackfin/reset.c2
-rw-r--r--cpu/blackfin/start.S83
-rw-r--r--cpu/blackfin/traps.c2
-rw-r--r--cpu/mpc5xxx/i2c.c30
17 files changed, 719 insertions, 429 deletions
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index 33dc427..e08f273 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -34,7 +34,8 @@ COBJS-y += hsdramc.o
COBJS-y += exception.o
COBJS-y += cache.o
COBJS-y += interrupts.o
-COBJS-y += pio.o
+COBJS-$(CONFIG_PORTMUX_PIO) += portmux-pio.o
+COBJS-$(CONFIG_PORTMUX_GPIO) += portmux-gpio.o
SRCS := $(START-y:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
diff --git a/cpu/at32ap/at32ap700x/Makefile b/cpu/at32ap/at32ap700x/Makefile
index 7404235..46e6ef6 100644
--- a/cpu/at32ap/at32ap700x/Makefile
+++ b/cpu/at32ap/at32ap700x/Makefile
@@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)lib$(SOC).a
-COBJS := gpio.o clk.o
+COBJS := portmux.o clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c
index 2b1cd36..2c2e19c 100644
--- a/cpu/at32ap/at32ap700x/clk.c
+++ b/cpu/at32ap/at32ap700x/clk.c
@@ -25,6 +25,7 @@
#include <asm/arch/clk.h>
#include <asm/arch/memory-map.h>
+#include <asm/arch/portmux.h>
#include "sm.h"
@@ -66,3 +67,27 @@ void clk_init(void)
sm_writel(PM_MCCTRL, SM_BIT(PLLSEL));
#endif
}
+
+unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent,
+ unsigned long rate, unsigned long parent_rate)
+{
+ unsigned long divider;
+
+ if (rate == 0 || parent_rate == 0) {
+ sm_writel(PM_GCCTRL(id), 0);
+ return 0;
+ }
+
+ divider = (parent_rate + rate / 2) / rate;
+ if (divider <= 1) {
+ sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN));
+ rate = parent_rate;
+ } else {
+ divider = min(255, divider / 2 - 1);
+ sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN) | SM_BIT(DIVEN)
+ | SM_BF(DIV, divider));
+ rate = parent_rate / (2 * (divider + 1));
+ }
+
+ return rate;
+}
diff --git a/cpu/at32ap/at32ap700x/gpio.c b/cpu/at32ap/at32ap700x/gpio.c
deleted file mode 100644
index 91bb636..0000000
--- a/cpu/at32ap/at32ap700x/gpio.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2006 Atmel Corporation
- *
- * 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/chip-features.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/memory-map.h>
-
-/*
- * Lots of small functions here. We depend on --gc-sections getting
- * rid of the ones we don't need.
- */
-void gpio_enable_ebi(void)
-{
-#ifdef CONFIG_SYS_HSDRAMC
-#ifndef CONFIG_SYS_SDRAM_16BIT
- gpio_select_periph_A(GPIO_PIN_PE0, 0);
- gpio_select_periph_A(GPIO_PIN_PE1, 0);
- gpio_select_periph_A(GPIO_PIN_PE2, 0);
- gpio_select_periph_A(GPIO_PIN_PE3, 0);
- gpio_select_periph_A(GPIO_PIN_PE4, 0);
- gpio_select_periph_A(GPIO_PIN_PE5, 0);
- gpio_select_periph_A(GPIO_PIN_PE6, 0);
- gpio_select_periph_A(GPIO_PIN_PE7, 0);
- gpio_select_periph_A(GPIO_PIN_PE8, 0);
- gpio_select_periph_A(GPIO_PIN_PE9, 0);
- gpio_select_periph_A(GPIO_PIN_PE10, 0);
- gpio_select_periph_A(GPIO_PIN_PE11, 0);
- gpio_select_periph_A(GPIO_PIN_PE12, 0);
- gpio_select_periph_A(GPIO_PIN_PE13, 0);
- gpio_select_periph_A(GPIO_PIN_PE14, 0);
- gpio_select_periph_A(GPIO_PIN_PE15, 0);
-#endif
- gpio_select_periph_A(GPIO_PIN_PE26, 0);
-#endif
-}
-
-#ifdef AT32AP700x_CHIP_HAS_USART
-void gpio_enable_usart0(void)
-{
- gpio_select_periph_B(GPIO_PIN_PA8, 0);
- gpio_select_periph_B(GPIO_PIN_PA9, 0);
-}
-
-void gpio_enable_usart1(void)
-{
- gpio_select_periph_A(GPIO_PIN_PA17, 0);
- gpio_select_periph_A(GPIO_PIN_PA18, 0);
-}
-
-void gpio_enable_usart2(void)
-{
- gpio_select_periph_B(GPIO_PIN_PB26, 0);
- gpio_select_periph_B(GPIO_PIN_PB27, 0);
-}
-
-void gpio_enable_usart3(void)
-{
- gpio_select_periph_B(GPIO_PIN_PB17, 0);
- gpio_select_periph_B(GPIO_PIN_PB18, 0);
-}
-#endif
-
-#ifdef AT32AP700x_CHIP_HAS_MACB
-void gpio_enable_macb0(void)
-{
- gpio_select_periph_A(GPIO_PIN_PC3, 0); /* TXD0 */
- gpio_select_periph_A(GPIO_PIN_PC4, 0); /* TXD1 */
- gpio_select_periph_A(GPIO_PIN_PC7, 0); /* TXEN */
- gpio_select_periph_A(GPIO_PIN_PC8, 0); /* TXCK */
- gpio_select_periph_A(GPIO_PIN_PC9, 0); /* RXD0 */
- gpio_select_periph_A(GPIO_PIN_PC10, 0); /* RXD1 */
- gpio_select_periph_A(GPIO_PIN_PC13, 0); /* RXER */
- gpio_select_periph_A(GPIO_PIN_PC15, 0); /* RXDV */
- gpio_select_periph_A(GPIO_PIN_PC16, 0); /* MDC */
- gpio_select_periph_A(GPIO_PIN_PC17, 0); /* MDIO */
-#if !defined(CONFIG_RMII)
- gpio_select_periph_A(GPIO_PIN_PC0, 0); /* COL */
- gpio_select_periph_A(GPIO_PIN_PC1, 0); /* CRS */
- gpio_select_periph_A(GPIO_PIN_PC2, 0); /* TXER */
- gpio_select_periph_A(GPIO_PIN_PC5, 0); /* TXD2 */
- gpio_select_periph_A(GPIO_PIN_PC6, 0); /* TXD3 */
- gpio_select_periph_A(GPIO_PIN_PC11, 0); /* RXD2 */
- gpio_select_periph_A(GPIO_PIN_PC12, 0); /* RXD3 */
- gpio_select_periph_A(GPIO_PIN_PC14, 0); /* RXCK */
- gpio_select_periph_A(GPIO_PIN_PC18, 0); /* SPD */
-#endif
-}
-
-void gpio_enable_macb1(void)
-{
- gpio_select_periph_B(GPIO_PIN_PD13, 0); /* TXD0 */
- gpio_select_periph_B(GPIO_PIN_PD14, 0); /* TXD1 */
- gpio_select_periph_B(GPIO_PIN_PD11, 0); /* TXEN */
- gpio_select_periph_B(GPIO_PIN_PD12, 0); /* TXCK */
- gpio_select_periph_B(GPIO_PIN_PD10, 0); /* RXD0 */
- gpio_select_periph_B(GPIO_PIN_PD6, 0); /* RXD1 */
- gpio_select_periph_B(GPIO_PIN_PD5, 0); /* RXER */
- gpio_select_periph_B(GPIO_PIN_PD4, 0); /* RXDV */
- gpio_select_periph_B(GPIO_PIN_PD3, 0); /* MDC */
- gpio_select_periph_B(GPIO_PIN_PD2, 0); /* MDIO */
-#if !defined(CONFIG_RMII)
- gpio_select_periph_B(GPIO_PIN_PC19, 0); /* COL */
- gpio_select_periph_B(GPIO_PIN_PC23, 0); /* CRS */
- gpio_select_periph_B(GPIO_PIN_PC26, 0); /* TXER */
- gpio_select_periph_B(GPIO_PIN_PC27, 0); /* TXD2 */
- gpio_select_periph_B(GPIO_PIN_PC28, 0); /* TXD3 */
- gpio_select_periph_B(GPIO_PIN_PC29, 0); /* RXD2 */
- gpio_select_periph_B(GPIO_PIN_PC30, 0); /* RXD3 */
- gpio_select_periph_B(GPIO_PIN_PC24, 0); /* RXCK */
- gpio_select_periph_B(GPIO_PIN_PD15, 0); /* SPD */
-#endif
-}
-#endif
-
-#ifdef AT32AP700x_CHIP_HAS_MMCI
-void gpio_enable_mmci(void)
-{
- gpio_select_periph_A(GPIO_PIN_PA10, 0); /* CLK */
- gpio_select_periph_A(GPIO_PIN_PA11, 0); /* CMD */
- gpio_select_periph_A(GPIO_PIN_PA12, 0); /* DATA0 */
- gpio_select_periph_A(GPIO_PIN_PA13, 0); /* DATA1 */
- gpio_select_periph_A(GPIO_PIN_PA14, 0); /* DATA2 */
- gpio_select_periph_A(GPIO_PIN_PA15, 0); /* DATA3 */
-}
-#endif
-
-#ifdef AT32AP700x_CHIP_HAS_SPI
-void gpio_enable_spi0(unsigned long cs_mask)
-{
- gpio_select_periph_A(GPIO_PIN_PA0, 0); /* MISO */
- gpio_select_periph_A(GPIO_PIN_PA1, 0); /* MOSI */
- gpio_select_periph_A(GPIO_PIN_PA2, 0); /* SCK */
-
- /* Set up NPCSx as GPIO outputs, initially high */
- if (cs_mask & (1 << 0)) {
- gpio_set_value(GPIO_PIN_PA3, 1);
- gpio_select_pio(GPIO_PIN_PA3, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 1)) {
- gpio_set_value(GPIO_PIN_PA4, 1);
- gpio_select_pio(GPIO_PIN_PA4, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 2)) {
- gpio_set_value(GPIO_PIN_PA5, 1);
- gpio_select_pio(GPIO_PIN_PA5, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 3)) {
- gpio_set_value(GPIO_PIN_PA20, 1);
- gpio_select_pio(GPIO_PIN_PA20, GPIOF_OUTPUT);
- }
-}
-
-void gpio_enable_spi1(unsigned long cs_mask)
-{
- gpio_select_periph_B(GPIO_PIN_PA0, 0); /* MISO */
- gpio_select_periph_B(GPIO_PIN_PB1, 0); /* MOSI */
- gpio_select_periph_B(GPIO_PIN_PB5, 0); /* SCK */
-
- /* Set up NPCSx as GPIO outputs, initially high */
- if (cs_mask & (1 << 0)) {
- gpio_set_value(GPIO_PIN_PB2, 1);
- gpio_select_pio(GPIO_PIN_PB2, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 1)) {
- gpio_set_value(GPIO_PIN_PB3, 1);
- gpio_select_pio(GPIO_PIN_PB3, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 2)) {
- gpio_set_value(GPIO_PIN_PB4, 1);
- gpio_select_pio(GPIO_PIN_PB4, GPIOF_OUTPUT);
- }
- if (cs_mask & (1 << 3)) {
- gpio_set_value(GPIO_PIN_PA27, 1);
- gpio_select_pio(GPIO_PIN_PA27, GPIOF_OUTPUT);
- }
-}
-#endif
diff --git a/cpu/at32ap/at32ap700x/portmux.c b/cpu/at32ap/at32ap700x/portmux.c
new file mode 100644
index 0000000..2a3b004
--- /dev/null
+++ b/cpu/at32ap/at32ap700x/portmux.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2006, 2008 Atmel Corporation
+ *
+ * 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/chip-features.h>
+#include <asm/arch/memory-map.h>
+#include <asm/arch/portmux.h>
+
+/*
+ * Lots of small functions here. We depend on --gc-sections getting
+ * rid of the ones we don't need.
+ */
+void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width,
+ unsigned long flags, unsigned long drive_strength)
+{
+ unsigned long porte_mask = 0;
+
+ if (bus_width > 16)
+ portmux_select_peripheral(PORTMUX_PORT_E, 0xffff,
+ PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
+ if (addr_width > 23)
+ porte_mask |= (((1 << (addr_width - 23)) - 1) & 7) << 16;
+ if (flags & PORTMUX_EBI_CS(2))
+ porte_mask |= 1 << 25;
+ if (flags & PORTMUX_EBI_CS(4))
+ porte_mask |= 1 << 21;
+ if (flags & PORTMUX_EBI_CS(5))
+ porte_mask |= 1 << 22;
+ if (flags & (PORTMUX_EBI_CF(0) | PORTMUX_EBI_CF(1)))
+ porte_mask |= (1 << 19) | (1 << 20) | (1 << 23);
+
+ portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
+ PORTMUX_FUNC_A, 0);
+
+ if (flags & PORTMUX_EBI_NWAIT)
+ portmux_select_peripheral(PORTMUX_PORT_E, 1 << 24,
+ PORTMUX_FUNC_A, PORTMUX_PULL_UP);
+}
+
+#ifdef AT32AP700x_CHIP_HAS_MACB
+void portmux_enable_macb0(unsigned long flags, unsigned long drive_strength)
+{
+ unsigned long portc_mask;
+
+ portc_mask = (1 << 3) /* TXD0 */
+ | (1 << 4) /* TXD1 */
+ | (1 << 7) /* TXEN */
+ | (1 << 8) /* TXCK */
+ | (1 << 9) /* RXD0 */
+ | (1 << 10) /* RXD1 */
+ | (1 << 13) /* RXER */
+ | (1 << 15) /* RXDV */
+ | (1 << 16) /* MDC */
+ | (1 << 17); /* MDIO */
+
+ if (flags & PORTMUX_MACB_MII)
+ portc_mask |= (1 << 0) /* COL */
+ | (1 << 1) /* CRS */
+ | (1 << 2) /* TXER */
+ | (1 << 5) /* TXD2 */
+ | (1 << 6) /* TXD3 */
+ | (1 << 11) /* RXD2 */
+ | (1 << 12) /* RXD3 */
+ | (1 << 14); /* RXCK */
+
+ if (flags & PORTMUX_MACB_SPEED)
+ portc_mask |= (1 << 18);/* SPD */
+
+ /* REVISIT: Some pins are probably pure outputs */
+ portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
+ PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
+}
+
+void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength)
+{
+ unsigned long portc_mask = 0;
+ unsigned long portd_mask;
+
+ portd_mask = (1 << 13) /* TXD0 */
+ | (1 << 14) /* TXD1 */
+ | (1 << 11) /* TXEN */
+ | (1 << 12) /* TXCK */
+ | (1 << 10) /* RXD0 */
+ | (1 << 6) /* RXD1 */
+ | (1 << 5) /* RXER */
+ | (1 << 4) /* RXDV */
+ | (1 << 3) /* MDC */
+ | (1 << 2); /* MDIO */
+
+ if (flags & PORTMUX_MACB_MII)
+ portc_mask = (1 << 19) /* COL */
+ | (1 << 23) /* CRS */
+ | (1 << 26) /* TXER */
+ | (1 << 27) /* TXD2 */
+ | (1 << 28) /* TXD3 */
+ | (1 << 29) /* RXD2 */
+ | (1 << 30) /* RXD3 */
+ | (1 << 24); /* RXCK */
+
+ if (flags & PORTMUX_MACB_SPEED)
+ portd_mask |= (1 << 15);/* SPD */
+
+ /* REVISIT: Some pins are probably pure outputs */
+ portmux_select_peripheral(PORTMUX_PORT_D, portc_mask,
+ PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
+ portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
+ PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
+}
+#endif
+
+#ifdef AT32AP700x_CHIP_HAS_MMCI
+void portmux_enable_mmci(unsigned int slot, unsigned long flags,
+ unsigned long drive_strength)
+{
+ unsigned long mask;
+ unsigned long portmux_flags = PORTMUX_PULL_UP;
+
+ /* First, the common CLK signal. It doesn't need a pull-up */
+ portmux_select_peripheral(PORTMUX_PORT_A, 1 << 10,
+ PORTMUX_FUNC_A, 0);
+
+ if (flags & PORTMUX_MMCI_EXT_PULLUP)
+ portmux_flags = 0;
+
+ /* Then, the per-slot signals */
+ switch (slot) {
+ case 0:
+ mask = (1 << 11) | (1 << 12); /* CMD and DATA0 */
+ if (flags & PORTMUX_MMCI_4BIT)
+ /* DATA1..DATA3 */
+ mask |= (1 << 13) | (1 << 14) | (1 << 15);
+ portmux_select_peripheral(PORTMUX_PORT_A, mask,
+ PORTMUX_FUNC_A, portmux_flags);
+ break;
+ case 1:
+ mask = (1 << 6) | (1 << 7); /* CMD and DATA0 */
+ if (flags & PORTMUX_MMCI_4BIT)
+ /* DATA1..DATA3 */
+ mask |= (1 << 8) | (1 << 9) | (1 << 10);
+ portmux_select_peripheral(PORTMUX_PORT_B, mask,
+ PORTMUX_FUNC_B, portmux_flags);
+ break;
+ }
+}
+#endif
+
+#ifdef AT32AP700x_CHIP_HAS_SPI
+void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength)
+{
+ unsigned long pin_mask;
+
+ /* MOSI and SCK */
+ portmux_select_peripheral(PORTMUX_PORT_A, (1 << 1) | (1 << 2),
+ PORTMUX_FUNC_A, 0);
+ /* MISO may float */
+ portmux_select_peripheral(PORTMUX_PORT_A, 1 << 0,
+ PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
+
+ /* Set up NPCSx as GPIO outputs, initially high */
+ pin_mask = (cs_mask & 7) << 3;
+ if (cs_mask & (1 << 3))
+ pin_mask |= 1 << 20;
+
+ portmux_select_gpio(PORTMUX_PORT_A, pin_mask,
+ PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
+}
+
+void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength)
+{
+ /* MOSI and SCK */
+ portmux_select_peripheral(PORTMUX_PORT_B, (1 << 1) | (1 << 5),
+ PORTMUX_FUNC_B, 0);
+ /* MISO may float */
+ portmux_select_peripheral(PORTMUX_PORT_B, 1 << 0,
+ PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
+
+ /* Set up NPCSx as GPIO outputs, initially high */
+ portmux_select_gpio(PORTMUX_PORT_B, (cs_mask & 7) << 2,
+ PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
+ portmux_select_gpio(PORTMUX_PORT_A, (cs_mask & 8) << (27 - 3),
+ PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
+}
+#endif
diff --git a/cpu/at32ap/cache.c b/cpu/at32ap/cache.c
index 16a0565..28b9456 100644
--- a/cpu/at32ap/cache.c
+++ b/cpu/at32ap/cache.c
@@ -22,7 +22,7 @@
#include <common.h>
-#include <asm/cacheflush.h>
+#include <asm/arch/cacheflush.h>
void dcache_clean_range(volatile void *start, size_t size)
{
diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c
index f92d3e2..904bfb2 100644
--- a/cpu/at32ap/cpu.c
+++ b/cpu/at32ap/cpu.c
@@ -65,9 +65,6 @@ int cpu_init(void)
sysreg_write(EVBA, (unsigned long)&_evba);
asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET));
- if(gclk_init)
- gclk_init();
-
return 0;
}
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
deleted file mode 100644
index f64004b..0000000
--- a/cpu/at32ap/pio.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2006 Atmel Corporation
- *
- * 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/gpio.h>
-#include <asm/arch/memory-map.h>
-
-#include "pio2.h"
-
-void gpio_select_periph_A(unsigned int pin, int use_pullup)
-{
- void *base = gpio_pin_to_addr(pin);
- uint32_t mask = 1 << (pin & 0x1f);
-
- if (!base)
- panic("Invalid GPIO pin %u\n", pin);
-
- pio2_writel(base, ASR, mask);
- pio2_writel(base, PDR, mask);
- if (use_pullup)
- pio2_writel(base, PUER, mask);
- else
- pio2_writel(base, PUDR, mask);
-}
-
-void gpio_select_periph_B(unsigned int pin, int use_pullup)
-{
- void *base = gpio_pin_to_addr(pin);
- uint32_t mask = 1 << (pin & 0x1f);
-
- if (!base)
- panic("Invalid GPIO pin %u\n", pin);
-
- pio2_writel(base, BSR, mask);
- pio2_writel(base, PDR, mask);
- if (use_pullup)
- pio2_writel(base, PUER, mask);
- else
- pio2_writel(base, PUDR, mask);
-}
-
-void gpio_select_pio(unsigned int pin, unsigned long gpiof_flags)
-{
- void *base = gpio_pin_to_addr(pin);
- uint32_t mask = 1 << (pin & 0x1f);
-
- if (!base)
- panic("Invalid GPIO pin %u\n", pin);
-
- if (gpiof_flags & GPIOF_OUTPUT) {
- if (gpiof_flags & GPIOF_MULTIDRV)
- pio2_writel(base, MDER, mask);
- else
- pio2_writel(base, MDDR, mask);
- pio2_writel(base, PUDR, mask);
- pio2_writel(base, OER, mask);
- } else {
- if (gpiof_flags & GPIOF_PULLUP)
- pio2_writel(base, PUER, mask);
- else
- pio2_writel(base, PUDR, mask);
- if (gpiof_flags & GPIOF_DEGLITCH)
- pio2_writel(base, IFER, mask);
- else
- pio2_writel(base, IFDR, mask);
- pio2_writel(base, ODR, mask);
- }
-
- pio2_writel(base, PER, mask);
-}
-
-void gpio_set_value(unsigned int pin, int value)
-{
- void *base = gpio_pin_to_addr(pin);
- uint32_t mask = 1 << (pin & 0x1f);
-
- if (!base)
- panic("Invalid GPIO pin %u\n", pin);
-
- if (value)
- pio2_writel(base, SODR, mask);
- else
- pio2_writel(base, CODR, mask);
-}
-
-int gpio_get_value(unsigned int pin)
-{
- void *base = gpio_pin_to_addr(pin);
- int value;
-
- if (!base)
- panic("Invalid GPIO pin %u\n", pin);
-
- value = pio2_readl(base, PDSR);
- return (value >> (pin & 0x1f)) & 1;
-}
diff --git a/cpu/at32ap/portmux-gpio.c b/cpu/at32ap/portmux-gpio.c
new file mode 100644
index 0000000..9acd040
--- /dev/null
+++ b/cpu/at32ap/portmux-gpio.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * 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/memory-map.h>
+#include <asm/arch/gpio.h>
+
+void portmux_select_peripheral(void *port, unsigned long pin_mask,
+ enum portmux_function func, unsigned long flags)
+{
+ /* Both pull-up and pull-down set means buskeeper */
+ if (flags & PORTMUX_PULL_DOWN)
+ gpio_writel(port, PDERS, pin_mask);
+ else
+ gpio_writel(port, PDERC, pin_mask);
+ if (flags & PORTMUX_PULL_UP)
+ gpio_writel(port, PUERS, pin_mask);
+ else
+ gpio_writel(port, PUERC, pin_mask);
+
+ /* Select drive strength */
+ if (flags & PORTMUX_DRIVE_LOW)
+ gpio_writel(port, ODCR0S, pin_mask);
+ else
+ gpio_writel(port, ODCR0C, pin_mask);
+ if (flags & PORTMUX_DRIVE_HIGH)
+ gpio_writel(port, ODCR1S, pin_mask);
+ else
+ gpio_writel(port, ODCR1C, pin_mask);
+
+ /* Select function */
+ if (func & PORTMUX_FUNC_B)
+ gpio_writel(port, PMR0S, pin_mask);
+ else
+ gpio_writel(port, PMR0C, pin_mask);
+ if (func & PORTMUX_FUNC_C)
+ gpio_writel(port, PMR1S, pin_mask);
+ else
+ gpio_writel(port, PMR1C, pin_mask);
+
+ /* Disable GPIO (i.e. enable peripheral) */
+ gpio_writel(port, GPERC, pin_mask);
+}
+
+void portmux_select_gpio(void *port, unsigned long pin_mask,
+ unsigned long flags)
+{
+ /* Both pull-up and pull-down set means buskeeper */
+ if (flags & PORTMUX_PULL_DOWN)
+ gpio_writel(port, PDERS, pin_mask);
+ else
+ gpio_writel(port, PDERC, pin_mask);
+ if (flags & PORTMUX_PULL_UP)
+ gpio_writel(port, PUERS, pin_mask);
+ else
+ gpio_writel(port, PUERC, pin_mask);
+
+ /* Enable open-drain mode if requested */
+ if (flags & PORTMUX_OPEN_DRAIN)
+ gpio_writel(port, ODMERS, pin_mask);
+ else
+ gpio_writel(port, ODMERC, pin_mask);
+
+ /* Select drive strength */
+ if (flags & PORTMUX_DRIVE_LOW)
+ gpio_writel(port, ODCR0S, pin_mask);
+ else
+ gpio_writel(port, ODCR0C, pin_mask);
+ if (flags & PORTMUX_DRIVE_HIGH)
+ gpio_writel(port, ODCR1S, pin_mask);
+ else
+ gpio_writel(port, ODCR1C, pin_mask);
+
+ /* Select direction and initial pin state */
+ if (flags & PORTMUX_DIR_OUTPUT) {
+ if (flags & PORTMUX_INIT_HIGH)
+ gpio_writel(port, OVRS, pin_mask);
+ else
+ gpio_writel(port, OVRC, pin_mask);
+ gpio_writel(port, ODERS, pin_mask);
+ } else {
+ gpio_writel(port, ODERC, pin_mask);
+ }
+
+ /* Enable GPIO */
+ gpio_writel(port, GPERS, pin_mask);
+}
diff --git a/cpu/at32ap/portmux-pio.c b/cpu/at32ap/portmux-pio.c
new file mode 100644
index 0000000..a29f94e
--- /dev/null
+++ b/cpu/at32ap/portmux-pio.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006, 2008 Atmel Corporation
+ *
+ * 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/memory-map.h>
+#include <asm/arch/gpio.h>
+
+void portmux_select_peripheral(void *port, unsigned long pin_mask,
+ enum portmux_function func, unsigned long flags)
+{
+ if (flags & PORTMUX_PULL_UP)
+ pio_writel(port, PUER, pin_mask);
+ else
+ pio_writel(port, PUDR, pin_mask);
+
+ switch (func) {
+ case PORTMUX_FUNC_A:
+ pio_writel(port, ASR, pin_mask);
+ break;
+ case PORTMUX_FUNC_B:
+ pio_writel(port, BSR, pin_mask);
+ break;
+ }
+
+ pio_writel(port, PDR, pin_mask);
+}
+
+void portmux_select_gpio(void *port, unsigned long pin_mask,
+ unsigned long flags)
+{
+ if (flags & PORTMUX_PULL_UP)
+ pio_writel(port, PUER, pin_mask);
+ else
+ pio_writel(port, PUDR, pin_mask);
+
+ if (flags & PORTMUX_OPEN_DRAIN)
+ pio_writel(port, MDER, pin_mask);
+ else
+ pio_writel(port, MDDR, pin_mask);
+
+ if (flags & PORTMUX_DIR_OUTPUT) {
+ if (flags & PORTMUX_INIT_HIGH)
+ pio_writel(port, SODR, pin_mask);
+ else
+ pio_writel(port, CODR, pin_mask);
+ pio_writel(port, OER, pin_mask);
+ } else {
+ pio_writel(port, ODR, pin_mask);
+ }
+
+ pio_writel(port, PER, pin_mask);
+}
+
+void pio_set_output_value(unsigned int pin, int value)
+{
+ void *port = pio_pin_to_port(pin);
+
+ if (!port)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ __pio_set_output_value(port, pin & 0x1f, value);
+}
+
+int pio_get_input_value(unsigned int pin)
+{
+ void *port = pio_pin_to_port(pin);
+
+ if (!port)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ return __pio_get_input_value(port, pin & 0x1f);
+}
diff --git a/cpu/blackfin/cpu.c b/cpu/blackfin/cpu.c
index 30c214b..c2ff8cd 100644
--- a/cpu/blackfin/cpu.c
+++ b/cpu/blackfin/cpu.c
@@ -25,18 +25,12 @@ ulong bfin_poweron_retx;
__attribute__ ((__noreturn__))
void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
{
- /* Build a NOP slide over the LDR jump block. Whee! */
- serial_early_puts("NOP Slide\n");
- char nops[0xC];
- memset(nops, 0x00, sizeof(nops));
- extern char _stext_l1;
- memcpy(&_stext_l1 - sizeof(nops), nops, sizeof(nops));
-
if (!loaded_from_ldr) {
/* Relocate sections into L1 if the LDR didn't do it -- don't
* check length because the linker script does the size
* checking at build time.
*/
+ extern char _stext_l1;
serial_early_puts("L1 Relocate\n");
extern char _stext_l1, _etext_l1, _stext_l1_lma;
memcpy(&_stext_l1, &_stext_l1_lma, (&_etext_l1 - &_stext_l1));
diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c
index 3f3b479..7bd4b22 100644
--- a/cpu/blackfin/initcode.c
+++ b/cpu/blackfin/initcode.c
@@ -12,6 +12,7 @@
#include <config.h>
#include <asm/blackfin.h>
#include <asm/mach-common/bits/bootrom.h>
+#include <asm/mach-common/bits/core.h>
#include <asm/mach-common/bits/ebiu.h>
#include <asm/mach-common/bits/pll.h>
#include <asm/mach-common/bits/uart.h>
@@ -203,6 +204,48 @@ static inline void serial_putc(char c)
# define CONFIG_VR_CTL_VAL (CONFIG_VR_CTL_CLKBUF | CONFIG_VR_CTL_VLEV | CONFIG_VR_CTL_FREQ)
#endif
+/* some parts do not have an on-chip voltage regulator */
+#if defined(__ADSPBF51x__)
+# define CONFIG_HAS_VR 0
+# undef CONFIG_VR_CTL_VAL
+# define CONFIG_VR_CTL_VAL 0
+#else
+# define CONFIG_HAS_VR 1
+#endif
+
+#ifndef EBIU_RSTCTL
+/* Blackfin with SDRAM */
+#ifndef CONFIG_EBIU_SDBCTL_VAL
+# if CONFIG_MEM_SIZE == 16
+# define CONFIG_EBSZ_VAL EBSZ_16
+# elif CONFIG_MEM_SIZE == 32
+# define CONFIG_EBSZ_VAL EBSZ_32
+# elif CONFIG_MEM_SIZE == 64
+# define CONFIG_EBSZ_VAL EBSZ_64
+# elif CONFIG_MEM_SIZE == 128
+# define CONFIG_EBSZ_VAL EBSZ_128
+# elif CONFIG_MEM_SIZE == 256
+# define CONFIG_EBSZ_VAL EBSZ_256
+# elif CONFIG_MEM_SIZE == 512
+# define CONFIG_EBSZ_VAL EBSZ_512
+# else
+# error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_SIZE
+# endif
+# if CONFIG_MEM_ADD_WDTH == 8
+# define CONFIG_EBCAW_VAL EBCAW_8
+# elif CONFIG_MEM_ADD_WDTH == 9
+# define CONFIG_EBCAW_VAL EBCAW_9
+# elif CONFIG_MEM_ADD_WDTH == 10
+# define CONFIG_EBCAW_VAL EBCAW_10
+# elif CONFIG_MEM_ADD_WDTH == 11
+# define CONFIG_EBCAW_VAL EBCAW_11
+# else
+# error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_ADD_WDTH
+# endif
+# define CONFIG_EBIU_SDBCTL_VAL (CONFIG_EBCAW_VAL | CONFIG_EBSZ_VAL | EBE)
+#endif
+#endif
+
BOOTROM_CALLED_FUNC_ATTR
void initcode(ADI_BOOT_DATA *bootstruct)
{
@@ -215,6 +258,8 @@ void initcode(ADI_BOOT_DATA *bootstruct)
divB = serial_early_get_div();
}
+ serial_putc('A');
+
#ifdef CONFIG_HW_WATCHDOG
# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
# define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000
@@ -231,7 +276,23 @@ void initcode(ADI_BOOT_DATA *bootstruct)
}
#endif
- serial_putc('S');
+ serial_putc('B');
+
+ /* If external memory is enabled, put it into self refresh first. */
+ bool put_into_srfs = false;
+#ifdef EBIU_RSTCTL
+ if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) {
+ bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | SRREQ);
+ put_into_srfs = true;
+ }
+#else
+ if (bfin_read_EBIU_SDBCTL() & EBE) {
+ bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
+ put_into_srfs = true;
+ }
+#endif
+
+ serial_putc('C');
/* Blackfin bootroms use the SPI slow read opcode instead of the SPI
* fast read, so we need to slow down the SPI clock a lot more during
@@ -244,54 +305,81 @@ void initcode(ADI_BOOT_DATA *bootstruct)
bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK);
}
- serial_putc('B');
+ serial_putc('D');
- /* Disable all peripheral wakeups except for the PLL event. */
-#ifdef SIC_IWR0
- bfin_write_SIC_IWR0(1);
- bfin_write_SIC_IWR1(0);
-# ifdef SIC_IWR2
- bfin_write_SIC_IWR2(0);
-# endif
-#elif defined(SICA_IWR0)
- bfin_write_SICA_IWR0(1);
- bfin_write_SICA_IWR1(0);
+ /* If we're entering self refresh, make sure it has happened. */
+ if (put_into_srfs)
+#ifdef EBIU_RSTCTL
+ while (!(bfin_read_EBIU_RSTCTL() & SRACK))
#else
- bfin_write_SIC_IWR(1);
+ while (!(bfin_read_EBIU_SDSTAT() & SDSRA))
#endif
+ continue;
+
+ serial_putc('E');
/* With newer bootroms, we use the helper function to set up
* the memory controller. Older bootroms lacks such helpers
* so we do it ourselves.
*/
-#define BOOTROM_CAPS_SYSCONTROL 0
- if (BOOTROM_CAPS_SYSCONTROL) {
- serial_putc('S');
+ uint16_t vr_ctl = bfin_read_VR_CTL();
+ if (!ANOMALY_05000386) {
+ serial_putc('F');
ADI_SYSCTRL_VALUES memory_settings;
- memory_settings.uwVrCtl = CONFIG_VR_CTL_VAL;
+ uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT;
+ if (CONFIG_HAS_VR) {
+ actions |= SYSCTRL_VRCTL;
+ if (CONFIG_VR_CTL_VAL & FREQ_MASK)
+ actions |= SYSCTRL_INTVOLTAGE;
+ else
+ actions |= SYSCTRL_EXTVOLTAGE;
+ memory_settings.uwVrCtl = CONFIG_VR_CTL_VAL;
+ } else
+ actions |= SYSCTRL_EXTVOLTAGE;
memory_settings.uwPllCtl = CONFIG_PLL_CTL_VAL;
memory_settings.uwPllDiv = CONFIG_PLL_DIV_VAL;
memory_settings.uwPllLockCnt = CONFIG_PLL_LOCKCNT_VAL;
- syscontrol(SYSCTRL_WRITE | SYSCTRL_VRCTL | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT |
- (CONFIG_VR_CTL_VAL & FREQ_MASK ? SYSCTRL_INTVOLTAGE : SYSCTRL_EXTVOLTAGE), &memory_settings, NULL);
+#if ANOMALY_05000432
+ bfin_write_SIC_IWR1(0);
+#endif
+ bfrom_SysControl(actions, &memory_settings, NULL);
+#if ANOMALY_05000432
+ bfin_write_SIC_IWR1(-1);
+#endif
} else {
- serial_putc('L');
+ serial_putc('G');
+
+ /* Disable all peripheral wakeups except for the PLL event. */
+#ifdef SIC_IWR0
+ bfin_write_SIC_IWR0(1);
+ bfin_write_SIC_IWR1(0);
+# ifdef SIC_IWR2
+ bfin_write_SIC_IWR2(0);
+# endif
+#elif defined(SICA_IWR0)
+ bfin_write_SICA_IWR0(1);
+ bfin_write_SICA_IWR1(0);
+#else
+ bfin_write_SIC_IWR(1);
+#endif
+
+ serial_putc('H');
bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL);
- serial_putc('A');
+ serial_putc('I');
/* Only reprogram when needed to avoid triggering unnecessary
* PLL relock sequences.
*/
- if (bfin_read_VR_CTL() != CONFIG_VR_CTL_VAL) {
+ if (vr_ctl != CONFIG_VR_CTL_VAL) {
serial_putc('!');
bfin_write_VR_CTL(CONFIG_VR_CTL_VAL);
asm("idle;");
}
- serial_putc('C');
+ serial_putc('J');
bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL);
@@ -305,8 +393,26 @@ void initcode(ADI_BOOT_DATA *bootstruct)
bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL);
asm("idle;");
}
+
+ serial_putc('L');
+
+ /* Restore all peripheral wakeups. */
+#ifdef SIC_IWR0
+ bfin_write_SIC_IWR0(-1);
+ bfin_write_SIC_IWR1(-1);
+# ifdef SIC_IWR2
+ bfin_write_SIC_IWR2(-1);
+# endif
+#elif defined(SICA_IWR0)
+ bfin_write_SICA_IWR0(-1);
+ bfin_write_SICA_IWR1(-1);
+#else
+ bfin_write_SIC_IWR(-1);
+#endif
}
+ serial_putc('M');
+
/* Since we've changed the SCLK above, we may need to update
* the UART divisors (UART baud rates are based on SCLK).
* Do the division by hand as there are no native instructions
@@ -324,23 +430,32 @@ void initcode(ADI_BOOT_DATA *bootstruct)
serial_early_put_div(quotient - ANOMALY_05000230);
}
- serial_putc('F');
+ serial_putc('N');
- /* Program the async banks controller. */
- bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
- bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
- bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
+ /* Program the external memory controller before we come out of
+ * self-refresh. This only works with our SDRAM controller.
+ */
+#ifndef EBIU_RSTCTL
+ bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL);
+ bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL);
+ bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL);
+#endif
-#ifdef EBIU_MODE
- /* Not all parts have these additional MMRs. */
- bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
- bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
- bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
+ serial_putc('O');
+
+ /* Now that we've reprogrammed, take things out of self refresh. */
+ if (put_into_srfs)
+#ifdef EBIU_RSTCTL
+ bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
+#else
+ bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() & ~(SRFS));
#endif
- serial_putc('I');
+ serial_putc('P');
- /* Program the external memory controller. */
+ /* Our DDR controller sucks and cannot be programmed while in
+ * self-refresh. So we have to pull it out before programming.
+ */
#ifdef EBIU_RSTCTL
bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1 /*DDRSRESET*/ | CONFIG_EBIU_RSTCTL_VAL);
bfin_write_EBIU_DDRCTL0(CONFIG_EBIU_DDRCTL0_VAL);
@@ -350,28 +465,64 @@ void initcode(ADI_BOOT_DATA *bootstruct)
/* default is disable, so don't need to force this */
bfin_write_EBIU_DDRCTL3(CONFIG_EBIU_DDRCTL3_VAL);
# endif
-#else
- bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL);
- bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL);
- bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL);
+# ifdef CONFIG_EBIU_DDRQUE_VAL
+ bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() | CONFIG_EBIU_DDRQUE_VAL);
+# endif
#endif
- serial_putc('N');
+ serial_putc('Q');
- /* Restore all peripheral wakeups. */
-#ifdef SIC_IWR0
- bfin_write_SIC_IWR0(-1);
- bfin_write_SIC_IWR1(-1);
-# ifdef SIC_IWR2
- bfin_write_SIC_IWR2(-1);
-# endif
-#elif defined(SICA_IWR0)
- bfin_write_SICA_IWR0(-1);
- bfin_write_SICA_IWR1(-1);
-#else
- bfin_write_SIC_IWR(-1);
+ /* Are we coming out of hibernate (suspend to memory) ?
+ * The memory layout is:
+ * 0x0: hibernate magic for anomaly 307 (0xDEADBEEF)
+ * 0x4: return address
+ * 0x8: stack pointer
+ *
+ * SCKELOW is unreliable on older parts (anomaly 307)
+ */
+ if (ANOMALY_05000307 || vr_ctl & 0x8000) {
+ uint32_t *hibernate_magic = 0;
+ __builtin_bfin_ssync(); /* make sure memory controller is done */
+ if (hibernate_magic[0] == 0xDEADBEEF) {
+ serial_putc('R');
+ bfin_write_EVT15(hibernate_magic[1]);
+ bfin_write_IMASK(EVT_IVG15);
+ __asm__ __volatile__ (
+ /* load reti early to avoid anomaly 281 */
+ "reti = %0;"
+ /* clear hibernate magic */
+ "[%0] = %1;"
+ /* load stack pointer */
+ "SP = [%0 + 8];"
+ /* lower ourselves from reset ivg to ivg15 */
+ "raise 15;"
+ "rti;"
+ :
+ : "p"(hibernate_magic), "d"(0x2000 /* jump.s 0 */)
+ );
+ }
+ }
+
+ serial_putc('S');
+
+ /* Program the async banks controller. */
+ bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
+ bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
+ bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
+
+#ifdef EBIU_MODE
+ /* Not all parts have these additional MMRs. */
+ bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
+ bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
+ bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
#endif
+ serial_putc('T');
+
+ /* tell the bootrom where our entry point is */
+ if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS)
+ bfin_write_EVT1(CONFIG_SYS_MONITOR_BASE);
+
serial_putc('>');
serial_putc('\n');
diff --git a/cpu/blackfin/jtag-console.c b/cpu/blackfin/jtag-console.c
index 44c0a83..d58582f 100644
--- a/cpu/blackfin/jtag-console.c
+++ b/cpu/blackfin/jtag-console.c
@@ -54,16 +54,23 @@ static void jtag_puts(const char *s)
jtag_send(s, strlen(s));
}
-static int jtag_tstc(void)
+static size_t inbound_len, leftovers_len;
+
+/* Lower layers want to know when jtag has data */
+static int jtag_tstc_dbg(void)
{
return (bfin_read_DBGSTAT() & 0x2);
}
+/* Higher layers want to know when any data is available */
+static int jtag_tstc(void)
+{
+ return jtag_tstc_dbg() || leftovers_len;
+}
+
/* Receive a buffer. The format is:
* [32bit length][actual data]
*/
-static size_t inbound_len;
-static int leftovers_len;
static uint32_t leftovers;
static int jtag_getc(void)
{
@@ -79,7 +86,7 @@ static int jtag_getc(void)
}
/* wait for new data ! */
- while (!jtag_tstc())
+ while (!jtag_tstc_dbg())
continue;
__asm__("%0 = emudat;" : "=d"(emudat));
diff --git a/cpu/blackfin/reset.c b/cpu/blackfin/reset.c
index 284cea5..e3be740 100644
--- a/cpu/blackfin/reset.c
+++ b/cpu/blackfin/reset.c
@@ -20,7 +20,7 @@
* the core reset.
*/
__attribute__ ((__l1_text__, __noreturn__))
-void bfin_reset(void)
+static void bfin_reset(void)
{
/* Wait for completion of "system" events such as cache line
* line fills so that we avoid infinite stalls later on as
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S
index 6c8def4..506fea5 100644
--- a/cpu/blackfin/start.S
+++ b/cpu/blackfin/start.S
@@ -95,36 +95,64 @@ ENTRY(_start)
/* Save RETX so we can pass it while booting Linux */
r7 = RETX;
-#if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS)
- /* In bypass mode, we don't have an LDR with an init block
- * so we need to explicitly call it ourselves. This will
- * reprogram our clocks and setup our async banks.
- */
- /* XXX: we should DMA this into L1, put external memory into
- * self refresh, and then jump there ...
+ /* Figure out where we are currently executing so that we can decide
+ * how to best reprogram and relocate things. We'll pass below:
+ * R4: load address of _start
+ * R5: current (not load) address of _start
*/
+ serial_early_puts("Find ourselves");
+
call _get_pc;
- r3 = 0x0;
- r3.h = 0x2000;
- cc = r0 < r3 (iu);
- if cc jump .Lproc_initialized;
+.Loffset:
+ r1.l = .Loffset;
+ r1.h = .Loffset;
+ r4.l = _start;
+ r4.h = _start;
+ r3 = r1 - r4;
+ r5 = r0 - r3;
+
+ /* Inform upper layers if we had to do the relocation ourselves.
+ * This allows us to detect whether we were loaded by 'go 0x1000'
+ * or by the bootrom from an LDR. "R6" is "loaded_from_ldr".
+ */
+ r6 = 1 (x);
+ cc = r4 == r5;
+ if cc jump .Lnorelocate;
+ r6 = 0 (x);
+ /* In bypass mode, we don't have an LDR with an init block
+ * so we need to explicitly call it ourselves. This will
+ * reprogram our clocks, memory, and setup our async banks.
+ */
serial_early_puts("Program Clocks");
+ /* if we're executing >=0x20000000, then we dont need to dma */
+ r3 = 0x0;
+ r3.h = 0x2000;
+ cc = r5 < r3 (iu);
+ if cc jump .Ldma_and_reprogram;
call _initcode;
+ jump .Lprogrammed;
+
+ /* we're sitting in external memory, so dma into L1 and reprogram */
+.Ldma_and_reprogram:
+ r0.l = LO(L1_INST_SRAM);
+ r0.h = HI(L1_INST_SRAM);
+ r1.l = __initcode_start;
+ r1.h = __initcode_start;
+ r2.l = __initcode_end;
+ r2.h = __initcode_end;
+ r2 = r2 - r1; /* convert r2 into length of initcode */
+ r1 = r1 - r4; /* convert r1 from load address of initcode ... */
+ r1 = r1 + r5; /* ... to current (not load) address of initcode */
+ p3 = r0;
+ call _dma_memcpy_nocache;
+ call (p3);
/* Since we reprogrammed SCLK, we need to update the serial divisor */
+.Lprogrammed:
serial_early_set_baud
-.Lproc_initialized:
-#endif
-
- /* Inform upper layers if we had to do the relocation ourselves.
- * This allows us to detect whether we were loaded by 'go 0x1000'
- * or by the bootrom from an LDR. "r6" is "loaded_from_ldr".
- */
- r6 = 1 (x);
-
/* Relocate from wherever we are (FLASH/RAM/etc...) to the hardcoded
* monitor location in the end of RAM. We know that memcpy() only
* uses registers, so it is safe to call here. Note that this only
@@ -132,19 +160,8 @@ ENTRY(_start)
* it yet (see "lower to 15" below).
*/
serial_early_puts("Relocate");
- call _get_pc;
-.Loffset:
- r2.l = .Loffset;
- r2.h = .Loffset;
- r3.l = _start;
- r3.h = _start;
- r2 = r2 - r3;
- r1 = r0 - r2;
- cc = r1 == r3;
- if cc jump .Lnorelocate;
- r6 = 0 (x);
-
- r0 = r3;
+ r0 = r4;
+ r1 = r5;
r2.l = LO(CONFIG_SYS_MONITOR_LEN);
r2.h = HI(CONFIG_SYS_MONITOR_LEN);
call _memcpy_ASM;
diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c
index a2c6f1e..2121b0e 100644
--- a/cpu/blackfin/traps.c
+++ b/cpu/blackfin/traps.c
@@ -193,7 +193,7 @@ static const char *symbol_lookup(unsigned long addr, unsigned long *caddr)
while (*sym) {
sym_addr = simple_strtoul(sym, &esym, 16);
- sym = esym + 1;
+ sym = esym;
if (sym_addr > addr)
break;
*caddr = sym_addr;
diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c
index 7d76274..e2506d8 100644
--- a/cpu/mpc5xxx/i2c.c
+++ b/cpu/mpc5xxx/i2c.c
@@ -269,7 +269,8 @@ static int mpc_get_fdr(int speed)
if (gd->flags & GD_FLG_RELOC) {
fdr = divider;
} else {
- printf("%ld kHz, ", best_speed / 1000);
+ if (gd->have_console)
+ printf("%ld kHz, ", best_speed / 1000);
return divider;
}
}
@@ -310,29 +311,34 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
xaddr[3] = addr & 0xFF;
if (wait_for_bb()) {
- printf("i2c_read: bus is busy\n");
+ if (gd->have_console)
+ printf("i2c_read: bus is busy\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
if (do_address(chip, 0)) {
- printf("i2c_read: failed to address chip\n");
+ if (gd->have_console)
+ printf("i2c_read: failed to address chip\n");
goto Done;
}
if (send_bytes(chip, &xaddr[4-alen], alen)) {
- printf("i2c_read: send_bytes failed\n");
+ if (gd->have_console)
+ printf("i2c_read: send_bytes failed\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_RSTA, I2C_RSTA);
if (do_address(chip, 1)) {
- printf("i2c_read: failed to address chip\n");
+ if (gd->have_console)
+ printf("i2c_read: failed to address chip\n");
goto Done;
}
if (receive_bytes(chip, (char *)buf, len)) {
- printf("i2c_read: receive_bytes failed\n");
+ if (gd->have_console)
+ printf("i2c_read: receive_bytes failed\n");
goto Done;
}
@@ -354,23 +360,27 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
xaddr[3] = addr & 0xFF;
if (wait_for_bb()) {
- printf("i2c_write: bus is busy\n");
+ if (gd->have_console)
+ printf("i2c_write: bus is busy\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
if (do_address(chip, 0)) {
- printf("i2c_write: failed to address chip\n");
+ if (gd->have_console)
+ printf("i2c_write: failed to address chip\n");
goto Done;
}
if (send_bytes(chip, &xaddr[4-alen], alen)) {
- printf("i2c_write: send_bytes failed\n");
+ if (gd->have_console)
+ printf("i2c_write: send_bytes failed\n");
goto Done;
}
if (send_bytes(chip, (char *)buf, len)) {
- printf("i2c_write: send_bytes failed\n");
+ if (gd->have_console)
+ printf("i2c_write: send_bytes failed\n");
goto Done;
}