diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/spl.c | 35 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/board.c | 58 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/clock.c | 14 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/config.mk | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/funcmux.c | 58 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/board.h | 30 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/clock.h | 11 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/funcmux.h | 41 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/mmc.h | 27 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/tegra2.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/tegra2_spi.h | 76 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/uart-spi-switch.h | 46 |
14 files changed, 401 insertions, 3 deletions
diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile index 5ae89df5dba..da7efac0853 100644 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -38,7 +38,8 @@ COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o ifdef CONFIG_SPL_BUILD COBJS-y += spl.o -COBJS-y += dm365_lowlevel.o +COBJS-$(CONFIG_SOC_DM365) += dm365_lowlevel.o +COBJS-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o endif SOBJS = reset.o diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c index d9b9398b7e8..f475f9ba75f 100644 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ b/arch/arm/cpu/arm926ejs/davinci/spl.c @@ -26,6 +26,17 @@ #include <nand.h> #include <asm/arch/dm365_lowlevel.h> #include <ns16550.h> +#include <malloc.h> +#include <spi_flash.h> + +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT + +DECLARE_GLOBAL_DATA_PTR; +/* Define global data structure pointer to it*/ +static gd_t gdata __attribute__ ((section(".data"))); +static bd_t bdata __attribute__ ((section(".data"))); + +#else void puts(const char *str) { @@ -41,6 +52,8 @@ void putc(char c) NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); } +#endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ + inline void hang(void) { puts("### ERROR ### Please RESET the board ###\n"); @@ -50,14 +63,34 @@ inline void hang(void) void board_init_f(ulong dummy) { +#ifdef CONFIG_SOC_DM365 dm36x_lowlevel_init(0); +#endif +#ifdef CONFIG_SOC_DA8XX + arch_cpu_init(); +#endif relocate_code(CONFIG_SPL_STACK, NULL, CONFIG_SPL_TEXT_BASE); } void board_init_r(gd_t *id, ulong dummy) { - +#ifdef CONFIG_SOC_DM365 nand_init(); puts("Nand boot...\n"); nand_boot(); +#endif +#ifdef CONFIG_SOC_DA8XX + mem_malloc_init(CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN, + CONFIG_SYS_MALLOC_LEN); + + gd = &gdata; + gd->bd = &bdata; + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + serial_init(); /* serial communications setup */ + gd->have_console = 1; + + puts("SPI boot...\n"); + spi_boot(); +#endif } diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index 955c3b6dc41..f668a818fbf 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -33,7 +33,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := ap20.o board.o clock.o pinmux.o sys_info.o timer.o +COBJS := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 59dce8f8de9..ea06570bfaf 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -24,12 +24,22 @@ #include <common.h> #include <asm/io.h> #include "ap20.h" +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> #include <asm/arch/sys_proto.h> #include <asm/arch/tegra2.h> #include <asm/arch/pmc.h> DECLARE_GLOBAL_DATA_PTR; +enum { + /* UARTs which we can enable */ + UARTA = 1 << 0, + UARTB = 1 << 1, + UARTD = 1 << 3, + UART_COUNT = 4, +}; + /* * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0, * so we are using this value to identify memory size. @@ -80,6 +90,54 @@ int arch_cpu_init(void) { /* Fire up the Cortex A9 */ tegra2_start(); + + /* We didn't do this init in start.S, so do it now */ + cpu_init_cp15(); + + /* Initialize essential common plls */ + clock_early_init(); + return 0; } #endif + +/** + * Set up the specified uarts + * + * @param uarts_ids Mask containing UARTs to init (UARTx) + */ +static void setup_uarts(int uart_ids) +{ + static enum periph_id id_for_uart[] = { + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_UART4, + }; + size_t i; + + for (i = 0; i < UART_COUNT; i++) { + if (uart_ids & (1 << i)) { + enum periph_id id = id_for_uart[i]; + + funcmux_select(id, 0); + clock_ll_start_uart(id); + } + } +} + +void board_init_uart_f(void) +{ + int uart_ids = 0; /* bit mask of which UART ids to enable */ + +#ifdef CONFIG_TEGRA2_ENABLE_UARTA + uart_ids |= UARTA; +#endif +#ifdef CONFIG_TEGRA2_ENABLE_UARTB + uart_ids |= UARTB; +#endif +#ifdef CONFIG_TEGRA2_ENABLE_UARTD + uart_ids |= UARTD; +#endif + setup_uarts(uart_ids); +} diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c index 03ac1e3ed00..11d2346d83b 100644 --- a/arch/arm/cpu/armv7/tegra2/clock.c +++ b/arch/arm/cpu/armv7/tegra2/clock.c @@ -904,6 +904,20 @@ static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) return 0; } +void clock_ll_start_uart(enum periph_id periph_id) +{ + /* Assert UART reset and enable clock */ + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ + + /* wait for 2us */ + udelay(2); + + /* De-assert reset to UART */ + reset_set_enable(periph_id, 0); +} + int clock_verify(void) { struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk index 8f9bdc9ff02..2303dba0790 100644 --- a/arch/arm/cpu/armv7/tegra2/config.mk +++ b/arch/arm/cpu/armv7/tegra2/config.mk @@ -29,3 +29,5 @@ ifdef CONFIG_TEGRA2 CFLAGS_arch/arm/lib/board.o += -march=armv4t endif + +USE_PRIVATE_LIBGCC = yes diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c new file mode 100644 index 00000000000..0878f511104 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * 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 + */ + +/* Tegra2 high-level function multiplexing */ +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/pinmux.h> + +int funcmux_select(enum periph_id id, int config) +{ + if (config != 0) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + switch (id) { + case PERIPH_ID_UART1: + pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_IRRX); + pinmux_tristate_disable(PINGRP_IRTX); + break; + + case PERIPH_ID_UART2: + pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); + pinmux_tristate_disable(PINGRP_UAD); + break; + + case PERIPH_ID_UART4: + pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); + pinmux_tristate_disable(PINGRP_GMC); + break; + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + return 0; +} diff --git a/arch/arm/include/asm/arch-tegra2/board.h b/arch/arm/include/asm/arch-tegra2/board.h new file mode 100644 index 00000000000..a90d36c708c --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/board.h @@ -0,0 +1,30 @@ +/* + * (C) Copyright 2010,2011 + * NVIDIA Corporation <www.nvidia.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_BOARD_H_ +#define _TEGRA_BOARD_H_ + +/* Setup UARTs for the board according to the selected config */ +void board_init_uart_f(void); + +#endif diff --git a/arch/arm/include/asm/arch-tegra2/clock.h b/arch/arm/include/asm/arch-tegra2/clock.h index 49e9904b57c..080ef18e81d 100644 --- a/arch/arm/include/asm/arch-tegra2/clock.h +++ b/arch/arm/include/asm/arch-tegra2/clock.h @@ -344,6 +344,17 @@ unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, */ unsigned clock_get_rate(enum clock_id clkid); +/** + * Start up a UART using low-level calls + * + * Prior to relocation clock_start_periph_pll() cannot be called. This + * function provides a way to set up a UART using low-level calls which + * do not require BSS. + * + * @param periph_id Peripheral ID of UART to enable (e,g, PERIPH_ID_UART1) + */ +void clock_ll_start_uart(enum periph_id periph_id); + /* * Checks that clocks are valid and prints a warning if not * diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h new file mode 100644 index 00000000000..2d724a2872f --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * 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 + */ + +/* Tegra2 high-level function multiplexing */ + +#ifndef __FUNCMUX_H +#define __FUNCMUX_H + +/** + * Select a config for a particular peripheral. + * + * Each peripheral can operate through a number of configurations, + * which are sets of pins that it uses to bring out its signals. + * The basic config is 0, and higher numbers indicate different + * pinmux settings to bring the peripheral out on other pins, + * + * @param id Peripheral id + * @param config Configuration to use (generally 0) + * @return 0 if ok, -1 on error (e.g. incorrect id or config) + */ +int funcmux_select(enum periph_id id, int config); + +#endif diff --git a/arch/arm/include/asm/arch-tegra2/mmc.h b/arch/arm/include/asm/arch-tegra2/mmc.h new file mode 100644 index 00000000000..c1f12dbe491 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/mmc.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011, Google Inc. All rights reserved. + * 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 _TEGRA2_MMC_H_ +#define _TEGRA2_MMC_H_ + +int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio); + +#endif /* TEGRA2_MMC_H_ */ diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h index 742a75a0dac..8941443ad8e 100644 --- a/arch/arm/include/asm/arch-tegra2/tegra2.h +++ b/arch/arm/include/asm/arch-tegra2/tegra2.h @@ -38,6 +38,7 @@ #define NV_PA_APB_UARTC_BASE (NV_PA_APB_MISC_BASE + 0x6200) #define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300) #define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) +#define TEGRA2_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380) #define NV_PA_PMC_BASE 0x7000E400 #define NV_PA_CSITE_BASE 0x70040000 diff --git a/arch/arm/include/asm/arch-tegra2/tegra2_spi.h b/arch/arm/include/asm/arch-tegra2/tegra2_spi.h new file mode 100644 index 00000000000..ceec4287a3b --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/tegra2_spi.h @@ -0,0 +1,76 @@ +/* + * NVIDIA Tegra2 SPI-FLASH controller + * + * Copyright 2010-2011 NVIDIA Corporation + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * 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 _TEGRA2_SPI_H_ +#define _TEGRA2_SPI_H_ + +#include <asm/types.h> + +struct spi_tegra { + u32 command; /* SPI_COMMAND_0 register */ + u32 status; /* SPI_STATUS_0 register */ + u32 rx_cmp; /* SPI_RX_CMP_0 register */ + u32 dma_ctl; /* SPI_DMA_CTL_0 register */ + u32 tx_fifo; /* SPI_TX_FIFO_0 register */ + u32 rsvd[3]; /* offsets 0x14 to 0x1F reserved */ + u32 rx_fifo; /* SPI_RX_FIFO_0 register */ +}; + +#define SPI_CMD_GO (1 << 30) +#define SPI_CMD_ACTIVE_SCLK_SHIFT 26 +#define SPI_CMD_ACTIVE_SCLK_MASK (3 << SPI_CMD_ACTIVE_SCLK_SHIFT) +#define SPI_CMD_CK_SDA (1 << 21) +#define SPI_CMD_ACTIVE_SDA_SHIFT 18 +#define SPI_CMD_ACTIVE_SDA_MASK (3 << SPI_CMD_ACTIVE_SDA_SHIFT) +#define SPI_CMD_CS_POL (1 << 16) +#define SPI_CMD_TXEN (1 << 15) +#define SPI_CMD_RXEN (1 << 14) +#define SPI_CMD_CS_VAL (1 << 13) +#define SPI_CMD_CS_SOFT (1 << 12) +#define SPI_CMD_CS_DELAY (1 << 9) +#define SPI_CMD_CS3_EN (1 << 8) +#define SPI_CMD_CS2_EN (1 << 7) +#define SPI_CMD_CS1_EN (1 << 6) +#define SPI_CMD_CS0_EN (1 << 5) +#define SPI_CMD_BIT_LENGTH (1 << 4) +#define SPI_CMD_BIT_LENGTH_MASK 0x0000001F + +#define SPI_STAT_BSY (1 << 31) +#define SPI_STAT_RDY (1 << 30) +#define SPI_STAT_RXF_FLUSH (1 << 29) +#define SPI_STAT_TXF_FLUSH (1 << 28) +#define SPI_STAT_RXF_UNR (1 << 27) +#define SPI_STAT_TXF_OVF (1 << 26) +#define SPI_STAT_RXF_EMPTY (1 << 25) +#define SPI_STAT_RXF_FULL (1 << 24) +#define SPI_STAT_TXF_EMPTY (1 << 23) +#define SPI_STAT_TXF_FULL (1 << 22) +#define SPI_STAT_SEL_TXRX_N (1 << 16) +#define SPI_STAT_CUR_BLKCNT (1 << 15) + +#define SPI_TIMEOUT 1000 +#define TEGRA2_SPI_MAX_FREQ 52000000 + + +#endif /* _TEGRA2_SPI_H_ */ diff --git a/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h new file mode 100644 index 00000000000..e4503b15b07 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * 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 _UART_SPI_SWITCH_H +#define _UART_SPI_SWITCH_H + +#if defined(CONFIG_SPI_UART_SWITCH) +/* + * Signal that we are about to use the UART. This unfortunate hack is + * required by Seaboard, which cannot use its console and SPI at the same + * time! If the board file provides this, the board config will declare it. + * Let this be a lesson for others. + */ +void pinmux_select_uart(NS16550_t regs); + +/* + * Signal that we are about the use the SPI bus. + */ +void pinmux_select_spi(void); + +#else /* not CONFIG_SPI_UART_SWITCH */ + +static inline void pinmux_select_uart(NS16550_t regs) {} +static inline void pinmux_select_spi(void) {} + +#endif + +#endif |