diff options
Diffstat (limited to 'cpu')
81 files changed, 2563 insertions, 1269 deletions
diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c index f4e5fc5..9c8998b 100644 --- a/cpu/74xx_7xx/cpu.c +++ b/cpu/74xx_7xx/cpu.c @@ -44,6 +44,10 @@ #include <74xx_7xx.h> #include <asm/cache.h> +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#endif + #ifdef CONFIG_AMIGAONEG3SE #include "../board/MAI/AmigaOneG3SE/via686.h" #include "../board/MAI/AmigaOneG3SE/memio.h" @@ -101,6 +105,10 @@ get_cpu_type(void) type = CPU_7457; break; + case 0x8003: + type = CPU_7447A; + break; + case 0x8004: type = CPU_7448; break; @@ -156,6 +164,10 @@ int checkcpu (void) str = "MPC7410"; break; + case CPU_7447A: + str = "MPC7447A"; + break; + case CPU_7448: str = "MPC7448"; break; @@ -264,20 +276,19 @@ do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* * For the 7400 the TB clock runs at 1/4 the cpu bus speed. */ -#ifdef CONFIG_AMIGAONEG3SE +#if defined(CONFIG_AMIGAONEG3SE) || defined(CFG_CONFIG_BUS_CLK) unsigned long get_tbclk(void) { return (gd->bus_clk / 4); } -#else /* ! CONFIG_AMIGAONEG3SE */ +#else /* ! CONFIG_AMIGAONEG3SE and !CFG_CONFIG_BUS_CLK*/ unsigned long get_tbclk (void) { return CFG_BUS_HZ / 4; } -#endif /* CONFIG_AMIGAONEG3SE */ +#endif /* CONFIG_AMIGAONEG3SE or CFG_CONFIG_BUS_CLK*/ /* ------------------------------------------------------------------------- */ - #if defined(CONFIG_WATCHDOG) #if !defined(CONFIG_PCIPPC2) && !defined(CONFIG_BAB7xx) void @@ -289,3 +300,30 @@ watchdog_reset(void) #endif /* CONFIG_WATCHDOG */ /* ------------------------------------------------------------------------- */ + +#ifdef CONFIG_OF_FLAT_TREE +void +ft_cpu_setup (void *blob, bd_t *bd) +{ + u32 *p; + ulong clock; + int len; + + clock = bd->bi_busfreq; + + p = ft_get_prop (blob, "/cpus/" OF_CPU "/bus-frequency", &len); + if (p != NULL) + *p = cpu_to_be32 (clock); + +#if defined(CONFIG_TSI108_ETH) + p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6200/address", &len); + memcpy (p, bd->bi_enetaddr, 6); +#endif + +#if defined(CONFIG_HAS_ETH1) + p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6600/address", &len); + memcpy (p, bd->bi_enet1addr, 6); +#endif +} +#endif +/* ------------------------------------------------------------------------- */ diff --git a/cpu/74xx_7xx/cpu_init.c b/cpu/74xx_7xx/cpu_init.c index e02a4cc..1dd1b2c 100644 --- a/cpu/74xx_7xx/cpu_init.c +++ b/cpu/74xx_7xx/cpu_init.c @@ -43,6 +43,7 @@ cpu_init_f (void) case CPU_7450: case CPU_7455: case CPU_7457: + case CPU_7447A: case CPU_7448: /* enable the timebase bit in HID0 */ set_hid0(get_hid0() | 0x4000000); diff --git a/cpu/74xx_7xx/speed.c b/cpu/74xx_7xx/speed.c index d1800ed..d8c40ce 100644 --- a/cpu/74xx_7xx/speed.c +++ b/cpu/74xx_7xx/speed.c @@ -31,6 +31,8 @@ DECLARE_GLOBAL_DATA_PTR; +extern unsigned long get_board_bus_clk (void); + static const int hid1_multipliers_x_10[] = { 25, /* 0000 - 2.5x */ 75, /* 0001 - 7.5x */ @@ -50,6 +52,42 @@ static const int hid1_multipliers_x_10[] = { 0 /* 1111 - off */ }; +/* PLL_CFG[0:4] table for cpu 7448/7447A/7455/7457 */ +static const int hid1_74xx_multipliers_x_10[] = { + 115, /* 00000 - 11.5x */ + 170, /* 00001 - 17x */ + 75, /* 00010 - 7.5x */ + 150, /* 00011 - 15x */ + 70, /* 00100 - 7x */ + 180, /* 00101 - 18x */ + 10, /* 00110 - bypass */ + 200, /* 00111 - 20x */ + 20, /* 01000 - 2x */ + 210, /* 01001 - 21x */ + 65, /* 01010 - 6.5x */ + 130, /* 01011 - 13x */ + 85, /* 01100 - 8.5x */ + 240, /* 01101 - 24x */ + 95, /* 01110 - 9.5x */ + 90, /* 01111 - 9x */ + 30, /* 10000 - 3x */ + 105, /* 10001 - 10.5x */ + 55, /* 10010 - 5.5x */ + 110, /* 10011 - 11x */ + 40, /* 10100 - 4x */ + 100, /* 10101 - 10x */ + 50, /* 10110 - 5x */ + 120, /* 10111 - 12x */ + 80, /* 11000 - 8x */ + 140, /* 11001 - 14x */ + 60, /* 11010 - 6x */ + 160, /* 11011 - 16x */ + 135, /* 11100 - 13.5x */ + 280, /* 11101 - 28x */ + 0, /* 11110 - off */ + 125 /* 11111 - 12.5x */ +}; + static const int hid1_fx_multipliers_x_10[] = { 00, /* 0000 - off */ 00, /* 0001 - off */ @@ -89,22 +127,30 @@ int get_clocks (void) { ulong clock = 0; +#ifdef CFG_BUS_CLK + gd->bus_clk = CFG_BUS_CLK; /* bus clock is a fixed frequency */ +#else + gd->bus_clk = get_board_bus_clk (); /* bus clock is configurable */ +#endif + /* calculate the clock frequency based upon the CPU type */ switch (get_cpu_type()) { + case CPU_7447A: case CPU_7448: case CPU_7455: case CPU_7457: /* - * It is assumed that the PLL_EXT line is zero. * Make sure division is done before multiplication to prevent 32-bit * arithmetic overflows which will cause a negative number */ - clock = (CFG_BUS_CLK / 10) * hid1_multipliers_x_10[(get_hid1 () >> 13) & 0xF]; + clock = (gd->bus_clk / 10) * + hid1_74xx_multipliers_x_10[(get_hid1 () >> 12) & 0x1F]; break; case CPU_750GX: case CPU_750FX: - clock = CFG_BUS_CLK * hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10; + clock = gd->bus_clk * + hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10; break; case CPU_7450: @@ -121,7 +167,8 @@ int get_clocks (void) * Make sure division is done before multiplication to prevent 32-bit * arithmetic overflows which will cause a negative number */ - clock = (CFG_BUS_CLK / 10) * hid1_multipliers_x_10[get_hid1 () >> 28]; + clock = (gd->bus_clk / 10) * + hid1_multipliers_x_10[get_hid1 () >> 28]; break; case CPU_UNKNOWN: @@ -131,7 +178,6 @@ int get_clocks (void) } gd->cpu_clk = clock; - gd->bus_clk = CFG_BUS_CLK; return (0); } diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile index f62ec8b..f69b1f3 100644 --- a/cpu/at32ap/Makefile +++ b/cpu/at32ap/Makefile @@ -30,7 +30,7 @@ LIB := $(obj)lib$(CPU).a START := start.o SOBJS := entry.o COBJS := cpu.o hsdramc.o exception.o cache.o -COBJS += interrupts.o device.o pm.o pio.o +COBJS += interrupts.o pio.o atmel_mci.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) START := $(addprefix $(obj),$(START)) diff --git a/cpu/at32ap/at32ap7000/Makefile b/cpu/at32ap/at32ap7000/Makefile index 2ed74d2..d276712 100644 --- a/cpu/at32ap/at32ap7000/Makefile +++ b/cpu/at32ap/at32ap7000/Makefile @@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)lib$(SOC).a -COBJS := hebi.o devices.o +COBJS := gpio.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/at32ap/at32ap7000/devices.c b/cpu/at32ap/at32ap7000/devices.c deleted file mode 100644 index 8b216e9..0000000 --- a/cpu/at32ap/at32ap7000/devices.c +++ /dev/null @@ -1,448 +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/arch/memory-map.h> -#include <asm/arch/platform.h> - -#include "../sm.h" - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -const struct clock_domain chip_clock[] = { - [CLOCK_CPU] = { - .reg = SM_PM_CPU_MASK, - .id = CLOCK_CPU, - .bridge = NO_DEVICE, - }, - [CLOCK_HSB] = { - .reg = SM_PM_HSB_MASK, - .id = CLOCK_HSB, - .bridge = NO_DEVICE, - }, - [CLOCK_PBA] = { - .reg = SM_PM_PBA_MASK, - .id = CLOCK_PBA, - .bridge = DEVICE_PBA_BRIDGE, - }, - [CLOCK_PBB] = { - .reg = SM_PM_PBB_MASK, - .id = CLOCK_PBB, - .bridge = DEVICE_PBB_BRIDGE, - }, -}; - -static const struct resource hebi_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 0 }, - }, - }, { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 13 }, - }, - }, { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 14 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 }, - }, - }, -}; -static const struct resource pba_bridge_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 1 }, - } - }, { - .type = RESOURCE_CLOCK, - .u = { - /* HSB-HSB Bridge */ - .clock = { CLOCK_HSB, 4 }, - }, - }, -}; -static const struct resource pbb_bridge_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 2 }, - }, - }, -}; -static const struct resource hramc_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 3 }, - }, - }, -}; -static const struct resource pioa_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 10 }, - }, - }, -}; -static const struct resource piob_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 11 }, - }, - }, -}; -static const struct resource pioc_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 12 }, - }, - }, -}; -static const struct resource piod_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 13 }, - }, - }, -}; -static const struct resource pioe_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 14 }, - }, - }, -}; -static const struct resource sm_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 0 }, - }, - }, -}; -static const struct resource intc_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 1 }, - }, - }, -}; -static const struct resource hmatrix_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 2 }, - }, - }, -}; -#if defined(CFG_HPDC) -static const struct resource hpdc_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 16 }, - }, - }, -}; -#endif -#if defined(CFG_MACB0) -static const struct resource macb0_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 8 }, - }, - }, { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 6 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 }, - }, - }, -}; -#endif -#if defined(CFG_MACB1) -static const struct resource macb1_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 9 }, - }, - }, { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 7 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 }, - }, - }, -}; -#endif -#if defined(CFG_LCDC) -static const struct resource lcdc_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 7 }, - }, - }, -}; -#endif -#if defined(CFG_USART0) -static const struct resource usart0_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 3 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 }, - }, - }, -}; -#endif -#if defined(CFG_USART1) -static const struct resource usart1_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 4 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 }, - }, - }, -}; -#endif -#if defined(CFG_USART2) -static const struct resource usart2_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 5 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 }, - }, - }, -}; -#endif -#if defined(CFG_USART3) -static const struct resource usart3_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBA, 6 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 }, - }, - }, -}; -#endif -#if defined(CFG_MMCI) -static const struct resource mmci_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_PBB, 9 }, - }, - }, { - .type = RESOURCE_GPIO, - .u = { - .gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 }, - }, - }, -}; -#endif -#if defined(CFG_DMAC) -static const struct resource dmac_resource[] = { - { - .type = RESOURCE_CLOCK, - .u = { - .clock = { CLOCK_HSB, 10 }, - }, - }, -}; -#endif - -const struct device chip_device[] = { - [DEVICE_HEBI] = { - .regs = (void *)HSMC_BASE, - .nr_resources = ARRAY_SIZE(hebi_resource), - .resource = hebi_resource, - }, - [DEVICE_PBA_BRIDGE] = { - .nr_resources = ARRAY_SIZE(pba_bridge_resource), - .resource = pba_bridge_resource, - }, - [DEVICE_PBB_BRIDGE] = { - .nr_resources = ARRAY_SIZE(pbb_bridge_resource), - .resource = pbb_bridge_resource, - }, - [DEVICE_HRAMC] = { - .nr_resources = ARRAY_SIZE(hramc_resource), - .resource = hramc_resource, - }, - [DEVICE_PIOA] = { - .regs = (void *)PIOA_BASE, - .nr_resources = ARRAY_SIZE(pioa_resource), - .resource = pioa_resource, - }, - [DEVICE_PIOB] = { - .regs = (void *)PIOB_BASE, - .nr_resources = ARRAY_SIZE(piob_resource), - .resource = piob_resource, - }, - [DEVICE_PIOC] = { - .regs = (void *)PIOC_BASE, - .nr_resources = ARRAY_SIZE(pioc_resource), - .resource = pioc_resource, - }, - [DEVICE_PIOD] = { - .regs = (void *)PIOD_BASE, - .nr_resources = ARRAY_SIZE(piod_resource), - .resource = piod_resource, - }, - [DEVICE_PIOE] = { - .regs = (void *)PIOE_BASE, - .nr_resources = ARRAY_SIZE(pioe_resource), - .resource = pioe_resource, - }, - [DEVICE_SM] = { - .regs = (void *)SM_BASE, - .nr_resources = ARRAY_SIZE(sm_resource), - .resource = sm_resource, - }, - [DEVICE_INTC] = { - .regs = (void *)INTC_BASE, - .nr_resources = ARRAY_SIZE(intc_resource), - .resource = intc_resource, - }, - [DEVICE_HMATRIX] = { - .regs = (void *)HMATRIX_BASE, - .nr_resources = ARRAY_SIZE(hmatrix_resource), - .resource = hmatrix_resource, - }, -#if defined(CFG_HPDC) - [DEVICE_HPDC] = { - .nr_resources = ARRAY_SIZE(hpdc_resource), - .resource = hpdc_resource, - }, -#endif -#if defined(CFG_MACB0) - [DEVICE_MACB0] = { - .regs = (void *)MACB0_BASE, - .nr_resources = ARRAY_SIZE(macb0_resource), - .resource = macb0_resource, - }, -#endif -#if defined(CFG_MACB1) - [DEVICE_MACB1] = { - .regs = (void *)MACB1_BASE, - .nr_resources = ARRAY_SIZE(macb1_resource), - .resource = macb1_resource, - }, -#endif -#if defined(CFG_LCDC) - [DEVICE_LCDC] = { - .nr_resources = ARRAY_SIZE(lcdc_resource), - .resource = lcdc_resource, - }, -#endif -#if defined(CFG_USART0) - [DEVICE_USART0] = { - .regs = (void *)USART0_BASE, - .nr_resources = ARRAY_SIZE(usart0_resource), - .resource = usart0_resource, - }, -#endif -#if defined(CFG_USART1) - [DEVICE_USART1] = { - .regs = (void *)USART1_BASE, - .nr_resources = ARRAY_SIZE(usart1_resource), - .resource = usart1_resource, - }, -#endif -#if defined(CFG_USART2) - [DEVICE_USART2] = { - .regs = (void *)USART2_BASE, - .nr_resources = ARRAY_SIZE(usart2_resource), - .resource = usart2_resource, - }, -#endif -#if defined(CFG_USART3) - [DEVICE_USART3] = { - .regs = (void *)USART3_BASE, - .nr_resources = ARRAY_SIZE(usart3_resource), - .resource = usart3_resource, - }, -#endif -#if defined(CFG_MMCI) - [DEVICE_MMCI] = { - .regs = (void *)MMCI_BASE, - .nr_resources = ARRAY_SIZE(mmci_resource), - .resource = mmci_resource, - }, -#endif -#if defined(CFG_DMAC) - [DEVICE_DMAC] = { - .regs = (void *)DMAC_BASE, - .nr_resources = ARRAY_SIZE(dmac_resource), - .resource = dmac_resource, - }, -#endif -}; diff --git a/cpu/at32ap/at32ap7000/gpio.c b/cpu/at32ap/at32ap7000/gpio.c new file mode 100644 index 0000000..52f5372 --- /dev/null +++ b/cpu/at32ap/at32ap7000/gpio.c @@ -0,0 +1,137 @@ +/* + * 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/arch/gpio.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 CFG_HSDRAMC +#ifndef CFG_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 +} + +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_PB18, 0); + gpio_select_periph_B(GPIO_PIN_PB19, 0); +} + +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 +} + +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 */ +} diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c new file mode 100644 index 0000000..9f62c0f --- /dev/null +++ b/cpu/at32ap/atmel_mci.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2004-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> + +#ifdef CONFIG_MMC + +#include <part.h> +#include <mmc.h> + +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/byteorder.h> +#include <asm/arch/clk.h> +#include <asm/arch/memory-map.h> + +#include "atmel_mci.h" + +#ifdef DEBUG +#define pr_debug(fmt, args...) printf(fmt, ##args) +#else +#define pr_debug(...) do { } while(0) +#endif + +#ifndef CFG_MMC_CLK_OD +#define CFG_MMC_CLK_OD 150000 +#endif + +#ifndef CFG_MMC_CLK_PP +#define CFG_MMC_CLK_PP 5000000 +#endif + +#ifndef CFG_MMC_OP_COND +#define CFG_MMC_OP_COND 0x00100000 +#endif + +#define MMC_DEFAULT_BLKLEN 512 +#define MMC_DEFAULT_RCA 1 + +static unsigned int mmc_rca; +static block_dev_desc_t mmc_blkdev; + +block_dev_desc_t *mmc_get_dev(int dev) +{ + return &mmc_blkdev; +} + +static void mci_set_mode(unsigned long hz, unsigned long blklen) +{ + unsigned long bus_hz; + unsigned long clkdiv; + + bus_hz = get_mci_clk_rate(); + clkdiv = (bus_hz / hz) / 2 - 1; + + pr_debug("mmc: setting clock %lu Hz, block size %lu\n", + hz, blklen); + + if (clkdiv & ~255UL) { + clkdiv = 255; + printf("mmc: clock %lu too low; setting CLKDIV to 255\n", + hz); + } + + blklen &= 0xfffc; + mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv) + | MMCI_BF(BLKLEN, blklen))); +} + +#define RESP_NO_CRC 1 +#define R1 MMCI_BF(RSPTYP, 1) +#define R2 MMCI_BF(RSPTYP, 2) +#define R3 (R1 | RESP_NO_CRC) +#define R6 R1 +#define NID MMCI_BF(MAXLAT, 0) +#define NCR MMCI_BF(MAXLAT, 1) +#define TRCMD_START MMCI_BF(TRCMD, 1) +#define TRDIR_READ MMCI_BF(TRDIR, 1) +#define TRTYP_BLOCK MMCI_BF(TRTYP, 0) +#define INIT_CMD MMCI_BF(SPCMD, 1) +#define OPEN_DRAIN MMCI_BF(OPDCMD, 1) + +#define ERROR_FLAGS (MMCI_BIT(DTOE) \ + | MMCI_BIT(RDIRE) \ + | MMCI_BIT(RENDE) \ + | MMCI_BIT(RINDE) \ + | MMCI_BIT(RTOE)) + +static int +mmc_cmd(unsigned long cmd, unsigned long arg, + void *resp, unsigned long flags) +{ + unsigned long *response = resp; + int i, response_words = 0; + unsigned long error_flags; + u32 status; + + pr_debug("mmc: CMD%lu 0x%lx (flags 0x%lx)\n", + cmd, arg, flags); + + error_flags = ERROR_FLAGS; + if (!(flags & RESP_NO_CRC)) + error_flags |= MMCI_BIT(RCRCE); + + flags &= ~MMCI_BF(CMDNB, ~0UL); + + if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_48_BIT_RESP) + response_words = 1; + else if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_136_BIT_RESP) + response_words = 4; + + mmci_writel(ARGR, arg); + mmci_writel(CMDR, cmd | flags); + do { + udelay(40); + status = mmci_readl(SR); + } while (!(status & MMCI_BIT(CMDRDY))); + + pr_debug("mmc: status 0x%08lx\n", status); + + if (status & ERROR_FLAGS) { + printf("mmc: command %lu failed (status: 0x%08lx)\n", + cmd, status); + return -EIO; + } + + if (response_words) + pr_debug("mmc: response:"); + + for (i = 0; i < response_words; i++) { + response[i] = mmci_readl(RSPR); + pr_debug(" %08lx", response[i]); + } + pr_debug("\n"); + + return 0; +} + +static int mmc_acmd(unsigned long cmd, unsigned long arg, + void *resp, unsigned long flags) +{ + unsigned long aresp[4]; + int ret; + + /* + * Seems like the APP_CMD part of an ACMD has 64 cycles max + * latency even though the ACMD part doesn't. This isn't + * entirely clear in the SD Card spec, but some cards refuse + * to work if we attempt to use 5 cycles max latency here... + */ + ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp, + R1 | NCR | (flags & OPEN_DRAIN)); + if (ret) + return ret; + if ((aresp[0] & (R1_ILLEGAL_COMMAND | R1_APP_CMD)) != R1_APP_CMD) + return -ENODEV; + + ret = mmc_cmd(cmd, arg, resp, flags); + return ret; +} + +static unsigned long +mmc_bread(int dev, unsigned long start, lbaint_t blkcnt, + unsigned long *buffer) +{ + int ret, i = 0; + unsigned long resp[4]; + unsigned long card_status, data; + unsigned long wordcount; + u32 status; + + if (blkcnt == 0) + return 0; + + pr_debug("mmc_bread: dev %d, start %lx, blkcnt %lx\n", + dev, start, blkcnt); + + /* Put the device into Transfer state */ + ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, R1 | NCR); + if (ret) goto fail; + + /* Set block length */ + ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, R1 | NCR); + if (ret) goto fail; + + pr_debug("MCI_DTOR = %08lx\n", mmci_readl(DTOR)); + + for (i = 0; i < blkcnt; i++, start++) { + ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK, + start * mmc_blkdev.blksz, resp, + (R1 | NCR | TRCMD_START | TRDIR_READ + | TRTYP_BLOCK)); + if (ret) goto fail; + + ret = -EIO; + wordcount = 0; + do { + do { + status = mmci_readl(SR); + if (status & (ERROR_FLAGS | MMCI_BIT(OVRE))) + goto fail; + } while (!(status & MMCI_BIT(RXRDY))); + + if (status & MMCI_BIT(RXRDY)) { + data = mmci_readl(RDR); + /* pr_debug("%x\n", data); */ + *buffer++ = data; + wordcount++; + } + } while(wordcount < (512 / 4)); + + pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount); + + do { + status = mmci_readl(SR); + } while (!(status & MMCI_BIT(BLKE))); + + putc('.'); + } + +out: + /* Put the device back into Standby state */ + mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, NCR); + return i; + +fail: + mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR); + printf("mmc: bread failed, card status = ", card_status); + goto out; +} + +static void mmc_parse_cid(struct mmc_cid *cid, unsigned long *resp) +{ + cid->mid = resp[0] >> 24; + cid->oid = (resp[0] >> 8) & 0xffff; + cid->pnm[0] = resp[0]; + cid->pnm[1] = resp[1] >> 24; + cid->pnm[2] = resp[1] >> 16; + cid->pnm[3] = resp[1] >> 8; + cid->pnm[4] = resp[1]; + cid->pnm[5] = resp[2] >> 24; + cid->pnm[6] = 0; + cid->prv = resp[2] >> 16; + cid->psn = (resp[2] << 16) | (resp[3] >> 16); + cid->mdt = resp[3] >> 8; +} + +static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp) +{ + cid->mid = resp[0] >> 24; + cid->oid = (resp[0] >> 8) & 0xffff; + cid->pnm[0] = resp[0]; + cid->pnm[1] = resp[1] >> 24; + cid->pnm[2] = resp[1] >> 16; + cid->pnm[3] = resp[1] >> 8; + cid->pnm[4] = resp[1]; + cid->pnm[5] = 0; + cid->pnm[6] = 0; + cid->prv = resp[2] >> 24; + cid->psn = (resp[2] << 8) | (resp[3] >> 24); + cid->mdt = (resp[3] >> 8) & 0x0fff; +} + +static void mmc_dump_cid(const struct mmc_cid *cid) +{ + printf("Manufacturer ID: %02lX\n", cid->mid); + printf("OEM/Application ID: %04lX\n", cid->oid); + printf("Product name: %s\n", cid->pnm); + printf("Product Revision: %lu.%lu\n", + cid->prv >> 4, cid->prv & 0x0f); + printf("Product Serial Number: %lu\n", cid->psn); + printf("Manufacturing Date: %02lu/%02lu\n", + cid->mdt >> 4, cid->mdt & 0x0f); +} + +static void mmc_dump_csd(const struct mmc_csd *csd) +{ + unsigned long *csd_raw = (unsigned long *)csd; + printf("CSD data: %08lx %08lx %08lx %08lx\n", + csd_raw[0], csd_raw[1], csd_raw[2], csd_raw[3]); + printf("CSD structure version: 1.%u\n", csd->csd_structure); + printf("MMC System Spec version: %u\n", csd->spec_vers); + printf("Card command classes: %03x\n", csd->ccc); + printf("Read block length: %u\n", 1 << csd->read_bl_len); + if (csd->read_bl_partial) + puts("Supports partial reads\n"); + else + puts("Does not support partial reads\n"); + printf("Write block length: %u\n", 1 << csd->write_bl_len); + if (csd->write_bl_partial) + puts("Supports partial writes\n"); + else + puts("Does not support partial writes\n"); + if (csd->wp_grp_enable) + printf("Supports group WP: %u\n", csd->wp_grp_size + 1); + else + puts("Does not support group WP\n"); + printf("Card capacity: %u bytes\n", + (csd->c_size + 1) * (1 << (csd->c_size_mult + 2)) * + (1 << csd->read_bl_len)); + printf("File format: %u/%u\n", + csd->file_format_grp, csd->file_format); + puts("Write protection: "); + if (csd->perm_write_protect) + puts(" permanent"); + if (csd->tmp_write_protect) + puts(" temporary"); + putc('\n'); +} + +static int mmc_idle_cards(void) +{ + int ret; + + /* Reset and initialize all cards */ + ret = mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0); + if (ret) + return ret; + + /* Keep the bus idle for 74 clock cycles */ + return mmc_cmd(0, 0, NULL, INIT_CMD); +} + +static int sd_init_card(struct mmc_cid *cid, int verbose) +{ + unsigned long resp[4]; + int i, ret = 0; + + mmc_idle_cards(); + for (i = 0; i < 1000; i++) { + ret = mmc_acmd(MMC_ACMD_SD_SEND_OP_COND, CFG_MMC_OP_COND, + resp, R3 | NID); + if (ret || (resp[0] & 0x80000000)) + break; + ret = -ETIMEDOUT; + } + + if (ret) + return ret; + + ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID); + if (ret) + return ret; + sd_parse_cid(cid, resp); + if (verbose) + mmc_dump_cid(cid); + + /* Get RCA of the card that responded */ + ret = mmc_cmd(MMC_CMD_SD_SEND_RELATIVE_ADDR, 0, resp, R6 | NCR); + if (ret) + return ret; + + mmc_rca = resp[0] >> 16; + if (verbose) + printf("SD Card detected (RCA %u)\n", mmc_rca); + return 0; +} + +static int mmc_init_card(struct mmc_cid *cid, int verbose) +{ + unsigned long resp[4]; + int i, ret = 0; + + mmc_idle_cards(); + for (i = 0; i < 1000; i++) { + ret = mmc_cmd(MMC_CMD_SEND_OP_COND, CFG_MMC_OP_COND, resp, + R3 | NID | OPEN_DRAIN); + if (ret || (resp[0] & 0x80000000)) + break; + ret = -ETIMEDOUT; + } + + if (ret) + return ret; + + /* Get CID of all cards. FIXME: Support more than one card */ + ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID | OPEN_DRAIN); + if (ret) + return ret; + mmc_parse_cid(cid, resp); + if (verbose) + mmc_dump_cid(cid); + + /* Set Relative Address of the card that responded */ + ret = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, mmc_rca << 16, resp, + R1 | NCR | OPEN_DRAIN); + return ret; +} + +int mmc_init(int verbose) +{ + struct mmc_cid cid; + struct mmc_csd csd; + int ret; + + /* Initialize controller */ + mmci_writel(CR, MMCI_BIT(SWRST)); + mmci_writel(CR, MMCI_BIT(MCIEN)); + mmci_writel(DTOR, 0x5f); + mmci_writel(IDR, ~0UL); + mci_set_mode(CFG_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); + + ret = sd_init_card(&cid, verbose); + if (ret) { + mmc_rca = MMC_DEFAULT_RCA; + ret = mmc_init_card(&cid, verbose); + } + if (ret) + return ret; + + /* Get CSD from the card */ + ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, &csd, R2 | NCR); + if (ret) + return ret; + if (verbose) + mmc_dump_csd(&csd); + + /* Initialize the blockdev structure */ + mmc_blkdev.if_type = IF_TYPE_MMC; + mmc_blkdev.part_type = PART_TYPE_DOS; + mmc_blkdev.block_read = mmc_bread; + sprintf((char *)mmc_blkdev.vendor, + "Man %02x%04x Snr %08x", + cid.mid, cid.oid, cid.psn); + strncpy((char *)mmc_blkdev.product, cid.pnm, + sizeof(mmc_blkdev.product)); + sprintf((char *)mmc_blkdev.revision, "%x %x", + cid.prv >> 4, cid.prv & 0x0f); + mmc_blkdev.blksz = 1 << csd.read_bl_len; + mmc_blkdev.lba = (csd.c_size + 1) * (1 << (csd.c_size_mult + 2)); + + mci_set_mode(CFG_MMC_CLK_PP, mmc_blkdev.blksz); + +#if 0 + if (fat_register_device(&mmc_blkdev, 1)) + printf("Could not register MMC fat device\n"); +#else + init_part(&mmc_blkdev); +#endif + + return 0; +} + +int mmc_read(ulong src, uchar *dst, int size) +{ + return -ENOSYS; +} + +int mmc_write(uchar *src, ulong dst, int size) +{ + return -ENOSYS; +} + +int mmc2info(ulong addr) +{ + return 0; +} + +#endif /* CONFIG_MMC */ diff --git a/cpu/at32ap/atmel_mci.h b/cpu/at32ap/atmel_mci.h new file mode 100644 index 0000000..0ffbc4f --- /dev/null +++ b/cpu/at32ap/atmel_mci.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2005-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 + */ +#ifndef __CPU_AT32AP_ATMEL_MCI_H__ +#define __CPU_AT32AP_ATMEL_MCI_H__ + +/* Atmel MultiMedia Card Interface (MCI) registers */ +#define MMCI_CR 0x0000 +#define MMCI_MR 0x0004 +#define MMCI_DTOR 0x0008 +#define MMCI_SDCR 0x000c +#define MMCI_ARGR 0x0010 +#define MMCI_CMDR 0x0014 +#define MMCI_RSPR 0x0020 +#define MMCI_RSPR1 0x0024 +#define MMCI_RSPR2 0x0028 +#define MMCI_RSPR3 0x002c +#define MMCI_RDR 0x0030 +#define MMCI_TDR 0x0034 +#define MMCI_SR 0x0040 +#define MMCI_IER 0x0044 +#define MMCI_IDR 0x0048 +#define MMCI_IMR 0x004c + +/* Bitfields in CR */ +#define MMCI_MCIEN_OFFSET 0 +#define MMCI_MCIEN_SIZE 1 +#define MMCI_MCIDIS_OFFSET 1 +#define MMCI_MCIDIS_SIZE 1 +#define MMCI_PWSEN_OFFSET 2 +#define MMCI_PWSEN_SIZE 1 +#define MMCI_PWSDIS_OFFSET 3 +#define MMCI_PWSDIS_SIZE 1 +#define MMCI_SWRST_OFFSET 7 +#define MMCI_SWRST_SIZE 1 + +/* Bitfields in MR */ +#define MMCI_CLKDIV_OFFSET 0 +#define MMCI_CLKDIV_SIZE 8 +#define MMCI_PWSDIV_OFFSET 8 +#define MMCI_PWSDIV_SIZE 3 +#define MMCI_PDCPADV_OFFSET 14 +#define MMCI_PDCPADV_SIZE 1 +#define MMCI_PDCMODE_OFFSET 15 +#define MMCI_PDCMODE_SIZE 1 +#define MMCI_BLKLEN_OFFSET 16 +#define MMCI_BLKLEN_SIZE 16 + +/* Bitfields in DTOR */ +#define MMCI_DTOCYC_OFFSET 0 +#define MMCI_DTOCYC_SIZE 4 +#define MMCI_DTOMUL_OFFSET 4 +#define MMCI_DTOMUL_SIZE 3 + +/* Bitfields in SDCR */ +#define MMCI_SCDSEL_OFFSET 0 +#define MMCI_SCDSEL_SIZE 4 +#define MMCI_SCDBUS_OFFSET 7 +#define MMCI_SCDBUS_SIZE 1 + +/* Bitfields in ARGR */ +#define MMCI_ARG_OFFSET 0 +#define MMCI_ARG_SIZE 32 + +/* Bitfields in CMDR */ +#define MMCI_CMDNB_OFFSET 0 +#define MMCI_CMDNB_SIZE 6 +#define MMCI_RSPTYP_OFFSET 6 +#define MMCI_RSPTYP_SIZE 2 +#define MMCI_SPCMD_OFFSET 8 +#define MMCI_SPCMD_SIZE 3 +#define MMCI_OPDCMD_OFFSET 11 +#define MMCI_OPDCMD_SIZE 1 +#define MMCI_MAXLAT_OFFSET 12 +#define MMCI_MAXLAT_SIZE 1 +#define MMCI_TRCMD_OFFSET 16 +#define MMCI_TRCMD_SIZE 2 +#define MMCI_TRDIR_OFFSET 18 +#define MMCI_TRDIR_SIZE 1 +#define MMCI_TRTYP_OFFSET 19 +#define MMCI_TRTYP_SIZE 2 + +/* Bitfields in RSPRx */ +#define MMCI_RSP_OFFSET 0 +#define MMCI_RSP_SIZE 32 + +/* Bitfields in SR/IER/IDR/IMR */ +#define MMCI_CMDRDY_OFFSET 0 +#define MMCI_CMDRDY_SIZE 1 +#define MMCI_RXRDY_OFFSET 1 +#define MMCI_RXRDY_SIZE 1 +#define MMCI_TXRDY_OFFSET 2 +#define MMCI_TXRDY_SIZE 1 +#define MMCI_BLKE_OFFSET 3 +#define MMCI_BLKE_SIZE 1 +#define MMCI_DTIP_OFFSET 4 +#define MMCI_DTIP_SIZE 1 +#define MMCI_NOTBUSY_OFFSET 5 +#define MMCI_NOTBUSY_SIZE 1 +#define MMCI_ENDRX_OFFSET 6 +#define MMCI_ENDRX_SIZE 1 +#define MMCI_ENDTX_OFFSET 7 +#define MMCI_ENDTX_SIZE 1 +#define MMCI_RXBUFF_OFFSET 14 +#define MMCI_RXBUFF_SIZE 1 +#define MMCI_TXBUFE_OFFSET 15 +#define MMCI_TXBUFE_SIZE 1 +#define MMCI_RINDE_OFFSET 16 +#define MMCI_RINDE_SIZE 1 +#define MMCI_RDIRE_OFFSET 17 +#define MMCI_RDIRE_SIZE 1 +#define MMCI_RCRCE_OFFSET 18 +#define MMCI_RCRCE_SIZE 1 +#define MMCI_RENDE_OFFSET 19 +#define MMCI_RENDE_SIZE 1 +#define MMCI_RTOE_OFFSET 20 +#define MMCI_RTOE_SIZE 1 +#define MMCI_DCRCE_OFFSET 21 +#define MMCI_DCRCE_SIZE 1 +#define MMCI_DTOE_OFFSET 22 +#define MMCI_DTOE_SIZE 1 +#define MMCI_OVRE_OFFSET 30 +#define MMCI_OVRE_SIZE 1 +#define MMCI_UNRE_OFFSET 31 +#define MMCI_UNRE_SIZE 1 + +/* Constants for DTOMUL */ +#define MMCI_DTOMUL_1_CYCLE 0 +#define MMCI_DTOMUL_16_CYCLES 1 +#define MMCI_DTOMUL_128_CYCLES 2 +#define MMCI_DTOMUL_256_CYCLES 3 +#define MMCI_DTOMUL_1024_CYCLES 4 +#define MMCI_DTOMUL_4096_CYCLES 5 +#define MMCI_DTOMUL_65536_CYCLES 6 +#define MMCI_DTOMUL_1048576_CYCLES 7 + +/* Constants for RSPTYP */ +#define MMCI_RSPTYP_NO_RESP 0 +#define MMCI_RSPTYP_48_BIT_RESP 1 +#define MMCI_RSPTYP_136_BIT_RESP 2 + +/* Constants for SPCMD */ +#define MMCI_SPCMD_NO_SPEC_CMD 0 +#define MMCI_SPCMD_INIT_CMD 1 +#define MMCI_SPCMD_SYNC_CMD 2 +#define MMCI_SPCMD_INT_CMD 4 +#define MMCI_SPCMD_INT_RESP 5 + +/* Constants for TRCMD */ +#define MMCI_TRCMD_NO_TRANS 0 +#define MMCI_TRCMD_START_TRANS 1 +#define MMCI_TRCMD_STOP_TRANS 2 + +/* Constants for TRTYP */ +#define MMCI_TRTYP_BLOCK 0 +#define MMCI_TRTYP_MULTI_BLOCK 1 +#define MMCI_TRTYP_STREAM 2 + +/* Bit manipulation macros */ +#define MMCI_BIT(name) \ + (1 << MMCI_##name##_OFFSET) +#define MMCI_BF(name,value) \ + (((value) & ((1 << MMCI_##name##_SIZE) - 1)) \ + << MMCI_##name##_OFFSET) +#define MMCI_BFEXT(name,value) \ + (((value) >> MMCI_##name##_OFFSET)\ + & ((1 << MMCI_##name##_SIZE) - 1)) +#define MMCI_BFINS(name,value,old) \ + (((old) & ~(((1 << MMCI_##name##_SIZE) - 1) \ + << MMCI_##name##_OFFSET)) \ + | MMCI_BF(name,value)) + +/* Register access macros */ +#define mmci_readl(reg) \ + readl((void *)MMCI_BASE + MMCI_##reg) +#define mmci_writel(reg,value) \ + writel((value), (void *)MMCI_BASE + MMCI_##reg) + +#endif /* __CPU_AT32AP_ATMEL_MCI_H__ */ diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c index 37e3ea0..311466b 100644 --- a/cpu/at32ap/cpu.c +++ b/cpu/at32ap/cpu.c @@ -26,33 +26,79 @@ #include <asm/sections.h> #include <asm/sysreg.h> +#include <asm/arch/clk.h> #include <asm/arch/memory-map.h> -#include <asm/arch/platform.h> #include "hsmc3.h" +#include "sm.h" + +/* Sanity checks */ +#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \ + || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \ + || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB) +# error Constraint fCPU >= fHSB >= fPB{A,B} violated +#endif +#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1)) +# error Invalid PLL multiplier and/or divider +#endif DECLARE_GLOBAL_DATA_PTR; +static void pm_init(void) +{ + uint32_t cksel; + +#ifdef CONFIG_PLL + /* Initialize the PLL */ + sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES) + | SM_BF(PLLMUL, CFG_PLL0_MUL - 1) + | SM_BF(PLLDIV, CFG_PLL0_DIV - 1) + | SM_BF(PLLOPT, CFG_PLL0_OPT) + | SM_BF(PLLOSC, 0) + | SM_BIT(PLLEN))); + + /* Wait for lock */ + while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ; +#endif + + /* Set up clocks for the CPU and all peripheral buses */ + cksel = 0; + if (CFG_CLKDIV_CPU) + cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1); + if (CFG_CLKDIV_HSB) + cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1); + if (CFG_CLKDIV_PBA) + cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1); + if (CFG_CLKDIV_PBB) + cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1); + sm_writel(PM_CKSEL, cksel); + + gd->cpu_hz = get_cpu_clk_rate(); + +#ifdef CONFIG_PLL + /* Use PLL0 as main clock */ + sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); +#endif +} + int cpu_init(void) { - const struct device *hebi; extern void _evba(void); char *p; gd->cpu_hz = CFG_OSC0_HZ; - /* fff03400: 00010001 04030402 00050005 10011103 */ - hebi = get_device(DEVICE_HEBI); - hsmc3_writel(hebi, MODE0, 0x00031103); - hsmc3_writel(hebi, CYCLE0, 0x000c000d); - hsmc3_writel(hebi, PULSE0, 0x0b0a0906); - hsmc3_writel(hebi, SETUP0, 0x00010002); + /* TODO: Move somewhere else, but needs to be run before we + * increase the clock frequency. */ + hsmc3_writel(MODE0, 0x00031103); + hsmc3_writel(CYCLE0, 0x000c000d); + hsmc3_writel(PULSE0, 0x0b0a0906); + hsmc3_writel(SETUP0, 0x00010002); pm_init(); sysreg_write(EVBA, (unsigned long)&_evba); asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET)); - gd->console_uart = get_device(CFG_CONSOLE_UART_DEV); /* Lock everything that mess with the flash in the icache */ for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ); diff --git a/cpu/at32ap/device.c b/cpu/at32ap/device.c deleted file mode 100644 index 89914b6..0000000 --- a/cpu/at32ap/device.c +++ /dev/null @@ -1,126 +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/arch/platform.h> - -#include "sm.h" - -struct device_state { - int refcount; -}; - -static struct device_state device_state[NR_DEVICES]; - -static int claim_resource(const struct resource *res) -{ - int ret = 0; - - switch (res->type) { - case RESOURCE_GPIO: - ret = gpio_set_func(res->u.gpio.gpio_dev, - res->u.gpio.start, - res->u.gpio.nr_pins, - res->u.gpio.func); - break; - case RESOURCE_CLOCK: - ret = pm_enable_clock(res->u.clock.id, res->u.clock.index); - break; - } - - return ret; -} - -static void free_resource(const struct resource *res) -{ - switch (res->type) { - case RESOURCE_GPIO: - gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start, - res->u.gpio.nr_pins); - break; - case RESOURCE_CLOCK: - pm_disable_clock(res->u.clock.id, res->u.clock.index); - break; - } -} - -static int init_dev(const struct device *dev) -{ - unsigned int i; - int ret = 0; - - for (i = 0; i < dev->nr_resources; i++) { - ret = claim_resource(&dev->resource[i]); - if (ret) - goto cleanup; - } - - return 0; - -cleanup: - while (i--) - free_resource(&dev->resource[i]); - - return ret; -} - -const struct device *get_device(enum device_id devid) -{ - struct device_state *devstate; - const struct device *dev; - unsigned long flags; - int initialized = 0; - int ret = 0; - - devstate = &device_state[devid]; - dev = &chip_device[devid]; - - flags = disable_interrupts(); - if (devstate->refcount++) - initialized = 1; - if (flags) - enable_interrupts(); - - if (!initialized) - ret = init_dev(dev); - - return ret ? NULL : dev; -} - -void put_device(const struct device *dev) -{ - struct device_state *devstate; - unsigned long devid, flags; - - devid = (unsigned long)(dev - chip_device) / sizeof(struct device); - devstate = &device_state[devid]; - - flags = disable_interrupts(); - devstate--; - if (!devstate) { - unsigned int i; - for (i = 0; i < dev->nr_resources; i++) - free_resource(&dev->resource[i]); - } - if (flags) - enable_interrupts(); -} diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S index b52d798..a6fc688 100644 --- a/cpu/at32ap/entry.S +++ b/cpu/at32ap/entry.S @@ -42,8 +42,7 @@ timer_interrupt_handler: * We're running at interrupt level 3, so we don't need to save * r8-r12 or lr to the stack. */ - mov r8, lo(timer_overflow) - orh r8, hi(timer_overflow) + lda.w r8, timer_overflow ld.w r9, r8[0] mov r10, -1 mtsr SYSREG_COMPARE, r10 diff --git a/cpu/at32ap/exception.c b/cpu/at32ap/exception.c index 4123c44..0672685 100644 --- a/cpu/at32ap/exception.c +++ b/cpu/at32ap/exception.c @@ -24,6 +24,8 @@ #include <asm/sysreg.h> #include <asm/ptrace.h> +DECLARE_GLOBAL_DATA_PTR; + static const char * const cpu_modes[8] = { "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" @@ -109,11 +111,10 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) printf("CPU Mode: %s\n", cpu_modes[mode]); /* Avoid exception loops */ - if (regs->sp >= CFG_INIT_SP_ADDR - || regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE)) + if (regs->sp < CFG_SDRAM_BASE || regs->sp >= gd->stack_end) printf("\nStack pointer seems bogus, won't do stack dump\n"); else - dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR); + dump_mem("\nStack: ", regs->sp, gd->stack_end); panic("Unhandled exception\n"); } diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c index f36da35..a936e03 100644 --- a/cpu/at32ap/hsdramc.c +++ b/cpu/at32ap/hsdramc.c @@ -25,17 +25,11 @@ #include <asm/io.h> #include <asm/sdram.h> -#include <asm/arch/platform.h> +#include <asm/arch/clk.h> +#include <asm/arch/memory-map.h> #include "hsdramc1.h" -struct hsdramc { - const struct device *hebi; - void *regs; -}; - -static struct hsdramc hsdramc; - unsigned long sdram_init(const struct sdram_info *info) { unsigned long *sdram = (unsigned long *)uncached(info->phys_addr); @@ -44,16 +38,6 @@ unsigned long sdram_init(const struct sdram_info *info) unsigned long bus_hz; unsigned int i; - hsdramc.hebi = get_device(DEVICE_HEBI); - if (!hsdramc.hebi) - return 0; - - /* FIXME: Both of these lines are complete hacks */ - hsdramc.regs = hsdramc.hebi->regs + 0x400; - bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id); - - cpu_enable_sdram(); - tmp = (HSDRAMC1_BF(NC, info->col_bits - 8) | HSDRAMC1_BF(NR, info->row_bits - 11) | HSDRAMC1_BF(NB, info->bank_bits - 1) @@ -74,7 +58,7 @@ unsigned long sdram_init(const struct sdram_info *info) + info->bank_bits + 2); #endif - hsdramc1_writel(&hsdramc, CR, tmp); + hsdramc1_writel(CR, tmp); /* * Initialization sequence for SDRAM, from the data sheet: @@ -87,15 +71,15 @@ unsigned long sdram_init(const struct sdram_info *info) /* * 2. A Precharge All command is issued to the SDRAM */ - hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE); - hsdramc1_readl(&hsdramc, MR); + hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE); + hsdramc1_readl(MR); writel(0, sdram); /* * 3. Eight auto-refresh (CBR) cycles are provided */ - hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH); - hsdramc1_readl(&hsdramc, MR); + hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH); + hsdramc1_readl(MR); for (i = 0; i < 8; i++) writel(0, sdram); @@ -106,8 +90,8 @@ unsigned long sdram_init(const struct sdram_info *info) * * CAS from info struct, burst length 1, serial burst type */ - hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE); - hsdramc1_readl(&hsdramc, MR); + hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE); + hsdramc1_readl(MR); writel(0, sdram + (info->cas << 4)); /* @@ -117,9 +101,9 @@ unsigned long sdram_init(const struct sdram_info *info) * From the timing diagram, it looks like tMRD is 3 * cycles...try a dummy read from the peripheral bus. */ - hsdramc1_readl(&hsdramc, MR); - hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL); - hsdramc1_readl(&hsdramc, MR); + hsdramc1_readl(MR); + hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL); + hsdramc1_readl(MR); writel(0, sdram); /* @@ -128,7 +112,8 @@ unsigned long sdram_init(const struct sdram_info *info) * * 15.6 us is a typical value for a burst of length one */ - hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000); + bus_hz = get_sdram_clk_rate(); + hsdramc1_writel(TR, (156 * (bus_hz / 1000)) / 10000); printf("SDRAM: %u MB at address 0x%08lx\n", sdram_size >> 20, info->phys_addr); diff --git a/cpu/at32ap/hsdramc1.h b/cpu/at32ap/hsdramc1.h index ce229bc..305d2cb 100644 --- a/cpu/at32ap/hsdramc1.h +++ b/cpu/at32ap/hsdramc1.h @@ -135,9 +135,9 @@ | HSDRAMC1_BF(name,value)) /* Register access macros */ -#define hsdramc1_readl(port,reg) \ - readl((port)->regs + HSDRAMC1_##reg) -#define hsdramc1_writel(port,reg,value) \ - writel((value), (port)->regs + HSDRAMC1_##reg) +#define hsdramc1_readl(reg) \ + readl((void *)HSDRAMC_BASE + HSDRAMC1_##reg) +#define hsdramc1_writel(reg,value) \ + writel((value), (void *)HSDRAMC_BASE + HSDRAMC1_##reg) #endif /* __ASM_AVR32_HSDRAMC1_H__ */ diff --git a/cpu/at32ap/hsmc3.h b/cpu/at32ap/hsmc3.h index ec78cee..ca533b9 100644 --- a/cpu/at32ap/hsmc3.h +++ b/cpu/at32ap/hsmc3.h @@ -118,9 +118,9 @@ | HSMC3_BF(name,value)) /* Register access macros */ -#define hsmc3_readl(port,reg) \ - readl((port)->regs + HSMC3_##reg) -#define hsmc3_writel(port,reg,value) \ - writel((value), (port)->regs + HSMC3_##reg) +#define hsmc3_readl(reg) \ + readl((void *)HSMC_BASE + HSMC3_##reg) +#define hsmc3_writel(reg,value) \ + writel((value), (void *)HSMC_BASE + HSMC3_##reg) #endif /* __CPU_AT32AP_HSMC3_H__ */ diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c index d720cfa..c9e0499 100644 --- a/cpu/at32ap/interrupts.c +++ b/cpu/at32ap/interrupts.c @@ -27,7 +27,7 @@ #include <asm/processor.h> #include <asm/sysreg.h> -#include <asm/arch/platform.h> +#include <asm/arch/memory-map.h> #define HANDLER_MASK 0x00ffffff #define INTLEV_SHIFT 30 @@ -44,8 +44,6 @@ volatile unsigned long timer_overflow; */ static unsigned long tb_factor; -static const struct device *intc_dev; - unsigned long get_tbclk(void) { return gd->cpu_hz; @@ -117,16 +115,19 @@ void udelay(unsigned long usec) static int set_interrupt_handler(unsigned int nr, void (*handler)(void), unsigned int priority) { + extern void _evba(void); unsigned long intpr; unsigned long handler_addr = (unsigned long)handler; + handler_addr -= (unsigned long)&_evba; + if ((handler_addr & HANDLER_MASK) != handler_addr || (priority & INTLEV_MASK) != priority) return -EINVAL; intpr = (handler_addr & HANDLER_MASK); intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT; - writel(intpr, intc_dev->regs + 4 * nr); + writel(intpr, (void *)INTC_BASE + 4 * nr); return 0; } @@ -143,10 +144,7 @@ void timer_init(void) do_div(tmp, gd->cpu_hz); tb_factor = (u32)tmp; - intc_dev = get_device(DEVICE_INTC); - - if (!intc_dev - || set_interrupt_handler(0, &timer_interrupt_handler, 3)) + if (set_interrupt_handler(0, &timer_interrupt_handler, 3)) return; /* For all practical purposes, this gives us an overflow interrupt */ diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c index 8b6c3a3..9ba0b8e 100644 --- a/cpu/at32ap/pio.c +++ b/cpu/at32ap/pio.c @@ -21,74 +21,40 @@ */ #include <common.h> -#include <asm/errno.h> #include <asm/io.h> -#include <asm/arch/platform.h> +#include <asm/arch/gpio.h> +#include <asm/arch/memory-map.h> #include "pio2.h" -struct pio_state { - const struct device *dev; - u32 alloc_mask; -}; - -static struct pio_state pio_state[CFG_NR_PIOS]; - -int gpio_set_func(enum device_id gpio_devid, unsigned int start, - unsigned int nr_pins, enum gpio_func func) +void gpio_select_periph_A(unsigned int pin, int use_pullup) { - const struct device *gpio; - struct pio_state *state; - u32 mask; - - state = &pio_state[gpio_devid - DEVICE_PIOA]; - - gpio = get_device(gpio_devid); - if (!gpio) - return -EBUSY; - - state->dev = gpio; - mask = ((1 << nr_pins) - 1) << start; - - if (mask & state->alloc_mask) { - put_device(gpio); - return -EBUSY; - } - state->alloc_mask |= mask; - - switch (func) { - case GPIO_FUNC_GPIO: - /* TODO */ - return -EINVAL; - case GPIO_FUNC_A: - pio2_writel(gpio, ASR, mask); - pio2_writel(gpio, PDR, mask); - pio2_writel(gpio, PUDR, mask); - break; - case GPIO_FUNC_B: - pio2_writel(gpio, BSR, mask); - pio2_writel(gpio, PDR, mask); - pio2_writel(gpio, PUDR, mask); - break; - } - - return 0; + 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_free(enum device_id gpio_devid, unsigned int start, - unsigned int nr_pins) +void gpio_select_periph_B(unsigned int pin, int use_pullup) { - const struct device *gpio; - struct pio_state *state; - u32 mask; - - state = &pio_state[gpio_devid - DEVICE_PIOA]; - gpio = state->dev; - mask = ((1 << nr_pins) - 1) << start; - - pio2_writel(gpio, ODR, mask); - pio2_writel(gpio, PER, mask); - - state->alloc_mask &= ~mask; - put_device(gpio); + 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); } diff --git a/cpu/at32ap/pio2.h b/cpu/at32ap/pio2.h index 6b79de3..9719ea8 100644 --- a/cpu/at32ap/pio2.h +++ b/cpu/at32ap/pio2.h @@ -36,9 +36,9 @@ #define PIO2_OWSR 0x00a8 /* Register access macros */ -#define pio2_readl(port,reg) \ - readl((port)->regs + PIO2_##reg) -#define pio2_writel(port,reg,value) \ - writel((value), (port)->regs + PIO2_##reg) +#define pio2_readl(base,reg) \ + readl((void *)base + PIO2_##reg) +#define pio2_writel(base,reg,value) \ + writel((value), (void *)base + PIO2_##reg) #endif /* __CPU_AT32AP_PIO2_H__ */ diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c index 01ac325..c78d547 100644 --- a/cpu/at32ap/pm.c +++ b/cpu/at32ap/pm.c @@ -26,138 +26,17 @@ #include <asm/io.h> #include <asm/arch/memory-map.h> -#include <asm/arch/platform.h> #include "sm.h" -/* Sanity checks */ -#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \ - || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \ - || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB) -# error Constraint fCPU >= fHSB >= fPB{A,B} violated -#endif -#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1)) -# error Invalid PLL multiplier and/or divider -#endif - -DECLARE_GLOBAL_DATA_PTR; - -struct clock_domain_state { - const struct device *bridge; - unsigned long freq; - u32 mask; -}; -static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS]; - -int pm_enable_clock(enum clock_domain_id id, unsigned int index) -{ - const struct clock_domain *ckd = &chip_clock[id]; - struct clock_domain_state *state = &ckd_state[id]; - - if (ckd->bridge != NO_DEVICE) { - state->bridge = get_device(ckd->bridge); - if (!state->bridge) - return -EBUSY; - } - - state->mask |= 1 << index; - if (gd->sm) - writel(state->mask, gd->sm->regs + ckd->reg); - - return 0; -} - -void pm_disable_clock(enum clock_domain_id id, unsigned int index) -{ - const struct clock_domain *ckd = &chip_clock[id]; - struct clock_domain_state *state = &ckd_state[id]; - - state->mask &= ~(1 << index); - if (gd->sm) - writel(state->mask, gd->sm->regs + ckd->reg); - - if (ckd->bridge) - put_device(state->bridge); -} - -unsigned long pm_get_clock_freq(enum clock_domain_id domain) -{ - return ckd_state[domain].freq; -} - -void pm_init(void) -{ - uint32_t cksel = 0; - unsigned long main_clock; - - /* Make sure we don't disable any device we're already using */ - get_device(DEVICE_HRAMC); - get_device(DEVICE_HEBI); - - /* Enable the PICO as well */ - ckd_state[CLOCK_CPU].mask |= 1; - - gd->sm = get_device(DEVICE_SM); - if (!gd->sm) - panic("Unable to claim system manager device!\n"); - - /* Disable any devices that haven't been explicitly claimed */ - sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask); - sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask); - sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask); - sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask); #ifdef CONFIG_PLL - /* Initialize the PLL */ - main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL; - - sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES) - | SM_BF(PLLMUL, CFG_PLL0_MUL - 1) - | SM_BF(PLLDIV, CFG_PLL0_DIV - 1) - | SM_BF(PLLOPT, CFG_PLL0_OPT) - | SM_BF(PLLOSC, 0) - | SM_BIT(PLLEN))); - - /* Wait for lock */ - while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ; +#define MAIN_CLK_RATE ((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL) #else - main_clock = CFG_OSC0_HZ; +#define MAIN_CLK_RATE (CFG_OSC0_HZ) #endif - /* Set up clocks for the CPU and all peripheral buses */ - if (CFG_CLKDIV_CPU) { - cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1); - ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU); - } else { - ckd_state[CLOCK_CPU].freq = main_clock; - } - if (CFG_CLKDIV_HSB) { - cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1); - ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB); - } else { - ckd_state[CLOCK_HSB].freq = main_clock; - } - if (CFG_CLKDIV_PBA) { - cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1); - ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA); - } else { - ckd_state[CLOCK_PBA].freq = main_clock; - } - if (CFG_CLKDIV_PBB) { - cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1); - ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB); - } else { - ckd_state[CLOCK_PBB].freq = main_clock; - } - sm_writel(gd->sm, PM_CKSEL, cksel); - - /* CFG_HZ currently depends on cpu_hz */ - gd->cpu_hz = ckd_state[CLOCK_CPU].freq; +DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_PLL - /* Use PLL0 as main clock */ - sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL)); -#endif -} #endif /* CFG_POWER_MANAGER */ diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h index ce81ef0..6492c8e 100644 --- a/cpu/at32ap/sm.h +++ b/cpu/at32ap/sm.h @@ -196,9 +196,9 @@ | SM_BF(name,value)) /* Register access macros */ -#define sm_readl(port,reg) \ - readl((port)->regs + SM_##reg) -#define sm_writel(port,reg,value) \ - writel((value), (port)->regs + SM_##reg) +#define sm_readl(reg) \ + readl((void *)SM_BASE + SM_##reg) +#define sm_writel(reg,value) \ + writel((value), (void *)SM_BASE + SM_##reg) #endif /* __CPU_AT32AP_SM_H__ */ diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S index 79ee33b..ab8c2b7 100644 --- a/cpu/at32ap/start.S +++ b/cpu/at32ap/start.S @@ -70,32 +70,12 @@ _start: 2: lddpc sp, sp_init - /* - * Relocate the data section and initialize .bss. Everything - * is guaranteed to be at least doubleword aligned by the - * linker script. - */ - lddpc r12, .Ldata_vma - lddpc r11, .Ldata_lma - lddpc r10, .Ldata_end - sub r10, r12 -4: ld.d r8, r11++ - sub r10, 8 - st.d r12++, r8 - brne 4b - - mov r8, 0 - mov r9, 0 - lddpc r10, .Lbss_end - sub r10, r12 -4: sub r10, 8 - st.d r12++, r8 - brne 4b - /* Initialize the GOT pointer */ lddpc r6, got_init 3: rsub r6, pc - ld.w pc, r6[start_u_boot@got] + + /* Let's go */ + rjmp board_init_f .align 2 .type sp_init,@object @@ -103,11 +83,82 @@ sp_init: .long CFG_INIT_SP_ADDR got_init: .long 3b - _GLOBAL_OFFSET_TABLE_ -.Ldata_lma: - .long __data_lma -.Ldata_vma: - .long _data -.Ldata_end: - .long _edata -.Lbss_end: - .long _end + + /* + * void relocate_code(new_sp, new_gd, monitor_addr) + * + * Relocate the u-boot image into RAM and continue from there. + * Does not return. + */ + .global relocate_code + .type relocate_code,@function +relocate_code: + mov sp, r12 /* use new stack */ + mov r12, r11 /* save new_gd */ + mov r11, r10 /* save destination address */ + + /* copy .text section and flush the cache along the way */ + lda.w r8, _text + lda.w r9, _etext + sub lr, r10, r8 /* relocation offset */ + +1: ldm r8++, r0-r3 + stm r10, r0-r3 + sub r10, -16 + ldm r8++, r0-r3 + stm r10, r0-r3 + sub r10, -16 + cp.w r8, r9 + cache r10[-4], 0x0d /* dcache clean/invalidate */ + cache r10[-4], 0x01 /* icache invalidate */ + brlt 1b + + /* flush write buffer */ + sync 0 + + /* copy data sections */ + lda.w r9, _edata +1: ld.d r0, r8++ + st.d r10++, r0 + cp.w r8, r9 + brlt 1b + + /* zero out .bss */ + mov r0, 0 + mov r1, 0 + lda.w r9, _end + sub r9, r8 +1: st.d r10++, r0 + sub r9, 8 + brgt 1b + + /* jump to RAM */ + sub r0, pc, . - in_ram + add pc, r0, lr + + .align 2 +in_ram: + /* find the new GOT and relocate it */ + lddpc r6, got_init_reloc +3: rsub r6, pc + mov r8, r6 + lda.w r9, _egot + lda.w r10, _got + sub r9, r10 +1: ld.w r0, r8[0] + add r0, lr + st.w r8++, r0 + sub r9, 4 + brgt 1b + + /* Move the exception handlers */ + mfsr r2, SYSREG_EVBA + add r2, lr + mtsr SYSREG_EVBA, r2 + + /* Do the rest of the initialization sequence */ + call board_init_r + + .align 2 +got_init_reloc: + .long 3b - _GLOBAL_OFFSET_TABLE_ diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile index 90018f3..dd4f299 100644 --- a/cpu/bf533/Makefile +++ b/cpu/bf533/Makefile @@ -1,6 +1,6 @@ # U-boot - Makefile # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # include $(TOPDIR)/config.mk diff --git a/cpu/bf533/bf533_serial.h b/cpu/bf533/bf533_serial.h index 0a04f3e..25b96a9 100644 --- a/cpu/bf533/bf533_serial.h +++ b/cpu/bf533/bf533_serial.h @@ -1,7 +1,7 @@ /* * U-boot - bf533_serial.h Serial Driver defines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _Bf533_SERIAL_H diff --git a/cpu/bf533/config.mk b/cpu/bf533/config.mk index 10817d9..6a713c3 100644 --- a/cpu/bf533/config.mk +++ b/cpu/bf533/config.mk @@ -1,6 +1,6 @@ # U-boot - config.mk # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # PLATFORM_RELFLAGS += -mcpu=bf533 -ffixed-P5 diff --git a/cpu/bf533/cpu.c b/cpu/bf533/cpu.c index ac8ec51..8118861 100644 --- a/cpu/bf533/cpu.c +++ b/cpu/bf533/cpu.c @@ -1,7 +1,7 @@ /* * U-boot - cpu.c CPU specific functions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -21,8 +21,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> @@ -93,7 +93,7 @@ void icache_enable(void) /* Fill the rest with invalid entry */ if (j <= 15) { - for (; j <= 16; j++) { + for (; j < 16; j++) { debug("filling %i with 0", j); *I1++ = 0x0; } @@ -169,7 +169,7 @@ void dcache_enable(void) /* Fill the rest with invalid entry */ if (j <= 15) { - for (; j <= 16; j++) { + for (; j < 16; j++) { debug("filling %i with 0", j); *I1++ = 0x0; } diff --git a/cpu/bf533/cpu.h b/cpu/bf533/cpu.h index 821363e..b6b73b1 100644 --- a/cpu/bf533/cpu.h +++ b/cpu/bf533/cpu.h @@ -1,7 +1,7 @@ /* * U-boot - cpu.h * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _CPU_H_ diff --git a/cpu/bf533/flush.S b/cpu/bf533/flush.S index 0512f3b..62e3d65 100644 --- a/cpu/bf533/flush.S +++ b/cpu/bf533/flush.S @@ -1,9 +1,9 @@ -/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. - * Copyright (C) 2004 LG SOft India. All Rights Reserved. +/* Copyright (C) 2003-2007 Analog Devices Inc. * * This file is subject to the terms and conditions of the GNU General Public * License. */ + #define ASSEMBLY #include <asm/linkage.h> diff --git a/cpu/bf533/interrupt.S b/cpu/bf533/interrupt.S index 524da8f..c356d53 100644 --- a/cpu/bf533/interrupt.S +++ b/cpu/bf533/interrupt.S @@ -1,7 +1,7 @@ /* * U-boot - interrupt.S Processing of interrupts and exception handling * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -35,8 +35,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf533/interrupts.c b/cpu/bf533/interrupts.c index 9317f26..14d06cf 100644 --- a/cpu/bf533/interrupts.c +++ b/cpu/bf533/interrupts.c @@ -1,7 +1,7 @@ /* * U-boot - interrupts.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on interrupts.c * Copyright 1996 Roman Zippel @@ -30,8 +30,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf533/ints.c b/cpu/bf533/ints.c index f476f14..5586689 100644 --- a/cpu/bf533/ints.c +++ b/cpu/bf533/ints.c @@ -1,7 +1,7 @@ /* * U-boot - ints.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on ints.c * @@ -32,8 +32,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf533/serial.c b/cpu/bf533/serial.c index 11a46be..6cab5da 100644 --- a/cpu/bf533/serial.c +++ b/cpu/bf533/serial.c @@ -1,7 +1,7 @@ /* * U-boot - serial.c Serial driver for BF533 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf533/start.S b/cpu/bf533/start.S index 94556d6..67a60cf 100644 --- a/cpu/bf533/start.S +++ b/cpu/bf533/start.S @@ -1,7 +1,7 @@ /* * U-boot - start.S Startup file of u-boot for BF533/BF561 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on head.S * Copyright (c) 2003 Metrowerks/Motorola @@ -26,8 +26,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ /* diff --git a/cpu/bf533/start1.S b/cpu/bf533/start1.S index 72cfafb..6d4731b 100644 --- a/cpu/bf533/start1.S +++ b/cpu/bf533/start1.S @@ -1,7 +1,7 @@ /* * U-boot - start1.S Code running out of RAM after relocation * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf533/traps.c b/cpu/bf533/traps.c index 248e34f..19b1fde 100644 --- a/cpu/bf533/traps.c +++ b/cpu/bf533/traps.c @@ -1,7 +1,7 @@ /* * U-boot - traps.c Routines related to interrupts and exceptions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * No original Copyright holder listed, @@ -29,8 +29,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> @@ -39,7 +39,6 @@ #include <asm/irq.h> #include <asm/system.h> #include <asm/traps.h> -#include <asm/page.h> #include <asm/machdep.h> #include "cpu.h" #include <asm/arch/anomaly.h> diff --git a/cpu/bf537/Makefile b/cpu/bf537/Makefile index 61c7338..8b0f9c0 100644 --- a/cpu/bf537/Makefile +++ b/cpu/bf537/Makefile @@ -1,6 +1,6 @@ # U-boot - Makefile # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # include $(TOPDIR)/config.mk diff --git a/cpu/bf537/config.mk b/cpu/bf537/config.mk index 4d57d9c..8a35789 100644 --- a/cpu/bf537/config.mk +++ b/cpu/bf537/config.mk @@ -1,6 +1,6 @@ # U-boot - config.mk # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # PLATFORM_RELFLAGS += -mcpu=bf537 -ffixed-P5 diff --git a/cpu/bf537/cpu.c b/cpu/bf537/cpu.c index cb8dc3c..62f603b 100644 --- a/cpu/bf537/cpu.c +++ b/cpu/bf537/cpu.c @@ -1,7 +1,7 @@ /* * U-boot - cpu.c CPU specific functions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -21,8 +21,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf537/cpu.h b/cpu/bf537/cpu.h index 821363e..b6b73b1 100644 --- a/cpu/bf537/cpu.h +++ b/cpu/bf537/cpu.h @@ -1,7 +1,7 @@ /* * U-boot - cpu.h * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _CPU_H_ diff --git a/cpu/bf537/flush.S b/cpu/bf537/flush.S index c260a8f..fbd26cc 100644 --- a/cpu/bf537/flush.S +++ b/cpu/bf537/flush.S @@ -1,9 +1,9 @@ -/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. - * Copyright (C) 2004 LG SOft India. All Rights Reserved. +/* Copyright (C) 2003-2007 Analog Devices Inc. * * This file is subject to the terms and conditions of the GNU General Public * License. */ + #define ASSEMBLY #include <asm/linkage.h> diff --git a/cpu/bf537/interrupt.S b/cpu/bf537/interrupt.S index a8be34f..a71df55 100644 --- a/cpu/bf537/interrupt.S +++ b/cpu/bf537/interrupt.S @@ -1,7 +1,7 @@ /* * U-boot - interrupt.S Processing of interrupts and exception handling * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -35,8 +35,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf537/interrupts.c b/cpu/bf537/interrupts.c index 2ca76ec..d2213b1 100644 --- a/cpu/bf537/interrupts.c +++ b/cpu/bf537/interrupts.c @@ -1,7 +1,7 @@ /* * U-boot - interrupts.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on interrupts.c * Copyright 1996 Roman Zippel @@ -30,8 +30,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf537/ints.c b/cpu/bf537/ints.c index f476f14..5586689 100644 --- a/cpu/bf537/ints.c +++ b/cpu/bf537/ints.c @@ -1,7 +1,7 @@ /* * U-boot - ints.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on ints.c * @@ -32,8 +32,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf537/serial.c b/cpu/bf537/serial.c index dd4f916..e04d08a 100644 --- a/cpu/bf537/serial.c +++ b/cpu/bf537/serial.c @@ -1,7 +1,7 @@ /* * U-boot - serial.c Serial driver for BF537 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf537_serial.c: Serial driver for BlackFin BF537 internal UART. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf537/serial.h b/cpu/bf537/serial.h index c9ee3dc..76555c2 100644 --- a/cpu/bf537/serial.h +++ b/cpu/bf537/serial.h @@ -1,7 +1,7 @@ /* * U-boot - bf537_serial.h Serial Driver defines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _Bf537_SERIAL_H diff --git a/cpu/bf537/start.S b/cpu/bf537/start.S index 264e9b6..4e02bcb 100644 --- a/cpu/bf537/start.S +++ b/cpu/bf537/start.S @@ -1,7 +1,7 @@ /* * U-boot - start.S Startup file of u-boot for BF537 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on head.S * Copyright (c) 2003 Metrowerks/Motorola @@ -26,8 +26,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ /* diff --git a/cpu/bf537/start1.S b/cpu/bf537/start1.S index 72cfafb..6d4731b 100644 --- a/cpu/bf537/start1.S +++ b/cpu/bf537/start1.S @@ -1,7 +1,7 @@ /* * U-boot - start1.S Code running out of RAM after relocation * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf537/traps.c b/cpu/bf537/traps.c index 994ece8..4e18e27 100644 --- a/cpu/bf537/traps.c +++ b/cpu/bf537/traps.c @@ -1,7 +1,7 @@ /* * U-boot - traps.c Routines related to interrupts and exceptions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * No original Copyright holder listed, @@ -29,8 +29,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> @@ -39,7 +39,6 @@ #include <asm/irq.h> #include <asm/system.h> #include <asm/traps.h> -#include <asm/page.h> #include <asm/machdep.h> #include "cpu.h" #include <asm/arch/anomaly.h> diff --git a/cpu/bf561/Makefile b/cpu/bf561/Makefile index ee7842a..2947169 100644 --- a/cpu/bf561/Makefile +++ b/cpu/bf561/Makefile @@ -1,6 +1,6 @@ # U-boot - Makefile # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # include $(TOPDIR)/config.mk diff --git a/cpu/bf561/config.mk b/cpu/bf561/config.mk index c49a0ba..f4dc04b 100644 --- a/cpu/bf561/config.mk +++ b/cpu/bf561/config.mk @@ -1,6 +1,6 @@ # U-boot - config.mk # -# Copyright (c) 2005 blackfin.uclinux.org +# Copyright (c) 2005-2007 Analog Devices Inc. # # (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -20,8 +20,8 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA # PLATFORM_RELFLAGS += -mcpu=bf561 -ffixed-P5 diff --git a/cpu/bf561/cpu.c b/cpu/bf561/cpu.c index a7b53d8..5b907cd 100644 --- a/cpu/bf561/cpu.c +++ b/cpu/bf561/cpu.c @@ -1,7 +1,7 @@ /* * U-boot - cpu.c CPU specific functions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -21,8 +21,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf561/cpu.h b/cpu/bf561/cpu.h index 821363e..b6b73b1 100644 --- a/cpu/bf561/cpu.h +++ b/cpu/bf561/cpu.h @@ -1,7 +1,7 @@ /* * U-boot - cpu.h * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _CPU_H_ diff --git a/cpu/bf561/flush.S b/cpu/bf561/flush.S index 7e12c83..0140a60 100644 --- a/cpu/bf561/flush.S +++ b/cpu/bf561/flush.S @@ -1,9 +1,9 @@ -/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved. - * Copyright (C) 2004 LG SOft India. All Rights Reserved. +/* Copyright (C) 2003-2007 Analog Devices Inc. * * This file is subject to the terms and conditions of the GNU General Public * License. */ + #define ASSEMBLY #include <asm/linkage.h> diff --git a/cpu/bf561/interrupt.S b/cpu/bf561/interrupt.S index f82fd9b..21839ce 100644 --- a/cpu/bf561/interrupt.S +++ b/cpu/bf561/interrupt.S @@ -1,7 +1,7 @@ /* * U-boot - interrupt.S Processing of interrupts and exception handling * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -35,8 +35,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf561/interrupts.c b/cpu/bf561/interrupts.c index e314f60..ecbc6ad 100644 --- a/cpu/bf561/interrupts.c +++ b/cpu/bf561/interrupts.c @@ -1,7 +1,7 @@ /* * U-boot - interrupts.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on interrupts.c * Copyright 1996 Roman Zippel @@ -30,8 +30,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf561/ints.c b/cpu/bf561/ints.c index 328e5d8..27a38a3 100644 --- a/cpu/bf561/ints.c +++ b/cpu/bf561/ints.c @@ -1,7 +1,7 @@ /* * U-boot - ints.c Interrupt related routines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on ints.c * @@ -32,8 +32,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf561/serial.c b/cpu/bf561/serial.c index baec1d3..7f5c695 100644 --- a/cpu/bf561/serial.c +++ b/cpu/bf561/serial.c @@ -1,7 +1,7 @@ /* * U-boot - serial.c Serial driver for BF561 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/bf561/serial.h b/cpu/bf561/serial.h index 98c1242..c1cbf36 100644 --- a/cpu/bf561/serial.h +++ b/cpu/bf561/serial.h @@ -1,7 +1,7 @@ /* * U-boot - bf561_serial.h Serial Driver defines * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver. @@ -38,8 +38,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _Bf561_SERIAL_H diff --git a/cpu/bf561/start.S b/cpu/bf561/start.S index 9333648..bd26cf3 100644 --- a/cpu/bf561/start.S +++ b/cpu/bf561/start.S @@ -1,7 +1,7 @@ /* * U-boot - start.S Startup file of u-boot for BF533/BF561 * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on head.S * Copyright (c) 2003 Metrowerks/Motorola @@ -26,8 +26,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ /* diff --git a/cpu/bf561/start1.S b/cpu/bf561/start1.S index 72cfafb..6d4731b 100644 --- a/cpu/bf561/start1.S +++ b/cpu/bf561/start1.S @@ -1,7 +1,7 @@ /* * U-boot - start1.S Code running out of RAM after relocation * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -18,8 +18,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #define ASSEMBLY diff --git a/cpu/bf561/traps.c b/cpu/bf561/traps.c index f5ff3a8..7e2dcd1 100644 --- a/cpu/bf561/traps.c +++ b/cpu/bf561/traps.c @@ -1,7 +1,7 @@ /* * U-boot - traps.c Routines related to interrupts and exceptions * - * Copyright (c) 2005 blackfin.uclinux.org + * Copyright (c) 2005-2007 Analog Devices Inc. * * This file is based on * No original Copyright holder listed, @@ -29,8 +29,8 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <common.h> diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile index fd54425..db1afa5 100644 --- a/cpu/microblaze/Makefile +++ b/cpu/microblaze/Makefile @@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = cpu.o interrupts.o +SOBJS = dcache.o icache.o irq.o disable_int.o enable_int.o +COBJS = cpu.o interrupts.o cache.o exception.o timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c new file mode 100644 index 0000000..fc388eb --- /dev/null +++ b/cpu/microblaze/cache.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <moonstr@monstr.eu> + * + * 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> + +#if (CONFIG_COMMANDS & CFG_CMD_CACHE) + +int dcache_status (void) +{ + int i = 0; + int mask = 0x80; + __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); + /* i&=0x80 */ + __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); + return i; +} + +int icache_status (void) +{ + int i = 0; + int mask = 0x20; + __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); + /* i&=0x20 */ + __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); + return i; +} +#endif diff --git a/cpu/microblaze/dcache.S b/cpu/microblaze/dcache.S new file mode 100644 index 0000000..eaf9671 --- /dev/null +++ b/cpu/microblaze/dcache.S @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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 + */ + .text + .globl dcache_enable + .ent dcache_enable + .align 2 +dcache_enable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Set the instruction enable bit */ + ori r12, r12, 0x80 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end dcache_enable + + .text + .globl dcache_disable + .ent dcache_disable + .align 2 +dcache_disable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Clear the data cache enable bit */ + andi r12, r12, ~0x80 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end dcache_disable diff --git a/cpu/microblaze/disable_int.S b/cpu/microblaze/disable_int.S new file mode 100644 index 0000000..aecd795 --- /dev/null +++ b/cpu/microblaze/disable_int.S @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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 + */ + + .text + .globl microblaze_disable_interrupts + .ent microblaze_disable_interrupts + .align 2 +microblaze_disable_interrupts: + #Make space on stack for a temporary + addi r1, r1, -4 + #Save register r12 + swi r12, r1, 0 + #Read the MSR register + mfs r12, rmsr + #Clear the interrupt enable bit + andi r12, r12, ~2 + #Save the MSR register + mts rmsr, r12 + #Load register r12 + lwi r12, r1, 0 + #Return + rtsd r15, 8 + #Update stack in the delay slot + addi r1, r1, 4 + .end microblaze_disable_interrupts diff --git a/cpu/at32ap/at32ap7000/hebi.c b/cpu/microblaze/enable_int.S index 3b32adf..c096c6c 100644 --- a/cpu/at32ap/at32ap7000/hebi.c +++ b/cpu/microblaze/enable_int.S @@ -1,5 +1,7 @@ /* - * Copyright (C) 2006 Atmel Corporation + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstrmonstr.eu> * * See file CREDITS for list of people who contributed to this * project. @@ -11,7 +13,7 @@ * * 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 + * 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 @@ -19,20 +21,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ -#include <common.h> - -#include <asm/io.h> - -#include <asm/arch/hmatrix2.h> -#include <asm/arch/memory-map.h> -#include <asm/arch/platform.h> - -void cpu_enable_sdram(void) -{ - const struct device *hmatrix; - - hmatrix = get_device(DEVICE_HMATRIX); - /* Set the SDRAM_ENABLE bit in the HEBI SFR */ - hmatrix2_writel(hmatrix, SFR4, 1 << 1); -} + .text + .globl microblaze_enable_interrupts + .ent microblaze_enable_interrupts + .align 2 +microblaze_enable_interrupts: + addi r1, r1, -4 + swi r12, r1, 0 + mfs r12, rmsr + ori r12, r12, 2 + mts rmsr, r12 + lwi r12, r1, 0 + rtsd r15, 8 + addi r1, r1, 4 + .end microblaze_enable_interrupts diff --git a/cpu/microblaze/exception.c b/cpu/microblaze/exception.c new file mode 100644 index 0000000..b135acb --- /dev/null +++ b/cpu/microblaze/exception.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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> + +void _hw_exception_handler (void) +{ + int address = 0; + int state = 0; + /* loading address of exception EAR */ + __asm__ __volatile ("mfs %0,rear"::"r" (address):"memory"); + /* loading excetpion state register ESR */ + __asm__ __volatile ("mfs %0,resr"::"r" (state):"memory"); + printf ("Hardware exception at 0x%x address\n", address); + switch (state & 0x1f) { /* mask on exception cause */ + case 0x1: + puts ("Unaligned data access exception\n"); + break; + case 0x2: + puts ("Illegal op-code exception\n"); + break; + case 0x3: + puts ("Instruction bus error exception\n"); + break; + case 0x4: + puts ("Data bus error exception\n"); + break; + case 0x5: + puts ("Divide by zero exception\n"); + break; + default: + puts ("Undefined cause\n"); + break; + } + printf ("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); + printf ("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); + printf ("Register R%x\n", (state & 0x3E) >> 5); + hang (); +} + +#ifdef CFG_USR_EXCEP +void _exception_handler (void) +{ + puts ("User vector_exception\n"); + hang (); +} +#endif diff --git a/cpu/microblaze/icache.S b/cpu/microblaze/icache.S new file mode 100644 index 0000000..25940d1 --- /dev/null +++ b/cpu/microblaze/icache.S @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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 + */ + + .text + .globl icache_enable + .ent icache_enable + .align 2 +icache_enable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Set the instruction enable bit */ + ori r12, r12, 0x20 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end icache_enable + + .text + .globl icache_disable + .ent icache_disable + .align 2 +icache_disable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Clear the instruction enable bit */ + andi r12, r12, ~0x20 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end icache_disable diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c index ccf67e1..2db847c 100644 --- a/cpu/microblaze/interrupts.c +++ b/cpu/microblaze/interrupts.c @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK <monstr@monstr.eu> * Yasushi SHOJI <yashi@atmark-techno.com> * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * 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 + * 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 @@ -22,11 +24,185 @@ * MA 02111-1307 USA */ -void enable_interrupts(void) +#include <common.h> +#include <command.h> +#include <asm/microblaze_intc.h> + +#undef DEBUG_INT + +extern void microblaze_disable_interrupts (void); +extern void microblaze_enable_interrupts (void); + +void enable_interrupts (void) { + microblaze_enable_interrupts (); } -int disable_interrupts(void) +int disable_interrupts (void) { + microblaze_disable_interrupts (); return 0; } + +#ifdef CFG_INTC_0 +#ifdef CFG_TIMER_0 +extern void timer_init (void); +#endif + +static struct irq_action vecs[CFG_INTC_0_NUM]; + +/* mapping structure to interrupt controller */ +microblaze_intc_t *intc = (microblaze_intc_t *) (CFG_INTC_0_ADDR); + +/* default handler */ +void def_hdlr (void) +{ + puts ("def_hdlr\n"); +} + +void enable_one_interrupt (int irq) +{ + int mask; + int offset = 1; + offset <<= irq; + mask = intc->ier; + intc->ier = (mask | offset); +#ifdef DEBUG_INT + printf ("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, + intc->ier); + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +void disable_one_interrupt (int irq) +{ + int mask; + int offset = 1; + offset <<= irq; + mask = intc->ier; + intc->ier = (mask & ~offset); +#ifdef DEBUG_INT + printf ("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, + intc->ier); + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +/* adding new handler for interrupt */ +void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) +{ + struct irq_action *act; + /* irq out of range */ + if ((irq < 0) || (irq > CFG_INTC_0_NUM)) { + puts ("IRQ out of range\n"); + return; + } + act = &vecs[irq]; + if (hdlr) { /* enable */ + act->handler = hdlr; + act->arg = arg; + act->count = 0; + enable_one_interrupt (irq); + } else { /* disable */ + + act->handler = (interrupt_handler_t *) def_hdlr; + act->arg = (void *)irq; + disable_one_interrupt (irq); + } +} + +/* initialization interrupt controller - hardware */ +void intc_init (void) +{ + intc->mer = 0; + intc->ier = 0; + intc->iar = 0xFFFFFFFF; + /* XIntc_Start - hw_interrupt enable and all interrupt enable */ + intc->mer = 0x3; +#ifdef DEBUG_INT + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +int interrupts_init (void) +{ + int i; + /* initialize irq list */ + for (i = 0; i < CFG_INTC_0_NUM; i++) { + vecs[i].handler = (interrupt_handler_t *) def_hdlr; + vecs[i].arg = (void *)i; + vecs[i].count = 0; + } + /* initialize intc controller */ + intc_init (); +#ifdef CFG_TIMER_0 + timer_init (); +#endif + enable_interrupts (); + return 0; +} + +void interrupt_handler (void) +{ + int irqs; + irqs = (intc->isr & intc->ier); /* find active interrupt */ + +#ifdef DEBUG_INT + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); + printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); +#endif + struct irq_action *act = vecs; + while (irqs) { + if (irqs & 1) { +#ifdef DEBUG_INT + printf + ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", + act->handler, act->count, act->arg); +#endif + act->handler (act->arg); + act->count++; + } + irqs >>= 1; + act++; + } + intc->iar = 0xFFFFFFFF; /* erase all events */ +#ifdef DEBUG + printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, + intc->ier, intc->iar, intc->mer); + printf ("Interrupt handler on %x line, r14\n", irqs); +#endif +} +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_IRQ) +#ifdef CFG_INTC_0 +int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int i; + struct irq_action *act = vecs; + + puts ("\nInterrupt-Information:\n\n" + "Nr Routine Arg Count\n" + "-----------------------------\n"); + + for (i = 0; i < CFG_INTC_0_NUM; i++) { + if (act->handler != (interrupt_handler_t*) def_hdlr) { + printf ("%02d %08lx %08lx %d\n", i, + (int)act->handler, (int)act->arg, act->count); + } + act++; + } + puts ("\n"); + return (0); +} +#else +int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + puts ("Undefined interrupt controller\n"); +} +#endif +#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */ diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S new file mode 100644 index 0000000..a4e3fbf --- /dev/null +++ b/cpu/microblaze/irq.S @@ -0,0 +1,165 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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 <config.h> + .text + .global _interrupt_handler +_interrupt_handler: + addi r1, r1, -4 + swi r2, r1, 0 + addi r1, r1, -4 + swi r3, r1, 0 + addi r1, r1, -4 + swi r4, r1, 0 + addi r1, r1, -4 + swi r5, r1, 0 + addi r1, r1, -4 + swi r6, r1, 0 + addi r1, r1, -4 + swi r7, r1, 0 + addi r1, r1, -4 + swi r8, r1, 0 + addi r1, r1, -4 + swi r9, r1, 0 + addi r1, r1, -4 + swi r10, r1, 0 + addi r1, r1, -4 + swi r11, r1, 0 + addi r1, r1, -4 + swi r12, r1, 0 + addi r1, r1, -4 + swi r13, r1, 0 + addi r1, r1, -4 + swi r14, r1, 0 + addi r1, r1, -4 + swi r15, r1, 0 + addi r1, r1, -4 + swi r16, r1, 0 + addi r1, r1, -4 + swi r17, r1, 0 + addi r1, r1, -4 + swi r18, r1, 0 + addi r1, r1, -4 + swi r19, r1, 0 + addi r1, r1, -4 + swi r20, r1, 0 + addi r1, r1, -4 + swi r21, r1, 0 + addi r1, r1, -4 + swi r22, r1, 0 + addi r1, r1, -4 + swi r23, r1, 0 + addi r1, r1, -4 + swi r24, r1, 0 + addi r1, r1, -4 + swi r25, r1, 0 + addi r1, r1, -4 + swi r26, r1, 0 + addi r1, r1, -4 + swi r27, r1, 0 + addi r1, r1, -4 + swi r28, r1, 0 + addi r1, r1, -4 + swi r29, r1, 0 + addi r1, r1, -4 + swi r30, r1, 0 + addi r1, r1, -4 + swi r31, r1, 0 + brlid r15, interrupt_handler + nop + nop + lwi r31, r1, 0 + addi r1, r1, 4 + lwi r30, r1, 0 + addi r1, r1, 4 + lwi r29, r1, 0 + addi r1, r1, 4 + lwi r28, r1, 0 + addi r1, r1, 4 + lwi r27, r1, 0 + addi r1, r1, 4 + lwi r26, r1, 0 + addi r1, r1, 4 + lwi r25, r1, 0 + addi r1, r1, 4 + lwi r24, r1, 0 + addi r1, r1, 4 + lwi r23, r1, 0 + addi r1, r1, 4 + lwi r22, r1, 0 + addi r1, r1, 4 + lwi r21, r1, 0 + addi r1, r1, 4 + lwi r20, r1, 0 + addi r1, r1, 4 + lwi r19, r1, 0 + addi r1, r1, 4 + lwi r18, r1, 0 + addi r1, r1, 4 + lwi r17, r1, 0 + addi r1, r1, 4 + lwi r16, r1, 0 + addi r1, r1, 4 + lwi r15, r1, 0 + addi r1, r1, 4 + lwi r14, r1, 0 + addi r1, r1, 4 + lwi r13, r1, 0 + addi r1, r1, 4 + lwi r12, r1, 0 + addi r1, r1, 4 + lwi r11, r1, 0 + addi r1, r1, 4 + lwi r10, r1, 0 + addi r1, r1, 4 + lwi r9, r1, 0 + addi r1, r1, 4 + lwi r8, r1, 0 + addi r1, r1, 4 + lwi r7, r1, 0 + addi r1, r1, 4 + lwi r6, r1, 0 + addi r1, r1, 4 + lwi r5, r1, 0 + addi r1, r1, 4 + lwi r4, r1, 0 + addi r1, r1, 4 + lwi r3, r1, 0 + addi r1, r1, 4 + lwi r2, r1, 0 + addi r1, r1, 4 + + /* enable_interrupt */ + addi r1, r1, -4 + swi r12, r1, 0 + mfs r12, rmsr + ori r12, r12, 2 + mts rmsr, r12 + lwi r12, r1, 0 + addi r1, r1, 4 + nop + bra r14 + nop + nop + .size _interrupt_handler,.-_interrupt_handler diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S index 7efdbb0..ca3befc 100644 --- a/cpu/microblaze/start.S +++ b/cpu/microblaze/start.S @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK <monstr@monstr.eu> * Yasushi SHOJI <yashi@atmark-techno.com> * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * 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 + * 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 @@ -27,10 +29,91 @@ .text .global _start _start: + mts rmsr, r0 /* disable cache */ + addi r1, r0, CFG_INIT_SP_OFFSET + addi r1, r1, -4 /* Decrement SP to top of memory */ + /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/ + addi r6, r0, 0xb000 /* hex b000 opcode imm */ + bslli r6, r6, 16 /* shift */ + swi r6, r0, 0x0 /* reset address */ + swi r6, r0, 0x8 /* user vector exception */ + swi r6, r0, 0x10 /* interrupt */ + swi r6, r0, 0x20 /* hardware exception */ - addi r1, r0, CFG_SDRAM_BASE /* init stack pointer */ - addi r1, r1, CFG_SDRAM_SIZE /* set sp to high up */ + addi r6, r0, 0xb808 /* hew b808 opcode brai*/ + bslli r6, r6, 16 + swi r6, r0, 0x4 /* reset address */ + swi r6, r0, 0xC /* user vector exception */ + swi r6, r0, 0x14 /* interrupt */ + swi r6, r0, 0x24 /* hardware exception */ - brai board_init +#ifdef CFG_RESET_ADDRESS + /* reset address */ + addik r6, r0, CFG_RESET_ADDRESS + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x2 + shi r6, r0, 0x6 +/* + * Copy U-Boot code to TEXT_BASE + * solve problem with sbrk_base + */ +#if (CFG_RESET_ADDRESS != TEXT_BASE) + addi r4, r0, __end + addi r5, r0, __text_start + rsub r4, r5, r4 /* size = __end - __text_start */ + addi r6, r0, CFG_RESET_ADDRESS /* source address */ + addi r7, r0, 0 /* counter */ +4: + lw r8, r6, r7 + sw r8, r5, r7 + addi r7, r7, 0x4 + cmp r8, r4, r7 + blti r8, 4b +#endif +#endif + +#ifdef CFG_USR_EXCEP + /* user_vector_exception */ + addik r6, r0, _exception_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0xa + shi r6, r0, 0xe +#endif +#ifdef CFG_INTC_0 + /* interrupt_handler */ + addik r6, r0, _interrupt_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x12 + shi r6, r0, 0x16 +#endif + + /* hardware exception */ + addik r6, r0, _hw_exception_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x22 + shi r6, r0, 0x26 + + /* enable instruction and data cache */ + mfs r12, rmsr + ori r12, r12, 0xa0 + mts rmsr, r12 + +clear_bss: + /* clear BSS segments */ + addi r5, r0, __bss_start + addi r4, r0, __bss_end + cmp r6, r5, r4 + beqi r6, 3f +2: + swi r0, r5, 0 /* write zero to loc */ + addi r5, r5, 4 /* increment to next loc */ + cmp r6, r5, r4 /* check if we have reach the end */ + bnei r6, 2b +3: /* jumping to board_init */ + brai board_init 1: bri 1b diff --git a/cpu/microblaze/timer.c b/cpu/microblaze/timer.c new file mode 100644 index 0000000..be4fd57 --- /dev/null +++ b/cpu/microblaze/timer.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * 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/microblaze_timer.h> + +volatile int timestamp = 0; + +void reset_timer (void) +{ + timestamp = 0; +} + +ulong get_timer (ulong base) +{ + return (timestamp - base); +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +#ifdef CFG_INTC_0 +#ifdef CFG_TIMER_0 +extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, + void *arg); + +microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR); + +void timer_isr (void *arg) +{ + timestamp++; + tmr->control = tmr->control | TIMER_INTERRUPT; +} + +void timer_init (void) +{ + tmr->loadreg = CFG_TIMER_0_PRELOAD; + tmr->control = TIMER_INTERRUPT | TIMER_RESET; + tmr->control = + TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD | TIMER_DOWN_COUNT; + reset_timer (); + install_interrupt_handler (CFG_TIMER_0_IRQ, timer_isr, (void *)tmr); +} +#endif +#endif diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index 13a3870..e59bd85 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -467,6 +467,10 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis) miiphy_write(dev->name, phyAddr, 0x0, 0x8000); udelay(1000); +#if defined(CONFIG_UC101) + /* Set the LED configuration Register for the UC101 Board */ + miiphy_write(dev->name, phyAddr, 0x14, 0x4122); +#endif if (fec->xcv_type == MII10) { /* * Force 10Base-T, FDX operation diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index e4bc405..21b1646 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -30,8 +30,14 @@ #include <watchdog.h> #include <command.h> #include <mpc83xx.h> -#include <ft_build.h> #include <asm/processor.h> +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#endif +#if defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#include <libfdt_env.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -291,6 +297,100 @@ void watchdog_reset (void) } #endif +#if defined(CONFIG_OF_LIBFDT) + +/* + * Fixups to the fdt. If "create" is TRUE, the node is created + * unconditionally. If "create" is FALSE, the node is updated + * only if it already exists. + */ +#define FT_UPDATE 0x00000000 /* update existing property only */ +#define FT_CREATE 0x00000001 /* create property if it doesn't exist */ +#define FT_BUSFREQ 0x00000002 /* source is bd->bi_busfreq */ +#define FT_ENETADDR 0x00000004 /* source is bd->bi_enetaddr */ +static const struct { + int createflags; + char *node; + char *prop; +} fixup_props[] = { + { FT_CREATE | FT_BUSFREQ, + "/cpus/" OF_CPU, + "bus-frequency", + }, + { FT_CREATE | FT_BUSFREQ, + "/cpus/" OF_SOC, + "bus-frequency" + }, + { FT_CREATE | FT_BUSFREQ, + "/" OF_SOC "/serial@4500/", + "clock-frequency" + }, + { FT_CREATE | FT_BUSFREQ, + "/" OF_SOC "/serial@4600/", + "clock-frequency" + }, +#ifdef CONFIG_MPC83XX_TSEC1 + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@24000, + "mac-address", + }, + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@24000, + "local-mac-address", + }, +#endif +#ifdef CONFIG_MPC83XX_TSEC2 + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@25000, + "mac-address", + }, + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@25000, + "local-mac-address", + }, +#endif +}; + +void +ft_cpu_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int j; + + for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) { + nodeoffset = fdt_path_offset (fdt, fixup_props[j].node); + if (nodeoffset >= 0) { + /* + * If unconditional create or the property already exists... + */ + if ((fixup_props[j].createflags & FT_CREATE) || + (fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) { + if (fixup_props[j].createflags & FT_BUSFREQ) { + u32 tmp; + + tmp = cpu_to_be32(bd->bi_busfreq); + err = fdt_setprop(fdt, nodeoffset, + fixup_props[j].prop, &tmp, sizeof(tmp)); + } else if (fixup_props[j].createflags & FT_ENETADDR) { + err = fdt_setprop(fdt, nodeoffset, + fixup_props[j].prop, bd->bi_enetaddr, 6); + } else { + printf("ft_cpu_setup: %s %s has no flag for the value to set\n", + fixup_props[j].node, + fixup_props[j].prop); + } + if (err < 0) + printf("libfdt: %s %s returned %s\n", + fixup_props[j].node, + fixup_props[j].prop, + fdt_strerror(err)); + } + } + } +} +#endif + #if defined(CONFIG_OF_FLAT_TREE) void ft_cpu_setup(void *blob, bd_t *bd) diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 83c9911..2ecd3e4 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -107,10 +107,11 @@ #define CALC_ODT_RW(n) (CALC_ODT_R(n) | CALC_ODT_W(n)) /* Defines for the Read Cycle Delay test */ -#define NUMMEMTESTS 8 -#define NUMMEMWORDS 8 +#define NUMMEMTESTS 8 +#define NUMMEMWORDS 8 +#define NUMLOOPS 256 /* memory test loops */ -#define CONFIG_ECC_ERROR_RESET /* test-only: see description below, at check_ecc() */ +#undef CONFIG_ECC_ERROR_RESET /* test-only: see description below, at check_ecc() */ /* * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory @@ -584,10 +585,23 @@ static void get_spd_info(unsigned long *dimm_populated, #ifdef CONFIG_ADD_RAM_INFO void board_add_ram_info(int use_default) { + PPC440_SYS_INFO board_cfg; + u32 val; + if (is_ecc_enabled()) - puts(" (ECC enabled)"); + puts(" (ECC"); else - puts(" (ECC not enabled)"); + puts(" (ECC not"); + + get_sys_info(&board_cfg); + + mfsdr(SDR0_DDR0, val); + val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1); + printf(" enabled, %d MHz", (val * 2) / 1000000); + + mfsdram(SDRAM_MMODE, val); + val = (val & SDRAM_MMODE_DCL_MASK) >> 4; + printf(", CL%d)", val); } #endif @@ -731,6 +745,7 @@ static void check_frequency(unsigned long *dimm_populated, else cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); + debug("cycle_time=%d [10 picoseconds]\n", cycle_time); if (cycle_time > (calc_cycle_time + 10)) { /* @@ -1109,7 +1124,7 @@ static void program_codt(unsigned long *dimm_populated, modt3 = 0x00000000; } } - } else { + } else { codt |= SDRAM_CODT_DQS_2_5_V_DDR1; modt0 = 0x00000000; modt1 = 0x00000000; @@ -1315,6 +1330,7 @@ static void program_mode(unsigned long *dimm_populated, mfsdr(SDR0_DDR0, sdr_ddrpll); sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1); + debug("sdram_freq=%d\n", sdram_freq); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all @@ -1344,6 +1360,7 @@ static void program_mode(unsigned long *dimm_populated, /* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /* not used in this loop. */ cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); + debug("cas_bit[SPD byte 18]=%02x\n", cas_bit); /* For a particular DIMM, grab the three CAS values it supports */ for (cas_index = 0; cas_index < 3; cas_index++) { @@ -1362,7 +1379,8 @@ static void program_mode(unsigned long *dimm_populated, if ((tcyc_reg & 0x0F) >= 10) { if ((tcyc_reg & 0x0F) == 0x0D) { /* Convert from hex to decimal */ - cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + 75; + cycle_time_ns_x_100[cas_index] = + (((tcyc_reg & 0xF0) >> 4) * 100) + 75; } else { printf("ERROR: SPD reported Tcyc is incorrect for DIMM " "in slot %d\n", (unsigned int)dimm_num); @@ -1370,9 +1388,12 @@ static void program_mode(unsigned long *dimm_populated, } } else { /* Convert from hex to decimal */ - cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + + cycle_time_ns_x_100[cas_index] = + (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); } + debug("cas_index=%d: cycle_time_ns_x_100=%d\n", cas_index, + cycle_time_ns_x_100[cas_index]); } /* The rest of this routine determines if CAS 2.0, 2.5, 3.0, 4.0 and 5.0 are */ @@ -1385,8 +1406,10 @@ static void program_mode(unsigned long *dimm_populated, * Bit 7 6 5 4 3 2 1 0 * TBD 4.0 3.5 3.0 2.5 2.0 1.5 1.0 */ - if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1394,8 +1417,10 @@ static void program_mode(unsigned long *dimm_populated, cas_4_0_available = FALSE; } - if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1403,8 +1428,10 @@ static void program_mode(unsigned long *dimm_populated, cas_3_0_available = FALSE; } - if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1412,8 +1439,10 @@ static void program_mode(unsigned long *dimm_populated, cas_2_5_available = FALSE; } - if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1426,8 +1455,10 @@ static void program_mode(unsigned long *dimm_populated, * Bit 7 6 5 4 3 2 1 0 * TBD 6.0 5.0 4.0 3.0 2.0 TBD TBD */ - if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1435,8 +1466,10 @@ static void program_mode(unsigned long *dimm_populated, cas_5_0_available = FALSE; } - if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1444,8 +1477,10 @@ static void program_mode(unsigned long *dimm_populated, cas_4_0_available = FALSE; } - if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1468,6 +1503,9 @@ static void program_mode(unsigned long *dimm_populated, cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100) + 10; cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100) + 10; cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100) + 10; + debug("cycle_3_0_clk=%d\n", cycle_3_0_clk); + debug("cycle_4_0_clk=%d\n", cycle_4_0_clk); + debug("cycle_5_0_clk=%d\n", cycle_5_0_clk); if (sdram_ddr1 == TRUE) { /* DDR1 */ if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) { @@ -1486,6 +1524,9 @@ static void program_mode(unsigned long *dimm_populated, hang(); } } else { /* DDR2 */ + debug("cas_3_0_available=%d\n", cas_3_0_available); + debug("cas_4_0_available=%d\n", cas_4_0_available); + debug("cas_5_0_available=%d\n", cas_5_0_available); if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) { mmode |= SDRAM_MMODE_DCL_DDR2_3_0_CLK; *selected_cas = DDR_CAS_3; @@ -2137,6 +2178,18 @@ static unsigned long is_ecc_enabled(void) return ecc; } +static void blank_string(int size) +{ + int i; + + for (i=0; i<size; i++) + putc('\b'); + for (i=0; i<size; i++) + putc(' '); + for (i=0; i<size; i++) + putc('\b'); +} + #ifdef CONFIG_DDR_ECC /*-----------------------------------------------------------------------------+ * program_ecc. @@ -2233,8 +2286,10 @@ static void program_ecc_addr(unsigned long start_address, unsigned long end_address; unsigned long address_increment; unsigned long mcopt1; - char str[] = "ECC generation..."; - int i; + char str[] = "ECC generation -"; + char slash[] = "\\|/-\\|/-"; + int loop = 0; + int loopi = 0; current_address = start_address; mfsdram(SDRAM_MCOPT1, mcopt1); @@ -2257,14 +2312,20 @@ static void program_ecc_addr(unsigned long start_address, while (current_address < end_address) { *((unsigned long *)current_address) = 0x00000000; current_address += address_increment; + + if ((loop++ % (2 << 20)) == 0) { + putc('\b'); + putc(slash[loopi++ % 8]); + } } + } else { /* ECC bit set method for cached memory */ dcbz_area(start_address, num_bytes); dflush(); } - for (i=0; i<strlen(str); i++) - putc('\b'); + + blank_string(strlen(str)); sync(); eieio(); @@ -2347,7 +2408,7 @@ static void program_DQS_calibration(unsigned long *dimm_populated, #endif } -static u32 short_mem_test(void) +static int short_mem_test(void) { u32 *membase; u32 bxcr_num; @@ -2371,42 +2432,41 @@ static u32 short_mem_test(void) 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA}, {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} }; + int l; for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) { mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf); /* Banks enabled */ if ((bxcf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { - /* Bank is enabled */ - membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num))); /*------------------------------------------------------------------ * Run the short memory test. *-----------------------------------------------------------------*/ + membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num))); + for (i = 0; i < NUMMEMTESTS; i++) { for (j = 0; j < NUMMEMWORDS; j++) { membase[j] = test[i][j]; ppcDcbf((u32)&(membase[j])); } sync(); - for (j = 0; j < NUMMEMWORDS; j++) { - if (membase[j] != test[i][j]) { + for (l=0; l<NUMLOOPS; l++) { + for (j = 0; j < NUMMEMWORDS; j++) { + if (membase[j] != test[i][j]) { + ppcDcbf((u32)&(membase[j])); + return 0; + } ppcDcbf((u32)&(membase[j])); - break; } - ppcDcbf((u32)&(membase[j])); + sync(); } - sync(); - if (j < NUMMEMWORDS) - break; } - if (i < NUMMEMTESTS) - break; } /* if bank enabled */ } /* for bxcf_num */ - return bxcr_num; + return 1; } #ifndef HARD_CODED_DQS @@ -2415,12 +2475,10 @@ static u32 short_mem_test(void) *-----------------------------------------------------------------------------*/ static void DQS_calibration_process(void) { - unsigned long ecc_temp; unsigned long rfdc_reg; unsigned long rffd; unsigned long rqdc_reg; unsigned long rqfd; - unsigned long bxcr_num; unsigned long val; long rqfd_average; long rffd_average; @@ -2440,6 +2498,10 @@ static void DQS_calibration_process(void) long max_end; unsigned char fail_found; unsigned char pass_found; + u32 rqfd_start; + char str[] = "Auto calibration -"; + char slash[] = "\\|/-\\|/-"; + int loopi = 0; /*------------------------------------------------------------------ * Test to determine the best read clock delay tuning bits. @@ -2464,11 +2526,16 @@ static void DQS_calibration_process(void) * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed), * from experimentation it is safe to say you will always have a failure. *-----------------------------------------------------------------*/ - mfsdram(SDRAM_MCOPT1, ecc_temp); - ecc_temp &= SDRAM_MCOPT1_MCHK_MASK; - mfsdram(SDRAM_MCOPT1, val); - mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | - SDRAM_MCOPT1_MCHK_NON); + + /* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */ + rqfd_start = 64; /* test-only: don't know if this is the _best_ start value */ + + puts(str); + +calibration_loop: + mfsdram(SDRAM_RQDC, rqdc_reg); + mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) | + SDRAM_RQDC_RQFD_ENCODE(rqfd_start)); max_start = 0; min_end = 0; @@ -2492,9 +2559,6 @@ static void DQS_calibration_process(void) fail_found = FALSE; pass_found = FALSE; - /* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */ - /* rqdc_reg = mfsdram(SDRAM_RQDC) & ~(SDRAM_RQDC_RQFD_MASK); */ - /* * get the delay line calibration register value */ @@ -2510,13 +2574,10 @@ static void DQS_calibration_process(void) *-----------------------------------------------------------------*/ mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd)); - /* do the small memory test */ - bxcr_num = short_mem_test(); - /*------------------------------------------------------------------ * See if the rffd value passed. *-----------------------------------------------------------------*/ - if (bxcr_num == MAXBXCF) { + if (short_mem_test()) { if (fail_found == TRUE) { pass_found = TRUE; if (current_pass_length == 0) @@ -2578,13 +2639,10 @@ static void DQS_calibration_process(void) *-----------------------------------------------------------------*/ mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd)); - /* do the small memory test */ - bxcr_num = short_mem_test(); - /*------------------------------------------------------------------ * See if the rffd value passed. *-----------------------------------------------------------------*/ - if (bxcr_num == MAXBXCF) { + if (short_mem_test()) { if (fail_found == TRUE) { pass_found = TRUE; if (current_pass_length == 0) @@ -2612,17 +2670,28 @@ static void DQS_calibration_process(void) } } + rqfd_average = ((max_start + max_end) >> 1); + /*------------------------------------------------------------------ * Make sure we found the valid read passing window. Halt if not *-----------------------------------------------------------------*/ if (window_found == FALSE) { - printf("ERROR: Cannot determine a common read delay for the " + if (rqfd_start < SDRAM_RQDC_RQFD_MAX) { + putc('\b'); + putc(slash[loopi++ % 8]); + + /* try again from with a different RQFD start value */ + rqfd_start++; + goto calibration_loop; + } + + printf("\nERROR: Cannot determine a common read delay for the " "DIMM(s) installed.\n"); debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); hang(); } - rqfd_average = ((max_start + max_end) >> 1); + blank_string(strlen(str)); if (rqfd_average < 0) rqfd_average = 0; @@ -2630,12 +2699,6 @@ static void DQS_calibration_process(void) if (rqfd_average > SDRAM_RQDC_RQFD_MAX) rqfd_average = SDRAM_RQDC_RQFD_MAX; - /*------------------------------------------------------------------ - * Restore the ECC variable to what it originally was - *-----------------------------------------------------------------*/ - mfsdram(SDRAM_MCOPT1, val); - mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | ecc_temp); - mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) | SDRAM_RQDC_RQFD_ENCODE(rqfd_average)); diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index 96f0f62..4068b53 100644 --- a/cpu/ppc4xx/Makefile +++ b/cpu/ppc4xx/Makefile @@ -29,7 +29,7 @@ START = start.o resetvec.o kgdb.o SOBJS = dcr.o COBJS = 405gp_pci.o 4xx_enet.o \ bedbug_405.o commproc.o \ - cpu.o cpu_init.o i2c.o interrupts.o \ + cpu.o cpu_init.o gpio.o i2c.o interrupts.o \ miiphy.o ndfc.o sdram.o serial.o \ 40x_spd_sdram.o 44x_spd_ddr.o 44x_spd_ddr2.o speed.o \ tlb.o traps.o usb_ohci.o usbdev.o \ diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 2d8740c..8e6bc84 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -125,6 +125,7 @@ int i2c_bootrom_enabled(void) return (val & SDR0_SDCS_SDD); #endif } +#endif #if defined(CONFIG_440GX) #define SDR0_PINSTP_SHIFT 29 @@ -178,16 +179,37 @@ static char *bootstrap_str[] = { }; #endif +#if defined(CONFIG_405EZ) +#define SDR0_PINSTP_SHIFT 28 +static char *bootstrap_str[] = { + "EBC (8 bits)", + "SPI (fast)", + "NAND (512 page, 4 addr cycle)", + "I2C (Addr 0x50)", + "EBC (32 bits)", + "I2C (Addr 0x50)", + "NAND (2K page, 5 addr cycle)", + "I2C (Addr 0x50)", + "EBC (16 bits)", + "Reserved", + "NAND (2K page, 4 addr cycle)", + "I2C (Addr 0x50)", + "NAND (512 page, 3 addr cycle)", + "I2C (Addr 0x50)", + "SPI (slow)", + "I2C (Addr 0x50)", +}; +#endif + #if defined(SDR0_PINSTP_SHIFT) static int bootstrap_option(void) { unsigned long val; - mfsdr(sdr_pinstp, val); - return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT); + mfsdr(SDR_PINSTP, val); + return ((val & 0xf0000000) >> SDR0_PINSTP_SHIFT); } #endif /* SDR0_PINSTP_SHIFT */ -#endif #if defined(CONFIG_440) @@ -403,11 +425,11 @@ int checkcpu (void) #if defined(I2C_BOOTROM) printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis"); +#endif /* I2C_BOOTROM */ #if defined(SDR0_PINSTP_SHIFT) printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A'); printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]); #endif /* SDR0_PINSTP_SHIFT */ -#endif /* I2C_BOOTROM */ #if defined(CONFIG_PCI) printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis"); diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 9d1cd13..66e8637 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -25,6 +25,7 @@ #include <watchdog.h> #include <ppc4xx_enet.h> #include <asm/processor.h> +#include <asm/gpio.h> #include <ppc4xx.h> #if defined(CONFIG_405GP) || defined(CONFIG_405EP) @@ -98,118 +99,6 @@ DECLARE_GLOBAL_DATA_PTR; # endif #endif /* CFG_INIT_DCACHE_CS */ -#if defined(CFG_440_GPIO_TABLE) -gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE; - -void set_chip_gpio_configuration(gpio_param_s (*gpio_tab)[GPIO_GROUP_MAX][GPIO_MAX]) -{ - unsigned char i=0, j=0, reg_offset = 0, gpio_core; - unsigned long gpio_reg, gpio_core_add; - - for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) { - j = 0; - reg_offset = 0; - /* GPIO config of the GPIOs 0 to 31 */ - for (i=0; i<GPIO_MAX; i++, j++) { - if (i == GPIO_MAX/2) { - reg_offset = 4; - j = i-16; - } - - gpio_core_add = (*gpio_tab)[gpio_core][i].add; - - if (((*gpio_tab)[gpio_core][i].in_out == GPIO_IN) || - ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) { - - switch ((*gpio_tab)[gpio_core][i].alt_nb) { - case GPIO_SEL: - break; - - case GPIO_ALT1: - gpio_reg = in32(GPIO_IS1(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); - out32(GPIO_IS1(gpio_core_add+reg_offset), gpio_reg); - break; - - case GPIO_ALT2: - gpio_reg = in32(GPIO_IS2(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); - out32(GPIO_IS2(gpio_core_add+reg_offset), gpio_reg); - break; - - case GPIO_ALT3: - gpio_reg = in32(GPIO_IS3(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); - out32(GPIO_IS3(gpio_core_add+reg_offset), gpio_reg); - break; - } - } - - if (((*gpio_tab)[gpio_core][i].in_out == GPIO_OUT) || - ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) { - - switch ((*gpio_tab)[gpio_core][i].alt_nb) { - case GPIO_SEL: - if (gpio_core == GPIO0) { - gpio_reg = in32(GPIO0_TCR) | (0x80000000 >> (j)); - out32(GPIO0_TCR, gpio_reg); - } - - if (gpio_core == GPIO1) { - gpio_reg = in32(GPIO1_TCR) | (0x80000000 >> (j)); - out32(GPIO1_TCR, gpio_reg); - } - - gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); - gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); - break; - - case GPIO_ALT1: - gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2)); - out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); - gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2)); - out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); - break; - - case GPIO_ALT2: - gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2)); - out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); - gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2)); - out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); - break; - - case GPIO_ALT3: - gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2)); - out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); - gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) - & ~(GPIO_MASK >> (j*2)); - gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2)); - out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); - break; - } - } - } - } -} -#endif /* CFG_440_GPIO_TABLE */ - /* * Breath some life into the CPU... * @@ -248,7 +137,7 @@ cpu_init_f (void) #endif /* CONFIG_405EP */ #if defined(CFG_440_GPIO_TABLE) - set_chip_gpio_configuration(&gpio_tab); + gpio_set_chip_configuration(); #endif /* CFG_440_GPIO_TABLE */ /* diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c new file mode 100644 index 0000000..dd84e58 --- /dev/null +++ b/cpu/ppc4xx/gpio.c @@ -0,0 +1,214 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * 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/processor.h> +#include <asm/io.h> +#include <asm/gpio.h> + +#if defined(CFG_440_GPIO_TABLE) +gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE; +#endif + +#if defined(GPIO0_OSRL) +/* Only some 4xx variants support alternate funtions on the GPIO's */ +void gpio_config(int pin, int in_out, int gpio_alt, int out_val) +{ + u32 mask; + u32 mask2; + u32 val; + u32 offs = 0; + u32 offs2 = 0; + int pin2 = pin << 1; + + if (pin >= GPIO_MAX) { + offs = 0x100; + pin -= GPIO_MAX; + } + + if (pin >= GPIO_MAX/2) { + offs2 = 0x100; + pin2 = (pin - GPIO_MAX/2) << 1; + } + + mask = 0x80000000 >> pin; + mask2 = 0xc0000000 >> (pin2 << 1); + + /* first set TCR to 0 */ + out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) & ~mask); + + if (in_out == GPIO_OUT) { + val = in32(GPIO0_OSRL + offs + offs2) & ~mask2; + switch (gpio_alt) { + case GPIO_ALT1: + val |= GPIO_ALT1_SEL >> pin2; + break; + case GPIO_ALT2: + val |= GPIO_ALT2_SEL >> pin2; + break; + case GPIO_ALT3: + val |= GPIO_ALT3_SEL >> pin2; + break; + } + out32(GPIO0_OSRL + offs + offs2, val); + + /* setup requested output value */ + if (out_val == GPIO_OUT_0) + out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~mask); + else if (out_val == GPIO_OUT_1) + out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | mask); + + /* now configure TCR to drive output if selected */ + out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) | mask); + } else { + val = in32(GPIO0_ISR1L + offs + offs2) & ~mask2; + val |= GPIO_IN_SEL >> pin2; + out32(GPIO0_ISR1L + offs + offs2, val); + } +} +#endif /* GPIO_OSRL */ + +void gpio_write_bit(int pin, int val) +{ + u32 offs = 0; + + if (pin >= GPIO_MAX) { + offs = 0x100; + pin -= GPIO_MAX; + } + + if (val) + out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | GPIO_VAL(pin)); + else + out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~GPIO_VAL(pin)); +} + +#if defined(CFG_440_GPIO_TABLE) +void gpio_set_chip_configuration(void) +{ + unsigned char i=0, j=0, offs=0, gpio_core; + unsigned long reg, core_add; + + for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) { + j = 0; + offs = 0; + /* GPIO config of the GPIOs 0 to 31 */ + for (i=0; i<GPIO_MAX; i++, j++) { + if (i == GPIO_MAX/2) { + offs = 4; + j = i-16; + } + + core_add = gpio_tab[gpio_core][i].add; + + if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) || + (gpio_tab[gpio_core][i].in_out == GPIO_BI)) { + + switch (gpio_tab[gpio_core][i].alt_nb) { + case GPIO_SEL: + break; + + case GPIO_ALT1: + reg = in32(GPIO_IS1(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS1(core_add+offs), reg); + break; + + case GPIO_ALT2: + reg = in32(GPIO_IS2(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS2(core_add+offs), reg); + break; + + case GPIO_ALT3: + reg = in32(GPIO_IS3(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS3(core_add+offs), reg); + break; + } + } + + if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) || + (gpio_tab[gpio_core][i].in_out == GPIO_BI)) { + + switch (gpio_tab[gpio_core][i].alt_nb) { + case GPIO_SEL: + if (gpio_core == GPIO0) { + reg = in32(GPIO0_TCR) | (0x80000000 >> (j)); + out32(GPIO0_TCR, reg); + } + + if (gpio_core == GPIO1) { + reg = in32(GPIO1_TCR) | (0x80000000 >> (j)); + out32(GPIO1_TCR, reg); + } + + reg = in32(GPIO_OS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + out32(GPIO_OS(core_add+offs), reg); + reg = in32(GPIO_TS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + out32(GPIO_TS(core_add+offs), reg); + break; + + case GPIO_ALT1: + reg = in32(GPIO_OS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT1_SEL >> (j*2)); + out32(GPIO_OS(core_add+offs), reg); + reg = in32(GPIO_TS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT1_SEL >> (j*2)); + out32(GPIO_TS(core_add+offs), reg); + break; + + case GPIO_ALT2: + reg = in32(GPIO_OS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT2_SEL >> (j*2)); + out32(GPIO_OS(core_add+offs), reg); + reg = in32(GPIO_TS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT2_SEL >> (j*2)); + out32(GPIO_TS(core_add+offs), reg); + break; + + case GPIO_ALT3: + reg = in32(GPIO_OS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT3_SEL >> (j*2)); + out32(GPIO_OS(core_add+offs), reg); + reg = in32(GPIO_TS(core_add+offs)) + & ~(GPIO_MASK >> (j*2)); + reg = reg | (GPIO_ALT3_SEL >> (j*2)); + out32(GPIO_TS(core_add+offs), reg); + break; + } + } + } + } +} +#endif /* CFG_440_GPIO_TABLE */ diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 8f4da86..47c264e 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -91,7 +91,6 @@ static void _i2c_bus_reset(void) void i2c_init(int speed, int slaveadd) { - sys_info_t sysInfo; unsigned long freqOPB; int val, divisor; int bus; @@ -124,8 +123,7 @@ void i2c_init(int speed, int slaveadd) /* Clock divide Register */ /* get OPB frequency */ - get_sys_info(&sysInfo); - freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv; + freqOPB = get_OPB_freq(); /* set divisor according to freqOPB */ divisor = (freqOPB - 1) / 10000000; if (divisor == 0) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index d918b3e..a96083c 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -2,6 +2,7 @@ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de> + * Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering * * See file CREDITS for list of people who contributed to this * project. @@ -757,7 +758,6 @@ _start: #endif /* CONFIG_405EP */ #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE) -/* test-only... (clean up later when NAND booting is supported) */ #if defined(CONFIG_405EZ) /******************************************************************** * Setup OCM - On Chip Memory - PPC405EZ uses OCM Controller V2 @@ -786,41 +786,7 @@ _start: mtdcr ocmdsisdpc,r4 isync - -#if defined(CONFIG_NAND_SPL) - /* - * 405EZ can boot from NAND Flash. - * If we are booting the SPL (Pre-loader), copy code from - * the mapped 4K NAND Flash to the OCM - */ - li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1 - mtctr r4 - lis r2,CFG_NAND_BOOT_SPL_SRC@h - ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l - lis r3,CFG_NAND_BOOT_SPL_DST@h - ori r3,r3,CFG_NAND_BOOT_SPL_DST@l -spl_loop: - lwzu r4,4(r2) - stwu r4,4(r3) - bdnz spl_loop - - /* - * Jump to code in OCM Ram - */ - bl 00f -00: mflr r10 - lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h - ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l - sub r10,r10,r3 - addi r10,r10,28 - mtlr r10 - blr -start_ram: - sync - isync -#endif -#else -/* ...test-only */ +#else /* CONFIG_405EZ */ /******************************************************************** * Setup OCM - On Chip Memory *******************************************************************/ @@ -828,14 +794,15 @@ start_ram: lis r0, 0x7FFF ori r0, r0, 0xFFFF mfdcr r3, ocmiscntl /* get instr-side IRAM config */ - mfdcr r4, ocmdscntl /* get data-side IRAM config */ - and r3, r3, r0 /* disable data-side IRAM */ - and r4, r4, r0 /* disable data-side IRAM */ - mtdcr ocmiscntl, r3 /* set instr-side IRAM config */ - mtdcr ocmdscntl, r4 /* set data-side IRAM config */ + mfdcr r4, ocmdscntl /* get data-side IRAM config */ + and r3, r3, r0 /* disable data-side IRAM */ + and r4, r4, r0 /* disable data-side IRAM */ + mtdcr ocmiscntl, r3 /* set instr-side IRAM config */ + mtdcr ocmdscntl, r4 /* set data-side IRAM config */ isync - addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */ + lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */ + ori r3,r3,CFG_OCM_DATA_ADDR@l mtdcr ocmdsarc, r3 addis r4, 0, 0xC000 /* OCM data area enabled */ mtdcr ocmdscntl, r4 @@ -1925,11 +1892,11 @@ pll_wait: #endif /* CONFIG_405EP */ #if defined(CONFIG_440) -#define function_prolog(func_name) .text; \ +#define function_prolog(func_name) .text; \ .align 2; \ .globl func_name; \ func_name: -#define function_epilog(func_name) .type func_name,@function; \ +#define function_epilog(func_name) .type func_name,@function; \ .size func_name,.-func_name /*----------------------------------------------------------------------------+ @@ -1985,13 +1952,13 @@ pll_wait: +----------------------------------------------------------------------------*/ function_prolog(dcbz_area) rlwinm. r5,r4,0,27,31 - rlwinm r5,r4,27,5,31 - beq ..d_ra2 - addi r5,r5,0x0001 -..d_ra2:mtctr r5 -..d_ag2:dcbz r0,r3 - addi r3,r3,32 - bdnz ..d_ag2 + rlwinm r5,r4,27,5,31 + beq ..d_ra2 + addi r5,r5,0x0001 +..d_ra2:mtctr r5 +..d_ag2:dcbz r0,r3 + addi r3,r3,32 + bdnz ..d_ag2 sync blr function_epilog(dcbz_area) @@ -2000,26 +1967,26 @@ pll_wait: | dflush. Assume 32K at vector address is cachable. +----------------------------------------------------------------------------*/ function_prolog(dflush) - mfmsr r9 - rlwinm r8,r9,0,15,13 - rlwinm r8,r8,0,17,15 - mtmsr r8 - addi r3,r0,0x0000 - mtspr dvlim,r3 - mfspr r3,ivpr - addi r4,r0,1024 - mtctr r4 + mfmsr r9 + rlwinm r8,r9,0,15,13 + rlwinm r8,r8,0,17,15 + mtmsr r8 + addi r3,r0,0x0000 + mtspr dvlim,r3 + mfspr r3,ivpr + addi r4,r0,1024 + mtctr r4 ..dflush_loop: - lwz r6,0x0(r3) - addi r3,r3,32 - bdnz ..dflush_loop - addi r3,r3,-32 - mtctr r4 -..ag: dcbf r0,r3 - addi r3,r3,-32 - bdnz ..ag + lwz r6,0x0(r3) + addi r3,r3,32 + bdnz ..dflush_loop + addi r3,r3,-32 + mtctr r4 +..ag: dcbf r0,r3 + addi r3,r3,-32 + bdnz ..ag sync - mtmsr r9 + mtmsr r9 blr function_epilog(dflush) #endif /* CONFIG_440 */ |