From 078078cfa91f72331421e6f7a46938a58a9b21a7 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Tue, 15 May 2012 14:32:40 -0700 Subject: spi: Tegra2: Seaboard: fix UART corruption during SPI transactions Simon Glass's proposal to fix this on Seaboard was NAK'd, so I removed his NS16550 references and added a small delay before SPI/UART muxing. Tested on my Seaboard with large SPI reads/writes and saw no corruption (crc's matched) and no spurious comm chars. Signed-off-by: Tom Warren Acked-by: Simon Glass Tested-by: Jimmy Zhang --- arch/arm/include/asm/arch-tegra2/uart-spi-switch.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h index e4503b15b07..82ac180acd1 100644 --- a/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h +++ b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h @@ -29,7 +29,7 @@ * 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); +void pinmux_select_uart(void); /* * Signal that we are about the use the SPI bus. @@ -38,7 +38,7 @@ 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_uart(void) {} static inline void pinmux_select_spi(void) {} #endif -- cgit v1.2.3 From b9607e70614823893d1a47a377232d2a12e4464f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 14 May 2012 13:13:45 +0000 Subject: tegra: add alternate UART1 funcmux entry (In at least some configurations) Whistler uses UART1 on pingroups UAA, UAB. Signed-off-by: Stephen Warren Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/board.c | 14 +++++++++++++- arch/arm/cpu/armv7/tegra2/funcmux.c | 13 ++++++++++++- arch/arm/include/asm/arch-tegra2/funcmux.h | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index a50b1b988a2..629ad5d67f8 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -101,6 +101,18 @@ int arch_cpu_init(void) } #endif +static int uart_configs[] = { +#ifdef CONFIG_TEGRA2_UARTA_UAA_UAB + FUNCMUX_UART1_UAA_UAB, +#else + FUNCMUX_UART1_IRRX_IRTX, +#endif + FUNCMUX_UART2_IRDA, + -1, + FUNCMUX_UART4_GMC, + -1, +}; + /** * Set up the specified uarts * @@ -120,7 +132,7 @@ static void setup_uarts(int uart_ids) if (uart_ids & (1 << i)) { enum periph_id id = id_for_uart[i]; - funcmux_select(id, FUNCMUX_DEFAULT); + funcmux_select(id, uart_configs[i]); clock_ll_start_uart(id); } } diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index 0ef77530218..e2d1273dc91 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -31,11 +31,22 @@ int funcmux_select(enum periph_id id, int config) switch (id) { case PERIPH_ID_UART1: - if (config == FUNCMUX_UART1_IRRX_IRTX) { + switch (config) { + case FUNCMUX_UART1_IRRX_IRTX: 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 FUNCMUX_UART1_UAA_UAB: + pinmux_set_func(PINGRP_UAA, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_UAB, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_UAA); + pinmux_tristate_disable(PINGRP_UAB); + bad_config = 0; + break; + } + if (!bad_config) { /* * Tegra appears to boot with function UARTA pre- * selected on mux group SDB. If two mux groups are diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index ae73c72ebe2..b455122594d 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -30,6 +30,7 @@ enum { /* UART configs */ FUNCMUX_UART1_IRRX_IRTX = 0, + FUNCMUX_UART1_UAA_UAB, FUNCMUX_UART2_IRDA = 0, FUNCMUX_UART4_GMC = 0, -- cgit v1.2.3 From e21649be56a0cbe17ea892fc6c1a633369df0d50 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 16 May 2012 05:59:59 +0000 Subject: tegra: add UART1 on GPU funcmux entry TrimSlice uses UART1 on the GPU pingroup. Signed-off-by: Stephen Warren Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/board.c | 4 +++- arch/arm/cpu/armv7/tegra2/funcmux.c | 5 +++++ arch/arm/include/asm/arch-tegra2/funcmux.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 629ad5d67f8..6106ef99922 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -102,8 +102,10 @@ int arch_cpu_init(void) #endif static int uart_configs[] = { -#ifdef CONFIG_TEGRA2_UARTA_UAA_UAB +#if defined(CONFIG_TEGRA2_UARTA_UAA_UAB) FUNCMUX_UART1_UAA_UAB, +#elif defined(CONFIG_TEGRA2_UARTA_GPU) + FUNCMUX_UART1_GPU, #else FUNCMUX_UART1_IRRX_IRTX, #endif diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index e2d1273dc91..c27908821a1 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -45,6 +45,11 @@ int funcmux_select(enum periph_id id, int config) pinmux_tristate_disable(PINGRP_UAB); bad_config = 0; break; + case FUNCMUX_UART1_GPU: + pinmux_set_func(PINGRP_GPU, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_GPU); + bad_config = 0; + break; } if (!bad_config) { /* diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index b455122594d..dba2cf50d0c 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -31,6 +31,7 @@ enum { /* UART configs */ FUNCMUX_UART1_IRRX_IRTX = 0, FUNCMUX_UART1_UAA_UAB, + FUNCMUX_UART1_GPU, FUNCMUX_UART2_IRDA = 0, FUNCMUX_UART4_GMC = 0, -- cgit v1.2.3 From ffec1eb9c7a88db4be06dbf596fc8578e4586b62 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 May 2012 08:21:01 +0000 Subject: tegra: sync SDIO1 pingroup enum name with TRM Signed-off-by: Lucas Stach CC: Tom Warren Signed-off-by: Tom Warren --- arch/arm/include/asm/arch-tegra2/pinmux.h | 2 +- board/compal/paz00/paz00.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h index 469d742cc30..03fa7ca643b 100644 --- a/arch/arm/include/asm/arch-tegra2/pinmux.h +++ b/arch/arm/include/asm/arch-tegra2/pinmux.h @@ -67,7 +67,7 @@ enum pmux_pingrp { PINGRP_KBCF, PINGRP_GMA, PINGRP_GMC, - PINGRP_SDMMC1, + PINGRP_SDIO1, PINGRP_OWC, /* 32: APB_MISC_PP_TRISTATE_REG_B_0 */ diff --git a/board/compal/paz00/paz00.c b/board/compal/paz00/paz00.c index b07ce11cf14..0c09ce0a464 100644 --- a/board/compal/paz00/paz00.c +++ b/board/compal/paz00/paz00.c @@ -48,10 +48,10 @@ static void pin_mux_mmc(void) pinmux_tristate_disable(PINGRP_GMA); pinmux_tristate_disable(PINGRP_GME); - /* SDMMC1: SDIO1_CLK, SDIO1_CMD, SDIO1_DAT[3:0] */ - pinmux_set_func(PINGRP_SDMMC1, PMUX_FUNC_SDIO1); + /* SDIO1: SDIO1_CLK, SDIO1_CMD, SDIO1_DAT[3:0] */ + pinmux_set_func(PINGRP_SDIO1, PMUX_FUNC_SDIO1); - pinmux_tristate_disable(PINGRP_SDMMC1); + pinmux_tristate_disable(PINGRP_SDIO1); /* For power GPIO PV1 */ pinmux_tristate_disable(PINGRP_UAC); -- cgit v1.2.3 From a2cfe63eeb6a09c52a748849590a898f1032aeea Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 May 2012 08:21:02 +0000 Subject: tegra: add SDIO1 funcmux entry for UARTA This is based on top of: tegra: add alternate UART1 funcmux entry tegra: add UART1 on GPU funcmux entry v2: remove enum change Signed-off-by: Lucas Stach Acked-by: Stephen Warren CC: Stephen Warren CC: Tom Warren CC: Marek Vasut Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/board.c | 2 ++ arch/arm/cpu/armv7/tegra2/funcmux.c | 5 +++++ arch/arm/include/asm/arch-tegra2/funcmux.h | 1 + 3 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 6106ef99922..923678d063a 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -106,6 +106,8 @@ static int uart_configs[] = { FUNCMUX_UART1_UAA_UAB, #elif defined(CONFIG_TEGRA2_UARTA_GPU) FUNCMUX_UART1_GPU, +#elif defined(CONFIG_TEGRA2_UARTA_SDIO1) + FUNCMUX_UART1_SDIO1, #else FUNCMUX_UART1_IRRX_IRTX, #endif diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index c27908821a1..155986932a2 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -50,6 +50,11 @@ int funcmux_select(enum periph_id id, int config) pinmux_tristate_disable(PINGRP_GPU); bad_config = 0; break; + case FUNCMUX_UART1_SDIO1: + pinmux_set_func(PINGRP_SDIO1, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_SDIO1); + bad_config = 0; + break; } if (!bad_config) { /* diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index dba2cf50d0c..19184d1d29b 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -32,6 +32,7 @@ enum { FUNCMUX_UART1_IRRX_IRTX = 0, FUNCMUX_UART1_UAA_UAB, FUNCMUX_UART1_GPU, + FUNCMUX_UART1_SDIO1, FUNCMUX_UART2_IRDA = 0, FUNCMUX_UART4_GMC = 0, -- cgit v1.2.3 From d1e4607901883c84a2f727c9ae2dac3cfcfd2b91 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 16 May 2012 13:54:06 +0000 Subject: tegra: add SDMMC1 on SDIO1 funcmux entry This will be used on TrimSlice. Signed-off-by: Stephen Warren Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/funcmux.c | 7 +++++++ arch/arm/include/asm/arch-tegra2/funcmux.h | 1 + 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index 155986932a2..820ba4e902d 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -127,6 +127,13 @@ int funcmux_select(enum periph_id id, int config) } break; + case PERIPH_ID_SDMMC1: + if (config == FUNCMUX_SDMMC1_SDIO1_4BIT) { + pinmux_set_func(PINGRP_SDIO1, PMUX_FUNC_SDIO1); + pinmux_tristate_disable(PINGRP_SDIO1); + } + break; + case PERIPH_ID_SDMMC2: if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2); diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index 19184d1d29b..b16c496122a 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -44,6 +44,7 @@ enum { FUNCMUX_I2C3_DTF = 0, /* SDMMC configs */ + FUNCMUX_SDMMC1_SDIO1_4BIT = 0, FUNCMUX_SDMMC2_DTA_DTD_8BIT = 0, FUNCMUX_SDMMC3_SDB_4BIT = 0, FUNCMUX_SDMMC3_SDB_SLXA_8BIT, -- cgit v1.2.3 From 27c4a3318f716cce0a23248317534bda7792230b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Apr 2012 08:04:39 +0000 Subject: tegra: Correct PLL access in ap20.c and clock.c Correct this warning seen by Albert: ap20.c:44:18: warning: array subscript is above array bounds There is a subtle bug here which currently causes no errors, but might in future if people use PCI or the 32KHz clock. So take the opportunity to correct the logic now. Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/ap20.c | 6 ++++-- arch/arm/cpu/armv7/tegra2/clock.c | 4 ++-- arch/arm/include/asm/arch-tegra2/clock.h | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c index 698bfd0e171..24e582d95cc 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.c +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -77,8 +77,10 @@ static int ap20_cpu_is_cortexa9(void) void init_pllx(void) { - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU]; + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll_simple *pll = + &clkrst->crc_pll_simple[CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE]; u32 reg; /* If PLLX is already enabled, just return */ diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c index ccad3516398..602589cde0f 100644 --- a/arch/arm/cpu/armv7/tegra2/clock.c +++ b/arch/arm/cpu/armv7/tegra2/clock.c @@ -426,7 +426,7 @@ static struct clk_pll *get_pll(enum clock_id clkid) struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - assert(clock_id_isvalid(clkid)); + assert(clock_id_is_pll(clkid)); return &clkrst->crc_pll[clkid]; } @@ -439,7 +439,7 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, assert(clkid != CLOCK_ID_USB); /* Safety check, adds to code size but is small */ - if (!clock_id_isvalid(clkid) || clkid == CLOCK_ID_USB) + if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) return -1; data = readl(&pll->pll_base); *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; diff --git a/arch/arm/include/asm/arch-tegra2/clock.h b/arch/arm/include/asm/arch-tegra2/clock.h index 1d3ae386440..ff83bbf2938 100644 --- a/arch/arm/include/asm/arch-tegra2/clock.h +++ b/arch/arm/include/asm/arch-tegra2/clock.h @@ -186,8 +186,9 @@ enum periph_id { /* Mask value for a clock (within PERIPH_REG(id)) */ #define PERIPH_MASK(id) (1 << ((id) & 0x1f)) -/* return 1 if a PLL ID is in range */ -#define clock_id_isvalid(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT) +/* return 1 if a PLL ID is in range, and not a simple PLL */ +#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && \ + (id) < CLOCK_ID_FIRST_SIMPLE) /* PLL stabilization delay in usec */ #define CLOCK_PLL_STABLE_DELAY_US 300 -- cgit v1.2.3 From f3717ac5848ec389919596d5e518b528fb8bebdd Mon Sep 17 00:00:00 2001 From: amartin@nvidia.com Date: Mon, 14 May 2012 13:14:39 +0000 Subject: tegra: override compiler flags for low level init code Override -march setting for tegra to -march=armv4t for files that are necessary for low level init on tegra. The recent change to use -march=armv7-a for armv7 caused a regression on tegra because tegra starts boot on a arm7tdmi processor before transferring control to the cortex-a9. While still executing on the arm7tdmi there are calls to getenv_ulong() and memset() that cause an illegal instruction exception if compiled for armv7. Signed-off-by: Allen Martin Tested-by: Stephen Warren Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/config.mk | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk index fe9ef5b763b..4dd8cb8442b 100644 --- a/arch/arm/cpu/armv7/tegra2/config.mk +++ b/arch/arm/cpu/armv7/tegra2/config.mk @@ -24,10 +24,13 @@ # MA 02111-1307 USA # -# Tegra has an ARMv4T CPU which runs board_init_f(), so we must build this -# file with compatible flags +# Tegra has an ARMv4T CPU which runs board_init_f(), so we must build these +# files with compatible flags ifdef CONFIG_TEGRA2 CFLAGS_arch/arm/lib/board.o += -march=armv4t +CFLAGS_arch/arm/lib/memset.o += -march=armv4t +CFLAGS_lib/string.o += -march=armv4t +CFLAGS_common/cmd_nvedit.o += -march=armv4t endif USE_PRIVATE_LIBGCC = yes -- cgit v1.2.3 From edffa63d3d6e76991998789f9fcbaa483731ca65 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Tue, 22 May 2012 07:33:47 +0000 Subject: spi: tegra2: rename tegra2_spi.* to tegra_spi.* In anticipation of Tegra3 support, start removing/renaming Tegra2-specific files. No functional changes (yet). Also updated copyright to 2012. Signed-off-by: Tom Warren --- arch/arm/include/asm/arch-tegra2/tegra2_spi.h | 76 ------- arch/arm/include/asm/arch-tegra2/tegra_spi.h | 75 +++++++ board/nvidia/common/uart-spi-switch.c | 2 +- drivers/spi/Makefile | 2 +- drivers/spi/tegra2_spi.c | 290 -------------------------- drivers/spi/tegra_spi.c | 290 ++++++++++++++++++++++++++ include/configs/seaboard.h | 2 +- 7 files changed, 368 insertions(+), 369 deletions(-) delete mode 100644 arch/arm/include/asm/arch-tegra2/tegra2_spi.h create mode 100644 arch/arm/include/asm/arch-tegra2/tegra_spi.h delete mode 100644 drivers/spi/tegra2_spi.c create mode 100644 drivers/spi/tegra_spi.c (limited to 'arch') diff --git a/arch/arm/include/asm/arch-tegra2/tegra2_spi.h b/arch/arm/include/asm/arch-tegra2/tegra2_spi.h deleted file mode 100644 index ceec4287a3b..00000000000 --- a/arch/arm/include/asm/arch-tegra2/tegra2_spi.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 - -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/tegra_spi.h b/arch/arm/include/asm/arch-tegra2/tegra_spi.h new file mode 100644 index 00000000000..892d90c00ba --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/tegra_spi.h @@ -0,0 +1,75 @@ +/* + * NVIDIA Tegra2 SPI-FLASH controller + * + * Copyright 2010-2012 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 _TEGRA_SPI_H_ +#define _TEGRA_SPI_H_ + +#include + +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 /* _TEGRA_SPI_H_ */ diff --git a/board/nvidia/common/uart-spi-switch.c b/board/nvidia/common/uart-spi-switch.c index 1ba1afd1c91..307937a8364 100644 --- a/board/nvidia/common/uart-spi-switch.c +++ b/board/nvidia/common/uart-spi-switch.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include /* position of the UART/SPI select switch */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c967d87834a..c20f1f2daac 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -43,7 +43,7 @@ COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o COBJS-$(CONFIG_SH_SPI) += sh_spi.o COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o -COBJS-$(CONFIG_TEGRA2_SPI) += tegra2_spi.o +COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/tegra2_spi.c b/drivers/spi/tegra2_spi.c deleted file mode 100644 index fe7b405b132..00000000000 --- a/drivers/spi/tegra2_spi.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2010-2011 NVIDIA Corporation - * With help from the mpc8xxx SPI driver - * With more help from omap3_spi SPI driver - * - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_SPI_CORRUPTS_UART) - #define corrupt_delay() udelay(CONFIG_SPI_CORRUPTS_UART_DLY); -#else - #define corrupt_delay() -#endif - -struct tegra_spi_slave { - struct spi_slave slave; - struct spi_tegra *regs; - unsigned int freq; - unsigned int mode; -}; - -static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave) -{ - return container_of(slave, struct tegra_spi_slave, slave); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - /* Tegra2 SPI-Flash - only 1 device ('bus/cs') */ - if (bus != 0 || cs != 0) - return 0; - else - return 1; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct tegra_spi_slave *spi; - - if (!spi_cs_is_valid(bus, cs)) { - printf("SPI error: unsupported bus %d / chip select %d\n", - bus, cs); - return NULL; - } - - if (max_hz > TEGRA2_SPI_MAX_FREQ) { - printf("SPI error: unsupported frequency %d Hz. Max frequency" - " is %d Hz\n", max_hz, TEGRA2_SPI_MAX_FREQ); - return NULL; - } - - spi = malloc(sizeof(struct tegra_spi_slave)); - if (!spi) { - printf("SPI error: malloc of SPI structure failed\n"); - return NULL; - } - spi->slave.bus = bus; - spi->slave.cs = cs; - spi->freq = max_hz; - spi->regs = (struct spi_tegra *)TEGRA2_SPI_BASE; - spi->mode = mode; - - return &spi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct tegra_spi_slave *spi = to_tegra_spi(slave); - - free(spi); -} - -void spi_init(void) -{ - /* do nothing */ -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct tegra_spi_slave *spi = to_tegra_spi(slave); - struct spi_tegra *regs = spi->regs; - u32 reg; - - /* Change SPI clock to correct frequency, PLLP_OUT0 source */ - clock_start_periph_pll(PERIPH_ID_SPI1, CLOCK_ID_PERIPH, spi->freq); - - /* Clear stale status here */ - reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \ - SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF; - writel(reg, ®s->status); - debug("spi_init: STATUS = %08x\n", readl(®s->status)); - - /* - * Use sw-controlled CS, so we can clock in data after ReadID, etc. - */ - reg = (spi->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; - if (spi->mode & 2) - reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT; - clrsetbits_le32(®s->command, SPI_CMD_ACTIVE_SCLK_MASK | - SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg); - debug("spi_init: COMMAND = %08x\n", readl(®s->command)); - - /* - * SPI pins on Tegra2 are muxed - change pinmux later due to UART - * issue. - */ - pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH); - pinmux_tristate_disable(PINGRP_LSPI); - -#ifndef CONFIG_SPI_UART_SWITCH - /* - * NOTE: - * Only set PinMux bits 3:2 to SPI here on boards that don't have the - * SPI UART switch or subsequent UART data won't go out! See - * spi_uart_switch(). - */ - /* TODO: pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); */ -#endif - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* - * We can't release UART_DISABLE and set pinmux to UART4 here since - * some code (e,g, spi_flash_probe) uses printf() while the SPI - * bus is held. That is arguably bad, but it has the advantage of - * already being in the source tree. - */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - struct tegra_spi_slave *spi = to_tegra_spi(slave); - - pinmux_select_spi(); - - /* CS is negated on Tegra, so drive a 1 to get a 0 */ - setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); - - corrupt_delay(); /* Let UART settle */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct tegra_spi_slave *spi = to_tegra_spi(slave); - - pinmux_select_uart(); - - /* CS is negated on Tegra, so drive a 0 to get a 1 */ - clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); - - corrupt_delay(); /* Let SPI settle */ -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *data_out, void *data_in, unsigned long flags) -{ - struct tegra_spi_slave *spi = to_tegra_spi(slave); - struct spi_tegra *regs = spi->regs; - u32 reg, tmpdout, tmpdin = 0; - const u8 *dout = data_out; - u8 *din = data_in; - int num_bytes; - int ret; - - debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", - slave->bus, slave->cs, *(u8 *)dout, *(u8 *)din, bitlen); - if (bitlen % 8) - return -1; - num_bytes = bitlen / 8; - - ret = 0; - - reg = readl(®s->status); - writel(reg, ®s->status); /* Clear all SPI events via R/W */ - debug("spi_xfer entry: STATUS = %08x\n", reg); - - reg = readl(®s->command); - reg |= SPI_CMD_TXEN | SPI_CMD_RXEN; - writel(reg, ®s->command); - debug("spi_xfer: COMMAND = %08x\n", readl(®s->command)); - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - /* handle data in 32-bit chunks */ - while (num_bytes > 0) { - int bytes; - int is_read = 0; - int tm, i; - - tmpdout = 0; - bytes = (num_bytes > 4) ? 4 : num_bytes; - - if (dout != NULL) { - for (i = 0; i < bytes; ++i) - tmpdout = (tmpdout << 8) | dout[i]; - } - - num_bytes -= bytes; - if (dout) - dout += bytes; - - clrsetbits_le32(®s->command, SPI_CMD_BIT_LENGTH_MASK, - bytes * 8 - 1); - writel(tmpdout, ®s->tx_fifo); - setbits_le32(®s->command, SPI_CMD_GO); - - /* - * Wait for SPI transmit FIFO to empty, or to time out. - * The RX FIFO status will be read and cleared last - */ - for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) { - u32 status; - - status = readl(®s->status); - - /* We can exit when we've had both RX and TX activity */ - if (is_read && (status & SPI_STAT_TXF_EMPTY)) - break; - - if ((status & (SPI_STAT_BSY | SPI_STAT_RDY)) != - SPI_STAT_RDY) - tm++; - - else if (!(status & SPI_STAT_RXF_EMPTY)) { - tmpdin = readl(®s->rx_fifo); - is_read = 1; - - /* swap bytes read in */ - if (din != NULL) { - for (i = bytes - 1; i >= 0; --i) { - din[i] = tmpdin & 0xff; - tmpdin >>= 8; - } - din += bytes; - } - } - } - - if (tm >= SPI_TIMEOUT) - ret = tm; - - /* clear ACK RDY, etc. bits */ - writel(readl(®s->status), ®s->status); - } - - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - debug("spi_xfer: transfer ended. Value=%08x, status = %08x\n", - tmpdin, readl(®s->status)); - - if (ret) { - printf("spi_xfer: timeout during SPI transfer, tm %d\n", ret); - return -1; - } - - return 0; -} diff --git a/drivers/spi/tegra_spi.c b/drivers/spi/tegra_spi.c new file mode 100644 index 00000000000..4a3e7996f96 --- /dev/null +++ b/drivers/spi/tegra_spi.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2010-2012 NVIDIA Corporation + * With help from the mpc8xxx SPI driver + * With more help from omap3_spi SPI driver + * + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_SPI_CORRUPTS_UART) + #define corrupt_delay() udelay(CONFIG_SPI_CORRUPTS_UART_DLY); +#else + #define corrupt_delay() +#endif + +struct tegra_spi_slave { + struct spi_slave slave; + struct spi_tegra *regs; + unsigned int freq; + unsigned int mode; +}; + +static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave) +{ + return container_of(slave, struct tegra_spi_slave, slave); +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + /* Tegra2 SPI-Flash - only 1 device ('bus/cs') */ + if (bus != 0 || cs != 0) + return 0; + else + return 1; +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct tegra_spi_slave *spi; + + if (!spi_cs_is_valid(bus, cs)) { + printf("SPI error: unsupported bus %d / chip select %d\n", + bus, cs); + return NULL; + } + + if (max_hz > TEGRA2_SPI_MAX_FREQ) { + printf("SPI error: unsupported frequency %d Hz. Max frequency" + " is %d Hz\n", max_hz, TEGRA2_SPI_MAX_FREQ); + return NULL; + } + + spi = malloc(sizeof(struct tegra_spi_slave)); + if (!spi) { + printf("SPI error: malloc of SPI structure failed\n"); + return NULL; + } + spi->slave.bus = bus; + spi->slave.cs = cs; + spi->freq = max_hz; + spi->regs = (struct spi_tegra *)TEGRA2_SPI_BASE; + spi->mode = mode; + + return &spi->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct tegra_spi_slave *spi = to_tegra_spi(slave); + + free(spi); +} + +void spi_init(void) +{ + /* do nothing */ +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct tegra_spi_slave *spi = to_tegra_spi(slave); + struct spi_tegra *regs = spi->regs; + u32 reg; + + /* Change SPI clock to correct frequency, PLLP_OUT0 source */ + clock_start_periph_pll(PERIPH_ID_SPI1, CLOCK_ID_PERIPH, spi->freq); + + /* Clear stale status here */ + reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \ + SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF; + writel(reg, ®s->status); + debug("spi_init: STATUS = %08x\n", readl(®s->status)); + + /* + * Use sw-controlled CS, so we can clock in data after ReadID, etc. + */ + reg = (spi->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; + if (spi->mode & 2) + reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT; + clrsetbits_le32(®s->command, SPI_CMD_ACTIVE_SCLK_MASK | + SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg); + debug("spi_init: COMMAND = %08x\n", readl(®s->command)); + + /* + * SPI pins on Tegra2 are muxed - change pinmux later due to UART + * issue. + */ + pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH); + pinmux_tristate_disable(PINGRP_LSPI); + +#ifndef CONFIG_SPI_UART_SWITCH + /* + * NOTE: + * Only set PinMux bits 3:2 to SPI here on boards that don't have the + * SPI UART switch or subsequent UART data won't go out! See + * spi_uart_switch(). + */ + /* TODO: pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); */ +#endif + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + /* + * We can't release UART_DISABLE and set pinmux to UART4 here since + * some code (e,g, spi_flash_probe) uses printf() while the SPI + * bus is held. That is arguably bad, but it has the advantage of + * already being in the source tree. + */ +} + +void spi_cs_activate(struct spi_slave *slave) +{ + struct tegra_spi_slave *spi = to_tegra_spi(slave); + + pinmux_select_spi(); + + /* CS is negated on Tegra, so drive a 1 to get a 0 */ + setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + + corrupt_delay(); /* Let UART settle */ +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct tegra_spi_slave *spi = to_tegra_spi(slave); + + pinmux_select_uart(); + + /* CS is negated on Tegra, so drive a 0 to get a 1 */ + clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + + corrupt_delay(); /* Let SPI settle */ +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *data_out, void *data_in, unsigned long flags) +{ + struct tegra_spi_slave *spi = to_tegra_spi(slave); + struct spi_tegra *regs = spi->regs; + u32 reg, tmpdout, tmpdin = 0; + const u8 *dout = data_out; + u8 *din = data_in; + int num_bytes; + int ret; + + debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, *(u8 *)dout, *(u8 *)din, bitlen); + if (bitlen % 8) + return -1; + num_bytes = bitlen / 8; + + ret = 0; + + reg = readl(®s->status); + writel(reg, ®s->status); /* Clear all SPI events via R/W */ + debug("spi_xfer entry: STATUS = %08x\n", reg); + + reg = readl(®s->command); + reg |= SPI_CMD_TXEN | SPI_CMD_RXEN; + writel(reg, ®s->command); + debug("spi_xfer: COMMAND = %08x\n", readl(®s->command)); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* handle data in 32-bit chunks */ + while (num_bytes > 0) { + int bytes; + int is_read = 0; + int tm, i; + + tmpdout = 0; + bytes = (num_bytes > 4) ? 4 : num_bytes; + + if (dout != NULL) { + for (i = 0; i < bytes; ++i) + tmpdout = (tmpdout << 8) | dout[i]; + } + + num_bytes -= bytes; + if (dout) + dout += bytes; + + clrsetbits_le32(®s->command, SPI_CMD_BIT_LENGTH_MASK, + bytes * 8 - 1); + writel(tmpdout, ®s->tx_fifo); + setbits_le32(®s->command, SPI_CMD_GO); + + /* + * Wait for SPI transmit FIFO to empty, or to time out. + * The RX FIFO status will be read and cleared last + */ + for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) { + u32 status; + + status = readl(®s->status); + + /* We can exit when we've had both RX and TX activity */ + if (is_read && (status & SPI_STAT_TXF_EMPTY)) + break; + + if ((status & (SPI_STAT_BSY | SPI_STAT_RDY)) != + SPI_STAT_RDY) + tm++; + + else if (!(status & SPI_STAT_RXF_EMPTY)) { + tmpdin = readl(®s->rx_fifo); + is_read = 1; + + /* swap bytes read in */ + if (din != NULL) { + for (i = bytes - 1; i >= 0; --i) { + din[i] = tmpdin & 0xff; + tmpdin >>= 8; + } + din += bytes; + } + } + } + + if (tm >= SPI_TIMEOUT) + ret = tm; + + /* clear ACK RDY, etc. bits */ + writel(readl(®s->status), ®s->status); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + debug("spi_xfer: transfer ended. Value=%08x, status = %08x\n", + tmpdin, readl(®s->status)); + + if (ret) { + printf("spi_xfer: timeout during SPI transfer, tm %d\n", ret); + return -1; + } + + return 0; +} diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index f46740e53a1..db11d8a308c 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -67,7 +67,7 @@ #define CONFIG_BOARD_EARLY_INIT_F /* SPI */ -#define CONFIG_TEGRA2_SPI +#define CONFIG_TEGRA_SPI #define CONFIG_SPI_FLASH #define CONFIG_SPI_FLASH_WINBOND #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 -- cgit v1.2.3 From 52a8b82074d1c3a3dcde8e3d90e6a04f7eb3a1f8 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Tue, 22 May 2012 12:19:25 +0000 Subject: gpio: tegra2: rename tegra2_gpio.* to tegra_gpio.* In anticipation of Tegra3 support, continue removing/renaming Tegra2-specific files. No functional changes (yet). Updated copyrights to 2012. Signed-off-by: Tom Warren --- arch/arm/include/asm/arch-tegra2/gpio.h | 7 +- drivers/gpio/Makefile | 2 +- drivers/gpio/tegra2_gpio.c | 262 -------------------------------- drivers/gpio/tegra_gpio.c | 262 ++++++++++++++++++++++++++++++++ include/configs/tegra2-common.h | 4 +- 5 files changed, 269 insertions(+), 268 deletions(-) delete mode 100644 drivers/gpio/tegra2_gpio.c create mode 100644 drivers/gpio/tegra_gpio.c (limited to 'arch') diff --git a/arch/arm/include/asm/arch-tegra2/gpio.h b/arch/arm/include/asm/arch-tegra2/gpio.h index 41e66fe1b15..40ddb02565a 100644 --- a/arch/arm/include/asm/arch-tegra2/gpio.h +++ b/arch/arm/include/asm/arch-tegra2/gpio.h @@ -2,6 +2,7 @@ * Copyright (c) 2011, Google Inc. All rights reserved. * See file CREDITS for list of people who contributed to this * project. + * Portions Copyright 2011-2012 NVIDIA Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,8 +20,8 @@ * MA 02111-1307 USA */ -#ifndef _TEGRA2_GPIO_H_ -#define _TEGRA2_GPIO_H_ +#ifndef _TEGRA_GPIO_H_ +#define _TEGRA_GPIO_H_ /* * The Tegra 2x GPIO controller has 224 GPIOs arranged in 7 banks of 4 ports, @@ -286,4 +287,4 @@ enum gpio_pin { void gpio_info(void); #define gpio_status() gpio_info() -#endif /* TEGRA2_GPIO_H_ */ +#endif /* TEGRA_GPIO_H_ */ diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fb3b09ae74c..5ae68d5ba82 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -35,7 +35,7 @@ COBJS-$(CONFIG_PCA953X) += pca953x.o COBJS-$(CONFIG_PCA9698) += pca9698.o COBJS-$(CONFIG_S5P) += s5p_gpio.o COBJS-$(CONFIG_SANDBOX_GPIO) += sandbox.o -COBJS-$(CONFIG_TEGRA2_GPIO) += tegra2_gpio.o +COBJS-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o diff --git a/drivers/gpio/tegra2_gpio.c b/drivers/gpio/tegra2_gpio.c deleted file mode 100644 index 70ca46fae5c..00000000000 --- a/drivers/gpio/tegra2_gpio.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * NVIDIA Tegra2 GPIO handling. - * (C) Copyright 2010,2011 - * NVIDIA 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 - */ - -/* - * Based on (mostly copied from) kw_gpio.c based Linux 2.6 kernel driver. - * Tom Warren (twarren@nvidia.com) - */ - -#include -#include -#include -#include -#include - -enum { - TEGRA2_CMD_INFO, - TEGRA2_CMD_PORT, - TEGRA2_CMD_OUTPUT, - TEGRA2_CMD_INPUT, -}; - -static struct gpio_names { - char name[GPIO_NAME_SIZE]; -} gpio_names[MAX_NUM_GPIOS]; - -static char *get_name(int i) -{ - return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN"; -} - -/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */ -static int get_config(unsigned gpio) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - u32 u; - int type; - - u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); - type = (u >> GPIO_BIT(gpio)) & 1; - - debug("get_config: port = %d, bit = %d is %s\n", - GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); - - return type; -} - -/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */ -static void set_config(unsigned gpio, int type) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - u32 u; - - debug("set_config: port = %d, bit = %d, %s\n", - GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); - - u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); - if (type) /* GPIO */ - u |= 1 << GPIO_BIT(gpio); - else - u &= ~(1 << GPIO_BIT(gpio)); - writel(u, &bank->gpio_config[GPIO_PORT(gpio)]); -} - -/* Return GPIO pin 'gpio' direction - 0 = input or 1 = output */ -static int get_direction(unsigned gpio) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - u32 u; - int dir; - - u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]); - dir = (u >> GPIO_BIT(gpio)) & 1; - - debug("get_direction: port = %d, bit = %d, %s\n", - GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN"); - - return dir; -} - -/* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */ -static void set_direction(unsigned gpio, int output) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - u32 u; - - debug("set_direction: port = %d, bit = %d, %s\n", - GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN"); - - u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]); - if (output) - u |= 1 << GPIO_BIT(gpio); - else - u &= ~(1 << GPIO_BIT(gpio)); - writel(u, &bank->gpio_dir_out[GPIO_PORT(gpio)]); -} - -/* set GPIO pin 'gpio' output bit as 0 or 1 as per 'high' */ -static void set_level(unsigned gpio, int high) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - u32 u; - - debug("set_level: port = %d, bit %d == %d\n", - GPIO_FULLPORT(gpio), GPIO_BIT(gpio), high); - - u = readl(&bank->gpio_out[GPIO_PORT(gpio)]); - if (high) - u |= 1 << GPIO_BIT(gpio); - else - u &= ~(1 << GPIO_BIT(gpio)); - writel(u, &bank->gpio_out[GPIO_PORT(gpio)]); -} - -/* - * Generic_GPIO primitives. - */ - -int gpio_request(unsigned gpio, const char *label) -{ - if (gpio >= MAX_NUM_GPIOS) - return -1; - - if (label != NULL) { - strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE); - gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0'; - } - - /* Configure as a GPIO */ - set_config(gpio, 1); - - return 0; -} - -int gpio_free(unsigned gpio) -{ - if (gpio >= MAX_NUM_GPIOS) - return -1; - - gpio_names[gpio].name[0] = '\0'; - /* Do not configure as input or change pin mux here */ - return 0; -} - -/* read GPIO OUT value of pin 'gpio' */ -static int gpio_get_output_value(unsigned gpio) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - int val; - - debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); - - val = readl(&bank->gpio_out[GPIO_PORT(gpio)]); - - return (val >> GPIO_BIT(gpio)) & 1; -} - -/* set GPIO pin 'gpio' as an input */ -int gpio_direction_input(unsigned gpio) -{ - debug("gpio_direction_input: pin = %d (port %d:bit %d)\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); - - /* Configure GPIO direction as input. */ - set_direction(gpio, 0); - - return 0; -} - -/* set GPIO pin 'gpio' as an output, with polarity 'value' */ -int gpio_direction_output(unsigned gpio, int value) -{ - debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), - value ? "HIGH" : "LOW"); - - /* Configure GPIO output value. */ - set_level(gpio, value); - - /* Configure GPIO direction as output. */ - set_direction(gpio, 1); - - return 0; -} - -/* read GPIO IN value of pin 'gpio' */ -int gpio_get_value(unsigned gpio) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - int val; - - debug("gpio_get_value: pin = %d (port %d:bit %d)\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); - - val = readl(&bank->gpio_in[GPIO_PORT(gpio)]); - - return (val >> GPIO_BIT(gpio)) & 1; -} - -/* write GPIO OUT value to pin 'gpio' */ -int gpio_set_value(unsigned gpio, int value) -{ - debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value); - - /* Configure GPIO output value. */ - set_level(gpio, value); - - return 0; -} - -/* - * Display Tegra GPIO information - */ -void gpio_info(void) -{ - unsigned c; - int type; - - for (c = 0; c < MAX_NUM_GPIOS; c++) { - type = get_config(c); /* GPIO, not SFPIO */ - if (type) { - printf("GPIO_%d:\t%s is an %s, ", c, - get_name(c), - get_direction(c) ? "OUTPUT" : "INPUT"); - if (get_direction(c)) - printf("value = %d", gpio_get_output_value(c)); - else - printf("value = %d", gpio_get_value(c)); - printf("\n"); - } else - continue; - } -} diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c new file mode 100644 index 00000000000..60ec6e3d789 --- /dev/null +++ b/drivers/gpio/tegra_gpio.c @@ -0,0 +1,262 @@ +/* + * NVIDIA Tegra2 GPIO handling. + * (C) Copyright 2010-2012 + * NVIDIA 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 + */ + +/* + * Based on (mostly copied from) kw_gpio.c based Linux 2.6 kernel driver. + * Tom Warren (twarren@nvidia.com) + */ + +#include +#include +#include +#include +#include + +enum { + TEGRA2_CMD_INFO, + TEGRA2_CMD_PORT, + TEGRA2_CMD_OUTPUT, + TEGRA2_CMD_INPUT, +}; + +static struct gpio_names { + char name[GPIO_NAME_SIZE]; +} gpio_names[MAX_NUM_GPIOS]; + +static char *get_name(int i) +{ + return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN"; +} + +/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */ +static int get_config(unsigned gpio) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + u32 u; + int type; + + u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); + type = (u >> GPIO_BIT(gpio)) & 1; + + debug("get_config: port = %d, bit = %d is %s\n", + GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); + + return type; +} + +/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */ +static void set_config(unsigned gpio, int type) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + u32 u; + + debug("set_config: port = %d, bit = %d, %s\n", + GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO"); + + u = readl(&bank->gpio_config[GPIO_PORT(gpio)]); + if (type) /* GPIO */ + u |= 1 << GPIO_BIT(gpio); + else + u &= ~(1 << GPIO_BIT(gpio)); + writel(u, &bank->gpio_config[GPIO_PORT(gpio)]); +} + +/* Return GPIO pin 'gpio' direction - 0 = input or 1 = output */ +static int get_direction(unsigned gpio) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + u32 u; + int dir; + + u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]); + dir = (u >> GPIO_BIT(gpio)) & 1; + + debug("get_direction: port = %d, bit = %d, %s\n", + GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN"); + + return dir; +} + +/* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */ +static void set_direction(unsigned gpio, int output) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + u32 u; + + debug("set_direction: port = %d, bit = %d, %s\n", + GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN"); + + u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]); + if (output) + u |= 1 << GPIO_BIT(gpio); + else + u &= ~(1 << GPIO_BIT(gpio)); + writel(u, &bank->gpio_dir_out[GPIO_PORT(gpio)]); +} + +/* set GPIO pin 'gpio' output bit as 0 or 1 as per 'high' */ +static void set_level(unsigned gpio, int high) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + u32 u; + + debug("set_level: port = %d, bit %d == %d\n", + GPIO_FULLPORT(gpio), GPIO_BIT(gpio), high); + + u = readl(&bank->gpio_out[GPIO_PORT(gpio)]); + if (high) + u |= 1 << GPIO_BIT(gpio); + else + u &= ~(1 << GPIO_BIT(gpio)); + writel(u, &bank->gpio_out[GPIO_PORT(gpio)]); +} + +/* + * Generic_GPIO primitives. + */ + +int gpio_request(unsigned gpio, const char *label) +{ + if (gpio >= MAX_NUM_GPIOS) + return -1; + + if (label != NULL) { + strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE); + gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0'; + } + + /* Configure as a GPIO */ + set_config(gpio, 1); + + return 0; +} + +int gpio_free(unsigned gpio) +{ + if (gpio >= MAX_NUM_GPIOS) + return -1; + + gpio_names[gpio].name[0] = '\0'; + /* Do not configure as input or change pin mux here */ + return 0; +} + +/* read GPIO OUT value of pin 'gpio' */ +static int gpio_get_output_value(unsigned gpio) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + int val; + + debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); + + val = readl(&bank->gpio_out[GPIO_PORT(gpio)]); + + return (val >> GPIO_BIT(gpio)) & 1; +} + +/* set GPIO pin 'gpio' as an input */ +int gpio_direction_input(unsigned gpio) +{ + debug("gpio_direction_input: pin = %d (port %d:bit %d)\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); + + /* Configure GPIO direction as input. */ + set_direction(gpio, 0); + + return 0; +} + +/* set GPIO pin 'gpio' as an output, with polarity 'value' */ +int gpio_direction_output(unsigned gpio, int value) +{ + debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), + value ? "HIGH" : "LOW"); + + /* Configure GPIO output value. */ + set_level(gpio, value); + + /* Configure GPIO direction as output. */ + set_direction(gpio, 1); + + return 0; +} + +/* read GPIO IN value of pin 'gpio' */ +int gpio_get_value(unsigned gpio) +{ + struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; + struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; + int val; + + debug("gpio_get_value: pin = %d (port %d:bit %d)\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); + + val = readl(&bank->gpio_in[GPIO_PORT(gpio)]); + + return (val >> GPIO_BIT(gpio)) & 1; +} + +/* write GPIO OUT value to pin 'gpio' */ +int gpio_set_value(unsigned gpio, int value) +{ + debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value); + + /* Configure GPIO output value. */ + set_level(gpio, value); + + return 0; +} + +/* + * Display Tegra GPIO information + */ +void gpio_info(void) +{ + unsigned c; + int type; + + for (c = 0; c < MAX_NUM_GPIOS; c++) { + type = get_config(c); /* GPIO, not SFPIO */ + if (type) { + printf("GPIO_%d:\t%s is an %s, ", c, + get_name(c), + get_direction(c) ? "OUTPUT" : "INPUT"); + if (get_direction(c)) + printf("value = %d", gpio_get_output_value(c)); + else + printf("value = %d", gpio_get_value(c)); + printf("\n"); + } else + continue; + } +} diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h index a4146a50c6c..94e1aa628d4 100644 --- a/include/configs/tegra2-common.h +++ b/include/configs/tegra2-common.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2010,2011 + * (C) Copyright 2010-2012 * NVIDIA Corporation * * See file CREDITS for list of people who contributed to this @@ -190,6 +190,6 @@ CONFIG_SYS_INIT_RAM_SIZE - \ GENERATED_GBL_DATA_SIZE) -#define CONFIG_TEGRA2_GPIO +#define CONFIG_TEGRA_GPIO #define CONFIG_CMD_GPIO #endif /* __TEGRA2_COMMON_H */ -- cgit v1.2.3 From 76e350b7a3c568c8d27cf72f98036ec3ddb64f31 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Wed, 30 May 2012 14:06:09 -0700 Subject: arm: Tegra: Use ODMDATA from BCT in IRAM Walk the BIT and BCT to find the ODMDATA word in the CustomerData field and put it into Scratch20 reg for use by kernel, etc. Built all Tegra builds OK; Booted on Seaboard and saw ODMDATA in PMC scratch20 was the same as the value in my burn-u-boot.sh file (0x300D8011). NOTE: All flash utilities will have to specify the odmdata (nvflash --odmdata n) on the command line or via a cfg file, or built in to their BCT. Signed-off-by: Tom Warren Acked-by: Stephen Warren --- arch/arm/cpu/armv7/tegra2/ap20.c | 22 +++++++++++++++++++++- arch/arm/include/asm/arch-tegra2/tegra2.h | 4 ++++ include/configs/harmony.h | 1 - include/configs/medcom.h | 1 - include/configs/paz00.h | 1 - include/configs/plutux.h | 1 - include/configs/seaboard.h | 1 - include/configs/trimslice.h | 1 - include/configs/ventana.h | 1 - include/configs/whistler.h | 1 - 10 files changed, 25 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c index 24e582d95cc..1aad3879ee1 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.c +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -314,9 +314,28 @@ void enable_scu(void) writel(reg, &scu->scu_ctrl); } +static u32 get_odmdata(void) +{ + /* + * ODMDATA is stored in the BCT in IRAM by the BootROM. + * The BCT start and size are stored in the BIT in IRAM. + * Read the data @ bct_start + (bct_size - 12). This works + * on T20 and T30 BCTs, which are locked down. If this changes + * in new chips (T114, etc.), we can revisit this algorithm. + */ + + u32 bct_start, odmdata; + + bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); + odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); + + return odmdata; +} + void init_pmc_scratch(void) { struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + u32 odmdata; int i; /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ @@ -324,7 +343,8 @@ void init_pmc_scratch(void) writel(0, &pmc->pmc_scratch1+i); /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ - writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20); + odmdata = get_odmdata(); + writel(odmdata, &pmc->pmc_scratch20); #ifdef CONFIG_TEGRA2_LP0 /* save Sdram params to PMC 2, 4, and 24 for WB0 */ diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h index d4ada10ea8c..3c8d8a84b55 100644 --- a/arch/arm/include/asm/arch-tegra2/tegra2.h +++ b/arch/arm/include/asm/arch-tegra2/tegra2.h @@ -60,6 +60,10 @@ struct timerus { /* Address at which WB code runs, it must not overlap Bootrom's IRAM usage */ #define AP20_WB_RUN_ADDRESS 0x40020000 +#define NVBOOTINFOTABLE_BCTSIZE 0x38 /* BCT size in BIT in IRAM */ +#define NVBOOTINFOTABLE_BCTPTR 0x3C /* BCT pointer in BIT in IRAM */ +#define BCT_ODMDATA_OFFSET 4068 /* 12 bytes from end of BCT */ + /* These are the available SKUs (product types) for Tegra */ enum { SKU_ID_T20 = 0x8, diff --git a/include/configs/harmony.h b/include/configs/harmony.h index d13ead99098..df5265a5a0d 100644 --- a/include/configs/harmony.h +++ b/include/configs/harmony.h @@ -48,7 +48,6 @@ #endif #define CONFIG_MACH_TYPE MACH_TYPE_HARMONY -#define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/medcom.h b/include/configs/medcom.h index d3d10550af3..bdea7c9c531 100644 --- a/include/configs/medcom.h +++ b/include/configs/medcom.h @@ -31,7 +31,6 @@ /* High-level configuration options */ #define V_PROMPT "Tegra2 (Medcom) # " #define CONFIG_TEGRA2_BOARD_STRING "Avionic Design Medcom" -#define CONFIG_SYS_BOARD_ODMDATA 0x2b0d8011 /* Board-specific serial config */ #define CONFIG_SERIAL_MULTI diff --git a/include/configs/paz00.h b/include/configs/paz00.h index 29c368a99e0..0dd1e83a504 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -35,7 +35,6 @@ #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE #define CONFIG_MACH_TYPE MACH_TYPE_PAZ00 -#define CONFIG_SYS_BOARD_ODMDATA 0x800c0085 /* lp1, 512MB */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/plutux.h b/include/configs/plutux.h index e73be0bf929..6397eb104a6 100644 --- a/include/configs/plutux.h +++ b/include/configs/plutux.h @@ -31,7 +31,6 @@ /* High-level configuration options */ #define V_PROMPT "Tegra2 (Plutux) # " #define CONFIG_TEGRA2_BOARD_STRING "Avionic Design Plutux" -#define CONFIG_SYS_BOARD_ODMDATA 0x2b2d8011 /* Board-specific serial config */ #define CONFIG_SERIAL_MULTI diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index 537ab0e71cd..f661583fed6 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -53,7 +53,6 @@ #define CONFIG_UART_DISABLE_GPIO GPIO_PI3 #define CONFIG_MACH_TYPE MACH_TYPE_SEABOARD -#define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/trimslice.h b/include/configs/trimslice.h index 915b07ae23b..91de348d59e 100644 --- a/include/configs/trimslice.h +++ b/include/configs/trimslice.h @@ -43,7 +43,6 @@ #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE #define CONFIG_MACH_TYPE MACH_TYPE_TRIMSLICE -#define CONFIG_SYS_BOARD_ODMDATA 0x300c0011 /* lp?, 1GB, UARTA */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/ventana.h b/include/configs/ventana.h index 77a0a141520..5e4d53861c6 100644 --- a/include/configs/ventana.h +++ b/include/configs/ventana.h @@ -42,7 +42,6 @@ #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTD_BASE #define CONFIG_MACH_TYPE MACH_TYPE_VENTANA -#define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/whistler.h b/include/configs/whistler.h index 9dafe5cadca..f2952d5f45e 100644 --- a/include/configs/whistler.h +++ b/include/configs/whistler.h @@ -43,7 +43,6 @@ #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE #define CONFIG_MACH_TYPE MACH_TYPE_WHISTLER -#define CONFIG_SYS_BOARD_ODMDATA 0x2B080105 /* lp?, 512MB, UARTA */ #define CONFIG_BOARD_EARLY_INIT_F -- cgit v1.2.3 From 2ab281037555de1710aa597531562fe071470198 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 14 May 2012 12:38:18 +0000 Subject: am33xx: Do not call init_timer twice We do not need to call init_timer both in SPL and U-Boot itself, just SPL needs to initialize the timer. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/am33xx/board.c | 30 ++++++++++++++++-------------- arch/arm/include/asm/arch-am33xx/cpu.h | 2 -- board/ti/am335x/evm.c | 13 +------------ 3 files changed, 17 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 6b7a494d7cc..71309a7f479 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -40,6 +40,22 @@ struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; #define UART_SMART_IDLE_EN (0x1 << 0x3) #endif +#ifdef CONFIG_SPL_BUILD +/* Initialize timer */ +static void init_timer(void) +{ + /* Reset the Timer */ + writel(0x2, (&timer_base->tscir)); + + /* Wait until the reset is done */ + while (readl(&timer_base->tiocp_cfg) & 1) + ; + + /* Start the Timer */ + writel(0x1, (&timer_base->tclr)); +} +#endif + /* * early system init of muxing and clocks. */ @@ -88,20 +104,6 @@ void s_init(void) enable_mmc0_pin_mux(); } -/* Initialize timer */ -void init_timer(void) -{ - /* Reset the Timer */ - writel(0x2, (&timer_base->tscir)); - - /* Wait until the reset is done */ - while (readl(&timer_base->tiocp_cfg) & 1) - ; - - /* Start the Timer */ - writel(0x1, (&timer_base->tclr)); -} - #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) int board_mmc_init(bd_t *bis) { diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index cd002e632d2..8760cc042be 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -213,8 +213,6 @@ struct ctrl_stat { unsigned int resv1[16]; unsigned int statusreg; /* ofset 0x40 */ }; - -void init_timer(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL_STRICT_NAMES */ diff --git a/board/ti/am335x/evm.c b/board/ti/am335x/evm.c index 13dc60361a2..5e2d53ab42c 100644 --- a/board/ti/am335x/evm.c +++ b/board/ti/am335x/evm.c @@ -29,17 +29,6 @@ DECLARE_GLOBAL_DATA_PTR; /* * Basic board specific setup */ -int init_basic_setup(void) -{ - /* Initialize the Timer */ - init_timer(); - - /* address of boot parameters */ - gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100; - - return 0; -} - int board_init(void) { enable_uart0_pin_mux(); @@ -49,7 +38,7 @@ int board_init(void) i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif - init_basic_setup(); + gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100; return 0; } -- cgit v1.2.3 From e06e914d872f3bd5098d2f1120ecee1447a3f566 Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Thu, 17 May 2012 00:12:06 +0000 Subject: ARM: OMAP4+: dmm: Take care of overlapping dmm and trap sections. The DMM sections can be overlapping with each other, with sections 3 to 0 having the highest to lowest priority in that order. There could also be a section that is used trap the unmapped Tiler entries and this trap section could be overlapping with the actual sdram area. So take care of the above scenarios while calculating the size of the actual ram. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap-common/hwinit-common.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index cf71ab44438..660032330ef 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -162,11 +162,16 @@ void watchdog_init(void) */ u32 omap_sdram_size(void) { - u32 section, i, total_size = 0, size, addr; + u32 section, i, valid; + u64 sdram_start = 0, sdram_end = 0, addr, + size, total_size = 0, trap_size = 0; for (i = 0; i < 4; i++) { section = __raw_readl(DMM_BASE + i*4); + valid = (section & EMIF_SDRC_ADDRSPC_MASK) >> + (EMIF_SDRC_ADDRSPC_SHIFT); addr = section & EMIF_SYS_ADDR_MASK; + /* See if the address is valid */ if ((addr >= DRAM_ADDR_SPACE_START) && (addr < DRAM_ADDR_SPACE_END)) { @@ -174,9 +179,20 @@ u32 omap_sdram_size(void) EMIF_SYS_SIZE_SHIFT); size = 1 << size; size *= SZ_16M; - total_size += size; + + if (valid != DMM_SDRC_ADDR_SPC_INVALID) { + if (!sdram_start || (addr < sdram_start)) + sdram_start = addr; + if (!sdram_end || ((addr + size) > sdram_end)) + sdram_end = addr + size; + } else { + trap_size = size; + } + } + } + total_size = (sdram_end - sdram_start) - (trap_size); return total_size; } -- cgit v1.2.3 From 77efdeb7588aeae585fcde7e59cc8693df592fd7 Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Thu, 17 May 2012 00:12:07 +0000 Subject: ARM: OMAP5: dmm: Create a tiler trap section. The unmapped entries in tiler space are set with values 0xFF. So creating a DMM section of size 16MB at 0xFF000000 with ADDRSPACE set to 0x2. This way all the unmapped entry accesses to tiler will be trapped by the EMIF and a error response is sent to the L3 interconnect. L3 errors are inturn reported to MPU. Note that here the tiler trap section is overlapping with the actual ddr physical space and we lose 16MB out of the total 2GB. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap5/sdram.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index b2b5753e894..368b78bf498 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -88,9 +88,9 @@ const struct emif_regs emif_regs_266_mhz_2cs = { const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = { .dmm_lisa_map_0 = 0x0, - .dmm_lisa_map_1 = 0, - .dmm_lisa_map_2 = 0, - .dmm_lisa_map_3 = 0x80740300 + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80740300, + .dmm_lisa_map_3 = 0xFF020100 }; const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = { -- cgit v1.2.3 From 41321fd4d64492689bfad20c98b8970171aee7ce Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Thu, 17 May 2012 00:12:08 +0000 Subject: ARM: OMAP5: Align memory used for testing to the power of 2 get_ram_size checks the given memory range for valid ram, but expects the size of memory to be aligned to the power of 2. In case of OMAP5 evm board the memory available is 2GB - 16MB(used for TRAP section) = 2032MB. So always ensure that the size of memory used for testing is aligned to the power of 2. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap-common/emif-common.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index db509c92951..389feda7166 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -1161,6 +1161,9 @@ void sdram_init(void) /* Do some testing after the init */ if (!in_sdram) { size_prog = omap_sdram_size(); + size_prog = log_2_n_round_down(size_prog); + size_prog = (1 << size_prog); + size_detect = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, size_prog); /* Compare with the size programmed */ -- cgit v1.2.3 From e843d0f7ee1b67500d5cbbb20320df17ecbdf32c Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Thu, 17 May 2012 00:12:09 +0000 Subject: ARM: OMAP5: Correct the DRAM_ADDR_SPACE_END macro. OMAP5 evm board has 2GB of memory. So correct the macro to take in to account of the full dram size. Signed-off-by: R Sricharan --- arch/arm/include/asm/arch-omap5/omap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h index e3f55d20201..2961c6b5fa8 100644 --- a/arch/arm/include/asm/arch-omap5/omap.h +++ b/arch/arm/include/asm/arch-omap5/omap.h @@ -40,7 +40,7 @@ #define OMAP54XX_L4_PER_BASE 0x48000000 #define OMAP54XX_DRAM_ADDR_SPACE_START 0x80000000 -#define OMAP54XX_DRAM_ADDR_SPACE_END 0xD0000000 +#define OMAP54XX_DRAM_ADDR_SPACE_END 0xFFFFFFFF #define DRAM_ADDR_SPACE_START OMAP54XX_DRAM_ADDR_SPACE_START #define DRAM_ADDR_SPACE_END OMAP54XX_DRAM_ADDR_SPACE_END -- cgit v1.2.3 From d5b069ecb4199f1672fd98041bd0037bd33d2f0f Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Fri, 18 May 2012 13:21:59 +0000 Subject: DaVinci: fix ddr2 vtp i/o calibration Previously, only the low 5 bits (NCH) were being transfered from DDRVTPR to DDRVTPIOCR, the bits 5-9 where zeroed. VTP_RECAL should be bit 15, not 18. The only mainline board affected by this change is davinci_sonata. The other Davinci boards define CONFIG_SKIP_LOWLEVEL_INIT. However, if the program that loads u-boot on these boards copied the code from u-boot, they will need fixed as well. Signed-off-by: Troy Kisky Please get tested by acks before applying, where tested by means an overnight memory test. Thanks Troy --- arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S index 5b39484501c..0e45426fbc9 100644 --- a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S +++ b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S @@ -523,9 +523,8 @@ VTPLock: ldr r6, DDRVTPR ldr r7, [r6] - and r7, r7, $0x1f - and r8, r7, $0x3e0 - orr r8, r7, r8 + mov r8, r7, LSL #32-10 + mov r8, r8, LSR #32-10 /* grab low 10 bits */ ldr r7, VTP_RECAL orr r8, r7, r8 ldr r7, VTP_EN @@ -644,7 +643,7 @@ VTP_LOCK_COUNT: VTP_MASK: .word 0xffffdfff VTP_RECAL: - .word 0x40000 + .word 0x08000 VTP_EN: .word 0x02000 CFGTEST: -- cgit v1.2.3 From fe4f97b98faccc142fe6e1668ba7ff945fcf3994 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 21 May 2012 06:46:30 +0000 Subject: am335x: Correct i2c sysc offset Signed-off-by: Tom Rini Acked-by: Heiko Schocher --- arch/arm/include/asm/arch-am33xx/i2c.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-am33xx/i2c.h b/arch/arm/include/asm/arch-am33xx/i2c.h index 366e2bbec55..dcb294c35d5 100644 --- a/arch/arm/include/asm/arch-am33xx/i2c.h +++ b/arch/arm/include/asm/arch-am33xx/i2c.h @@ -34,9 +34,9 @@ struct i2c { unsigned short revnb_lo; /* 0x00 */ unsigned short res1; unsigned short revnb_hi; /* 0x04 */ - unsigned short res2[13]; - unsigned short sysc; /* 0x20 */ - unsigned short res3; + unsigned short res2[5]; + unsigned short sysc; /* 0x10 */ + unsigned short res3[9]; unsigned short irqstatus_raw; /* 0x24 */ unsigned short res4; unsigned short stat; /* 0x28 */ -- cgit v1.2.3 From d88bc0425b333ba5baa185b4f8797be444a03f44 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 21 May 2012 06:46:31 +0000 Subject: am33xx: Fill in more cm_wkuppll / cm_perpll Signed-off-by: Tom Rini Acked-by: Heiko Schocher --- arch/arm/include/asm/arch-am33xx/cpu.h | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index 8760cc042be..5a6534e32ea 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -62,7 +62,7 @@ struct cm_wkuppll { unsigned int wkclkstctrl; /* offset 0x00 */ unsigned int wkctrlclkctrl; /* offset 0x04 */ - unsigned int resv1[1]; + unsigned int wkgpio0clkctrl; /* offset 0x08 */ unsigned int wkl4wkclkctrl; /* offset 0x0c */ unsigned int resv2[4]; unsigned int idlestdpllmpu; /* offset 0x20 */ @@ -111,34 +111,54 @@ struct cm_perpll { unsigned int l3clkstctrl; /* offset 0x0c */ unsigned int resv1; unsigned int cpgmac0clkctrl; /* offset 0x14 */ - unsigned int resv2[4]; + unsigned int lcdclkctrl; /* offset 0x18 */ + unsigned int usb0clkctrl; /* offset 0x1C */ + unsigned int resv2; + unsigned int tptc0clkctrl; /* offset 0x24 */ unsigned int emifclkctrl; /* offset 0x28 */ unsigned int ocmcramclkctrl; /* offset 0x2c */ unsigned int gpmcclkctrl; /* offset 0x30 */ - unsigned int resv3[2]; + unsigned int mcasp0clkctrl; /* offset 0x34 */ + unsigned int uart5clkctrl; /* offset 0x38 */ unsigned int mmc0clkctrl; /* offset 0x3C */ unsigned int elmclkctrl; /* offset 0x40 */ unsigned int i2c2clkctrl; /* offset 0x44 */ unsigned int i2c1clkctrl; /* offset 0x48 */ unsigned int spi0clkctrl; /* offset 0x4C */ unsigned int spi1clkctrl; /* offset 0x50 */ - unsigned int resv4[3]; + unsigned int resv3[3]; unsigned int l4lsclkctrl; /* offset 0x60 */ unsigned int l4fwclkctrl; /* offset 0x64 */ - unsigned int resv5[6]; + unsigned int mcasp1clkctrl; /* offset 0x68 */ + unsigned int uart1clkctrl; /* offset 0x6C */ + unsigned int uart2clkctrl; /* offset 0x70 */ + unsigned int uart3clkctrl; /* offset 0x74 */ + unsigned int uart4clkctrl; /* offset 0x78 */ + unsigned int timer7clkctrl; /* offset 0x7C */ unsigned int timer2clkctrl; /* offset 0x80 */ - unsigned int resv6[11]; + unsigned int timer3clkctrl; /* offset 0x84 */ + unsigned int timer4clkctrl; /* offset 0x88 */ + unsigned int resv4[8]; + unsigned int gpio1clkctrl; /* offset 0xAC */ unsigned int gpio2clkctrl; /* offset 0xB0 */ - unsigned int resv7[7]; + unsigned int gpio3clkctrl; /* offset 0xB4 */ + unsigned int resv5; + unsigned int tpccclkctrl; /* offset 0xBC */ + unsigned int dcan0clkctrl; /* offset 0xC0 */ + unsigned int dcan1clkctrl; /* offset 0xC4 */ + unsigned int resv6[2]; unsigned int emiffwclkctrl; /* offset 0xD0 */ - unsigned int resv8[2]; + unsigned int resv7[2]; unsigned int l3instrclkctrl; /* offset 0xDC */ unsigned int l3clkctrl; /* Offset 0xE0 */ - unsigned int resv9[14]; + unsigned int resv8[4]; + unsigned int mmc1clkctrl; /* offset 0xF4 */ + unsigned int mmc2clkctrl; /* offset 0xF8 */ + unsigned int resv9[8]; unsigned int l4hsclkstctrl; /* offset 0x11C */ unsigned int l4hsclkctrl; /* offset 0x120 */ unsigned int resv10[8]; - unsigned int cpswclkctrl; /* offset 0x144 */ + unsigned int cpswclkstctrl; /* offset 0x144 */ }; /* Encapsulating Display pll registers */ -- cgit v1.2.3 From 65c206b68896e3486c4d05c0a0b570513ba0291f Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 21 May 2012 06:46:32 +0000 Subject: am33xx: Fix i2c sampling rate typo Signed-off-by: Tom Rini Acked-by: Heiko Schocher --- arch/arm/include/asm/arch-am33xx/i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-am33xx/i2c.h b/arch/arm/include/asm/arch-am33xx/i2c.h index dcb294c35d5..32b225800db 100644 --- a/arch/arm/include/asm/arch-am33xx/i2c.h +++ b/arch/arm/include/asm/arch-am33xx/i2c.h @@ -76,6 +76,6 @@ struct i2c { }; #define I2C_IP_CLK 48000000 -#define I2C_INTERNAL_SAMLPING_CLK 12000000 +#define I2C_INTERNAL_SAMPLING_CLK 12000000 #endif /* _I2C_H_ */ -- cgit v1.2.3 From 851bebd68cfc0cd3f638b3afbd3325a3b32df341 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:21 +0000 Subject: OMAP5: Adding correct Control id code for OMAP5430 Control id code for omap5430 ES1.0 is hard coded with a wrong value. This patch corrects the value Signed-off-by: Lokesh Vutla --- arch/arm/include/asm/arch-omap5/omap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h index 2961c6b5fa8..3d4d08c8836 100644 --- a/arch/arm/include/asm/arch-omap5/omap.h +++ b/arch/arm/include/asm/arch-omap5/omap.h @@ -56,7 +56,7 @@ #define CONTROL_ID_CODE (CTRL_BASE + 0x204) /* To be verified */ -#define OMAP5_CONTROL_ID_CODE_ES1_0 0x0B85202F +#define OMAP5_CONTROL_ID_CODE_ES1_0 0x0B94202F /* STD_FUSE_PROD_ID_1 */ #define STD_FUSE_PROD_ID_1 (CTRL_BASE + 0x218) -- cgit v1.2.3 From 0a0bf7b217660589b846bd5d6fcebc1deef20971 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:22 +0000 Subject: OMAP5: ADD chip detection for OMAP5432 SOC This patch adds chip detection for OMAP5432 Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap5/hwinit.c | 10 +++++++++- arch/arm/include/asm/arch-omap5/omap.h | 3 ++- arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c index d01cc81333b..e2f76a1bbde 100644 --- a/arch/arm/cpu/armv7/omap5/hwinit.c +++ b/arch/arm/cpu/armv7/omap5/hwinit.c @@ -154,7 +154,15 @@ void init_omap_revision(void) switch (rev) { case MIDR_CORTEX_A15_R0P0: - *omap_si_rev = OMAP5430_ES1_0; + switch (readl(CONTROL_ID_CODE)) { + case OMAP5430_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = OMAP5430_ES1_0; + break; + case OMAP5432_CONTROL_ID_CODE_ES1_0: + default: + *omap_si_rev = OMAP5432_ES1_0; + break; + } break; default: *omap_si_rev = OMAP5430_SILICON_ID_INVALID; diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h index 3d4d08c8836..94b6f3a89bd 100644 --- a/arch/arm/include/asm/arch-omap5/omap.h +++ b/arch/arm/include/asm/arch-omap5/omap.h @@ -56,7 +56,8 @@ #define CONTROL_ID_CODE (CTRL_BASE + 0x204) /* To be verified */ -#define OMAP5_CONTROL_ID_CODE_ES1_0 0x0B94202F +#define OMAP5430_CONTROL_ID_CODE_ES1_0 0x0B94202F +#define OMAP5432_CONTROL_ID_CODE_ES1_0 0x0B99802F /* STD_FUSE_PROD_ID_1 */ #define STD_FUSE_PROD_ID_1 (CTRL_BASE + 0x218) diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 459b6b16e24..4e95eee59b4 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -136,4 +136,5 @@ static inline u32 omap_revision(void) /* omap5 */ #define OMAP5430_SILICON_ID_INVALID 0 #define OMAP5430_ES1_0 0x54300100 +#define OMAP5432_ES1_0 0x54320100 #endif /* _OMAP_COMMON_H_ */ -- cgit v1.2.3 From eb4e18e89eec8d63f064cb5ec597ba9387fe4987 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:23 +0000 Subject: OMAP5: Configure the io settings for omap5432 uevm board This patch adds the IO settings required for OMAP5432 uevm's DDR3 pads Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap5/hwinit.c | 98 +++++++++++++++++++++++++++------- arch/arm/include/asm/arch-omap5/omap.h | 15 +++++- 2 files changed, 93 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c index e2f76a1bbde..df0b76050db 100644 --- a/arch/arm/cpu/armv7/omap5/hwinit.c +++ b/arch/arm/cpu/armv7/omap5/hwinit.c @@ -52,6 +52,81 @@ static struct gpio_bank gpio_bank_54xx[6] = { const struct gpio_bank *const omap_gpio_bank = gpio_bank_54xx; #ifdef CONFIG_SPL_BUILD +/* LPDDR2 specific IO settings */ +static void io_settings_lpddr2(void) +{ + struct omap_sys_ctrl_regs *ioregs_base = + (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; + + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, + &(ioregs_base->control_ddrch1_0)); + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, + &(ioregs_base->control_ddrch1_1)); + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, + &(ioregs_base->control_ddrch2_0)); + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, + &(ioregs_base->control_ddrch2_1)); + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN, + &(ioregs_base->control_lpddr2ch1_0)); + writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN, + &(ioregs_base->control_lpddr2ch1_1)); + writel(DDR_IO_0_DDR2_DQ_INT_EN_ALL_DDR3_CA_DIS_ALL, + &(ioregs_base->control_ddrio_0)); + writel(DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL, + &(ioregs_base->control_ddrio_1)); + writel(DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL, + &(ioregs_base->control_ddrio_2)); +} + +/* DDR3 specific IO settings */ +static void io_settings_ddr3(void) +{ + u32 io_settings = 0; + struct omap_sys_ctrl_regs *ioregs_base = + (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; + + writel(DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddr3ch1_0)); + writel(DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddrch1_0)); + writel(DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddrch1_1)); + + writel(DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddr3ch2_0)); + writel(DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddrch2_0)); + writel(DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL, + &(ioregs_base->control_ddrch2_1)); + + writel(DDR_IO_0_VREF_CELLS_DDR3_VALUE, + &(ioregs_base->control_ddrio_0)); + writel(DDR_IO_1_VREF_CELLS_DDR3_VALUE, + &(ioregs_base->control_ddrio_1)); + writel(DDR_IO_2_VREF_CELLS_DDR3_VALUE, + &(ioregs_base->control_ddrio_2)); + + /* omap5432 does not use lpddr2 */ + writel(0x0, &(ioregs_base->control_lpddr2ch1_0)); + writel(0x0, &(ioregs_base->control_lpddr2ch1_1)); + + writel(SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES, + &(ioregs_base->control_emif1_sdram_config_ext)); + writel(SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES, + &(ioregs_base->control_emif2_sdram_config_ext)); + + /* Disable DLL select */ + io_settings = (readl(&(ioregs_base->control_port_emif1_sdram_config)) + & 0xFFEFFFFF); + writel(io_settings, + &(ioregs_base->control_port_emif1_sdram_config)); + + io_settings = (readl(&(ioregs_base->control_port_emif2_sdram_config)) + & 0xFFEFFFFF); + writel(io_settings, + &(ioregs_base->control_port_emif2_sdram_config)); +} + /* * Some tuning of IOs for optimal power and performance */ @@ -115,25 +190,10 @@ void do_io_settings(void) (sc_fast << 17) | (sc_fast << 14); writel(io_settings, &(ioregs_base->control_smart3io_padconf_1)); - /* LPDDR2 io settings */ - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, - &(ioregs_base->control_ddrch1_0)); - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, - &(ioregs_base->control_ddrch1_1)); - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, - &(ioregs_base->control_ddrch2_0)); - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, - &(ioregs_base->control_ddrch2_1)); - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN, - &(ioregs_base->control_lpddr2ch1_0)); - writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN, - &(ioregs_base->control_lpddr2ch1_1)); - writel(DDR_IO_0_DDR2_DQ_INT_EN_ALL_DDR3_CA_DIS_ALL, - &(ioregs_base->control_ddrio_0)); - writel(DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL, - &(ioregs_base->control_ddrio_1)); - writel(DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL, - &(ioregs_base->control_ddrio_2)); + if (omap_revision() <= OMAP5430_ES1_0) + io_settings_lpddr2(); + else + io_settings_ddr3(); /* Efuse settings */ writel(EFUSE_1, &(ioregs_base->control_efuse_1)); diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h index 94b6f3a89bd..7f05cb5b4a7 100644 --- a/arch/arm/include/asm/arch-omap5/omap.h +++ b/arch/arm/include/asm/arch-omap5/omap.h @@ -179,7 +179,14 @@ struct omap_sys_ctrl_regs { u32 control_srcomp_east_side; /*0x4A002E7C*/ u32 control_srcomp_west_side; /*0x4A002E80*/ u32 control_srcomp_code_latch; /*0x4A002E84*/ - u32 pad4[3680198]; + u32 pad4[3679394]; + u32 control_port_emif1_sdram_config; /*0x4AE0C110*/ + u32 control_port_emif1_lpddr2_nvm_config; /*0x4AE0C114*/ + u32 control_port_emif2_sdram_config; /*0x4AE0C118*/ + u32 pad5[10]; + u32 control_emif1_sdram_config_ext; /* 0x4AE0C144 */ + u32 control_emif2_sdram_config_ext; /* 0x4AE0C148 */ + u32 pad6[789]; u32 control_smart1nopmio_padconf_0; /* 0x4AE0CDA0 */ u32 control_smart1nopmio_padconf_1; /* 0x4AE0CDA4 */ u32 control_padconf_mode; /* 0x4AE0CDA8 */ @@ -234,6 +241,12 @@ struct omap_sys_ctrl_regs { #define DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL 0x8421084 #define DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL 0x8421000 +#define DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL 0x7C7C7C6C +#define DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL 0x64646464 +#define DDR_IO_0_VREF_CELLS_DDR3_VALUE 0xBAE8C631 +#define DDR_IO_1_VREF_CELLS_DDR3_VALUE 0xBC6318DC +#define DDR_IO_2_VREF_CELLS_DDR3_VALUE 0x0 + #define EFUSE_1 0x45145100 #define EFUSE_2 0x45145100 #define EFUSE_3 0x45145100 -- cgit v1.2.3 From 43037d76316db1a53be16a4c1ed97203257fa4ee Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:24 +0000 Subject: OMAP5: ADD precalculated timings for ddr3 Adding precalculated timings for ddr3 with 1cs adding required registers for ddr3 Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap4/sdram_elpida.c | 1 + arch/arm/cpu/armv7/omap5/sdram.c | 50 ++++++++++++++++++++++++++++++++- arch/arm/include/asm/emif.h | 5 ++++ 3 files changed, 55 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/arch/arm/cpu/armv7/omap4/sdram_elpida.c index b5389606b62..239ad2b07c5 100644 --- a/arch/arm/cpu/armv7/omap4/sdram_elpida.c +++ b/arch/arm/cpu/armv7/omap4/sdram_elpida.c @@ -92,6 +92,7 @@ const struct emif_regs emif_regs_elpida_400_mhz_2cs = { /* Dummy registers for OMAP44xx */ const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; +const u32 ddr3_ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { .dmm_lisa_map_0 = 0xFF020100, diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index 368b78bf498..817f933eda9 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -86,6 +86,29 @@ const struct emif_regs emif_regs_266_mhz_2cs = { .emif_ddr_ext_phy_ctrl_5 = 0x04010040 }; +const struct emif_regs emif_regs_ddr3_532_mhz_1cs = { + .sdram_config_init = 0x61851B32, + .sdram_config = 0x61851B32, + .ref_ctrl = 0x00001035, + .sdram_tim1 = 0xCCCF36B3, + .sdram_tim2 = 0x308F7FDA, + .sdram_tim3 = 0x027F88A8, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x0007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0020420A, + .emif_ddr_phy_ctlr_1 = 0x0024420A, + .emif_ddr_ext_phy_ctrl_1 = 0x04040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00000000, + .emif_ddr_ext_phy_ctrl_3 = 0x00000000, + .emif_ddr_ext_phy_ctrl_4 = 0x00000000, + .emif_ddr_ext_phy_ctrl_5 = 0x04010040, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x80000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x00000305 +}; + const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = { .dmm_lisa_map_0 = 0x0, .dmm_lisa_map_1 = 0x0, @@ -115,9 +138,34 @@ const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = { 0x00000077 }; +const u32 ddr3_ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = { + 0x01004010, + 0x00001004, + 0x04010040, + 0x01004010, + 0x00001004, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80080080, + 0x00800800, + 0x08102040, + 0x00000002, + 0x0, + 0x0, + 0x0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000057 +}; + static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) { - *regs = &emif_regs_532_mhz_2cs; + if (omap_revision() == OMAP5432_ES1_0) + *regs = &emif_regs_ddr3_532_mhz_1cs; + else + *regs = &emif_regs_532_mhz_2cs; } void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) __attribute__((weak, alias("emif_get_reg_dump_sdp"))); diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index f1e3ad212eb..5d2649e121b 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -650,6 +650,7 @@ struct dmm_lisa_map_regs { }; extern const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; +extern const u32 ddr3_ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; #define CS0 0 #define CS1 1 @@ -1073,6 +1074,10 @@ struct emif_regs { u32 emif_ddr_ext_phy_ctrl_3; u32 emif_ddr_ext_phy_ctrl_4; u32 emif_ddr_ext_phy_ctrl_5; + u32 emif_rd_wr_lvl_rmp_win; + u32 emif_rd_wr_lvl_rmp_ctl; + u32 emif_rd_wr_lvl_ctl; + u32 emif_rd_wr_exec_thresh; }; /* assert macros */ -- cgit v1.2.3 From 784ab7c545d25288a82216d18e2b0ca3beae470b Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:25 +0000 Subject: OMAP5: EMIF: Add support for DDR3 device In OMAP5432 EMIF controlller supports DDR3 device. This patch adds support for ddr3 device intialization and configuration. Initialization sequence is done as specified in JEDEC specs. This also adds support for ddr3 leveling. Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap-common/emif-common.c | 105 ++++++++++++++++++++++++++- arch/arm/cpu/armv7/omap4/hwinit.c | 5 ++ arch/arm/cpu/armv7/omap5/hwinit.c | 15 ++++ arch/arm/include/asm/emif.h | 45 +++++++++++- 4 files changed, 166 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 389feda7166..846511d03bd 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -190,7 +190,7 @@ void emif_update_timings(u32 base, const struct emif_regs *regs) writel(regs->temp_alert_config, &emif->emif_temp_alert_config); writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw); - if (omap_revision() == OMAP5430_ES1_0) { + if (omap_revision() >= OMAP5430_ES1_0) { writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, &emif->emif_l3_config); } else if (omap_revision() >= OMAP4460_ES1_0) { @@ -202,6 +202,101 @@ void emif_update_timings(u32 base, const struct emif_regs *regs) } } +static void ddr3_leveling(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + /* keep sdram in self-refresh */ + writel(((LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT) + & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl); + __udelay(130); + + /* + * Set invert_clkout (if activated)--DDR_PHYCTRL_1 + * Invert clock adds an additional half cycle delay on the command + * interface. The additional half cycle, is usually meant to enable + * leveling in the situation that DQS is later than CK on the board.It + * also helps provide some additional margin for leveling. + */ + writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1); + writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw); + __udelay(130); + + writel(((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT) + & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl); + + /* Launch Full leveling */ + writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl); + + /* Wait till full leveling is complete */ + readl(&emif->emif_rd_wr_lvl_ctl); + __udelay(130); + + /* Read data eye leveling no of samples */ + config_data_eye_leveling_samples(base); + + /* Launch 8 incremental WR_LVL- to compensate for PHY limitation */ + writel(0x2 << EMIF_REG_WRLVLINC_INT_SHIFT, &emif->emif_rd_wr_lvl_ctl); + __udelay(130); + + /* Launch Incremental leveling */ + writel(DDR3_INC_LVL, &emif->emif_rd_wr_lvl_ctl); + __udelay(130); +} + +static void ddr3_init(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + u32 *ext_phy_ctrl_base = 0; + u32 *emif_ext_phy_ctrl_base = 0; + u32 i = 0; + + /* + * Set SDRAM_CONFIG and PHY control registers to locked frequency + * and RL =7. As the default values of the Mode Registers are not + * defined, contents of mode Registers must be fully initialized. + * H/W takes care of this initialization + */ + writel(regs->sdram_config_init, &emif->emif_sdram_config); + + writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1); + + /* Update timing registers */ + writel(regs->sdram_tim1, &emif->emif_sdram_tim_1); + writel(regs->sdram_tim2, &emif->emif_sdram_tim_2); + writel(regs->sdram_tim3, &emif->emif_sdram_tim_3); + + writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl); + writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl); + + ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1); + emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1); + + /* Configure external phy control timing registers */ + for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { + writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); + } + + /* + * external phy 6-24 registers do not change with + * ddr frequency + */ + for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) { + writel(ddr3_ext_phy_ctrl_const_base[i], + emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(ddr3_ext_phy_ctrl_const_base[i], + emif_ext_phy_ctrl_base++); + } + + /* enable leveling */ + writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl); + + ddr3_leveling(base, regs); +} + #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS #define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) @@ -975,8 +1070,12 @@ static void do_sdram_init(u32 base) * Changing the timing registers in EMIF can happen(going from one * OPP to another) */ - if (!in_sdram) - lpddr2_init(base, regs); + if (!in_sdram) { + if (omap_revision() != OMAP5432_ES1_0) + lpddr2_init(base, regs); + else + ddr3_init(base, regs); + } /* Write to the shadow registers */ emif_update_timings(base, regs); diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c index 187e93887b6..2c34e48f428 100644 --- a/arch/arm/cpu/armv7/omap4/hwinit.c +++ b/arch/arm/cpu/armv7/omap4/hwinit.c @@ -118,6 +118,11 @@ void do_io_settings(void) } #endif +/* dummy fuction for omap4 */ +void config_data_eye_leveling_samples(u32 emif_base) +{ +} + void init_omap_revision(void) { /* diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c index df0b76050db..d0c3ff70218 100644 --- a/arch/arm/cpu/armv7/omap5/hwinit.c +++ b/arch/arm/cpu/armv7/omap5/hwinit.c @@ -35,6 +35,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -203,6 +204,20 @@ void do_io_settings(void) } #endif +void config_data_eye_leveling_samples(u32 emif_base) +{ + struct omap_sys_ctrl_regs *ioregs_base = + (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; + + /*EMIF_SDRAM_CONFIG_EXT-Read data eye leveling no of samples =4*/ + if (emif_base == EMIF1_BASE) + writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES, + &(ioregs_base->control_emif1_sdram_config_ext)); + else if (emif_base == EMIF2_BASE) + writel(SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES, + &(ioregs_base->control_emif2_sdram_config_ext)); +} + void init_omap_revision(void) { /* diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index 5d2649e121b..c2ad877ab24 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -471,6 +471,49 @@ #define EMIF_REG_DDR_PHY_CTRL_2_SHIFT 0 #define EMIF_REG_DDR_PHY_CTRL_2_MASK (0xffffffff << 0) +/*EMIF_READ_WRITE_LEVELING_CONTROL*/ +#define EMIF_REG_RDWRLVLFULL_START_SHIFT 31 +#define EMIF_REG_RDWRLVLFULL_START_MASK (1 << 31) +#define EMIF_REG_RDWRLVLINC_PRE_SHIFT 24 +#define EMIF_REG_RDWRLVLINC_PRE_MASK (0x7F << 24) +#define EMIF_REG_RDLVLINC_INT_SHIFT 16 +#define EMIF_REG_RDLVLINC_INT_MASK (0xFF << 16) +#define EMIF_REG_RDLVLGATEINC_INT_SHIFT 8 +#define EMIF_REG_RDLVLGATEINC_INT_MASK (0xFF << 8) +#define EMIF_REG_WRLVLINC_INT_SHIFT 0 +#define EMIF_REG_WRLVLINC_INT_MASK (0xFF << 0) + +/*EMIF_READ_WRITE_LEVELING_RAMP_CONTROL*/ +#define EMIF_REG_RDWRLVL_EN_SHIFT 31 +#define EMIF_REG_RDWRLVL_EN_MASK (1 << 31) +#define EMIF_REG_RDWRLVLINC_RMP_PRE_SHIFT 24 +#define EMIF_REG_RDWRLVLINC_RMP_PRE_MASK (0x7F << 24) +#define EMIF_REG_RDLVLINC_RMP_INT_SHIFT 16 +#define EMIF_REG_RDLVLINC_RMP_INT_MASK (0xFF << 16) +#define EMIF_REG_RDLVLGATEINC_RMP_INT_SHIFT 8 +#define EMIF_REG_RDLVLGATEINC_RMP_INT_MASK (0xFF << 8) +#define EMIF_REG_WRLVLINC_RMP_INT_SHIFT 0 +#define EMIF_REG_WRLVLINC_RMP_INT_MASK (0xFF << 0) + +/*EMIF_READ_WRITE_LEVELING_RAMP_WINDOW*/ +#define EMIF_REG_RDWRLVLINC_RMP_WIN_SHIFT 0 +#define EMIF_REG_RDWRLVLINC_RMP_WIN_MASK (0x1FFF << 0) + +/*Leveling Fields */ +#define DDR3_WR_LVL_INT 0x73 +#define DDR3_RD_LVL_INT 0x33 +#define DDR3_RD_LVL_GATE_INT 0x59 +#define RD_RW_LVL_INC_PRE 0x0 +#define DDR3_FULL_LVL (1 << EMIF_REG_RDWRLVL_EN_SHIFT) + +#define DDR3_INC_LVL ((DDR3_WR_LVL_INT << EMIF_REG_WRLVLINC_INT_SHIFT) \ + | (DDR3_RD_LVL_GATE_INT << EMIF_REG_RDLVLGATEINC_INT_SHIFT) \ + | (DDR3_RD_LVL_INT << EMIF_REG_RDLVLINC_RMP_INT_SHIFT) \ + | (RD_RW_LVL_INC_PRE << EMIF_REG_RDWRLVLINC_RMP_PRE_SHIFT)) + +#define SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES 0x0000C1A7 +#define SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES 0x000001A7 + /* DMM */ #define DMM_BASE 0x4E000040 @@ -1104,5 +1147,5 @@ extern u32 *const T_den; extern u32 *const emif_sizes; #endif - +void config_data_eye_leveling_samples(u32 emif_base); #endif -- cgit v1.2.3 From 753bae8c5dd4ba92a39b06ea9a551be962053f93 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:26 +0000 Subject: OMAP5: DPLL core lock for OMAP5432 No need to Unlock DPLL initially. DDR3 can work at normal OPP from initialozation Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap-common/clocks-common.c | 8 ++++++-- arch/arm/cpu/armv7/omap-common/emif-common.c | 13 +++++++++---- arch/arm/include/asm/arch-omap4/clocks.h | 5 +++++ arch/arm/include/asm/arch-omap5/clocks.h | 5 +++++ 4 files changed, 25 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index 10d286a6d4d..b1fd277d6d5 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -299,8 +299,12 @@ static void setup_dplls(void) * Core DPLL will be locked after setting up EMIF * using the FREQ_UPDATE method(freq_update_core()) */ - do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK, - "core"); + if (omap_revision() != OMAP5432_ES1_0) + do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, + DPLL_NO_LOCK, "core"); + else + do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, + DPLL_LOCK, "core"); /* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */ temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) | (CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) | diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 846511d03bd..23cf6199eb7 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -1232,6 +1232,7 @@ void dmm_init(u32 base) void sdram_init(void) { u32 in_sdram, size_prog, size_detect; + u32 omap_rev = omap_revision(); debug(">>sdram_init()\n"); @@ -1241,9 +1242,12 @@ void sdram_init(void) in_sdram = running_from_sdram(); debug("in_sdram = %d\n", in_sdram); - if (!in_sdram) - bypass_dpll(&prcm->cm_clkmode_dpll_core); - + if (!in_sdram) { + if (omap_rev != OMAP5432_ES1_0) + bypass_dpll(&prcm->cm_clkmode_dpll_core); + else + writel(CM_DLL_CTRL_NO_OVERRIDE, &prcm->cm_dll_ctrl); + } do_sdram_init(EMIF1_BASE); do_sdram_init(EMIF2_BASE); @@ -1255,7 +1259,8 @@ void sdram_init(void) } /* for the shadow registers to take effect */ - freq_update_core(); + if (omap_rev != OMAP5432_ES1_0) + freq_update_core(); /* Do some testing after the init */ if (!in_sdram) { diff --git a/arch/arm/include/asm/arch-omap4/clocks.h b/arch/arm/include/asm/arch-omap4/clocks.h index 617729c32b7..be20fc0ce66 100644 --- a/arch/arm/include/asm/arch-omap4/clocks.h +++ b/arch/arm/include/asm/arch-omap4/clocks.h @@ -525,6 +525,11 @@ struct omap4_scrm_regs { #define DPLL_CLKOUT_DIV_MASK 0x1F /* post-divider mask */ +/* CM_DLL_CTRL */ +#define CM_DLL_CTRL_OVERRIDE_SHIFT 0 +#define CM_DLL_CTRL_OVERRIDE_MASK (1 << 0) +#define CM_DLL_CTRL_NO_OVERRIDE 0 + /* CM_CLKMODE_DPLL */ #define CM_CLKMODE_DPLL_REGM4XEN_SHIFT 11 #define CM_CLKMODE_DPLL_REGM4XEN_MASK (1 << 11) diff --git a/arch/arm/include/asm/arch-omap5/clocks.h b/arch/arm/include/asm/arch-omap5/clocks.h index f32cf3eeef7..409e0e3f8c1 100644 --- a/arch/arm/include/asm/arch-omap5/clocks.h +++ b/arch/arm/include/asm/arch-omap5/clocks.h @@ -490,6 +490,11 @@ struct omap5_prcm_regs { #define DPLL_CLKOUT_DIV_MASK 0x1F /* post-divider mask */ +/* CM_DLL_CTRL */ +#define CM_DLL_CTRL_OVERRIDE_SHIFT 0 +#define CM_DLL_CTRL_OVERRIDE_MASK (1 << 0) +#define CM_DLL_CTRL_NO_OVERRIDE 0 + /* CM_CLKMODE_DPLL */ #define CM_CLKMODE_DPLL_REGM4XEN_SHIFT 11 #define CM_CLKMODE_DPLL_REGM4XEN_MASK (1 << 11) -- cgit v1.2.3 From 7fd5b9bfe4a66a0eec232ab36ddafdd823e263c2 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 22 May 2012 00:03:27 +0000 Subject: OMAP5: Change voltages for omap5432 Change voltages for OMAP5432 Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap5/clocks.c | 31 +++++++++++++++++++++---------- arch/arm/include/asm/arch-omap5/clocks.h | 10 ++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap5/clocks.c b/arch/arm/cpu/armv7/omap5/clocks.c index 1a59f265f7b..65dc5c75953 100644 --- a/arch/arm/cpu/armv7/omap5/clocks.c +++ b/arch/arm/cpu/armv7/omap5/clocks.c @@ -260,20 +260,31 @@ const struct dpll_params *get_abe_dpll_params(void) */ void scale_vcores(void) { - u32 volt; + u32 volt_core, volt_mpu, volt_mm; omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ); /* Palmas settings */ - volt = VDD_CORE; - do_scale_vcore(SMPS_REG_ADDR_8_CORE, volt); - - volt = VDD_MPU; - do_scale_vcore(SMPS_REG_ADDR_12_MPU, volt); - - volt = VDD_MM; - do_scale_vcore(SMPS_REG_ADDR_45_IVA, volt); - + if (omap_revision() != OMAP5432_ES1_0) { + volt_core = VDD_CORE; + volt_mpu = VDD_MPU; + volt_mm = VDD_MM; + } else { + volt_core = VDD_CORE_5432; + volt_mpu = VDD_MPU_5432; + volt_mm = VDD_MM_5432; + } + + do_scale_vcore(SMPS_REG_ADDR_8_CORE, volt_core); + do_scale_vcore(SMPS_REG_ADDR_12_MPU, volt_mpu); + do_scale_vcore(SMPS_REG_ADDR_45_IVA, volt_mm); + + if (omap_revision() == OMAP5432_ES1_0) { + /* Configure LDO SRAM "magic" bits */ + writel(2, &prcm->prm_sldo_core_setup); + writel(2, &prcm->prm_sldo_mpu_setup); + writel(2, &prcm->prm_sldo_mm_setup); + } } u32 get_offset_code(u32 volt_offset) diff --git a/arch/arm/include/asm/arch-omap5/clocks.h b/arch/arm/include/asm/arch-omap5/clocks.h index 409e0e3f8c1..5f1a7aa770d 100644 --- a/arch/arm/include/asm/arch-omap5/clocks.h +++ b/arch/arm/include/asm/arch-omap5/clocks.h @@ -480,6 +480,13 @@ struct omap5_prcm_regs { u32 pad217[4]; u32 prm_vc_cfg_i2c_mode; /* 4ae07bb4 */ u32 prm_vc_cfg_i2c_clk; /* 4ae07bb8 */ + u32 pad218[2]; + u32 prm_sldo_core_setup; /* 4ae07bc4 */ + u32 prm_sldo_core_ctrl; /* 4ae07bc8 */ + u32 prm_sldo_mpu_setup; /* 4ae07bcc */ + u32 prm_sldo_mpu_ctrl; /* 4ae07bd0 */ + u32 prm_sldo_mm_setup; /* 4ae07bd4 */ + u32 prm_sldo_mm_ctrl; /* 4ae07bd8 */ }; /* DPLL register offsets */ @@ -646,6 +653,9 @@ struct omap5_prcm_regs { #define VDD_MPU 1000 #define VDD_MM 1000 #define VDD_CORE 1040 +#define VDD_MPU_5432 1150 +#define VDD_MM_5432 1150 +#define VDD_CORE_5432 1150 /* Standard offset is 0.5v expressed in uv */ #define PALMAS_SMPS_BASE_VOLT_UV 500000 -- cgit v1.2.3 From e423a8f76d8dac55d067fd4c0eea8f18fb8929dc Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Thu, 24 May 2012 00:30:25 +0000 Subject: ARM: OMAP4: Correct the lpddr2 io settings register value. To meet certain timing requirements on the lpddr2 cmd and data phy interfaces ,lpddr iopads have to be configured as differential buffers and a Vref has to be internally generated and provided to these buffers. Correcting the above settings here. Signed-off-by: R Sricharan --- arch/arm/include/asm/arch-omap4/omap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-omap4/omap.h b/arch/arm/include/asm/arch-omap4/omap.h index 47c5883025c..03bd9231450 100644 --- a/arch/arm/include/asm/arch-omap4/omap.h +++ b/arch/arm/include/asm/arch-omap4/omap.h @@ -112,7 +112,7 @@ #define CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER 0x9E9E9E9E #define CONTROL_LPDDR2IO_SLEW_315PS_DRV12_PULL_DOWN 0x7C7C7C7C #define LPDDR2IO_GR10_WD_MASK (3 << 17) -#define CONTROL_LPDDR2IO_3_VAL 0xA0888C00 +#define CONTROL_LPDDR2IO_3_VAL 0xA0888C0F /* CONTROL_EFUSE_2 */ #define CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1 0x00ffc000 -- cgit v1.2.3 From 7775831dd39ba3cadefd3158ee84aa619873b759 Mon Sep 17 00:00:00 2001 From: Minkyu Kang Date: Thu, 26 Apr 2012 15:48:32 +0900 Subject: Exynos: fix cpuinfo and cpu detecting Since Exynos architecture have new SoCs, need to fix cpuinfo correctly. Signed-off-by: Minkyu Kang Signed-off-by: Kyungmin Park Tested-by: Jaehoon Chung Cc: Chander Kashyap --- arch/arm/cpu/armv7/s5p-common/cpu_info.c | 5 ++-- arch/arm/include/asm/arch-exynos/cpu.h | 42 +++++++++++++++++++++----------- arch/arm/include/asm/arch-s5pc1xx/cpu.h | 6 +++++ 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/s5p-common/cpu_info.c b/arch/arm/cpu/armv7/s5p-common/cpu_info.c index 527f32deefc..16427333ac0 100644 --- a/arch/arm/cpu/armv7/s5p-common/cpu_info.c +++ b/arch/arm/cpu/armv7/s5p-common/cpu_info.c @@ -48,8 +48,9 @@ int print_cpuinfo(void) { char buf[32]; - printf("CPU:\tS5P%X@%sMHz\n", - s5p_cpu_id, strmhz(buf, get_arm_clk())); + printf("CPU:\t%s%X@%sMHz\n", + s5p_get_cpu_name(), s5p_cpu_id, + strmhz(buf, get_arm_clk())); return 0; } diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index ac4ddc7354f..b1e22f2c151 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -24,6 +24,7 @@ #define DEVICE_NOT_AVAILABLE 0 +#define EXYNOS_CPU_NAME "Exynos" #define EXYNOS4_ADDR_BASE 0x10000000 /* EXYNOS4 */ @@ -93,29 +94,42 @@ static inline int s5p_get_cpu_rev(void) static inline void s5p_set_cpu_id(void) { - s5p_cpu_id = readl(EXYNOS4_PRO_ID); - s5p_cpu_id = (0xC000 | ((s5p_cpu_id & 0x00FFF000) >> 12)); - - /* - * 0xC200: EXYNOS4210 EVT0 - * 0xC210: EXYNOS4210 EVT1 - */ - if (s5p_cpu_id == 0xC200) { - s5p_cpu_id |= 0x10; + unsigned int pro_id = (readl(EXYNOS4_PRO_ID) & 0x00FFF000) >> 12; + + switch (pro_id) { + case 0x200: + /* Exynos4210 EVT0 */ + s5p_cpu_id = 0x4210; s5p_cpu_rev = 0; - } else if (s5p_cpu_id == 0xC210) { - s5p_cpu_rev = 1; + break; + case 0x210: + /* Exynos4210 EVT1 */ + s5p_cpu_id = 0x4210; + break; + case 0x412: + /* Exynos4412 */ + s5p_cpu_id = 0x4412; + break; + case 0x520: + /* Exynos5250 */ + s5p_cpu_id = 0x5250; + break; } } +static inline char *s5p_get_cpu_name(void) +{ + return EXYNOS_CPU_NAME; +} + #define IS_SAMSUNG_TYPE(type, id) \ static inline int cpu_is_##type(void) \ { \ - return s5p_cpu_id == id ? 1 : 0; \ + return (s5p_cpu_id >> 12) == id; \ } -IS_SAMSUNG_TYPE(exynos4, 0xc210) -IS_SAMSUNG_TYPE(exynos5, 0xc520) +IS_SAMSUNG_TYPE(exynos4, 0x4) +IS_SAMSUNG_TYPE(exynos5, 0x5) #define SAMSUNG_BASE(device, base) \ static inline unsigned int samsung_get_base_##device(void) \ diff --git a/arch/arm/include/asm/arch-s5pc1xx/cpu.h b/arch/arm/include/asm/arch-s5pc1xx/cpu.h index 510ead4d993..2362b9985b7 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/cpu.h +++ b/arch/arm/include/asm/arch-s5pc1xx/cpu.h @@ -23,6 +23,7 @@ #ifndef _S5PC1XX_CPU_H #define _S5PC1XX_CPU_H +#define S5P_CPU_NAME "S5P" #define S5PC1XX_ADDR_BASE 0xE0000000 /* S5PC100 */ @@ -71,6 +72,11 @@ static inline void s5p_set_cpu_id(void) s5p_cpu_id = 0xC000 | ((s5p_cpu_id & 0x00FFF000) >> 12); } +static inline char *s5p_get_cpu_name(void) +{ + return S5P_CPU_NAME; +} + #define IS_SAMSUNG_TYPE(type, id) \ static inline int cpu_is_##type(void) \ { \ -- cgit v1.2.3 From c5e3710a185d821c3c68ae92f932a7a9956522bd Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 6 Jun 2012 19:54:29 +0000 Subject: EXYNOS5: PINMUX: Added default pinumx settings This patch performs the pinmux configuration in a common file. As of now only EXYNOS5 pinmux for SDMMC, UART and Ethernet is supported. Signed-off-by: Abhilash Kesavan Signed-off-by: Che-Liang Chiou Signed-off-by: Rajeshwari Shinde Acked-by: Chander Kashyap Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/Makefile | 2 +- arch/arm/cpu/armv7/exynos/pinmux.c | 220 ++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/periph.h | 47 +++++++ arch/arm/include/asm/arch-exynos/pinmux.h | 58 ++++++++ 4 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/exynos/pinmux.c create mode 100644 arch/arm/include/asm/arch-exynos/periph.h create mode 100644 arch/arm/include/asm/arch-exynos/pinmux.h (limited to 'arch') diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index 90ec2bd4048..9119961d95d 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -22,7 +22,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS += clock.o power.o soc.o system.o +COBJS += clock.o power.o soc.o system.o pinmux.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c new file mode 100644 index 00000000000..d2b7d2cba7f --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2012 Samsung Electronics. + * Abhilash Kesavan + * + * 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 +#include +#include +#include + +static void exynos5_uart_config(int peripheral) +{ + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + struct s5p_gpio_bank *bank; + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + bank = &gpio1->a0; + start = 0; + count = 4; + break; + case PERIPH_ID_UART1: + bank = &gpio1->a0; + start = 4; + count = 4; + break; + case PERIPH_ID_UART2: + bank = &gpio1->a1; + start = 0; + count = 4; + break; + case PERIPH_ID_UART3: + bank = &gpio1->a1; + start = 4; + count = 2; + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + } +} + +static int exynos5_mmc_config(int peripheral, int flags) +{ + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + struct s5p_gpio_bank *bank, *bank_ext; + int i; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + bank = &gpio1->c0; + bank_ext = &gpio1->c1; + break; + case PERIPH_ID_SDMMC1: + bank = &gpio1->c1; + bank_ext = NULL; + break; + case PERIPH_ID_SDMMC2: + bank = &gpio1->c2; + bank_ext = &gpio1->c3; + break; + case PERIPH_ID_SDMMC3: + bank = &gpio1->c3; + bank_ext = NULL; + break; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = 3; i <= 6; i++) { + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); + } + } + for (i = 0; i < 2; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + for (i = 3; i <= 6; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + return 0; +} + +static void exynos5_sromc_config(int flags) +{ + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + int i; + + /* + * SROM:CS1 and EBI + * + * GPY0[0] SROM_CSn[0] + * GPY0[1] SROM_CSn[1](2) + * GPY0[2] SROM_CSn[2] + * GPY0[3] SROM_CSn[3] + * GPY0[4] EBI_OEn(2) + * GPY0[5] EBI_EEn(2) + * + * GPY1[0] EBI_BEn[0](2) + * GPY1[1] EBI_BEn[1](2) + * GPY1[2] SROM_WAIT(2) + * GPY1[3] EBI_DATA_RDn(2) + */ + s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK), + GPIO_FUNC(2)); + s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2)); + s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2)); + + for (i = 0; i < 4; i++) + s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2)); + + /* + * EBI: 8 Addrss Lines + * + * GPY3[0] EBI_ADDR[0](2) + * GPY3[1] EBI_ADDR[1](2) + * GPY3[2] EBI_ADDR[2](2) + * GPY3[3] EBI_ADDR[3](2) + * GPY3[4] EBI_ADDR[4](2) + * GPY3[5] EBI_ADDR[5](2) + * GPY3[6] EBI_ADDR[6](2) + * GPY3[7] EBI_ADDR[7](2) + * + * EBI: 16 Data Lines + * + * GPY5[0] EBI_DATA[0](2) + * GPY5[1] EBI_DATA[1](2) + * GPY5[2] EBI_DATA[2](2) + * GPY5[3] EBI_DATA[3](2) + * GPY5[4] EBI_DATA[4](2) + * GPY5[5] EBI_DATA[5](2) + * GPY5[6] EBI_DATA[6](2) + * GPY5[7] EBI_DATA[7](2) + * + * GPY6[0] EBI_DATA[8](2) + * GPY6[1] EBI_DATA[9](2) + * GPY6[2] EBI_DATA[10](2) + * GPY6[3] EBI_DATA[11](2) + * GPY6[4] EBI_DATA[12](2) + * GPY6[5] EBI_DATA[13](2) + * GPY6[6] EBI_DATA[14](2) + * GPY6[7] EBI_DATA[15](2) + */ + for (i = 0; i < 8; i++) { + s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2)); + s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP); + + s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2)); + s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP); + + s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2)); + s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP); + } +} + +static int exynos5_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos5_uart_config(peripheral); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + return exynos5_mmc_config(peripheral, flags); + case PERIPH_ID_SROMC: + exynos5_sromc_config(flags); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +int exynos_pinmux_config(int peripheral, int flags) +{ + if (cpu_is_exynos5()) + return exynos5_pinmux_config(peripheral, flags); + else { + debug("pinmux functionality not supported\n"); + return -1; + } +} diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h new file mode 100644 index 00000000000..5db25aa88a7 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Rajeshwari Shinde + * + * 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 __ASM_ARM_ARCH_PERIPH_H +#define __ASM_ARM_ARCH_PERIPH_H + +/* + * Peripherals requiring clock/pinmux configuration. List will + * grow with support for more devices getting added. + * + */ +enum periph_id { + PERIPH_ID_SDMMC0, + PERIPH_ID_SDMMC1, + PERIPH_ID_SDMMC2, + PERIPH_ID_SDMMC3, + PERIPH_ID_SROMC, + PERIPH_ID_UART0, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + + PERIPH_ID_COUNT, + PERIPH_ID_NONE = -1, +}; + +#endif /* __ASM_ARM_ARCH_PERIPH_H */ diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h new file mode 100644 index 00000000000..10ea736c7dd --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Abhilash Kesavan + * + * 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 __ASM_ARM_ARCH_PINMUX_H +#define __ASM_ARM_ARCH_PINMUX_H + +#include "periph.h" + +/* + * Flags for setting specific configarations of peripherals. + * List will grow with support for more devices getting added. + */ +enum { + PINMUX_FLAG_NONE = 0x00000000, + + /* Flags for eMMC */ + PINMUX_FLAG_8BIT_MODE = 1 << 0, /* SDMMC 8-bit mode */ + + /* Flags for SROM controller */ + PINMUX_FLAG_BANK = 3 << 0, /* bank number (0-3) */ + PINMUX_FLAG_16BIT = 1 << 2, /* 16-bit width */ +}; + +/** + * Configures the pinmux for a particular peripheral. + * + * Each gpio can be configured in many different ways (4 bits on exynos) + * such as "input", "output", "special function", "external interrupt" + * etc. This function will configure the peripheral pinmux along with + * pull-up/down and drive strength. + * + * @param peripheral peripheral to be configured + * @param flags configure flags + * @return 0 if ok, -1 on error (e.g. unsupported peripheral) + */ +int exynos_pinmux_config(int peripheral, int flags); + +#endif -- cgit v1.2.3 From 0d952e5d2eef9320338a87007959ce0d80a264e3 Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Wed, 11 Apr 2012 01:18:02 +0000 Subject: i.mx: i.mx6x: NO_MUX_I/NO_PAD_I not set correctly If one PAD does not have mux or pad config register, we need set the NO_MUX_I/NO_PAD_I to 0, the old value is not correct Signed-off-by: Jason Liu CC: Stefano Babic Acked-by: Stefano Babic --- arch/arm/include/asm/arch-mx6/mx6x_pins.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-mx6/mx6x_pins.h b/arch/arm/include/asm/arch-mx6/mx6x_pins.h index afaa068bb93..9979651b0f2 100644 --- a/arch/arm/include/asm/arch-mx6/mx6x_pins.h +++ b/arch/arm/include/asm/arch-mx6/mx6x_pins.h @@ -48,8 +48,8 @@ #define PAD_CTL_SRE_FAST (1 << 0) #define PAD_CTL_SRE_SLOW (0 << 0) -#define NO_MUX_I 0x3FF -#define NO_PAD_I 0x7FF +#define NO_MUX_I 0 +#define NO_PAD_I 0 enum { MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 = IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, 0), -- cgit v1.2.3 From 3f5f200bbe9aee283b88a2647763b1f97abb96ac Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 11 May 2012 14:39:11 +0000 Subject: mx53: Fix mask for SATA reference clock SATA_ALT_REF_CLK field corresponds to bits 1 and 2 of offset 0x180c. Fix the mask for these bits. Signed-off-by: Fabio Estevam --- arch/arm/cpu/armv7/mx5/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c index fc2406bcad7..64862b31f1f 100644 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -843,7 +843,7 @@ void mxc_set_sata_internal_clock(void) set_usb_phy1_clk(); - writel((readl(tmp_base) & (~0x7)) | 0x4, tmp_base); + writel((readl(tmp_base) & (~0x6)) | 0x4, tmp_base); } #endif -- cgit v1.2.3 From 8b8d81047df5ac005adf4f5ed7db637d6bfb196c Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Fri, 11 May 2012 05:37:59 +0000 Subject: MX28: Fix a typo in mx28_reg_8 macro The macro mistakenly referred to 32bit struct instead of 8bit one. Signed-off-by: Otavio Salvador Cc: Fabio Estevam Cc: Marek Vasut Acked-by: Marek Vasut --- arch/arm/include/asm/arch-mx28/regs-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-mx28/regs-common.h b/arch/arm/include/asm/arch-mx28/regs-common.h index 94b512d18ac..d2e19538af2 100644 --- a/arch/arm/include/asm/arch-mx28/regs-common.h +++ b/arch/arm/include/asm/arch-mx28/regs-common.h @@ -70,7 +70,7 @@ struct mx28_register_32 { #define mx28_reg_8(name) \ union { \ struct { __mx28_reg_8(name) }; \ - struct mx28_register_32 name##_reg; \ + struct mx28_register_8 name##_reg; \ }; #define mx28_reg_32(name) \ -- cgit v1.2.3 From e3ddc646031551627c4eeae4598f8862251a3f94 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 29 May 2012 19:43:13 +0000 Subject: i.MX28: Add function to adjust memory parameters This function can be overridden at run-time and allows implementors of new boards based on the i.MX28 chip to fine-tune the memory params. It is possible to write into the dram_vals array because when the SPL runs, it is located SRAM. Therefore the location is writable. There is no possibility of these data to be read-only. Signed-off-by: Marek Vasut Cc: Wolfgang Denk Cc: Detlev Zundel Cc: Stefano Babic Cc: Fabio Estevam --- arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c index 9fa5d29e6c7..e17a4d7c7fb 100644 --- a/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c @@ -82,10 +82,18 @@ uint32_t dram_vals[] = { 0x00000000, 0x00010001 }; +void __mx28_adjust_memory_params(uint32_t *dram_vals) +{ +} +void mx28_adjust_memory_params(uint32_t *dram_vals) + __attribute__((weak, alias("__mx28_adjust_memory_params"))); + void init_m28_200mhz_ddr2(void) { int i; + mx28_adjust_memory_params(dram_vals); + for (i = 0; i < ARRAY_SIZE(dram_vals); i++) writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); } -- cgit v1.2.3 From 5c23712dbdeeaef84ee28a18dc23abd479a95ede Mon Sep 17 00:00:00 2001 From: Michael Langer Date: Thu, 14 Jun 2012 03:44:33 +0000 Subject: i.MX6 USDHC: Use the ESDHC clock The commit "i.mx: fsl_esdhc: add the i.mx6q support" (4692708d) introduces support for the i.MX6Q MMC host controller USDHC. MXC_IPG_PERCLK sets the clock to 66MHz. This seems to be the default clock of the ESDHC IP found in < i.MX6 silicon. However, the default clock for the USDHC IP found in i.MX6 is 200MHz (MXC_ESDHC_CLK). This difference will cause a 3 times higher clock on SD_CLK than expected (see fsl_esdh.c -> set_sysctl()). Signed-off-by: Michael Langer CC: Stefano Babic CC: Jason Liu Acked-by: Stefano Babic --- arch/arm/cpu/armv7/imx-common/speed.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/imx-common/speed.c b/arch/arm/cpu/armv7/imx-common/speed.c index 2187e8ee5de..80989c49837 100644 --- a/arch/arm/cpu/armv7/imx-common/speed.c +++ b/arch/arm/cpu/armv7/imx-common/speed.c @@ -35,7 +35,11 @@ DECLARE_GLOBAL_DATA_PTR; int get_clocks(void) { #ifdef CONFIG_FSL_ESDHC +#ifdef CONFIG_FSL_USDHC + gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); +#else gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); +#endif #endif return 0; } -- cgit v1.2.3 From 2b3b1c668be539d897d2a9352bc8dca54467f425 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Sun, 20 May 2012 15:50:00 +0000 Subject: ATMEL/PIO: Enable new feature of PIO on Atmel device Enable new PIO feature supported by Atmel SoC. Using CPU_HAS_PIO3 micro to enable PIO new feature. Signed-off-by: Bo Shen Signed-off-by: Andreas Bießmann --- arch/arm/include/asm/arch-at91/at91_pio.h | 45 ++++++++++- drivers/gpio/at91_gpio.c | 125 +++++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-at91/at91_pio.h b/arch/arm/include/asm/arch-at91/at91_pio.h index 416cabf87c1..0483c9820e5 100644 --- a/arch/arm/include/asm/arch-at91/at91_pio.h +++ b/arch/arm/include/asm/arch-at91/at91_pio.h @@ -66,14 +66,50 @@ typedef struct at91_port { u32 puer; /* 0x64 Pull-up Enable Register */ u32 pusr; /* 0x68 Pad Pull-up Status Register */ u32 reserved4; +#if defined(CPU_HAS_PIO3) + u32 abcdsr1; /* 0x70 Peripheral ABCD Select Register 1 */ + u32 abcdsr2; /* 0x74 Peripheral ABCD Select Register 2 */ + u32 reserved5[2]; + u32 ifscdr; /* 0x80 Input Filter SCLK Disable Register */ + u32 ifscer; /* 0x84 Input Filter SCLK Enable Register */ + u32 ifscsr; /* 0x88 Input Filter SCLK Status Register */ + u32 scdr; /* 0x8C SCLK Divider Debouncing Register */ + u32 ppddr; /* 0x90 Pad Pull-down Disable Register */ + u32 ppder; /* 0x94 Pad Pull-down Enable Register */ + u32 ppdsr; /* 0x98 Pad Pull-down Status Register */ + u32 reserved6; /* */ +#else u32 asr; /* 0x70 Select A Register */ u32 bsr; /* 0x74 Select B Register */ u32 absr; /* 0x78 AB Select Status Register */ u32 reserved5[9]; /* */ +#endif u32 ower; /* 0xA0 Output Write Enable Register */ u32 owdr; /* 0xA4 Output Write Disable Register */ - u32 owsr; /* OxA8 utput Write Status Register */ + u32 owsr; /* OxA8 Output Write Status Register */ +#if defined(CPU_HAS_PIO3) + u32 reserved7; /* */ + u32 aimer; /* 0xB0 Additional INT Modes Enable Register */ + u32 aimdr; /* 0xB4 Additional INT Modes Disable Register */ + u32 aimmr; /* 0xB8 Additional INT Modes Mask Register */ + u32 reserved8; /* */ + u32 esr; /* 0xC0 Edge Select Register */ + u32 lsr; /* 0xC4 Level Select Register */ + u32 elsr; /* 0xC8 Edge/Level Status Register */ + u32 reserved9; /* 0xCC */ + u32 fellsr; /* 0xD0 Falling /Low Level Select Register */ + u32 rehlsr; /* 0xD4 Rising /High Level Select Register */ + u32 frlhsr; /* 0xD8 Fall/Rise - Low/High Status Register */ + u32 reserved10; /* */ + u32 locksr; /* 0xE0 Lock Status */ + u32 wpmr; /* 0xE4 Write Protect Mode Register */ + u32 wpsr; /* 0xE8 Write Protect Status Register */ + u32 reserved11[5]; /* */ + u32 schmitt; /* 0x100 Schmitt Trigger Register */ + u32 reserved12[63]; +#else u32 reserved6[85]; +#endif } at91_port_t; typedef union at91_pio { @@ -94,6 +130,13 @@ typedef union at91_pio { #ifdef CONFIG_AT91_GPIO int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup); int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup); +#if defined(CPU_HAS_PIO3) +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div); +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on); +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin); +#endif int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup); int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on); int at91_set_pio_output(unsigned port, unsigned pin, int value); diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index be2a0268e84..ac3b322af23 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -86,7 +86,14 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) mask = 1 << pin; writel(mask, &pio->port[port].idr); at91_set_pio_pullup(port, pin, use_pullup); +#if defined(CPU_HAS_PIO3) + writel(readl(&pio->port[port].abcdsr1) & ~mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) & ~mask, + &pio->port[port].abcdsr2); +#else writel(mask, &pio->port[port].asr); +#endif writel(mask, &pio->port[port].pdr); } return 0; @@ -104,12 +111,63 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) mask = 1 << pin; writel(mask, &pio->port[port].idr); at91_set_pio_pullup(port, pin, use_pullup); +#if defined(CPU_HAS_PIO3) + writel(readl(&pio->port[port].abcdsr1) | mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) & ~mask, + &pio->port[port].abcdsr2); +#else writel(mask, &pio->port[port].bsr); +#endif writel(mask, &pio->port[port].pdr); } return 0; } +#if defined(CPU_HAS_PIO3) +/* + * mux the pin to the "C" internal peripheral role. + */ +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].idr); + at91_set_pio_pullup(port, pin, use_pullup); + writel(readl(&pio->port[port].abcdsr1) & ~mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) | mask, + &pio->port[port].abcdsr2); + writel(mask, &pio->port[port].pdr); + } + return 0; +} + +/* + * mux the pin to the "D" internal peripheral role. + */ +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].idr); + at91_set_pio_pullup(port, pin, use_pullup); + writel(readl(&pio->port[port].abcdsr1) | mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) | mask, + &pio->port[port].abcdsr2); + writel(mask, &pio->port[port].pdr); + } + return 0; +} +#endif + /* * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and * configure it for an input. @@ -162,13 +220,76 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { mask = 1 << pin; - if (is_on) + if (is_on) { +#if defined(CPU_HAS_PIO3) + writel(mask, &pio->port[port].ifscdr); +#endif writel(mask, &pio->port[port].ifer); - else + } else { writel(mask, &pio->port[port].ifdr); + } + } + return 0; +} + +#if defined(CPU_HAS_PIO3) +/* + * enable/disable the debounce filter. + */ +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + if (is_on) { + writel(mask, &pio->port[port].ifscer); + writel(div & PIO_SCDR_DIV, &pio->port[port].scdr); + writel(mask, &pio->port[port].ifer); + } else { + writel(mask, &pio->port[port].ifdr); + } + } + return 0; +} + +/* + * enable/disable the pull-down. + * If pull-up already enabled while calling the function, we disable it. + */ +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].pudr); + if (is_on) + writel(mask, &pio->port[port].ppder); + else + writel(mask, &pio->port[port].ppddr); + } + return 0; +} + +/* + * disable Schmitt trigger + */ +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(readl(&pio->port[port].schmitt) | mask, + &pio->port[port].schmitt); } return 0; } +#endif /* * enable/disable the multi-driver. This is only valid for output and -- cgit v1.2.3 From 8f5d7a03986ac357f95c1131074e2abaa9e3fd22 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 1 Jun 2012 01:30:59 +0000 Subject: kirkwood: add save functionality kirkwood_mpp_conf function If a second non NULL argument is given to the kirkwood_mpp_conf function, it will be used to store the current configuration of the MPP registers. mpp_save must be a preallocated table of the same size as mpp_list and it must be zero terminated as well. A later call to kirkwood_mpp_conf function with this saved list as first (mpp_conf) argment will set the configuration back. Signed-off-by: Valentin Longchamp cc: Holger Brunck cc: Prafulla Wadaskar --- arch/arm/cpu/arm926ejs/kirkwood/mpp.c | 10 +++++++++- arch/arm/include/asm/arch-kirkwood/mpp.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c index 3da6c98d11a..03eb2de520f 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c @@ -31,7 +31,7 @@ static u32 kirkwood_variant(void) #define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) #define MPP_NR_REGS (1 + MPP_MAX/8) -void kirkwood_mpp_conf(u32 *mpp_list) +void kirkwood_mpp_conf(u32 *mpp_list, u32 *mpp_save) { u32 mpp_ctrl[MPP_NR_REGS]; unsigned int variant_mask; @@ -52,6 +52,7 @@ void kirkwood_mpp_conf(u32 *mpp_list) while (*mpp_list) { unsigned int num = MPP_NUM(*mpp_list); unsigned int sel = MPP_SEL(*mpp_list); + unsigned int sel_save; int shift; if (num > MPP_MAX) { @@ -66,6 +67,13 @@ void kirkwood_mpp_conf(u32 *mpp_list) } shift = (num & 7) << 2; + + if (mpp_save) { + sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; + *mpp_save = num | (sel_save << 8) | variant_mask; + mpp_save++; + } + mpp_ctrl[num / 8] &= ~(0xf << shift); mpp_ctrl[num / 8] |= sel << shift; diff --git a/arch/arm/include/asm/arch-kirkwood/mpp.h b/arch/arm/include/asm/arch-kirkwood/mpp.h index b3c090edcde..8e50ee7f14d 100644 --- a/arch/arm/include/asm/arch-kirkwood/mpp.h +++ b/arch/arm/include/asm/arch-kirkwood/mpp.h @@ -312,6 +312,6 @@ #define MPP_MAX 49 -void kirkwood_mpp_conf(unsigned int *mpp_list); +void kirkwood_mpp_conf(u32 *mpp_list, u32 *mpp_save); #endif -- cgit v1.2.3 From ac486e3ba16c37514d135c359f61ed6e32a2921d Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 1 Jun 2012 01:31:02 +0000 Subject: kw_spi: support spi_claim/release_bus functions These two function nows ensure that the MPP is configured correctly for the SPI controller before any SPI access, and restore the initial configuration when the access is over. Since the used pins for the SPI controller can differ (2 possibilities for each signal), the used pins are configured with CONFIG_SYS_KW_SPI_MPP. Signed-off-by: Valentin Longchamp cc: Holger Brunck cc: Prafulla Wadaskar --- arch/arm/include/asm/arch-kirkwood/spi.h | 11 ++++++++++ drivers/spi/kirkwood_spi.c | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-kirkwood/spi.h b/arch/arm/include/asm/arch-kirkwood/spi.h index 1d5043f94f7..c79bed7ed9d 100644 --- a/arch/arm/include/asm/arch-kirkwood/spi.h +++ b/arch/arm/include/asm/arch-kirkwood/spi.h @@ -37,6 +37,17 @@ struct kwspi_registers { u32 irq_mask; /* 0x10614 */ }; +/* They are used to define CONFIG_SYS_KW_SPI_MPP + * each of the below #defines selects which mpp is + * configured for each SPI signal in spi_claim_bus + * bit 0: selects pin for MOSI (MPP1 if 0, MPP6 if 1) + * bit 1: selects pin for SCK (MPP2 if 0, MPP10 if 1) + * bit 2: selects pin for MISO (MPP3 if 0, MPP11 if 1) + */ +#define MOSI_MPP6 (1 << 0) +#define SCK_MPP10 (1 << 1) +#define MISO_MPP11 (1 << 2) + #define KWSPI_CLKPRESCL_MASK 0x1f #define KWSPI_CSN_ACT 1 /* Activates serial memory interface */ #define KWSPI_SMEMRDY (1 << 1) /* SerMem Data xfer ready */ diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c index 01e1d119723..db4bb0ae615 100644 --- a/drivers/spi/kirkwood_spi.c +++ b/drivers/spi/kirkwood_spi.c @@ -83,13 +83,49 @@ void spi_free_slave(struct spi_slave *slave) free(slave); } +#if defined(CONFIG_SYS_KW_SPI_MPP) +u32 spi_mpp_backup[4]; +#endif + int spi_claim_bus(struct spi_slave *slave) { +#if defined(CONFIG_SYS_KW_SPI_MPP) + u32 config; + u32 spi_mpp_config[4]; + + config = CONFIG_SYS_KW_SPI_MPP; + + if (config & MOSI_MPP6) + spi_mpp_config[0] = MPP6_SPI_MOSI; + else + spi_mpp_config[0] = MPP1_SPI_MOSI; + + if (config & SCK_MPP10) + spi_mpp_config[1] = MPP10_SPI_SCK; + else + spi_mpp_config[1] = MPP2_SPI_SCK; + + if (config & MISO_MPP11) + spi_mpp_config[2] = MPP11_SPI_MISO; + else + spi_mpp_config[2] = MPP3_SPI_MISO; + + spi_mpp_config[3] = 0; + spi_mpp_backup[3] = 0; + + /* set new spi mpp and save current mpp config */ + kirkwood_mpp_conf(spi_mpp_config, spi_mpp_backup); + +#endif + return 0; } void spi_release_bus(struct spi_slave *slave) { +#if defined(CONFIG_SYS_KW_SPI_MPP) + kirkwood_mpp_conf(spi_mpp_backup, NULL); +#endif } #ifndef CONFIG_SPI_CS_IS_VALID -- cgit v1.2.3 From dacc8c6f79aa4016e431278d31431a19d43c6b37 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Wed, 13 Jun 2012 03:03:52 +0000 Subject: arm/kirkwood: protect the ENV_SPI #defines So that they can be redefined by some boards specific values. Signed-off-by: Valentin Longchamp Signed-off-by: Holger Brunck cc: Prafulla Wadaskar --- arch/arm/include/asm/arch-kirkwood/config.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-kirkwood/config.h b/arch/arm/include/asm/arch-kirkwood/config.h index 91164eb4021..a9499b70cd3 100644 --- a/arch/arm/include/asm/arch-kirkwood/config.h +++ b/arch/arm/include/asm/arch-kirkwood/config.h @@ -82,9 +82,15 @@ #ifdef CONFIG_CMD_SF #define CONFIG_HARD_SPI 1 #define CONFIG_KIRKWOOD_SPI 1 -#define CONFIG_ENV_SPI_BUS 0 -#define CONFIG_ENV_SPI_CS 0 -#define CONFIG_ENV_SPI_MAX_HZ 50000000 /*50Mhz */ +#ifndef CONFIG_ENV_SPI_BUS +# define CONFIG_ENV_SPI_BUS 0 +#endif +#ifndef CONFIG_ENV_SPI_CS +# define CONFIG_ENV_SPI_CS 0 +#endif +#ifndef CONFIG_ENV_SPI_MAX_HZ +# define CONFIG_ENV_SPI_MAX_HZ 50000000 +#endif #endif /* -- cgit v1.2.3 From f8b9d1d30ece82abccefac3c860c06f8b7da8fbb Mon Sep 17 00:00:00 2001 From: Tetsuyuki Kobayashi Date: Mon, 25 Jun 2012 02:40:57 +0000 Subject: arm: bugfix: Move vector table before jumping relocated code Interrupts and exceptions doesn't work in relocated code. It badly use IRQ_STACK_START_IN in rom area as interrupt stack. It is because the vecotr table is not moved to ram area. This patch moves vector table before jumping relocated code. Signed-off-by: Tetsuyuki Kobayashi Tested-by: Tom Rini --- arch/arm/cpu/armv7/start.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 261835b6c6b..22a3cedcb0d 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -277,6 +277,18 @@ jump_2_ram: mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB #endif +/* + * Move vector table + */ +#if !defined(CONFIG_TEGRA2) +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + add r0, r0, r9 + mcr p15, 0, r0, c12, c0, 0 @Set VBAR +#endif +#endif /* !Tegra2 */ + ldr r0, _board_init_r_ofs adr r1, _start add lr, r0, r1 -- cgit v1.2.3 From 702395073fa746f0dcfe6f16f781b4d84645fc40 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 29 May 2012 19:26:41 +0000 Subject: ARM: OMAP3+: Detect reset type Certain modules are not affected by means of a warm reset and need not be configured again. Adding an API to detect the reset reason warm/cold. This will be used to skip the module configurations that are retained across a warm reset. Signed-off-by: Lokesh Vutla Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap-common/reset.c | 5 +++++ arch/arm/include/asm/arch-am33xx/cpu.h | 2 ++ arch/arm/include/asm/arch-omap3/cpu.h | 2 ++ arch/arm/include/asm/arch-omap3/sys_proto.h | 1 + arch/arm/include/asm/arch-omap4/cpu.h | 2 ++ arch/arm/include/asm/arch-omap4/sys_proto.h | 1 + arch/arm/include/asm/arch-omap5/cpu.h | 2 ++ arch/arm/include/asm/arch-omap5/sys_proto.h | 1 + 8 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/reset.c b/arch/arm/cpu/armv7/omap-common/reset.c index 234e90a8683..587bb47745a 100644 --- a/arch/arm/cpu/armv7/omap-common/reset.c +++ b/arch/arm/cpu/armv7/omap-common/reset.c @@ -34,3 +34,8 @@ void __weak reset_cpu(unsigned long ignored) { writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL); } + +u32 __weak warm_reset(void) +{ + return (readl(PRM_RSTST) & PRM_RSTST_WARM_RESET_MASK); +} diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index 5a6534e32ea..a027e3128f4 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -53,8 +53,10 @@ /* Reset control */ #ifdef CONFIG_AM33XX #define PRM_RSTCTRL 0x44E00F00 +#define PRM_RSTST 0x44E00F08 #endif #define PRM_RSTCTRL_RESET 0x01 +#define PRM_RSTST_WARM_RESET_MASK 0x232 #ifndef __KERNEL_STRICT_NAMES #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h index 457f99d2c50..5683e16177d 100644 --- a/arch/arm/include/asm/arch-omap3/cpu.h +++ b/arch/arm/include/asm/arch-omap3/cpu.h @@ -479,6 +479,8 @@ struct prm { #define PRM_RSTCTRL 0x48307250 #define PRM_RSTCTRL_RESET 0x04 +#define PRM_RSTST 0x48307258 +#define PRM_RSTST_WARM_RESET_MASK 0x7D2 #define SYSCLKDIV_1 (0x1 << 6) #define SYSCLKDIV_2 (0x1 << 7) diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 2a89e565340..9e52b12aa29 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -74,4 +74,5 @@ void power_init_r(void); void dieid_num_r(void); void do_omap3_emu_romcode_call(u32 service_id, u32 parameters); void omap3_gp_romcode_call(u32 service_id, u32 parameter); +u32 warm_reset(void); #endif diff --git a/arch/arm/include/asm/arch-omap4/cpu.h b/arch/arm/include/asm/arch-omap4/cpu.h index feddb7de514..a8c4c60c8c9 100644 --- a/arch/arm/include/asm/arch-omap4/cpu.h +++ b/arch/arm/include/asm/arch-omap4/cpu.h @@ -178,5 +178,7 @@ struct watchdog { #define PRM_RSTCTRL PRM_DEVICE_BASE #define PRM_RSTCTRL_RESET 0x01 +#define PRM_RSTST (PRM_DEVICE_BASE + 0x4) +#define PRM_RSTST_WARM_RESET_MASK 0x07EA #endif /* _CPU_H */ diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index c6e3ad26ff2..4f0a29da7fa 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -57,6 +57,7 @@ void init_omap_revision(void); void do_io_settings(void); void omap_vc_init(u16 speed_khz); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); +u32 warm_reset(void); /* * This is used to verify if the configuration header * was executed by Romcode prior to control of transfer diff --git a/arch/arm/include/asm/arch-omap5/cpu.h b/arch/arm/include/asm/arch-omap5/cpu.h index 8ef17c9a146..5e62013236e 100644 --- a/arch/arm/include/asm/arch-omap5/cpu.h +++ b/arch/arm/include/asm/arch-omap5/cpu.h @@ -182,5 +182,7 @@ struct watchdog { #define PRM_RSTCTRL PRM_DEVICE_BASE #define PRM_RSTCTRL_RESET 0x01 +#define PRM_RSTST (PRM_DEVICE_BASE + 0x4) +#define PRM_RSTST_WARM_RESET_MASK 0x7FEA #endif /* _CPU_H */ diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index 8396a221418..b3bbdb7cd8d 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -57,6 +57,7 @@ void init_omap_revision(void); void do_io_settings(void); void omap_vc_init(u16 speed_khz); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); +u32 warm_reset(void); /* * This is used to verify if the configuration header -- cgit v1.2.3 From 784229cc25feee0bb3f2bba6c1318f4d73c293e0 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 29 May 2012 19:26:42 +0000 Subject: OMAP4+: Handle sdram init after warm reset EMIF and DDR device state are preserved in warmreset. Redoing the full initialisation would cause unexpected behaviour. Do only partial initialisation to account for frequency change. Signed-off-by: Lokesh Vutla Signed-off-by: R Sricharan Signed-off-by: Senthilvadivu Guruswamy --- arch/arm/cpu/armv7/omap-common/emif-common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 23cf6199eb7..edc63fa9cb5 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -990,7 +990,7 @@ struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs, return NULL; /* Do the minimum init for mode register accesses */ - if (!running_from_sdram()) { + if (!(running_from_sdram() || warm_reset())) { phy = get_ddr_phy_ctrl_1(get_sys_clk_freq() / 2, RL_BOOT); writel(phy, &emif->emif_ddr_phy_ctrl_1); } @@ -1070,7 +1070,7 @@ static void do_sdram_init(u32 base) * Changing the timing registers in EMIF can happen(going from one * OPP to another) */ - if (!in_sdram) { + if (!(in_sdram || warm_reset())) { if (omap_revision() != OMAP5432_ES1_0) lpddr2_init(base, regs); else @@ -1242,7 +1242,7 @@ void sdram_init(void) in_sdram = running_from_sdram(); debug("in_sdram = %d\n", in_sdram); - if (!in_sdram) { + if (!(in_sdram || warm_reset())) { if (omap_rev != OMAP5432_ES1_0) bypass_dpll(&prcm->cm_clkmode_dpll_core); else @@ -1252,8 +1252,10 @@ void sdram_init(void) do_sdram_init(EMIF1_BASE); do_sdram_init(EMIF2_BASE); - if (!in_sdram) { + if (!in_sdram) dmm_init(DMM_BASE); + + if (!(in_sdram || warm_reset())) { emif_post_init_config(EMIF1_BASE); emif_post_init_config(EMIF2_BASE); } -- cgit v1.2.3 From 38f25b125e446ab4a64a54e9aa2c10023d8eccc3 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 29 May 2012 19:26:43 +0000 Subject: OMAP4+: Force DDR in self-refresh after warm reset Errata ID:i727 Description: The refresh rate is programmed in the EMIF_SDRAM_REF_CTRL[15:0] REG_REFRESH_RATE parameter taking into account frequency of the device. When a warm reset is applied on the system, the OMAP processor restarts with another OPP and so frequency is not the same. Due to this frequency change, the refresh rate will be too low and could result in an unexpected behavior on the memory side. Workaround: The workaround is to force self-refresh when coming back from the warm reset with the following sequence: • Set EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE to 0x2 • Set EMIF_PWR_MGMT_CTRL[7:4] REG_SR_TIM to 0x0 • Do a dummy read (loads automatically new value of sr_tim) This will reduce the risk of memory content corruption, but memory content can't be guaranteed after a warm reset. This errata is impacted on OMAP4430: 1.0, 2.0, 2.1, 2.2, 2.3 OMAP4460: 1.0, 1.1 OMAP4470: 1.0 OMAP5430: 1.0 Signed-off-by: Lokesh Vutla Signed-off-by: R Sricharan Signed-off-by: Senthilvadivu Guruswamy --- arch/arm/cpu/armv7/omap-common/emif-common.c | 21 +++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/hwinit-common.c | 4 ++++ arch/arm/include/asm/arch-omap4/sys_proto.h | 1 + arch/arm/include/asm/arch-omap5/sys_proto.h | 1 + 4 files changed, 27 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index edc63fa9cb5..64427e61dad 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -32,6 +32,27 @@ #include #include +void set_lpmode_selfrefresh(u32 base) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + u32 reg; + + reg = readl(&emif->emif_pwr_mgmt_ctrl); + reg &= ~EMIF_REG_LP_MODE_MASK; + reg |= LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT; + reg &= ~EMIF_REG_SR_TIM_MASK; + writel(reg, &emif->emif_pwr_mgmt_ctrl); + + /* dummy read for the new SR_TIM to be loaded */ + readl(&emif->emif_pwr_mgmt_ctrl); +} + +void force_emif_self_refresh() +{ + set_lpmode_selfrefresh(EMIF1_BASE); + set_lpmode_selfrefresh(EMIF2_BASE); +} + inline u32 emif_num(u32 base) { if (base == EMIF1_BASE) diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 660032330ef..459ebb55e57 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -111,6 +111,10 @@ static void init_boot_params(void) void s_init(void) { init_omap_revision(); +#ifdef CONFIG_SPL_BUILD + if (warm_reset() && (omap_revision() <= OMAP5430_ES1_0)) + force_emif_self_refresh(); +#endif watchdog_init(); set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index 4f0a29da7fa..d633573c258 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -58,6 +58,7 @@ void do_io_settings(void); void omap_vc_init(u16 speed_khz); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); u32 warm_reset(void); +void force_emif_self_refresh(void); /* * This is used to verify if the configuration header * was executed by Romcode prior to control of transfer diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index b3bbdb7cd8d..74feb90277c 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -58,6 +58,7 @@ void do_io_settings(void); void omap_vc_init(u16 speed_khz); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); u32 warm_reset(void); +void force_emif_self_refresh(void); /* * This is used to verify if the configuration header -- cgit v1.2.3 From 55c1284942b18cf83a297d33c8746aadcbf5f096 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 30 May 2012 07:38:07 +0000 Subject: omap: emif: deal with rams that return duplicate mr data on all byte lanes Some rams (Micron for example) return duplicate mr data on all byte lanes. Users of the get_mr function currently don't deal with this duplicated data gracefully. This patch detects the duplicated data and returns only the expected 8 bit mr data. Signed-off-by: Steve Sakoman --- arch/arm/cpu/armv7/omap-common/emif-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 64427e61dad..61ade4c5987 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -77,7 +77,12 @@ static inline u32 get_mr(u32 base, u32 cs, u32 mr_addr) mr = readl(&emif->emif_lpddr2_mode_reg_data); debug("get_mr: EMIF%d cs %d mr %08x val 0x%x\n", emif_num(base), cs, mr_addr, mr); - return mr; + if (((mr & 0x0000ff00) >> 8) == (mr & 0xff) && + ((mr & 0x00ff0000) >> 16) == (mr & 0xff) && + ((mr & 0xff000000) >> 24) == (mr & 0xff)) + return mr & 0xff; + else + return mr; } static inline void set_mr(u32 base, u32 cs, u32 mr_addr, u32 mr_val) -- cgit v1.2.3 From ad0878a7492928696a93245c1f9190d51eebe549 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 30 May 2012 07:38:08 +0000 Subject: omap: emif: fix bug in manufacturer code test Code currently tests for <= 0xff. Micron manufacturer code is 0xff, so Micron memory will not be detected! Signed-off-by: Steve Sakoman --- arch/arm/cpu/armv7/omap-common/emif-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 61ade4c5987..7c2352c7fd5 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -947,7 +947,7 @@ static u8 is_lpddr2_sdram_present(u32 base, u32 cs, } mr = get_mr(base, cs, LPDDR2_MR5); - if (mr >= 0xFF) { + if (mr > 0xFF) { /* Mode register value bigger than 8 bit */ return 0; } -- cgit v1.2.3 From f2b37a6533cfc45af53cdd1f5c721a6f64c0d7da Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 30 May 2012 07:46:00 +0000 Subject: omap: am33xx: accomodate input clocks other than 24 Mhz The PLL setup values currently assume a 24 Mhz input clock. This patch uses V_OSCK from the board config file to support boards with different input clock rates. Signed-off-by: Steve Sakoman --- arch/arm/include/asm/arch-am33xx/clocks_am33xx.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h index abc5b6b411d..d748dd27873 100644 --- a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h +++ b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h @@ -19,16 +19,16 @@ #ifndef _CLOCKS_AM33XX_H_ #define _CLOCKS_AM33XX_H_ -#define OSC 24 +#define OSC (V_OSCK/1000000) /* MAIN PLL Fdll = 550 MHZ, */ #define MPUPLL_M 550 -#define MPUPLL_N 23 +#define MPUPLL_N (OSC-1) #define MPUPLL_M2 1 /* Core PLL Fdll = 1 GHZ, */ #define COREPLL_M 1000 -#define COREPLL_N 23 +#define COREPLL_N (OSC-1) #define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */ #define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */ @@ -40,13 +40,13 @@ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below */ #define PERPLL_M 960 -#define PERPLL_N 23 +#define PERPLL_N (OSC-1) #define PERPLL_M2 5 /* DDR Freq is 266 MHZ for now */ /* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */ #define DDRPLL_M 266 -#define DDRPLL_N 23 +#define DDRPLL_N (OSC-1) #define DDRPLL_M2 1 extern void pll_init(void); -- cgit v1.2.3 From cc009defa4211aa58b3387b59d568cf8ea863ef4 Mon Sep 17 00:00:00 2001 From: Sebastien Jan Date: Wed, 13 Jun 2012 05:16:40 +0000 Subject: omap4: Use a smaller M,N couple for IVA DPLL This reduced M,N couple corresponds to the advised value from TI HW team. Tested on 4460 Pandaboard, it also provides peripheral clocks closer to the advised values. Signed-off-by: Sebastien Jan --- arch/arm/cpu/armv7/omap4/clocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c index c568951a91a..1d92e665453 100644 --- a/arch/arm/cpu/armv7/omap4/clocks.c +++ b/arch/arm/cpu/armv7/omap4/clocks.c @@ -146,7 +146,7 @@ static const struct dpll_params iva_dpll_params_1862mhz[NUM_SYS_CLKS] = { {727, 14, -1, -1, 4, 7, -1, -1}, /* 19.2 MHz */ {931, 25, -1, -1, 4, 7, -1, -1}, /* 26 MHz */ {931, 26, -1, -1, 4, 7, -1, -1}, /* 27 MHz */ - {412, 16, -1, -1, 4, 7, -1, -1} /* 38.4 MHz */ + {291, 11, -1, -1, 4, 7, -1, -1} /* 38.4 MHz */ }; /* ABE M & N values with sys_clk as source */ -- cgit v1.2.3 From 254763822e966b6c630d78dc17018b97a50d8f6e Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Mon, 4 Jun 2012 03:40:23 +0000 Subject: ARM: OMAP4+: Move external phy initialisations to arch specific place. The external phy is present in the case OMAP5 soc is currently configured in emif-common.c. This results in having dummy structures for those Socs which do not have a external phy. So by having a weak function in emif-common and overriding it in OMAP5, avoids the use of dummy structures. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap-common/emif-common.c | 32 ++++++---------------------- arch/arm/cpu/armv7/omap4/sdram_elpida.c | 1 - arch/arm/cpu/armv7/omap5/sdram.c | 31 +++++++++++++++++++++++++++ arch/arm/include/asm/emif.h | 2 ++ 4 files changed, 39 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 7c2352c7fd5..30dcf1b0b04 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -31,6 +31,7 @@ #include #include #include +#include void set_lpmode_selfrefresh(u32 base) { @@ -140,9 +141,6 @@ static void do_lpddr2_init(u32 base, u32 cs) static void lpddr2_init(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - u32 *ext_phy_ctrl_base = 0; - u32 *emif_ext_phy_ctrl_base = 0; - u32 i = 0; /* Not NVM */ clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK); @@ -160,29 +158,7 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs) writel(regs->sdram_config_init, &emif->emif_sdram_config); writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1); - ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1); - emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1); - - if (omap_revision() >= OMAP5430_ES1_0) { - /* Configure external phy control timing registers */ - for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { - writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); - /* Update shadow registers */ - writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); - } - - /* - * external phy 6-24 registers do not change with - * ddr frequency - */ - for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) { - writel(ext_phy_ctrl_const_base[i], - emif_ext_phy_ctrl_base++); - /* Update shadow registers */ - writel(ext_phy_ctrl_const_base[i], - emif_ext_phy_ctrl_base++); - } - } + do_ext_phy_settings(base, regs); do_lpddr2_init(base, CS0); if (regs->sdram_config & EMIF_REG_EBANK_MASK) @@ -194,6 +170,10 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs) /* Enable refresh now */ clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK); + } + +__weak void do_ext_phy_settings(u32 base, const struct emif_regs *regs) +{ } void emif_update_timings(u32 base, const struct emif_regs *regs) diff --git a/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/arch/arm/cpu/armv7/omap4/sdram_elpida.c index 239ad2b07c5..b9128faa567 100644 --- a/arch/arm/cpu/armv7/omap4/sdram_elpida.c +++ b/arch/arm/cpu/armv7/omap4/sdram_elpida.c @@ -91,7 +91,6 @@ const struct emif_regs emif_regs_elpida_400_mhz_2cs = { }; /* Dummy registers for OMAP44xx */ -const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; const u32 ddr3_ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG]; const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index 817f933eda9..6ebdf5fbfd0 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -204,6 +204,37 @@ void emif_get_device_details(u32 emif_nr, #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ +void do_ext_phy_settings(u32 base, const struct emif_regs *regs) +{ + u32 *ext_phy_ctrl_base = 0; + u32 *emif_ext_phy_ctrl_base = 0; + u32 i = 0; + + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1); + emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1); + + /* Configure external phy control timing registers */ + for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { + writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); + } + + /* + * external phy 6-24 registers do not change with + * ddr frequency + */ + for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) { + writel(ext_phy_ctrl_const_base[i], + emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(ext_phy_ctrl_const_base[i], + emif_ext_phy_ctrl_base++); + } +} + #ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS static const struct lpddr2_ac_timings timings_jedec_532_mhz = { .max_freq = 532000000, diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index c2ad877ab24..674c3de6617 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -1141,6 +1141,8 @@ void emif_get_device_timings(u32 emif_nr, const struct lpddr2_device_timings **cs1_device_timings); #endif +void do_ext_phy_settings(u32 base, const struct emif_regs *regs); + #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS extern u32 *const T_num; extern u32 *const T_den; -- cgit v1.2.3 From dbf8fb6ad1fc8b1708e0460bf3b5b7b2035badea Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Tue, 12 Jun 2012 19:53:30 +0000 Subject: ARM: OMAP4/5: Move gpmc clocks to essential group. GPMC clocks are currently getting enabled as a part non-essential clocks. This will be required during NOR boot. Move this to essential group to keep the functionality, when non-essential clocks are not enabled. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap4/clocks.c | 2 +- arch/arm/cpu/armv7/omap5/clocks.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c index 1d92e665453..484a96abf16 100644 --- a/arch/arm/cpu/armv7/omap4/clocks.c +++ b/arch/arm/cpu/armv7/omap4/clocks.c @@ -354,6 +354,7 @@ void enable_basic_clocks(void) }; u32 *const clk_modules_hw_auto_essential[] = { + &prcm->cm_l3_2_gpmc_clkctrl, &prcm->cm_memif_emif_1_clkctrl, &prcm->cm_memif_emif_2_clkctrl, &prcm->cm_l4cfg_l4_cfg_clkctrl, @@ -452,7 +453,6 @@ void enable_non_essential_clocks(void) }; u32 *const clk_modules_hw_auto_non_essential[] = { - &prcm->cm_l3_2_gpmc_clkctrl, &prcm->cm_l3instr_l3_3_clkctrl, &prcm->cm_l3instr_l3_instr_clkctrl, &prcm->cm_l3instr_intrconn_wp1_clkctrl, diff --git a/arch/arm/cpu/armv7/omap5/clocks.c b/arch/arm/cpu/armv7/omap5/clocks.c index 65dc5c75953..d553d12b6b4 100644 --- a/arch/arm/cpu/armv7/omap5/clocks.c +++ b/arch/arm/cpu/armv7/omap5/clocks.c @@ -317,6 +317,7 @@ void enable_basic_clocks(void) }; u32 *const clk_modules_hw_auto_essential[] = { + &prcm->cm_l3_2_gpmc_clkctrl, &prcm->cm_memif_emif_1_clkctrl, &prcm->cm_memif_emif_2_clkctrl, &prcm->cm_l4cfg_l4_cfg_clkctrl, @@ -427,7 +428,6 @@ void enable_non_essential_clocks(void) &prcm->cm_ivahd_ivahd_clkctrl, &prcm->cm_ivahd_sl2_clkctrl, &prcm->cm_dsp_dsp_clkctrl, - &prcm->cm_l3_2_gpmc_clkctrl, &prcm->cm_l3instr_l3_3_clkctrl, &prcm->cm_l3instr_l3_instr_clkctrl, &prcm->cm_l3instr_intrconn_wp1_clkctrl, -- cgit v1.2.3 From 5e9cd44ca08a03fdf1b8271f265981bc0a038c8d Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Tue, 12 Jun 2012 19:53:31 +0000 Subject: ARM: OMAP4/5: Move USB clocks to essential group. USB clocks will be required for fastboot, tftp related functionalities. Move these clocks to essential group inorder to have the functionality working when non-essential clocks are not enabled. Signed-off-by: R Sricharan --- arch/arm/cpu/armv7/omap4/clocks.c | 10 ++++------ arch/arm/cpu/armv7/omap5/clocks.c | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c index 484a96abf16..5bd0a88fdeb 100644 --- a/arch/arm/cpu/armv7/omap4/clocks.c +++ b/arch/arm/cpu/armv7/omap4/clocks.c @@ -364,9 +364,6 @@ void enable_basic_clocks(void) &prcm->cm_l4per_gpio4_clkctrl, &prcm->cm_l4per_gpio5_clkctrl, &prcm->cm_l4per_gpio6_clkctrl, - &prcm->cm_l3init_usbphy_clkctrl, - &prcm->cm_clksel_usb_60mhz, - &prcm->cm_l3init_hsusbtll_clkctrl, 0 }; @@ -377,7 +374,6 @@ void enable_basic_clocks(void) &prcm->cm_l4per_gptimer2_clkctrl, &prcm->cm_wkup_wdtimer2_clkctrl, &prcm->cm_l4per_uart3_clkctrl, - &prcm->cm_l3init_hsusbhost_clkctrl, 0 }; @@ -414,6 +410,9 @@ void enable_basic_uboot_clocks(void) u32 *const clk_modules_hw_auto_essential[] = { &prcm->cm_l3init_hsusbotg_clkctrl, &prcm->cm_l3init_usbphy_clkctrl, + &prcm->cm_l3init_usbphy_clkctrl, + &prcm->cm_clksel_usb_60mhz, + &prcm->cm_l3init_hsusbtll_clkctrl, 0 }; @@ -423,6 +422,7 @@ void enable_basic_uboot_clocks(void) &prcm->cm_l4per_i2c2_clkctrl, &prcm->cm_l4per_i2c3_clkctrl, &prcm->cm_l4per_i2c4_clkctrl, + &prcm->cm_l3init_hsusbhost_clkctrl, 0 }; @@ -457,7 +457,6 @@ void enable_non_essential_clocks(void) &prcm->cm_l3instr_l3_instr_clkctrl, &prcm->cm_l3instr_intrconn_wp1_clkctrl, &prcm->cm_l3init_hsi_clkctrl, - &prcm->cm_l3init_hsusbtll_clkctrl, 0 }; @@ -497,7 +496,6 @@ void enable_non_essential_clocks(void) &prcm->cm_cam_fdif_clkctrl, &prcm->cm_dss_dss_clkctrl, &prcm->cm_sgx_sgx_clkctrl, - &prcm->cm_l3init_hsusbhost_clkctrl, 0 }; diff --git a/arch/arm/cpu/armv7/omap5/clocks.c b/arch/arm/cpu/armv7/omap5/clocks.c index d553d12b6b4..eecfbade354 100644 --- a/arch/arm/cpu/armv7/omap5/clocks.c +++ b/arch/arm/cpu/armv7/omap5/clocks.c @@ -394,6 +394,9 @@ void enable_basic_uboot_clocks(void) &prcm->cm_l4per_i2c2_clkctrl, &prcm->cm_l4per_i2c3_clkctrl, &prcm->cm_l4per_i2c4_clkctrl, + &prcm->cm_l3init_hsusbtll_clkctrl, + &prcm->cm_l3init_hsusbhost_clkctrl, + &prcm->cm_l3init_fsusb_clkctrl, 0 }; @@ -432,7 +435,6 @@ void enable_non_essential_clocks(void) &prcm->cm_l3instr_l3_instr_clkctrl, &prcm->cm_l3instr_intrconn_wp1_clkctrl, &prcm->cm_l3init_hsi_clkctrl, - &prcm->cm_l3init_hsusbtll_clkctrl, &prcm->cm_l4per_hdq1w_clkctrl, 0 }; @@ -471,8 +473,6 @@ void enable_non_essential_clocks(void) &prcm->cm_cam_fdif_clkctrl, &prcm->cm_dss_dss_clkctrl, &prcm->cm_sgx_sgx_clkctrl, - &prcm->cm_l3init_hsusbhost_clkctrl, - &prcm->cm_l3init_fsusb_clkctrl, 0 }; -- cgit v1.2.3 From fa042186b932e9b9ee9a2fd8a04a3acf7c70d224 Mon Sep 17 00:00:00 2001 From: Tetsuyuki Kobayashi Date: Thu, 28 Jun 2012 23:36:21 +0000 Subject: arm: bugfix: save_boot_params_default accesses uninitalized stack when -O0 save_boot_params_default() in cpu.c accesses uninitialized stack area when it compiled with -O0 (not optimized). Signed-off-by: Tetsuyuki Kobayashi Acked-by: Tom Rini --- arch/arm/cpu/armv7/cpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index c6fa8ef1361..9eb484af183 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -36,9 +36,15 @@ #include #include #include +#include -void save_boot_params_default(u32 r0, u32 r1, u32 r2, u32 r3) +void __naked save_boot_params_default(u32 r0, u32 r1, u32 r2, u32 r3) { + /* + * Stack pointer is not yet initialized + * Don't save anything to stack even if compiled with -O0 + */ + asm("bx lr"); } void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) -- cgit v1.2.3 From 1fa943b99d06fee8b6552f4215923e4681d4a5a4 Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Tue, 22 May 2012 00:15:55 +0000 Subject: SPEAr: Configure FSMC driver for NAND interface Since FSMC is a standard IP and it supports different memory interfaces, it is supported independent of spear platform and spear is configured to use that driver for interfacing with the NAND device Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Signed-off-by: Stefan Roese Acked-by: Scott Wood --- arch/arm/include/asm/arch-spear/hardware.h | 8 ++++---- board/spear/spear300/spear300.c | 14 +++++++++----- board/spear/spear310/spear310.c | 14 +++++++++----- board/spear/spear320/spear320.c | 13 +++++++++---- board/spear/spear600/spear600.c | 14 +++++++++----- include/configs/spear-common.h | 3 ++- include/configs/spear3xx.h | 4 ++++ include/configs/spear6xx.h | 3 +++ 8 files changed, 49 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h index 818f36cc667..a6517b2187f 100644 --- a/arch/arm/include/asm/arch-spear/hardware.h +++ b/arch/arm/include/asm/arch-spear/hardware.h @@ -37,15 +37,15 @@ #if defined(CONFIG_SPEAR600) #define CONFIG_SYS_I2C_BASE (0xD0200000) -#define CONFIG_SPEAR_FSMCBASE (0xD1800000) +#define CONFIG_SYS_FSMC_BASE (0xD1800000) #elif defined(CONFIG_SPEAR300) #define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SPEAR_FSMCBASE (0x94000000) +#define CONFIG_SYS_FSMC_BASE (0x94000000) #elif defined(CONFIG_SPEAR310) #define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SPEAR_FSMCBASE (0x44000000) +#define CONFIG_SYS_FSMC_BASE (0x44000000) #undef CONFIG_SYS_NAND_CLE #undef CONFIG_SYS_NAND_ALE @@ -57,7 +57,7 @@ #elif defined(CONFIG_SPEAR320) #define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SPEAR_FSMCBASE (0x4C000000) +#define CONFIG_SYS_FSMC_BASE (0x4C000000) #define CONFIG_SPEAR_EMIBASE (0x40000000) #define CONFIG_SPEAR_RASBASE (0xB3000000) diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c index 60ee54470e4..72a36314089 100644 --- a/board/spear/spear300/spear300.c +++ b/board/spear/spear300/spear300.c @@ -24,10 +24,12 @@ #include #include #include +#include #include #include #include -#include + +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; int board_init(void) { @@ -41,18 +43,20 @@ int board_init(void) * Called by nand_init_chip to initialize the board specific functions */ -int board_nand_init(struct nand_chip *nand) +void board_nand_init() { struct misc_regs *const misc_regs_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct nand_chip *nand = &nand_chip[0]; +#if defined(CONFIG_NAND_FSMC) if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG30) || ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG31)) { - return spear_nand_init(nand); + fsmc_nand_init(nand); } - - return -1; +#endif + return; } diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index 03dfe16175e..14e666d6417 100644 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -25,10 +25,12 @@ #include #include #include +#include #include #include #include -#include + +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; int board_init(void) { @@ -42,18 +44,20 @@ int board_init(void) * Called by nand_init_chip to initialize the board specific functions */ -int board_nand_init(struct nand_chip *nand) +void board_nand_init() { struct misc_regs *const misc_regs_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct nand_chip *nand = &nand_chip[0]; +#if defined(CONFIG_NAND_FSMC) if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG30) || ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG31)) { - return spear_nand_init(nand); + fsmc_nand_init(nand); } - - return -1; +#endif + return; } diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index 2ba2dbb5666..994eb2b64d2 100644 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -25,10 +25,12 @@ #include #include #include +#include #include #include #include -#include + +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; int board_init(void) { @@ -42,18 +44,21 @@ int board_init(void) * Called by nand_init_chip to initialize the board specific functions */ -int board_nand_init(struct nand_chip *nand) +void board_nand_init() { struct misc_regs *const misc_regs_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct nand_chip *nand = &nand_chip[0]; +#if defined(CONFIG_NAND_FSMC) if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG30) || ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == MISC_SOCCFG31)) { - return spear_nand_init(nand); + fsmc_nand_init(nand); } +#endif - return -1; + return; } diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c index eef9a3771cf..ab0f760678b 100644 --- a/board/spear/spear600/spear600.c +++ b/board/spear/spear600/spear600.c @@ -24,10 +24,12 @@ #include #include #include +#include #include #include #include -#include + +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; int board_init(void) { @@ -41,13 +43,15 @@ int board_init(void) * Called by nand_init_chip to initialize the board specific functions */ -int board_nand_init(struct nand_chip *nand) +void board_nand_init() { struct misc_regs *const misc_regs_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct nand_chip *nand = &nand_chip[0]; +#if defined(CONFIG_NAND_FSMC) if (!(readl(&misc_regs_p->auto_cfg_reg) & MISC_NANDDIS)) - return spear_nand_init(nand); - - return -1; + fsmc_nand_init(nand); +#endif + return; } diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index ab1b33209e3..8d0f0369ca9 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -88,9 +88,10 @@ #define CONFIG_SYS_LOADS_BAUD_CHANGE /* NAND FLASH Configuration */ +#define CONFIG_SYS_NAND_SELF_INIT #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS -#define CONFIG_NAND_SPEAR 1 +#define CONFIG_NAND_FSMC #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_MTD_NAND_VERIFY_WRITE 1 diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h index 37bdebb392c..2a86c212531 100644 --- a/include/configs/spear3xx.h +++ b/include/configs/spear3xx.h @@ -117,6 +117,10 @@ #endif +/* NAND flash configuration */ +#define CONFIG_SYS_FSMC_NAND_SP +#define CONFIG_SYS_FSMC_NAND_8BIT + #if defined(CONFIG_SPEAR300) #define CONFIG_SYS_NAND_BASE (0x80000000) diff --git a/include/configs/spear6xx.h b/include/configs/spear6xx.h index 2ad5beb82c6..c5bcc30cb75 100644 --- a/include/configs/spear6xx.h +++ b/include/configs/spear6xx.h @@ -38,6 +38,9 @@ #define CONFIG_PL01x_PORTS { (void *)CONFIG_SYS_SERIAL0, \ (void *)CONFIG_SYS_SERIAL1 } +/* NAND flash configuration */ +#define CONFIG_SYS_FSMC_NAND_SP +#define CONFIG_SYS_FSMC_NAND_8BIT #define CONFIG_SYS_NAND_BASE (0xD2000000) #endif /* __CONFIG_H */ -- cgit v1.2.3 From 0def98e7be905e4e02eb22cb312bb4e3b327d2fa Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Tue, 22 May 2012 00:15:56 +0000 Subject: mtd/NAND: Remove obsolete SPEAr specific NAND drivers Since, SPEAr platform uses generic FSMC driver now, so spear specific files drivers/mtd/nand/spr_nand.c, arch/arm/include/asm/arch-spear/spr_nand.h are removed Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Signed-off-by: Stefan Roese Acked-by: Scott Wood --- arch/arm/include/asm/arch-spear/spr_nand.h | 57 ------------- drivers/mtd/nand/spr_nand.c | 124 ----------------------------- 2 files changed, 181 deletions(-) delete mode 100644 arch/arm/include/asm/arch-spear/spr_nand.h delete mode 100644 drivers/mtd/nand/spr_nand.c (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/spr_nand.h b/arch/arm/include/asm/arch-spear/spr_nand.h deleted file mode 100644 index 2b63dc7e8e8..00000000000 --- a/arch/arm/include/asm/arch-spear/spr_nand.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.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 __SPR_NAND_H__ -#define __SPR_NAND_H__ - -struct fsmc_regs { - u32 reserved_1[0x10]; - u32 genmemctrl_pc; - u32 reserved_2; - u32 genmemctrl_comm; - u32 genmemctrl_attrib; - u32 reserved_3; - u32 genmemctrl_ecc; -}; - -/* genmemctrl_pc register definitions */ -#define FSMC_RESET (1 << 0) -#define FSMC_WAITON (1 << 1) -#define FSMC_ENABLE (1 << 2) -#define FSMC_DEVTYPE_NAND (1 << 3) -#define FSMC_DEVWID_8 (0 << 4) -#define FSMC_DEVWID_16 (1 << 4) -#define FSMC_ECCEN (1 << 6) -#define FSMC_ECCPLEN_512 (0 << 7) -#define FSMC_ECCPLEN_256 (1 << 7) -#define FSMC_TCLR_1 (1 << 9) -#define FSMC_TAR_1 (1 << 13) - -/* genmemctrl_comm register definitions */ -#define FSMC_TSET_0 (0 << 0) -#define FSMC_TWAIT_6 (6 << 8) -#define FSMC_THOLD_4 (4 << 16) -#define FSMC_THIZ_1 (1 << 24) - -extern int spear_nand_init(struct nand_chip *nand); -#endif diff --git a/drivers/mtd/nand/spr_nand.c b/drivers/mtd/nand/spr_nand.c deleted file mode 100644 index 097d0c60bfc..00000000000 --- a/drivers/mtd/nand/spr_nand.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -static struct fsmc_regs *const fsmc_regs_p = - (struct fsmc_regs *)CONFIG_SPEAR_FSMCBASE; - -static struct nand_ecclayout spear_nand_ecclayout = { - .eccbytes = 24, - .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, - 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, - .oobfree = { - {.offset = 8, .length = 8}, - {.offset = 24, .length = 8}, - {.offset = 40, .length = 8}, - {.offset = 56, .length = 8}, - {.offset = 72, .length = 8}, - {.offset = 88, .length = 8}, - {.offset = 104, .length = 8}, - {.offset = 120, .length = 8} - } -}; - -static void spear_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl) -{ - struct nand_chip *this = mtd->priv; - ulong IO_ADDR_W; - - if (ctrl & NAND_CTRL_CHANGE) { - IO_ADDR_W = (ulong)this->IO_ADDR_W; - - IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE); - if (ctrl & NAND_CLE) - IO_ADDR_W |= CONFIG_SYS_NAND_CLE; - if (ctrl & NAND_ALE) - IO_ADDR_W |= CONFIG_SYS_NAND_ALE; - - if (ctrl & NAND_NCE) { - writel(readl(&fsmc_regs_p->genmemctrl_pc) | - FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc); - } else { - writel(readl(&fsmc_regs_p->genmemctrl_pc) & - ~FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc); - } - this->IO_ADDR_W = (void *)IO_ADDR_W; - } - - if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); -} - -static int spear_read_hwecc(struct mtd_info *mtd, - const u_char *data, u_char ecc[3]) -{ - u_int ecc_tmp; - - /* read the h/w ECC */ - ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc); - - ecc[0] = (u_char) (ecc_tmp & 0xFF); - ecc[1] = (u_char) ((ecc_tmp & 0xFF00) >> 8); - ecc[2] = (u_char) ((ecc_tmp & 0xFF0000) >> 16); - - return 0; -} - -void spear_enable_hwecc(struct mtd_info *mtd, int mode) -{ - writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~0x80, - &fsmc_regs_p->genmemctrl_pc); - writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~FSMC_ECCEN, - &fsmc_regs_p->genmemctrl_pc); - writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_ECCEN, - &fsmc_regs_p->genmemctrl_pc); -} - -int spear_nand_init(struct nand_chip *nand) -{ - writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON, - &fsmc_regs_p->genmemctrl_pc); - writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_TCLR_1 | FSMC_TAR_1, - &fsmc_regs_p->genmemctrl_pc); - writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, - &fsmc_regs_p->genmemctrl_comm); - writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, - &fsmc_regs_p->genmemctrl_attrib); - - nand->options = 0; - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.layout = &spear_nand_ecclayout; - nand->ecc.size = 512; - nand->ecc.bytes = 3; - nand->ecc.calculate = spear_read_hwecc; - nand->ecc.hwctl = spear_enable_hwecc; - nand->ecc.correct = nand_correct_data; - nand->cmd_ctrl = spear_nand_hwcontrol; - return 0; -} -- cgit v1.2.3 From f3fcf92d595b297b47a1b58b8ec39f93f40ef912 Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Mon, 7 May 2012 13:00:19 +0530 Subject: st_smi: Add support for SPEAr SMI driver SMI is the serial memory interface controller provided by ST. Earlier, a driver exists in the u-boot source code for the SMI IP. However, it was specific to spear platforms. This commit converts the same driver to a more generic driver. As a result, the driver files are renamed to st_smi.c and st_smi.h and moved into drivers/mtd folder for reusability by other platforms using smi controller peripheral. Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/spr_smi.h | 115 ------- drivers/mtd/Makefile | 2 +- drivers/mtd/spr_smi.c | 518 ----------------------------- drivers/mtd/st_smi.c | 519 ++++++++++++++++++++++++++++++ include/configs/spear-common.h | 6 +- include/linux/mtd/st_smi.h | 117 +++++++ 6 files changed, 640 insertions(+), 637 deletions(-) delete mode 100644 arch/arm/include/asm/arch-spear/spr_smi.h delete mode 100644 drivers/mtd/spr_smi.c create mode 100644 drivers/mtd/st_smi.c create mode 100644 include/linux/mtd/st_smi.h (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/spr_smi.h b/arch/arm/include/asm/arch-spear/spr_smi.h deleted file mode 100644 index 06df74557fd..00000000000 --- a/arch/arm/include/asm/arch-spear/spr_smi.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.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 SPR_SMI_H -#define SPR_SMI_H - -/* 0xF800.0000 . 0xFBFF.FFFF 64MB SMI (Serial Flash Mem) */ -/* 0xFC00.0000 . 0xFC1F.FFFF 2MB SMI (Serial Flash Reg.) */ - -#define FLASH_START_ADDRESS CONFIG_SYS_FLASH_BASE -#define FLASH_BANK_SIZE CONFIG_SYS_FLASH_BANK_SIZE - -#define SMIBANK0_BASE (FLASH_START_ADDRESS) -#define SMIBANK1_BASE (SMIBANK0_BASE + FLASH_BANK_SIZE) -#define SMIBANK2_BASE (SMIBANK1_BASE + FLASH_BANK_SIZE) -#define SMIBANK3_BASE (SMIBANK2_BASE + FLASH_BANK_SIZE) - -#define BANK0 0 -#define BANK1 1 -#define BANK2 2 -#define BANK3 3 - -struct smi_regs { - u32 smi_cr1; - u32 smi_cr2; - u32 smi_sr; - u32 smi_tr; - u32 smi_rr; -}; - -/* CONTROL REG 1 */ -#define BANK_EN 0x0000000F /* enables all banks */ -#define DSEL_TIME 0x00000060 /* Deselect time */ -#define PRESCAL5 0x00000500 /* AHB_CK prescaling value */ -#define PRESCALA 0x00000A00 /* AHB_CK prescaling value */ -#define PRESCAL3 0x00000300 /* AHB_CK prescaling value */ -#define PRESCAL4 0x00000400 /* AHB_CK prescaling value */ -#define SW_MODE 0x10000000 /* enables SW Mode */ -#define WB_MODE 0x20000000 /* Write Burst Mode */ -#define FAST_MODE 0x00008000 /* Fast Mode */ -#define HOLD1 0x00010000 - -/* CONTROL REG 2 */ -#define RD_STATUS_REG 0x00000400 /* reads status reg */ -#define WE 0x00000800 /* Write Enable */ -#define BANK0_SEL 0x00000000 /* Select Banck0 */ -#define BANK1_SEL 0x00001000 /* Select Banck1 */ -#define BANK2_SEL 0x00002000 /* Select Banck2 */ -#define BANK3_SEL 0x00003000 /* Select Banck3 */ -#define BANKSEL_SHIFT 12 -#define SEND 0x00000080 /* Send data */ -#define TX_LEN_1 0x00000001 /* data length = 1 byte */ -#define TX_LEN_2 0x00000002 /* data length = 2 byte */ -#define TX_LEN_3 0x00000003 /* data length = 3 byte */ -#define TX_LEN_4 0x00000004 /* data length = 4 byte */ -#define RX_LEN_1 0x00000010 /* data length = 1 byte */ -#define RX_LEN_2 0x00000020 /* data length = 2 byte */ -#define RX_LEN_3 0x00000030 /* data length = 3 byte */ -#define RX_LEN_4 0x00000040 /* data length = 4 byte */ -#define TFIE 0x00000100 /* Tx Flag Interrupt Enable */ -#define WCIE 0x00000200 /* WCF Interrupt Enable */ - -/* STATUS_REG */ -#define INT_WCF_CLR 0xFFFFFDFF /* clear: WCF clear */ -#define INT_TFF_CLR 0xFFFFFEFF /* clear: TFF clear */ -#define WIP_BIT 0x00000001 /* WIP Bit of SPI SR */ -#define WEL_BIT 0x00000002 /* WEL Bit of SPI SR */ -#define RSR 0x00000005 /* Read Status regiser */ -#define TFF 0x00000100 /* Transfer Finished FLag */ -#define WCF 0x00000200 /* Transfer Finished FLag */ -#define ERF1 0x00000400 /* Error Flag 1 */ -#define ERF2 0x00000800 /* Error Flag 2 */ -#define WM0 0x00001000 /* WM Bank 0 */ -#define WM1 0x00002000 /* WM Bank 1 */ -#define WM2 0x00004000 /* WM Bank 2 */ -#define WM3 0x00008000 /* WM Bank 3 */ -#define WM_SHIFT 12 - -/* TR REG */ -#define READ_ID 0x0000009F /* Read Identification */ -#define BULK_ERASE 0x000000C7 /* BULK erase */ -#define SECTOR_ERASE 0x000000D8 /* SECTOR erase */ -#define WRITE_ENABLE 0x00000006 /* Wenable command to FLASH */ - -struct flash_dev { - u32 density; - ulong size; - ushort sector_count; -}; - -#define SFLASH_PAGE_SIZE 0x100 /* flash page size */ -#define XFER_FINISH_TOUT 2 /* xfer finish timeout */ -#define WMODE_TOUT 2 /* write enable timeout */ - -#endif diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 5a5ecdfe3c6..543c845ff01 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -35,7 +35,7 @@ COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o COBJS-$(CONFIG_FTSMC020) += ftsmc020.o COBJS-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o COBJS-$(CONFIG_MW_EEPROM) += mw_eeprom.o -COBJS-$(CONFIG_SPEARSMI) += spr_smi.o +COBJS-$(CONFIG_ST_SMI) += st_smi.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/mtd/spr_smi.c b/drivers/mtd/spr_smi.c deleted file mode 100644 index 6d4257a3f50..00000000000 --- a/drivers/mtd/spr_smi.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - -#if !defined(CONFIG_SYS_NO_FLASH) - -static struct smi_regs *const smicntl = - (struct smi_regs * const)CONFIG_SYS_SMI_BASE; -static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = - CONFIG_SYS_FLASH_ADDR_BASE; -flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; - -#define ST_M25Pxx_ID 0x00002020 - -static struct flash_dev flash_ids[] = { - {0x10, 0x10000, 2}, /* 64K Byte */ - {0x11, 0x20000, 4}, /* 128K Byte */ - {0x12, 0x40000, 4}, /* 256K Byte */ - {0x13, 0x80000, 8}, /* 512K Byte */ - {0x14, 0x100000, 16}, /* 1M Byte */ - {0x15, 0x200000, 32}, /* 2M Byte */ - {0x16, 0x400000, 64}, /* 4M Byte */ - {0x17, 0x800000, 128}, /* 8M Byte */ - {0x18, 0x1000000, 64}, /* 16M Byte */ - {0x00,} -}; - -/* - * smi_wait_xfer_finish - Wait until TFF is set in status register - * @timeout: timeout in milliseconds - * - * Wait until TFF is set in status register - */ -static void smi_wait_xfer_finish(int timeout) -{ - while (timeout--) { - if (readl(&smicntl->smi_sr) & TFF) - break; - udelay(1000); - } -} - -/* - * smi_read_id - Read flash id - * @info: flash_info structure pointer - * @banknum: bank number - * - * Read the flash id present at bank #banknum - */ -static unsigned int smi_read_id(flash_info_t *info, int banknum) -{ - unsigned int value; - - writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1); - writel(READ_ID, &smicntl->smi_tr); - writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3, - &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); - - value = (readl(&smicntl->smi_rr) & 0x00FFFFFF); - - writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr); - writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); - - return value; -} - -/* - * flash_get_size - Detect the SMI flash by reading the ID. - * @base: Base address of the flash area bank #banknum - * @banknum: Bank number - * - * Detect the SMI flash by reading the ID. Initializes the flash_info structure - * with size, sector count etc. - */ -static ulong flash_get_size(ulong base, int banknum) -{ - flash_info_t *info = &flash_info[banknum]; - struct flash_dev *dev; - unsigned int value; - unsigned int density; - int i; - - value = smi_read_id(info, banknum); - density = (value >> 16) & 0xff; - - for (i = 0, dev = &flash_ids[0]; dev->density != 0x0; - i++, dev = &flash_ids[i]) { - if (dev->density == density) { - info->size = dev->size; - info->sector_count = dev->sector_count; - break; - } - } - - if (dev->density == 0x0) - return 0; - - info->flash_id = value & 0xffff; - info->start[0] = base; - - return info->size; -} - -/* - * smi_read_sr - Read status register of SMI - * @bank: bank number - * - * This routine will get the status register of the flash chip present at the - * given bank - */ -static unsigned int smi_read_sr(int bank) -{ - u32 ctrlreg1; - - /* store the CTRL REG1 state */ - ctrlreg1 = readl(&smicntl->smi_cr1); - - /* Program SMI in HW Mode */ - writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE), - &smicntl->smi_cr1); - - /* Performing a RSR instruction in HW mode */ - writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2); - - smi_wait_xfer_finish(XFER_FINISH_TOUT); - - /* Restore the CTRL REG1 state */ - writel(ctrlreg1, &smicntl->smi_cr1); - - return readl(&smicntl->smi_sr); -} - -/* - * smi_wait_till_ready - Wait till last operation is over. - * @bank: bank number shifted. - * @timeout: timeout in milliseconds. - * - * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0) - * The routine checks for #timeout loops, each at interval of 1 milli-second. - * If successful the routine returns 0. - */ -static int smi_wait_till_ready(int bank, int timeout) -{ - int count; - unsigned int sr; - - /* One chip guarantees max 5 msec wait here after page writes, - but potentially three seconds (!) after page erase. */ - for (count = 0; count < timeout; count++) { - - sr = smi_read_sr(bank); - if (sr < 0) - break; - else if (!(sr & WIP_BIT)) - return 0; - - /* Try again after 1m-sec */ - udelay(1000); - } - printf("SMI controller is still in wait, timeout=%d\n", timeout); - return -EIO; -} - -/* - * smi_write_enable - Enable the flash to do write operation - * @bank: bank number - * - * Set write enable latch with Write Enable command. - * Returns negative if error occurred. - */ -static int smi_write_enable(int bank) -{ - u32 ctrlreg1; - int timeout = WMODE_TOUT; - - /* Store the CTRL REG1 state */ - ctrlreg1 = readl(&smicntl->smi_cr1); - - /* Program SMI in H/W Mode */ - writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); - - /* Give the Flash, Write Enable command */ - writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2); - - smi_wait_xfer_finish(XFER_FINISH_TOUT); - - /* Restore the CTRL REG1 state */ - writel(ctrlreg1, &smicntl->smi_cr1); - - while (timeout--) { - if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT))) - break; - udelay(1000); - } - - if (timeout) - return 0; - - return -1; -} - -/* - * smi_init - SMI initialization routine - * - * SMI initialization routine. Sets SMI control register1. - */ -static void smi_init(void) -{ - /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */ - writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4, - &smicntl->smi_cr1); -} - -/* - * smi_sector_erase - Erase flash sector - * @info: flash_info structure pointer - * @sector: sector number - * - * Set write enable latch with Write Enable command. - * Returns negative if error occurred. - */ -static int smi_sector_erase(flash_info_t *info, unsigned int sector) -{ - int bank; - unsigned int sect_add; - unsigned int instruction; - - switch (info->start[0]) { - case SMIBANK0_BASE: - bank = BANK0; - break; - case SMIBANK1_BASE: - bank = BANK1; - break; - case SMIBANK2_BASE: - bank = BANK2; - break; - case SMIBANK3_BASE: - bank = BANK3; - break; - default: - return -1; - } - - sect_add = sector * (info->size / info->sector_count); - instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE; - - writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr); - - if (info->flash_id == ST_M25Pxx_ID) { - /* Wait until finished previous write command. */ - if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT)) - return -EBUSY; - - /* Send write enable, before erase commands. */ - if (smi_write_enable(bank)) - return -EIO; - - /* Put SMI in SW mode */ - writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1); - - /* Send Sector Erase command in SW Mode */ - writel(instruction, &smicntl->smi_tr); - writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4, - &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); - - if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT)) - return -EBUSY; - - /* Put SMI in HW mode */ - writel(readl(&smicntl->smi_cr1) & ~SW_MODE, - &smicntl->smi_cr1); - - return 0; - } else { - /* Put SMI in HW mode */ - writel(readl(&smicntl->smi_cr1) & ~SW_MODE, - &smicntl->smi_cr1); - return -EINVAL; - } -} - -/* - * smi_write - Write to SMI flash - * @src_addr: source buffer - * @dst_addr: destination buffer - * @length: length to write in words - * @bank: bank base address - * - * Write to SMI flash - */ -static int smi_write(unsigned int *src_addr, unsigned int *dst_addr, - unsigned int length, ulong bank_addr) -{ - int banknum; - - switch (bank_addr) { - case SMIBANK0_BASE: - banknum = BANK0; - break; - case SMIBANK1_BASE: - banknum = BANK1; - break; - case SMIBANK2_BASE: - banknum = BANK2; - break; - case SMIBANK3_BASE: - banknum = BANK3; - break; - default: - return -1; - } - - if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT)) - return -EBUSY; - - /* Set SMI in Hardware Mode */ - writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); - - if (smi_write_enable(banknum)) - return -EIO; - - /* Perform the write command */ - while (length--) { - if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) { - if (smi_wait_till_ready(banknum, - CONFIG_SYS_FLASH_WRITE_TOUT)) - return -EBUSY; - - if (smi_write_enable(banknum)) - return -EIO; - } - - *dst_addr++ = *src_addr++; - - if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2))) - return -EIO; - } - - if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT)) - return -EBUSY; - - writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr); - - return 0; -} - -/* - * write_buff - Write to SMI flash - * @info: flash info structure - * @src: source buffer - * @dest_addr: destination buffer - * @length: length to write in words - * - * Write to SMI flash - */ -int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length) -{ - return smi_write((unsigned int *)src, (unsigned int *)dest_addr, - (length + 3) / 4, info->start[0]); -} - -/* - * flash_init - SMI flash initialization - * - * SMI flash initialization - */ -unsigned long flash_init(void) -{ - unsigned long size = 0; - int i, j; - - smi_init(); - - for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { - flash_info[i].flash_id = FLASH_UNKNOWN; - size += flash_info[i].size = flash_get_size(bank_base[i], i); - } - - for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) { - for (i = 1; i < flash_info[j].sector_count; i++) - flash_info[j].start[i] = - flash_info[j].start[i - 1] + - flash_info->size / flash_info->sector_count; - - } - - return size; -} - -/* - * flash_print_info - Print SMI flash information - * - * Print SMI flash information - */ -void flash_print_info(flash_info_t *info) -{ - int i; - if (info->flash_id == FLASH_UNKNOWN) { - puts("missing or unknown FLASH type\n"); - return; - } - printf(" Size: %ld MB in %d Sectors\n", - info->size >> 20, info->sector_count); - - puts(" Sector Start Addresses:"); - for (i = 0; i < info->sector_count; ++i) { -#ifdef CONFIG_SYS_FLASH_EMPTY_INFO - int size; - int erased; - u32 *flash; - - /* - * Check if whole sector is erased - */ - size = (info->size) / (info->sector_count); - flash = (u32 *) info->start[i]; - size = size / sizeof(int); - - while ((size--) && (*flash++ == ~0)) - ; - - size++; - if (size) - erased = 0; - else - erased = 1; - - if ((i % 5) == 0) - printf("\n"); - - printf(" %08lX%s%s", - info->start[i], - erased ? " E" : " ", info->protect[i] ? "RO " : " "); -#else - if ((i % 5) == 0) - printf("\n "); - printf(" %08lX%s", - info->start[i], info->protect[i] ? " (RO) " : " "); -#endif - } - putc('\n'); - return; -} - -/* - * flash_erase - Erase SMI flash - * - * Erase SMI flash - */ -int flash_erase(flash_info_t *info, int s_first, int s_last) -{ - int rcode = 0; - int prot = 0; - flash_sect_t sect; - - if (info->flash_id != ST_M25Pxx_ID) { - puts("Can't erase unknown flash type - aborted\n"); - return 1; - } - - if ((s_first < 0) || (s_first > s_last)) { - puts("- no sectors to erase\n"); - return 1; - } - - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) - prot++; - } - if (prot) { - printf("- Warning: %d protected sectors will not be erased!\n", - prot); - } else { - putc('\n'); - } - - for (sect = s_first; sect <= s_last; sect++) { - if (info->protect[sect] == 0) { - if (smi_sector_erase(info, sect)) - rcode = 1; - else - putc('.'); - } - } - puts(" done\n"); - return rcode; -} -#endif diff --git a/drivers/mtd/st_smi.c b/drivers/mtd/st_smi.c new file mode 100644 index 00000000000..db08ab97e43 --- /dev/null +++ b/drivers/mtd/st_smi.c @@ -0,0 +1,519 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include +#include + +#if !defined(CONFIG_SYS_NO_FLASH) + +static struct smi_regs *const smicntl = + (struct smi_regs * const)CONFIG_SYS_SMI_BASE; +static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = + CONFIG_SYS_FLASH_ADDR_BASE; +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +#define ST_M25Pxx_ID 0x00002020 + +static struct flash_dev flash_ids[] = { + {0x10, 0x10000, 2}, /* 64K Byte */ + {0x11, 0x20000, 4}, /* 128K Byte */ + {0x12, 0x40000, 4}, /* 256K Byte */ + {0x13, 0x80000, 8}, /* 512K Byte */ + {0x14, 0x100000, 16}, /* 1M Byte */ + {0x15, 0x200000, 32}, /* 2M Byte */ + {0x16, 0x400000, 64}, /* 4M Byte */ + {0x17, 0x800000, 128}, /* 8M Byte */ + {0x18, 0x1000000, 64}, /* 16M Byte */ + {0x00,} +}; + +/* + * smi_wait_xfer_finish - Wait until TFF is set in status register + * @timeout: timeout in milliseconds + * + * Wait until TFF is set in status register + */ +static void smi_wait_xfer_finish(int timeout) +{ + while (timeout--) { + if (readl(&smicntl->smi_sr) & TFF) + break; + udelay(1000); + } +} + +/* + * smi_read_id - Read flash id + * @info: flash_info structure pointer + * @banknum: bank number + * + * Read the flash id present at bank #banknum + */ +static unsigned int smi_read_id(flash_info_t *info, int banknum) +{ + unsigned int value; + + writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1); + writel(READ_ID, &smicntl->smi_tr); + writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3, + &smicntl->smi_cr2); + + smi_wait_xfer_finish(XFER_FINISH_TOUT); + + value = (readl(&smicntl->smi_rr) & 0x00FFFFFF); + + writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr); + writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); + + return value; +} + +/* + * flash_get_size - Detect the SMI flash by reading the ID. + * @base: Base address of the flash area bank #banknum + * @banknum: Bank number + * + * Detect the SMI flash by reading the ID. Initializes the flash_info structure + * with size, sector count etc. + */ +static ulong flash_get_size(ulong base, int banknum) +{ + flash_info_t *info = &flash_info[banknum]; + struct flash_dev *dev; + unsigned int value; + unsigned int density; + int i; + + value = smi_read_id(info, banknum); + density = (value >> 16) & 0xff; + + for (i = 0, dev = &flash_ids[0]; dev->density != 0x0; + i++, dev = &flash_ids[i]) { + if (dev->density == density) { + info->size = dev->size; + info->sector_count = dev->sector_count; + break; + } + } + + if (dev->density == 0x0) + return 0; + + info->flash_id = value & 0xffff; + info->start[0] = base; + + return info->size; +} + +/* + * smi_read_sr - Read status register of SMI + * @bank: bank number + * + * This routine will get the status register of the flash chip present at the + * given bank + */ +static unsigned int smi_read_sr(int bank) +{ + u32 ctrlreg1; + + /* store the CTRL REG1 state */ + ctrlreg1 = readl(&smicntl->smi_cr1); + + /* Program SMI in HW Mode */ + writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE), + &smicntl->smi_cr1); + + /* Performing a RSR instruction in HW mode */ + writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2); + + smi_wait_xfer_finish(XFER_FINISH_TOUT); + + /* Restore the CTRL REG1 state */ + writel(ctrlreg1, &smicntl->smi_cr1); + + return readl(&smicntl->smi_sr); +} + +/* + * smi_wait_till_ready - Wait till last operation is over. + * @bank: bank number shifted. + * @timeout: timeout in milliseconds. + * + * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0) + * The routine checks for #timeout loops, each at interval of 1 milli-second. + * If successful the routine returns 0. + */ +static int smi_wait_till_ready(int bank, int timeout) +{ + int count; + unsigned int sr; + + /* One chip guarantees max 5 msec wait here after page writes, + but potentially three seconds (!) after page erase. */ + for (count = 0; count < timeout; count++) { + + sr = smi_read_sr(bank); + if (sr < 0) + break; + else if (!(sr & WIP_BIT)) + return 0; + + /* Try again after 1m-sec */ + udelay(1000); + } + printf("SMI controller is still in wait, timeout=%d\n", timeout); + return -EIO; +} + +/* + * smi_write_enable - Enable the flash to do write operation + * @bank: bank number + * + * Set write enable latch with Write Enable command. + * Returns negative if error occurred. + */ +static int smi_write_enable(int bank) +{ + u32 ctrlreg1; + int timeout = WMODE_TOUT; + + /* Store the CTRL REG1 state */ + ctrlreg1 = readl(&smicntl->smi_cr1); + + /* Program SMI in H/W Mode */ + writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); + + /* Give the Flash, Write Enable command */ + writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2); + + smi_wait_xfer_finish(XFER_FINISH_TOUT); + + /* Restore the CTRL REG1 state */ + writel(ctrlreg1, &smicntl->smi_cr1); + + while (timeout--) { + if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT))) + break; + udelay(1000); + } + + if (timeout) + return 0; + + return -1; +} + +/* + * smi_init - SMI initialization routine + * + * SMI initialization routine. Sets SMI control register1. + */ +void smi_init(void) +{ + /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */ + writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4, + &smicntl->smi_cr1); +} + +/* + * smi_sector_erase - Erase flash sector + * @info: flash_info structure pointer + * @sector: sector number + * + * Set write enable latch with Write Enable command. + * Returns negative if error occurred. + */ +static int smi_sector_erase(flash_info_t *info, unsigned int sector) +{ + int bank; + unsigned int sect_add; + unsigned int instruction; + + switch (info->start[0]) { + case SMIBANK0_BASE: + bank = BANK0; + break; + case SMIBANK1_BASE: + bank = BANK1; + break; + case SMIBANK2_BASE: + bank = BANK2; + break; + case SMIBANK3_BASE: + bank = BANK3; + break; + default: + return -1; + } + + sect_add = sector * (info->size / info->sector_count); + instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE; + + writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr); + + if (info->flash_id == ST_M25Pxx_ID) { + /* Wait until finished previous write command. */ + if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT)) + return -EBUSY; + + /* Send write enable, before erase commands. */ + if (smi_write_enable(bank)) + return -EIO; + + /* Put SMI in SW mode */ + writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1); + + /* Send Sector Erase command in SW Mode */ + writel(instruction, &smicntl->smi_tr); + writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4, + &smicntl->smi_cr2); + smi_wait_xfer_finish(XFER_FINISH_TOUT); + + if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT)) + return -EBUSY; + + /* Put SMI in HW mode */ + writel(readl(&smicntl->smi_cr1) & ~SW_MODE, + &smicntl->smi_cr1); + + return 0; + } else { + /* Put SMI in HW mode */ + writel(readl(&smicntl->smi_cr1) & ~SW_MODE, + &smicntl->smi_cr1); + return -EINVAL; + } +} + +/* + * smi_write - Write to SMI flash + * @src_addr: source buffer + * @dst_addr: destination buffer + * @length: length to write in words + * @bank: bank base address + * + * Write to SMI flash + */ +static int smi_write(unsigned int *src_addr, unsigned int *dst_addr, + unsigned int length, ulong bank_addr) +{ + int banknum; + + switch (bank_addr) { + case SMIBANK0_BASE: + banknum = BANK0; + break; + case SMIBANK1_BASE: + banknum = BANK1; + break; + case SMIBANK2_BASE: + banknum = BANK2; + break; + case SMIBANK3_BASE: + banknum = BANK3; + break; + default: + return -1; + } + + if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT)) + return -EBUSY; + + /* Set SMI in Hardware Mode */ + writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); + + if (smi_write_enable(banknum)) + return -EIO; + + /* Perform the write command */ + while (length--) { + if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) { + if (smi_wait_till_ready(banknum, + CONFIG_SYS_FLASH_WRITE_TOUT)) + return -EBUSY; + + if (smi_write_enable(banknum)) + return -EIO; + } + + *dst_addr++ = *src_addr++; + + if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2))) + return -EIO; + } + + if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT)) + return -EBUSY; + + writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr); + + return 0; +} + +/* + * write_buff - Write to SMI flash + * @info: flash info structure + * @src: source buffer + * @dest_addr: destination buffer + * @length: length to write in words + * + * Write to SMI flash + */ +int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length) +{ + return smi_write((unsigned int *)src, (unsigned int *)dest_addr, + (length + 3) / 4, info->start[0]); +} + +/* + * flash_init - SMI flash initialization + * + * SMI flash initialization + */ +unsigned long flash_init(void) +{ + unsigned long size = 0; + int i, j; + + smi_init(); + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + flash_info[i].flash_id = FLASH_UNKNOWN; + size += flash_info[i].size = flash_get_size(bank_base[i], i); + } + + for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) { + for (i = 1; i < flash_info[j].sector_count; i++) + flash_info[j].start[i] = + flash_info[j].start[i - 1] + + flash_info->size / flash_info->sector_count; + + } + + return size; +} + +/* + * flash_print_info - Print SMI flash information + * + * Print SMI flash information + */ +void flash_print_info(flash_info_t *info) +{ + int i; + if (info->flash_id == FLASH_UNKNOWN) { + puts("missing or unknown FLASH type\n"); + return; + } + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + puts(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { +#ifdef CONFIG_SYS_FLASH_EMPTY_INFO + int size; + int erased; + u32 *flash; + + /* + * Check if whole sector is erased + */ + size = (info->size) / (info->sector_count); + flash = (u32 *) info->start[i]; + size = size / sizeof(int); + + while ((size--) && (*flash++ == ~0)) + ; + + size++; + if (size) + erased = 0; + else + erased = 1; + + if ((i % 5) == 0) + printf("\n"); + + printf(" %08lX%s%s", + info->start[i], + erased ? " E" : " ", info->protect[i] ? "RO " : " "); +#else + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s", + info->start[i], info->protect[i] ? " (RO) " : " "); +#endif + } + putc('\n'); + return; +} + +/* + * flash_erase - Erase SMI flash + * + * Erase SMI flash + */ +int flash_erase(flash_info_t *info, int s_first, int s_last) +{ + int rcode = 0; + int prot = 0; + flash_sect_t sect; + + if (info->flash_id != ST_M25Pxx_ID) { + puts("Can't erase unknown flash type - aborted\n"); + return 1; + } + + if ((s_first < 0) || (s_first > s_last)) { + puts("- no sectors to erase\n"); + return 1; + } + + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) + prot++; + } + if (prot) { + printf("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + putc('\n'); + } + + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { + if (smi_sector_erase(info, sect)) + rcode = 1; + else + putc('.'); + } + } + puts(" done\n"); + return rcode; +} +#endif diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 8d0f0369ca9..75cc5fff64c 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -55,10 +55,10 @@ #if defined(CONFIG_FLASH_PNOR) #define CONFIG_SPEAR_EMI 1 #else -#define CONFIG_SPEARSMI 1 +#define CONFIG_ST_SMI #endif -#if defined(CONFIG_SPEARSMI) +#if defined(CONFIG_ST_SMI) #define CONFIG_SYS_MAX_FLASH_BANKS 2 #define CONFIG_SYS_FLASH_BASE (0xF8000000) @@ -125,7 +125,7 @@ * U-Boot Environment placing definitions. */ #if defined(CONFIG_ENV_IS_IN_FLASH) -#ifdef CONFIG_SPEARSMI +#ifdef CONFIG_ST_SMI /* * Environment is in serial NOR flash */ diff --git a/include/linux/mtd/st_smi.h b/include/linux/mtd/st_smi.h new file mode 100644 index 00000000000..b7a78acd7c2 --- /dev/null +++ b/include/linux/mtd/st_smi.h @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.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 ST_SMI_H +#define ST_SMI_H + +/* 0xF800.0000 . 0xFBFF.FFFF 64MB SMI (Serial Flash Mem) */ +/* 0xFC00.0000 . 0xFC1F.FFFF 2MB SMI (Serial Flash Reg.) */ + +#define FLASH_START_ADDRESS CONFIG_SYS_FLASH_BASE +#define FLASH_BANK_SIZE CONFIG_SYS_FLASH_BANK_SIZE + +#define SMIBANK0_BASE (FLASH_START_ADDRESS) +#define SMIBANK1_BASE (SMIBANK0_BASE + FLASH_BANK_SIZE) +#define SMIBANK2_BASE (SMIBANK1_BASE + FLASH_BANK_SIZE) +#define SMIBANK3_BASE (SMIBANK2_BASE + FLASH_BANK_SIZE) + +#define BANK0 0 +#define BANK1 1 +#define BANK2 2 +#define BANK3 3 + +struct smi_regs { + u32 smi_cr1; + u32 smi_cr2; + u32 smi_sr; + u32 smi_tr; + u32 smi_rr; +}; + +/* CONTROL REG 1 */ +#define BANK_EN 0x0000000F /* enables all banks */ +#define DSEL_TIME 0x00000060 /* Deselect time */ +#define PRESCAL5 0x00000500 /* AHB_CK prescaling value */ +#define PRESCALA 0x00000A00 /* AHB_CK prescaling value */ +#define PRESCAL3 0x00000300 /* AHB_CK prescaling value */ +#define PRESCAL4 0x00000400 /* AHB_CK prescaling value */ +#define SW_MODE 0x10000000 /* enables SW Mode */ +#define WB_MODE 0x20000000 /* Write Burst Mode */ +#define FAST_MODE 0x00008000 /* Fast Mode */ +#define HOLD1 0x00010000 + +/* CONTROL REG 2 */ +#define RD_STATUS_REG 0x00000400 /* reads status reg */ +#define WE 0x00000800 /* Write Enable */ +#define BANK0_SEL 0x00000000 /* Select Banck0 */ +#define BANK1_SEL 0x00001000 /* Select Banck1 */ +#define BANK2_SEL 0x00002000 /* Select Banck2 */ +#define BANK3_SEL 0x00003000 /* Select Banck3 */ +#define BANKSEL_SHIFT 12 +#define SEND 0x00000080 /* Send data */ +#define TX_LEN_1 0x00000001 /* data length = 1 byte */ +#define TX_LEN_2 0x00000002 /* data length = 2 byte */ +#define TX_LEN_3 0x00000003 /* data length = 3 byte */ +#define TX_LEN_4 0x00000004 /* data length = 4 byte */ +#define RX_LEN_1 0x00000010 /* data length = 1 byte */ +#define RX_LEN_2 0x00000020 /* data length = 2 byte */ +#define RX_LEN_3 0x00000030 /* data length = 3 byte */ +#define RX_LEN_4 0x00000040 /* data length = 4 byte */ +#define TFIE 0x00000100 /* Tx Flag Interrupt Enable */ +#define WCIE 0x00000200 /* WCF Interrupt Enable */ + +/* STATUS_REG */ +#define INT_WCF_CLR 0xFFFFFDFF /* clear: WCF clear */ +#define INT_TFF_CLR 0xFFFFFEFF /* clear: TFF clear */ +#define WIP_BIT 0x00000001 /* WIP Bit of SPI SR */ +#define WEL_BIT 0x00000002 /* WEL Bit of SPI SR */ +#define RSR 0x00000005 /* Read Status regiser */ +#define TFF 0x00000100 /* Transfer Finished FLag */ +#define WCF 0x00000200 /* Transfer Finished FLag */ +#define ERF1 0x00000400 /* Error Flag 1 */ +#define ERF2 0x00000800 /* Error Flag 2 */ +#define WM0 0x00001000 /* WM Bank 0 */ +#define WM1 0x00002000 /* WM Bank 1 */ +#define WM2 0x00004000 /* WM Bank 2 */ +#define WM3 0x00008000 /* WM Bank 3 */ +#define WM_SHIFT 12 + +/* TR REG */ +#define READ_ID 0x0000009F /* Read Identification */ +#define BULK_ERASE 0x000000C7 /* BULK erase */ +#define SECTOR_ERASE 0x000000D8 /* SECTOR erase */ +#define WRITE_ENABLE 0x00000006 /* Wenable command to FLASH */ + +struct flash_dev { + u32 density; + ulong size; + ushort sector_count; +}; + +#define SFLASH_PAGE_SIZE 0x100 /* flash page size */ +#define XFER_FINISH_TOUT 2 /* xfer finish timeout */ +#define WMODE_TOUT 2 /* write enable timeout */ + +extern void smi_init(void); + +#endif -- cgit v1.2.3 From 70fdbefc6c50010cc56196b65a233369d2b2ce68 Mon Sep 17 00:00:00 2001 From: Amit Virdi Date: Mon, 7 May 2012 13:06:40 +0530 Subject: SPEAr: Eliminate dependency on Xloader table Xloader table was used primarily to inform u-boot about the DDR size. However, now the ddr size is calculated at runtime which eliminates any need for the Xloader table. So removing this unnecessary code. Signed-off-by: Amit Virdi Acked-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/spr_defs.h | 7 --- .../arm/include/asm/arch-spear/spr_xloader_table.h | 67 ---------------------- board/spear/common/spr_misc.c | 41 ------------- 3 files changed, 115 deletions(-) delete mode 100644 arch/arm/include/asm/arch-spear/spr_xloader_table.h (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/spr_defs.h b/arch/arm/include/asm/arch-spear/spr_defs.h index fa8412ccfc1..0ddce621e39 100644 --- a/arch/arm/include/asm/arch-spear/spr_defs.h +++ b/arch/arm/include/asm/arch-spear/spr_defs.h @@ -28,13 +28,6 @@ extern int spear_board_init(ulong); extern void setfreq(unsigned int, unsigned int); extern unsigned int setfreq_sz; -struct chip_data { - int cpufreq; - int dramfreq; - int dramtype; - uchar version[32]; -}; - /* HW mac id in i2c memory definitions */ #define MAGIC_OFF 0x0 #define MAGIC_LEN 0x2 diff --git a/arch/arm/include/asm/arch-spear/spr_xloader_table.h b/arch/arm/include/asm/arch-spear/spr_xloader_table.h deleted file mode 100644 index 7e3da185784..00000000000 --- a/arch/arm/include/asm/arch-spear/spr_xloader_table.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.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 _SPR_XLOADER_TABLE_H -#define _SPR_XLOADER_TABLE_H - -#define XLOADER_TABLE_VERSION_1_1 2 -#define XLOADER_TABLE_VERSION_1_2 3 - -#define XLOADER_TABLE_ADDRESS 0xD2801FF0 - -#define DDRMOBILE 1 -#define DDR2 2 - -#define REV_BA 1 -#define REV_AA 2 -#define REV_AB 3 - -struct xloader_table_1_1 { - unsigned short ddrfreq; - unsigned char ddrsize; - unsigned char ddrtype; - - unsigned char soc_rev; -} __attribute__ ((packed)); - -struct xloader_table_1_2 { - unsigned const char *version; - - unsigned short ddrfreq; - unsigned char ddrsize; - unsigned char ddrtype; - - unsigned char soc_rev; -} __attribute__ ((packed)); - -union table_contents { - struct xloader_table_1_1 table_1_1; - struct xloader_table_1_2 table_1_2; -}; - -struct xloader_table { - unsigned char table_version; - union table_contents table; -} __attribute__ ((packed)); - -#endif diff --git a/board/spear/common/spr_misc.c b/board/spear/common/spr_misc.c index 3ab278f83a7..be96c1504e6 100644 --- a/board/spear/common/spr_misc.c +++ b/board/spear/common/spr_misc.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #define CPU 0 @@ -36,7 +35,6 @@ #define SRAM_REL 0xD2801000 DECLARE_GLOBAL_DATA_PTR; -static struct chip_data chip_data; int dram_init(void) { @@ -127,25 +125,11 @@ void spear_emi_init(void) int spear_board_init(ulong mach_type) { - struct xloader_table *xloader_tb = - (struct xloader_table *)XLOADER_TABLE_ADDRESS; - struct xloader_table_1_2 *table_1_2; - struct chip_data *chip = &chip_data; - gd->bd->bi_arch_number = mach_type; /* adress of boot parameters */ gd->bd->bi_boot_params = CONFIG_BOOT_PARAMS_ADDR; - /* CPU is initialized to work at 333MHz in Xloader */ - chip->cpufreq = 333; - - if (XLOADER_TABLE_VERSION_1_2 == xloader_tb->table_version) { - table_1_2 = &xloader_tb->table.table_1_2; - memcpy(chip->version, table_1_2->version, - sizeof(chip->version)); - } - #ifdef CONFIG_SPEAR_EMI spear_emi_init(); #endif @@ -195,7 +179,6 @@ static int write_mac(uchar *mac) int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void (*sram_setfreq) (unsigned int, unsigned int); - struct chip_data *chip = &chip_data; unsigned char mac[6]; unsigned int reg, frequency; char *s, *e; @@ -218,13 +201,9 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (!strcmp(argv[1], "cpufreq")) { sram_setfreq(CPU, frequency); printf("CPU frequency changed to %u\n", frequency); - - chip->cpufreq = frequency; } else { sram_setfreq(DDR, frequency); printf("DDR frequency changed to %u\n", frequency); - - chip->dramfreq = frequency; } return 0; @@ -240,24 +219,6 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } else if (!strcmp(argv[1], "print")) { - - if (chip->cpufreq == -1) - printf("CPU Freq = Not Known\n"); - else - printf("CPU Freq = %d MHz\n", chip->cpufreq); - - if (chip->dramfreq == -1) - printf("DDR Freq = Not Known\n"); - else - printf("DDR Freq = %d MHz\n", chip->dramfreq); - - if (chip->dramtype == DDRMOBILE) - printf("DDR Type = MOBILE\n"); - else if (chip->dramtype == DDR2) - printf("DDR Type = DDR2\n"); - else - printf("DDR Type = Not Known\n"); - if (!i2c_read_mac(mac)) { sprintf(i2c_mac, "%pM", mac); printf("Ethaddr (from i2c mem) = %s\n", i2c_mac); @@ -265,8 +226,6 @@ int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Ethaddr (from i2c mem) = Not set\n"); } - printf("Xloader Rev = %s\n", chip->version); - return 0; } -- cgit v1.2.3 From deb005622782bf568a4daa8daeb8adf95b606492 Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Mon, 7 May 2012 13:06:42 +0530 Subject: SPEAr: Configure network support for spear SoCs Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/hardware.h | 1 + board/spear/spear300/spear300.c | 10 ++++++++++ board/spear/spear310/spear310.c | 10 ++++++++++ board/spear/spear320/spear320.c | 10 ++++++++++ board/spear/spear600/spear600.c | 10 ++++++++++ include/configs/spear-common.h | 14 ++++++++++++-- include/configs/spear3xx.h | 3 +++ 7 files changed, 56 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h index a6517b2187f..70fc0303553 100644 --- a/arch/arm/include/asm/arch-spear/hardware.h +++ b/arch/arm/include/asm/arch-spear/hardware.h @@ -31,6 +31,7 @@ #define CONFIG_SPEAR_SYSCNTLBASE (0xFCA00000) #define CONFIG_SPEAR_TIMERBASE (0xFC800000) #define CONFIG_SPEAR_MISCBASE (0xFCA80000) +#define CONFIG_SPEAR_ETHBASE 0xE0800000 #define CONFIG_SYS_NAND_CLE (1 << 16) #define CONFIG_SYS_NAND_ALE (1 << 17) diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c index 72a36314089..2283ad5ddbc 100644 --- a/board/spear/spear300/spear300.c +++ b/board/spear/spear300/spear300.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -60,3 +61,12 @@ void board_nand_init() #endif return; } + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DESIGNWARE_ETH) + return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); +#else + return -1; +#endif +} diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index 14e666d6417..043a9f3aee9 100644 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -61,3 +62,12 @@ void board_nand_init() #endif return; } + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DESIGNWARE_ETH) + return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); +#else + return -1; +#endif +} diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index 994eb2b64d2..1b6f362b5d8 100644 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -62,3 +63,12 @@ void board_nand_init() return; } + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DESIGNWARE_ETH) + return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); +#else + return -1; +#endif +} diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c index ab0f760678b..d18d313b298 100644 --- a/board/spear/spear600/spear600.c +++ b/board/spear/spear600/spear600.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -55,3 +56,12 @@ void board_nand_init() #endif return; } + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DESIGNWARE_ETH) + return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); +#else + return -1; +#endif +} diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 75cc5fff64c..669d83eb7eb 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -27,6 +27,14 @@ * Common configurations used for both spear3xx as well as spear6xx */ +/* Ethernet driver configuration */ +#define CONFIG_MII +#define CONFIG_DESIGNWARE_ETH +#define CONFIG_DW_SEARCH_PHY +#define CONFIG_DW0_PHY 1 +#define CONFIG_NET_MULTI +#define CONFIG_PHY_RESET_DELAY 10000 /* in usec */ + /* USBD driver configuration */ #define CONFIG_DW_UDC #define CONFIG_USB_DEVICE @@ -104,11 +112,13 @@ #define CONFIG_CMD_MEMORY #define CONFIG_CMD_RUN #define CONFIG_CMD_SAVES +#define CONFIG_CMD_NET +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP /* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_NFS /* * Default Environment Varible definitions diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h index 2a86c212531..035b32129dc 100644 --- a/include/configs/spear3xx.h +++ b/include/configs/spear3xx.h @@ -41,6 +41,9 @@ #include +/* Ethernet driver configuration */ +#define CONFIG_DW_ALTDESCRIPTOR 1 + /* Serial Configuration (PL011) */ #define CONFIG_SYS_SERIAL0 0xD0000000 -- cgit v1.2.3 From 8eb0ee6a649d09a41155bf6c9dbd4d531ed41f9e Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Mon, 7 May 2012 13:06:43 +0530 Subject: SPEAr: Add macb driver support for spear310 and spear320 SPEAr310 and SPEAr320 SoCs have an extra ethernet controller. The driver for this device is already supported by u-boot, so configuring board configuration file and defining base addresses etc to make use of the common driver Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/clk.h | 27 +++++++++++++++++++++++++++ arch/arm/include/asm/arch-spear/hardware.h | 7 +++++++ board/spear/spear310/spear310.c | 25 ++++++++++++++++++++++--- board/spear/spear320/spear320.c | 12 +++++++++--- include/configs/spear3xx.h | 13 +++++++++++++ 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 arch/arm/include/asm/arch-spear/clk.h (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/clk.h b/arch/arm/include/asm/arch-spear/clk.h new file mode 100644 index 00000000000..a45ec1861cb --- /dev/null +++ b/arch/arm/include/asm/arch-spear/clk.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2010 + * Vipin Kumar, STMicroelectronics, + * + * 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 + */ + +static inline unsigned long get_macb_pclk_rate(unsigned int dev_id) +{ + return 83000000; +} diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h index 70fc0303553..0012dd7e631 100644 --- a/arch/arm/include/asm/arch-spear/hardware.h +++ b/arch/arm/include/asm/arch-spear/hardware.h @@ -56,6 +56,11 @@ #define CONFIG_SPEAR_EMIBASE (0x4F000000) #define CONFIG_SPEAR_RASBASE (0xB4000000) +#define CONFIG_SYS_MACB0_BASE 0xB0000000 +#define CONFIG_SYS_MACB1_BASE 0xB0800000 +#define CONFIG_SYS_MACB2_BASE 0xB1000000 +#define CONFIG_SYS_MACB3_BASE 0xB1800000 + #elif defined(CONFIG_SPEAR320) #define CONFIG_SYS_I2C_BASE (0xD0180000) #define CONFIG_SYS_FSMC_BASE (0x4C000000) @@ -63,5 +68,7 @@ #define CONFIG_SPEAR_EMIBASE (0x40000000) #define CONFIG_SPEAR_RASBASE (0xB3000000) +#define CONFIG_SYS_MACB0_BASE 0xAA000000 + #endif #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index 043a9f3aee9..c0e68299944 100644 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -65,9 +65,28 @@ void board_nand_init() int board_eth_init(bd_t *bis) { + int ret = 0; + #if defined(CONFIG_DESIGNWARE_ETH) - return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); -#else - return -1; + if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY) < 0) + ret += -1; +#endif +#if defined(CONFIG_MACB) + if (macb_eth_initialize(0, (void *)CONFIG_SYS_MACB0_BASE, + CONFIG_MACB0_PHY) < 0) + ret += -1; + + if (macb_eth_initialize(1, (void *)CONFIG_SYS_MACB1_BASE, + CONFIG_MACB1_PHY) < 0) + ret += -1; + + if (macb_eth_initialize(2, (void *)CONFIG_SYS_MACB2_BASE, + CONFIG_MACB2_PHY) < 0) + ret += -1; + + if (macb_eth_initialize(3, (void *)CONFIG_SYS_MACB3_BASE, + CONFIG_MACB3_PHY) < 0) + ret += -1; #endif + return ret; } diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index 1b6f362b5d8..e101888e044 100644 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -66,9 +66,15 @@ void board_nand_init() int board_eth_init(bd_t *bis) { + int ret = 0; #if defined(CONFIG_DESIGNWARE_ETH) - return designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY); -#else - return -1; + if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY) < 0) + ret += -1; #endif +#if defined(CONFIG_MACB) + if (macb_eth_initialize(0, (void *)CONFIG_SYS_MACB0_BASE, + CONFIG_MACB0_PHY) < 0) + ret += -1; +#endif + return ret; } diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h index 035b32129dc..f3e335465df 100644 --- a/include/configs/spear3xx.h +++ b/include/configs/spear3xx.h @@ -44,6 +44,19 @@ /* Ethernet driver configuration */ #define CONFIG_DW_ALTDESCRIPTOR 1 +#if defined(CONFIG_SPEAR310) +#define CONFIG_MACB 1 +#define CONFIG_MACB0_PHY 0x01 +#define CONFIG_MACB1_PHY 0x03 +#define CONFIG_MACB2_PHY 0x05 +#define CONFIG_MACB3_PHY 0x07 + +#elif defined(CONFIG_SPEAR320) +#define CONFIG_MACB 1 +#define CONFIG_MACB0_PHY 0x01 + +#endif + /* Serial Configuration (PL011) */ #define CONFIG_SYS_SERIAL0 0xD0000000 -- cgit v1.2.3 From 962d026b6aaf7d801d182f3188e4bbc106e057e3 Mon Sep 17 00:00:00 2001 From: Vipin KUMAR Date: Mon, 7 May 2012 13:06:45 +0530 Subject: SPEAr: Add basic arch related support for SPEAr SoCs Earlier, architecture specific init code was mixed with board initialization code in board/spear/... This patch updates architecture support for SPEAr in latest u-boot and prints the SoC information. Signed-off-by: Vipin Kumar Signed-off-by: Amit Virdi Acked-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/cpu/arm926ejs/spear/Makefile | 3 +- arch/arm/cpu/arm926ejs/spear/cpu.c | 82 ++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-spear/spr_misc.h | 7 +++ include/configs/spear-common.h | 2 + 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/arm926ejs/spear/cpu.c (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/spear/Makefile b/arch/arm/cpu/arm926ejs/spear/Makefile index f32ec4ccf38..46923a42fb1 100644 --- a/arch/arm/cpu/arm926ejs/spear/Makefile +++ b/arch/arm/cpu/arm926ejs/spear/Makefile @@ -25,7 +25,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS := reset.o \ +COBJS := cpu.o \ + reset.o \ timer.o SOBJS := diff --git a/arch/arm/cpu/arm926ejs/spear/cpu.c b/arch/arm/cpu/arm926ejs/spear/cpu.c new file mode 100644 index 00000000000..9e074bc9eb5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/cpu.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2010 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +int arch_cpu_init(void) +{ + struct misc_regs *const misc_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 periph1_clken; + + periph1_clken = readl(&misc_p->periph1_clken); + +#if defined(CONFIG_SPEAR3XX) + periph1_clken |= MISC_GPT2ENB; +#elif defined(CONFIG_SPEAR600) + periph1_clken |= MISC_GPT3ENB; +#endif + +#if defined(CONFIG_PL011_SERIAL) + periph1_clken |= MISC_UART0ENB; +#endif +#if defined(CONFIG_DESIGNWARE_ETH) + periph1_clken |= MISC_ETHENB; +#endif +#if defined(CONFIG_DW_UDC) + periph1_clken |= MISC_USBDENB; +#endif +#if defined(CONFIG_DW_I2C) + periph1_clken |= MISC_I2CENB; +#endif +#if defined(CONFIG_ST_SMI) + periph1_clken |= MISC_SMIENB; +#endif +#if defined(CONFIG_NAND_FSMC) + periph1_clken |= MISC_FSMCENB; +#endif + + writel(periph1_clken, &misc_p->periph1_clken); + return 0; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ +#ifdef CONFIG_SPEAR300 + printf("CPU: SPEAr300\n"); +#elif defined(CONFIG_SPEAR310) + printf("CPU: SPEAr310\n"); +#elif defined(CONFIG_SPEAR320) + printf("CPU: SPEAr320\n"); +#elif defined(CONFIG_SPEAR600) + printf("CPU: SPEAr600\n"); +#else +#error CPU not supported in spear platform +#endif + return 0; +} +#endif diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h index 8b96d9b52ae..b10c72607a5 100644 --- a/arch/arm/include/asm/arch-spear/spr_misc.h +++ b/arch/arm/include/asm/arch-spear/spr_misc.h @@ -126,5 +126,12 @@ struct misc_regs { /* PERIPH1_CLKEN, PERIPH1_RST value */ #define MISC_USBDENB 0x01000000 +#define MISC_ETHENB 0x00800000 +#define MISC_SMIENB 0x00200000 +#define MISC_GPT3ENB 0x00010000 +#define MISC_GPT2ENB 0x00000800 +#define MISC_FSMCENB 0x00000200 +#define MISC_I2CENB 0x00000080 +#define MISC_UART0ENB 0x00000008 #endif diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 669d83eb7eb..3a238945dcf 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -183,6 +183,8 @@ #define CONFIG_ENV_SIZE 0x02000 /* Miscellaneous configurable options */ +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO #define CONFIG_BOOT_PARAMS_ADDR 0x00000100 #define CONFIG_CMDLINE_TAG 1 #define CONFIG_SETUP_MEMORY_TAGS 1 -- cgit v1.2.3 From 7c885a0e5532abcd6bc802d21a7858420e5c127b Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Mon, 7 May 2012 13:06:59 +0530 Subject: SPEAr: explicitly select clk src for UART UART in u-boot intends to run on 48MHz clock supplied by USB PLL. Explicitly select the intended clock source. Signed-off-by: Shiraz Hashim Signed-off-by: Amit Virdi Acked-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/cpu/arm926ejs/spear/cpu.c | 7 ++++++- arch/arm/include/asm/arch-spear/spr_misc.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/spear/cpu.c b/arch/arm/cpu/arm926ejs/spear/cpu.c index 9e074bc9eb5..e299de3137a 100644 --- a/arch/arm/cpu/arm926ejs/spear/cpu.c +++ b/arch/arm/cpu/arm926ejs/spear/cpu.c @@ -30,7 +30,7 @@ int arch_cpu_init(void) { struct misc_regs *const misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; - u32 periph1_clken; + u32 periph1_clken, periph_clk_cfg; periph1_clken = readl(&misc_p->periph1_clken); @@ -42,6 +42,11 @@ int arch_cpu_init(void) #if defined(CONFIG_PL011_SERIAL) periph1_clken |= MISC_UART0ENB; + + periph_clk_cfg = readl(&misc_p->periph_clk_cfg); + periph_clk_cfg &= ~CONFIG_SPEAR_UARTCLKMSK; + periph_clk_cfg |= CONFIG_SPEAR_UART48M; + writel(periph_clk_cfg, &misc_p->periph_clk_cfg); #endif #if defined(CONFIG_DESIGNWARE_ETH) periph1_clken |= MISC_ETHENB; diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h index b10c72607a5..384944d33e3 100644 --- a/arch/arm/include/asm/arch-spear/spr_misc.h +++ b/arch/arm/include/asm/arch-spear/spr_misc.h @@ -110,6 +110,8 @@ struct misc_regs { /* PERIPH_CLK_CFG value */ #define MISC_GPT3SYNTH 0x00000400 #define MISC_GPT4SYNTH 0x00000800 +#define CONFIG_SPEAR_UART48M 0 +#define CONFIG_SPEAR_UARTCLKMSK (0x1 << 4) /* PRSC_CLK_CFG value */ /* -- cgit v1.2.3 From f28e5c946d6c88b1c8639896863c7ad7d8889bf4 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Mon, 7 May 2012 13:07:00 +0530 Subject: SPEAr: Correct SoC ID offset in misc configuration space SoC Core ID offset is 0x30 in miscellaneous configuration address space. It was wrongly mentioned as periph2 clk enable. Signed-off-by: Shiraz Hashim Signed-off-by: Amit Virdi Acked-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/spr_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h index 384944d33e3..b8fcf49febb 100644 --- a/arch/arm/include/asm/arch-spear/spr_misc.h +++ b/arch/arm/include/asm/arch-spear/spr_misc.h @@ -37,7 +37,7 @@ struct misc_regs { u32 amba_clk_cfg; /* 0x24 */ u32 periph_clk_cfg; /* 0x28 */ u32 periph1_clken; /* 0x2C */ - u32 periph2_clken; /* 0x30 */ + u32 soc_core_id; /* 0x30 */ u32 ras_clken; /* 0x34 */ u32 periph1_rst; /* 0x38 */ u32 periph2_rst; /* 0x3C */ -- cgit v1.2.3 From bc0bdf4c2296d02802ddfa76f349cbba3a869138 Mon Sep 17 00:00:00 2001 From: Amit Virdi Date: Mon, 7 May 2012 13:07:01 +0530 Subject: cleanup/SPEAr: Remove unnecessary parenthesis In SPEAr configuration files, unnecessary paranthesis are used in some \#defines. Remove them as they serve no purpose Signed-off-by: Amit Virdi Acked-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/spr_gpt.h | 4 ++-- include/configs/spear-common.h | 8 ++++---- include/configs/spear3xx_evb.h | 6 +++--- include/configs/spear6xx_evb.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/spr_gpt.h b/arch/arm/include/asm/arch-spear/spr_gpt.h index 965b5abb9ab..d95ba525973 100644 --- a/arch/arm/include/asm/arch-spear/spr_gpt.h +++ b/arch/arm/include/asm/arch-spear/spr_gpt.h @@ -79,7 +79,7 @@ struct gpt_regs { #define GPT_FREE_RUNNING 0xFFFF /* Timer, HZ specific defines */ -#define CONFIG_SPEAR_HZ (1000) -#define CONFIG_SPEAR_HZ_CLOCK (8300000) +#define CONFIG_SPEAR_HZ 1000 +#define CONFIG_SPEAR_HZ_CLOCK 8300000 #endif diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 32e1fcc98d5..0aa9551bfe3 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -62,7 +62,7 @@ #define CONFIG_I2C_CHIPADDRESS 0x50 /* Timer, HZ specific defines */ -#define CONFIG_SYS_HZ (1000) +#define CONFIG_SYS_HZ 1000 /* Flash configuration */ #if defined(CONFIG_FLASH_PNOR) @@ -74,9 +74,9 @@ #if defined(CONFIG_ST_SMI) #define CONFIG_SYS_MAX_FLASH_BANKS 2 -#define CONFIG_SYS_FLASH_BASE (0xF8000000) -#define CONFIG_SYS_CS1_FLASH_BASE (0xF9000000) -#define CONFIG_SYS_FLASH_BANK_SIZE (0x01000000) +#define CONFIG_SYS_FLASH_BASE 0xF8000000 +#define CONFIG_SYS_CS1_FLASH_BASE 0xF9000000 +#define CONFIG_SYS_FLASH_BANK_SIZE 0x01000000 #define CONFIG_SYS_FLASH_ADDR_BASE {CONFIG_SYS_FLASH_BASE, \ CONFIG_SYS_CS1_FLASH_BASE} #define CONFIG_SYS_MAX_FLASH_SECT 128 diff --git a/include/configs/spear3xx_evb.h b/include/configs/spear3xx_evb.h index 242e648fc1d..d63c9dff399 100644 --- a/include/configs/spear3xx_evb.h +++ b/include/configs/spear3xx_evb.h @@ -150,13 +150,13 @@ #define CONFIG_SYS_FSMC_NAND_8BIT #if defined(CONFIG_SPEAR300) -#define CONFIG_SYS_NAND_BASE (0x80000000) +#define CONFIG_SYS_NAND_BASE 0x80000000 #elif defined(CONFIG_SPEAR310) -#define CONFIG_SYS_NAND_BASE (0x40000000) +#define CONFIG_SYS_NAND_BASE 0x40000000 #elif defined(CONFIG_SPEAR320) -#define CONFIG_SYS_NAND_BASE (0x50000000) +#define CONFIG_SYS_NAND_BASE 0x50000000 #endif diff --git a/include/configs/spear6xx_evb.h b/include/configs/spear6xx_evb.h index 3e0f50bda8c..4a761341a81 100644 --- a/include/configs/spear6xx_evb.h +++ b/include/configs/spear6xx_evb.h @@ -51,7 +51,7 @@ /* NAND flash configuration */ #define CONFIG_SYS_FSMC_NAND_SP #define CONFIG_SYS_FSMC_NAND_8BIT -#define CONFIG_SYS_NAND_BASE (0xD2000000) +#define CONFIG_SYS_NAND_BASE 0xD2000000 /* Environment Settings */ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_USBTTY -- cgit v1.2.3 From 2cb06a4fda4e7a88c734adaec9eeb5059e50f76b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 14 Feb 2012 14:01:36 +0100 Subject: GPIO: Add SPEAr GPIO driver Tested on x600 (SPEAr600). Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-spear/gpio.h | 40 +++++++++++++ drivers/gpio/Makefile | 1 + drivers/gpio/spear_gpio.c | 102 +++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 arch/arm/include/asm/arch-spear/gpio.h create mode 100644 drivers/gpio/spear_gpio.c (limited to 'arch') diff --git a/arch/arm/include/asm/arch-spear/gpio.h b/arch/arm/include/asm/arch-spear/gpio.h new file mode 100644 index 00000000000..c3697de8c50 --- /dev/null +++ b/arch/arm/include/asm/arch-spear/gpio.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Stefan Roese + * + * 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 __ASM_ARCH_SPEAR_GPIO_H +#define __ASM_ARCH_SPEAR_GPIO_H + +enum gpio_direction { + GPIO_DIRECTION_IN, + GPIO_DIRECTION_OUT, +}; + +struct gpio_regs { + u32 gpiodata[0x100]; /* 0x000 ... 0x3fc */ + u32 gpiodir; /* 0x400 */ +}; + +#define SPEAR_GPIO_COUNT 8 +#define DATA_REG_ADDR(gpio) (1 << (gpio + 2)) + +#endif /* __ASM_ARCH_SPEAR_GPIO_H */ diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 5ae68d5ba82..32a24749805 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -35,6 +35,7 @@ COBJS-$(CONFIG_PCA953X) += pca953x.o COBJS-$(CONFIG_PCA9698) += pca9698.o COBJS-$(CONFIG_S5P) += s5p_gpio.o COBJS-$(CONFIG_SANDBOX_GPIO) += sandbox.o +COBJS-$(CONFIG_SPEAR_GPIO) += spear_gpio.o COBJS-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o diff --git a/drivers/gpio/spear_gpio.c b/drivers/gpio/spear_gpio.c new file mode 100644 index 00000000000..d3c728e1374 --- /dev/null +++ b/drivers/gpio/spear_gpio.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 Stefan Roese + * + * 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 + */ + +/* + * Driver for SPEAr600 GPIO controller + */ + +#include +#include +#include +#include +#include + +static int gpio_direction(unsigned gpio, + enum gpio_direction direction) +{ + struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; + u32 val; + + val = readl(®s->gpiodir); + + if (direction == GPIO_DIRECTION_OUT) + val |= 1 << gpio; + else + val &= ~(1 << gpio); + + writel(val, ®s->gpiodir); + + return 0; +} + +int gpio_set_value(unsigned gpio, int value) +{ + struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; + + writel(1 << gpio, ®s->gpiodata[DATA_REG_ADDR(gpio)]); + + return 0; +} + +int gpio_get_value(unsigned gpio) +{ + struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; + u32 val; + + val = readl(®s->gpiodata[DATA_REG_ADDR(gpio)]); + + return !!val; +} + +int gpio_request(unsigned gpio, const char *label) +{ + if (gpio >= SPEAR_GPIO_COUNT) + return -EINVAL; + + return 0; +} + +int gpio_free(unsigned gpio) +{ + return 0; +} + +void gpio_toggle_value(unsigned gpio) +{ + gpio_set_value(gpio, !gpio_get_value(gpio)); +} + +int gpio_direction_input(unsigned gpio) +{ + return gpio_direction(gpio, GPIO_DIRECTION_IN); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + int ret = gpio_direction(gpio, GPIO_DIRECTION_OUT); + + if (ret < 0) + return ret; + + gpio_set_value(gpio, value); + return 0; +} -- cgit v1.2.3 From fe901f2d9bd09292a67e562b8c96a1a496004c9e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 3 Mar 2012 12:33:15 -0800 Subject: arm: Don't use printf() in SPL builds raise() likes to call printf() if it is available, but in SPL builds it either is not available, or adds a large chunk to the resulting image size. So don't call it even if it is available. This change reduces SPL size from 10KB to 6.3KB on hawkboard, for example, using generic relocation. Signed-off-by: Simon Glass Acked-by: Stefan Roese --- arch/arm/lib/eabi_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/lib/eabi_compat.c b/arch/arm/lib/eabi_compat.c index 2028dbd715b..44eebe0a5d2 100644 --- a/arch/arm/lib/eabi_compat.c +++ b/arch/arm/lib/eabi_compat.c @@ -13,7 +13,8 @@ int raise (int signum) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) + /* Even if printf() is available, it's large. Punt it for SPL builds */ +#if !defined(CONFIG_SPL_BUILD) printf("raise: Signal # %d caught\n", signum); #endif return 0; -- cgit v1.2.3 From 4ae8bc4392ec038566276e15c4dfe29f0fe9682f Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 3 Jan 2012 16:49:01 +0100 Subject: SPL: ARM: spear: Add SPL support for SPEAr600 platform This patch adds SPL support for SPEAr600. Currently only SNOR (Serial NOR) flash support is included. Other boot devices (NAND, MMC, USB ...) may be added with later patches. Tested on the STM SPEAr600 evaluation and x600 SPEAr600 boards. Signed-off-by: Stefan Roese Cc: Amit Virdi Cc: Vipin Kumar --- arch/arm/cpu/arm926ejs/spear/Makefile | 24 +- arch/arm/cpu/arm926ejs/spear/spear600.c | 236 +++++++++++++++++ arch/arm/cpu/arm926ejs/spear/spl.c | 282 +++++++++++++++++++++ arch/arm/cpu/arm926ejs/spear/spl_boot.c | 197 ++++++++++++++ .../spear/spr600_mt47h128m8_3_266_cl5_async.c | 130 ++++++++++ .../spear/spr600_mt47h32m16_333_cl5_psync.c | 135 ++++++++++ .../spear/spr600_mt47h32m16_37e_166_cl4_sync.c | 130 ++++++++++ .../spear/spr600_mt47h64m16_3_333_cl5_psync.c | 144 +++++++++++ arch/arm/cpu/arm926ejs/spear/start.S | 122 +++++++++ arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds | 87 +++++++ arch/arm/include/asm/arch-spear/hardware.h | 55 ++-- arch/arm/include/asm/arch-spear/spr_defs.h | 30 +++ arch/arm/include/asm/arch-spear/spr_misc.h | 136 +++++++++- arch/arm/include/asm/arch-spear/spr_ssp.h | 45 ++++ arch/arm/include/asm/arch-spear/spr_syscntl.h | 14 + 15 files changed, 1740 insertions(+), 27 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/spear/spear600.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spl.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spl_boot.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c create mode 100644 arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c create mode 100644 arch/arm/cpu/arm926ejs/spear/start.S create mode 100644 arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds create mode 100644 arch/arm/include/asm/arch-spear/spr_ssp.h (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/spear/Makefile b/arch/arm/cpu/arm926ejs/spear/Makefile index 46923a42fb1..d06f03d080b 100644 --- a/arch/arm/cpu/arm926ejs/spear/Makefile +++ b/arch/arm/cpu/arm926ejs/spear/Makefile @@ -25,17 +25,27 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS := cpu.o \ +COBJS-y := cpu.o \ reset.o \ timer.o -SOBJS := -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +ifdef CONFIG_SPL_BUILD +COBJS-y += spl.o spl_boot.o +COBJS-$(CONFIG_SPEAR600) += spear600.o +COBJS-$(CONFIG_DDR_MT47H64M16) += spr600_mt47h64m16_3_333_cl5_psync.o +COBJS-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_333_cl5_psync.o +COBJS-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_37e_166_cl4_sync.o +COBJS-$(CONFIG_DDR_MT47H128M8) += spr600_mt47h128m8_3_266_cl5_async.o +endif -$(LIB): $(obj).depend $(OBJS) $(SOBJS) - $(call cmd_link_o_target, $(OBJS) $(SOBJS)) +SRCS := $(START:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) ######################################################################### diff --git a/arch/arm/cpu/arm926ejs/spear/spear600.c b/arch/arm/cpu/arm926ejs/spear/spear600.c new file mode 100644 index 00000000000..ff52131b093 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spear600.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2000-2009 + * Viresh Kumar, ST Microelectronics, viresh.kumar@st.com + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#define FALSE 0 +#define TRUE (!FALSE) + +static void sel_1v8(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddr1v8, ddr2v5; + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000003; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000010; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + while (!(readl(&misc_p->ddr_1v8_compensation) & DDR_COMP_ACCURATE)) + ; +} + +static void sel_2v5(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddr1v8, ddr2v5; + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000003; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000010; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + while (!(readl(&misc_p->ddr_2v5_compensation) & DDR_COMP_ACCURATE)) + ; +} + +/* + * plat_ddr_init: + */ +void plat_ddr_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddrpad; + u32 core3v3, ddr1v8, ddr2v5; + + /* DDR pad register configurations */ + ddrpad = readl(&misc_p->ddr_pad); + ddrpad &= ~DDR_PAD_CNF_MSK; + +#if (CONFIG_DDR_HCLK) + ddrpad |= 0xEAAB; +#elif (CONFIG_DDR_2HCLK) + ddrpad |= 0xEAAD; +#elif (CONFIG_DDR_PLL2) + ddrpad |= 0xEAAD; +#endif + writel(ddrpad, &misc_p->ddr_pad); + + /* Compensation register configurations */ + core3v3 = readl(&misc_p->core_3v3_compensation); + core3v3 &= 0x8080ffe0; + core3v3 |= 0x78000002; + writel(core3v3, &misc_p->core_3v3_compensation); + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000004; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000004; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + if ((readl(&misc_p->ddr_pad) & DDR_PAD_SW_CONF) == DDR_PAD_SW_CONF) { + /* Software memory configuration */ + if (readl(&misc_p->ddr_pad) & DDR_PAD_SSTL_SEL) + sel_1v8(); + else + sel_2v5(); + } else { + /* Hardware memory configuration */ + if (readl(&misc_p->ddr_pad) & DDR_PAD_DRAM_TYPE) + sel_1v8(); + else + sel_2v5(); + } +} + +/* + * soc_init: + */ +void soc_init(void) +{ + /* Nothing to be done for SPEAr600 */ +} + +/* + * xxx_boot_selected: + * + * return TRUE if the particular booting option is selected + * return FALSE otherwise + */ +static u32 read_bootstrap(void) +{ + return (readl(CONFIG_SPEAR_BOOTSTRAPCFG) >> CONFIG_SPEAR_BOOTSTRAPSHFT) + & CONFIG_SPEAR_BOOTSTRAPMASK; +} + +int snor_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (SNOR_BOOT_SUPPORTED) { + /* Check whether SNOR boot is selected */ + if ((bootstrap & CONFIG_SPEAR_ONLYSNORBOOT) == + CONFIG_SPEAR_ONLYSNORBOOT) + return TRUE; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND8BOOT) + return TRUE; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND16BOOT) + return TRUE; + } + + return FALSE; +} + +int nand_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (NAND_BOOT_SUPPORTED) { + /* Check whether NAND boot is selected */ + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND8BOOT) + return TRUE; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND16BOOT) + return TRUE; + } + + return FALSE; +} + +int pnor_boot_selected(void) +{ + /* Parallel NOR boot is not selected in any SPEAr600 revision */ + return FALSE; +} + +int usb_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (USB_BOOT_SUPPORTED) { + /* Check whether USB boot is selected */ + if (!(bootstrap & CONFIG_SPEAR_USBBOOT)) + return TRUE; + } + + return FALSE; +} + +int tftp_boot_selected(void) +{ + /* TFTP boot is not selected in any SPEAr600 revision */ + return FALSE; +} + +int uart_boot_selected(void) +{ + /* UART boot is not selected in any SPEAr600 revision */ + return FALSE; +} + +int spi_boot_selected(void) +{ + /* SPI boot is not selected in any SPEAr600 revision */ + return FALSE; +} + +int i2c_boot_selected(void) +{ + /* I2C boot is not selected in any SPEAr600 revision */ + return FALSE; +} + +int mmc_boot_selected(void) +{ + return FALSE; +} + +void plat_late_init(void) +{ + spear_late_init(); +} diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c new file mode 100644 index 00000000000..48e6efbc473 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spl.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * Copyright (C) 2012 Stefan Roese + * + * 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 +#include +#include +#include +#include +#include +#include + +inline void hang(void) +{ + serial_puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +} + +static void ddr_clock_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 clkenb, ddrpll; + + clkenb = readl(&misc_p->periph1_clken); + clkenb &= ~PERIPH_MPMCMSK; + clkenb |= PERIPH_MPMC_WE; + + /* Intentionally done twice */ + writel(clkenb, &misc_p->periph1_clken); + writel(clkenb, &misc_p->periph1_clken); + + ddrpll = readl(&misc_p->pll_ctr_reg); + ddrpll &= ~MEM_CLK_SEL_MSK; +#if (CONFIG_DDR_HCLK) + ddrpll |= MEM_CLK_HCLK; +#elif (CONFIG_DDR_2HCLK) + ddrpll |= MEM_CLK_2HCLK; +#elif (CONFIG_DDR_PLL2) + ddrpll |= MEM_CLK_PLL2; +#else +#error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)" +#endif + writel(ddrpll, &misc_p->pll_ctr_reg); + + writel(readl(&misc_p->periph1_clken) | PERIPH_MPMC_EN, + &misc_p->periph1_clken); +} + +static void mpmc_init_values(void) +{ + u32 i; + u32 *mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE; + u32 *mpmc_val_p = &mpmc_conf_vals[0]; + + for (i = 0; i < CONFIG_SPEAR_MPMCREGS; i++, mpmc_reg_p++, mpmc_val_p++) + writel(*mpmc_val_p, mpmc_reg_p); + + mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE; + + /* + * MPMC controller start + * MPMC waiting for DLLLOCKREG high + */ + writel(0x01000100, &mpmc_reg_p[7]); + + while (!(readl(&mpmc_reg_p[3]) & 0x10000)) + ; +} + +static void mpmc_init(void) +{ + /* Clock related settings for DDR */ + ddr_clock_init(); + + /* + * DDR pad register bits are different for different SoCs + * Compensation values are also handled separately + */ + plat_ddr_init(); + + /* Initialize mpmc register values */ + mpmc_init_values(); +} + +static void pll_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + /* Initialize PLLs */ + writel(FREQ_332, &misc_p->pll1_frq); + writel(0x1C0A, &misc_p->pll1_cntl); + writel(0x1C0E, &misc_p->pll1_cntl); + writel(0x1C06, &misc_p->pll1_cntl); + writel(0x1C0E, &misc_p->pll1_cntl); + + writel(FREQ_332, &misc_p->pll2_frq); + writel(0x1C0A, &misc_p->pll2_cntl); + writel(0x1C0E, &misc_p->pll2_cntl); + writel(0x1C06, &misc_p->pll2_cntl); + writel(0x1C0E, &misc_p->pll2_cntl); + + /* wait for pll locks */ + while (!(readl(&misc_p->pll1_cntl) & 0x1)) + ; + while (!(readl(&misc_p->pll2_cntl) & 0x1)) + ; +} + +static void mac_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + writel(readl(&misc_p->periph1_clken) & (~PERIPH_GMAC), + &misc_p->periph1_clken); + + writel(SYNTH23, &misc_p->gmac_synth_clk); + + switch (get_socrev()) { + case SOC_SPEAR600_AA: + case SOC_SPEAR600_AB: + case SOC_SPEAR600_BA: + case SOC_SPEAR600_BB: + case SOC_SPEAR600_BC: + case SOC_SPEAR600_BD: + writel(0x0, &misc_p->gmac_ctr_reg); + break; + + case SOC_SPEAR300: + case SOC_SPEAR310: + case SOC_SPEAR320: + writel(0x4, &misc_p->gmac_ctr_reg); + break; + } + + writel(readl(&misc_p->periph1_clken) | PERIPH_GMAC, + &misc_p->periph1_clken); + + writel(readl(&misc_p->periph1_rst) | PERIPH_GMAC, + &misc_p->periph1_rst); + writel(readl(&misc_p->periph1_rst) & (~PERIPH_GMAC), + &misc_p->periph1_rst); +} + +static void sys_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct syscntl_regs *syscntl_p = + (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE; + + /* Set system state to SLOW */ + writel(SLOW, &syscntl_p->scctrl); + writel(PLL_TIM << 3, &syscntl_p->scpllctrl); + + /* Initialize PLLs */ + pll_init(); + + /* + * Ethernet configuration + * To be done only if the tftp boot is not selected already + * Boot code ensures the correct configuration in tftp booting + */ + if (!tftp_boot_selected()) + mac_init(); + + writel(RTC_DISABLE | PLLTIMEEN, &misc_p->periph_clk_cfg); + writel(0x555, &misc_p->amba_clk_cfg); + + writel(NORMAL, &syscntl_p->scctrl); + + /* Wait for system to switch to normal mode */ + while (((readl(&syscntl_p->scctrl) >> MODE_SHIFT) & MODE_MASK) + != NORMAL) + ; +} + +/* + * get_socrev + * + * Get SoC Revision. + * @return SOC_SPEARXXX + */ +int get_socrev(void) +{ +#if defined(CONFIG_SPEAR600) + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 soc_id = readl(&misc_p->soc_core_id); + u32 pri_socid = (soc_id >> SOC_PRI_SHFT) & 0xFF; + u32 sec_socid = (soc_id >> SOC_SEC_SHFT) & 0xFF; + + if ((pri_socid == 'B') && (sec_socid == 'B')) + return SOC_SPEAR600_BB; + else if ((pri_socid == 'B') && (sec_socid == 'C')) + return SOC_SPEAR600_BC; + else if ((pri_socid == 'B') && (sec_socid == 'D')) + return SOC_SPEAR600_BD; + else if (soc_id == 0) + return SOC_SPEAR600_BA; + else + return SOC_SPEAR_NA; +#elif defined(CONFIG_SPEAR300) + return SOC_SPEAR300; +#elif defined(CONFIG_SPEAR310) + return SOC_SPEAR310; +#elif defined(CONFIG_SPEAR320) + return SOC_SPEAR320; +#endif +} + +void lowlevel_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + const char *u_boot_rev = U_BOOT_VERSION; + + /* Initialize PLLs */ + sys_init(); + + /* Initialize UART */ + serial_init(); + + /* Print U-Boot SPL version string */ + serial_puts("\nU-Boot SPL "); + /* Avoid a second "U-Boot" coming from this string */ + u_boot_rev = &u_boot_rev[7]; + serial_puts(u_boot_rev); + serial_puts(" ("); + serial_puts(U_BOOT_DATE); + serial_puts(" - "); + serial_puts(U_BOOT_TIME); + serial_puts(")\n"); + +#if defined(CONFIG_OS_BOOT) + writel(readl(&misc_p->periph1_clken) | PERIPH_UART1, + &misc_p->periph1_clken); +#endif + + /* Enable IPs (release reset) */ + writel(PERIPH_RST_ALL, &misc_p->periph1_rst); + + /* Initialize MPMC */ + serial_puts("Configure DDR\n"); + mpmc_init(); + + /* SoC specific initialization */ + soc_init(); +} + +void spear_late_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + writel(0x80000007, &misc_p->arb_icm_ml1); + writel(0x80000007, &misc_p->arb_icm_ml2); + writel(0x80000007, &misc_p->arb_icm_ml3); + writel(0x80000007, &misc_p->arb_icm_ml4); + writel(0x80000007, &misc_p->arb_icm_ml5); + writel(0x80000007, &misc_p->arb_icm_ml6); + writel(0x80000007, &misc_p->arb_icm_ml7); + writel(0x80000007, &misc_p->arb_icm_ml8); + writel(0x80000007, &misc_p->arb_icm_ml9); +} diff --git a/arch/arm/cpu/arm926ejs/spear/spl_boot.c b/arch/arm/cpu/arm926ejs/spear/spl_boot.c new file mode 100644 index 00000000000..f2f9a4974e9 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spl_boot.c @@ -0,0 +1,197 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * Copyright (C) 2012 Stefan Roese + * + * 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 +#include +#include +#include +#include +#include + +static const char kernel_name[] = "Linux"; +static const char loader_name[] = "U-Boot"; + +int image_check_header(image_header_t *hdr, const char *name) +{ + if (image_check_magic(hdr) && + (!strncmp(image_get_name(hdr), name, strlen(name))) && + image_check_hcrc(hdr)) { + return 1; + } + return 0; +} + +int image_check_data(image_header_t *hdr) +{ + if (image_check_dcrc(hdr)) + return 1; + + return 0; +} + +/* + * SNOR (Serial NOR flash) related functions + */ +void snor_init(void) +{ + struct smi_regs *const smicntl = + (struct smi_regs * const)CONFIG_SYS_SMI_BASE; + + /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */ + writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4, + &smicntl->smi_cr1); +} + +static int snor_image_load(u8 *load_addr, void (**image_p)(void), + const char *image_name) +{ + image_header_t *header; + + /* + * Since calculating the crc in the SNOR flash does not + * work, we copy the image to the destination address + * minus the header size. And point the header to this + * new destination. This will not work for address 0 + * of course. + */ + header = (image_header_t *)load_addr; + memcpy((ulong *)(image_get_load(header) - sizeof(image_header_t)), + (const ulong *)load_addr, + image_get_data_size(header) + sizeof(image_header_t)); + header = (image_header_t *)(image_get_load(header) - + sizeof(image_header_t)); + + if (image_check_header(header, image_name)) { + if (image_check_data(header)) { + /* Jump to boot image */ + *image_p = (void *)image_get_load(header); + return 1; + } + } + + return 0; +} + +static void boot_image(void (*image)(void)) +{ + void (*funcp)(void) __noreturn = (void *)image; + + (*funcp)(); +} + +/* + * spl_boot: + * + * All supported booting types of all supported SoCs are listed here. + * Generic readback APIs are provided for each supported booting type + * eg. nand_read_skip_bad + */ +u32 spl_boot(void) +{ + void (*image)(void); + +#ifdef CONFIG_SPEAR_USBTTY + plat_late_init(); + return 1; +#endif + + /* + * All the supported booting devices are listed here. Each of + * the booting type supported by the platform would define the + * macro xxx_BOOT_SUPPORTED to TRUE. + */ + + if (SNOR_BOOT_SUPPORTED && snor_boot_selected()) { + /* SNOR-SMI initialization */ + snor_init(); + + serial_puts("Booting via SNOR\n"); + /* Serial NOR booting */ + if (1 == snor_image_load((u8 *)CONFIG_SYS_UBOOT_BASE, + &image, loader_name)) { + /* Platform related late initialasations */ + plat_late_init(); + + /* Jump to boot image */ + serial_puts("Jumping to U-Boot\n"); + boot_image(image); + return 1; + } + } + + if (NAND_BOOT_SUPPORTED && nand_boot_selected()) { + /* NAND booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (PNOR_BOOT_SUPPORTED && pnor_boot_selected()) { + /* PNOR booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (MMC_BOOT_SUPPORTED && mmc_boot_selected()) { + /* MMC booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (SPI_BOOT_SUPPORTED && spi_boot_selected()) { + /* SPI booting */ + /* Not supported for any platform as of now */ + return 0; + } + + if (I2C_BOOT_SUPPORTED && i2c_boot_selected()) { + /* I2C booting */ + /* Not supported for any platform as of now */ + return 0; + } + + /* + * All booting types without memory are listed as below + * Control has to be returned to BootROM in case of all + * the following booting scenarios + */ + + if (USB_BOOT_SUPPORTED && usb_boot_selected()) { + plat_late_init(); + return 1; + } + + if (TFTP_BOOT_SUPPORTED && tftp_boot_selected()) { + plat_late_init(); + return 1; + } + + if (UART_BOOT_SUPPORTED && uart_boot_selected()) { + plat_late_init(); + return 1; + } + + /* Ideally, the control should not reach here. */ + hang(); +} diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c new file mode 100644 index 00000000000..5edc115d106 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c @@ -0,0 +1,130 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_DDR_PLL2) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { + 0x00000001, + 0x00000000, + 0x01000000, + 0x00000101, + 0x00000001, + 0x01000000, + 0x00010001, + 0x00000100, + 0x00010001, + 0x00000003, + 0x01000201, + 0x06000202, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000404, + 0x02030202, + 0x03000204, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x08080a01, + 0x0000023f, + 0x00040800, + 0x00000000, + 0x00000f02, + 0x00001b1b, + 0x7f000000, + 0x005f0000, + 0x1c040b6a, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x000007ff, + 0x00000000, + 0x47ec00c8, + 0x00c8001f, + 0x00000000, + 0x0000cd98, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00270000, + 0x00250027, + 0x00300000, + 0x008900b7, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c new file mode 100644 index 00000000000..616b86194dc --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c @@ -0,0 +1,135 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { +#if (CONFIG_DDR_PLL2) + 0x00000001, + 0x00000000, +#elif (CONFIG_DDR_2HCLK) + 0x02020201, + 0x02020202, +#endif + 0x01000000, + 0x00000101, + 0x00000101, + 0x01000000, + 0x00010001, + 0x00000100, + 0x01010001, + 0x00000201, + 0x01000101, + 0x06000002, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000405, + 0x03040202, + 0x04000305, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x0a0a0a01, + 0x0000023f, + 0x00050a00, + 0x11000000, + 0x00001302, + 0x00000A0A, + 0x72000000, + 0x00550000, + 0x2b050e86, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00000a24, + 0x43C20000, + 0x5b1c00c8, + 0x00c8002e, + 0x00000000, + 0x0001046b, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00210000, + 0x00010021, + 0x00200000, + 0x006c0090, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c new file mode 100644 index 00000000000..b89f77deb01 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c @@ -0,0 +1,130 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_DDR_HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { + 0x03030301, + 0x03030303, + 0x01000000, + 0x00000101, + 0x00000001, + 0x01000000, + 0x00010001, + 0x00000100, + 0x00010001, + 0x00000003, + 0x01000201, + 0x06000202, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000404, + 0x02020202, + 0x03000203, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x08080a01, + 0x0000023f, + 0x00030600, + 0x00000000, + 0x00000a02, + 0x00001c1c, + 0x7f000000, + 0x005f0000, + 0x12030743, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x0000050e, + 0x00000000, + 0x2d8900c8, + 0x00c80014, + 0x00000000, + 0x00008236, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00400000, + 0x003a0040, + 0x00680000, + 0x00d80120, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c new file mode 100644 index 00000000000..0c39cd10593 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { +#if (CONFIG_DDR_PLL2) + 0x00000001, + 0x00000000, +#elif (CONFIG_DDR_2HCLK) + 0x02020201, + 0x02020202, +#endif + 0x01000000, + 0x00000101, + 0x00000101, + 0x01000000, + 0x00010001, + 0x00000100, + 0x01010001, + 0x00000201, + 0x01000101, + 0x06000002, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, +#ifdef CONFIG_X600 + 0x02030206, +#else + 0x02010106, +#endif + 0x03000405, + 0x03040202, + 0x04000305, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x0a0a0a01, + 0x0000023f, + 0x00050a00, + 0x11000000, + 0x00001302, + 0x00000A0A, +#ifdef CONFIG_X600 + 0x7f000000, + 0x005c0000, +#else + 0x72000000, + 0x00550000, +#endif + 0x2b050e86, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00000a24, + 0x43C20000, + 0x5b1c00c8, + 0x00c8002e, + 0x00000000, + 0x0001046b, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00210000, + 0x00010021, + 0x00200000, + 0x006c0090, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif diff --git a/arch/arm/cpu/arm926ejs/spear/start.S b/arch/arm/cpu/arm926ejs/spear/start.S new file mode 100644 index 00000000000..a103c0f4ab5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/start.S @@ -0,0 +1,122 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * 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 + +.globl _start +_start: + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: +_software_interrupt: +_prefetch_abort: +_data_abort: +_not_used: +_irq: +_fiq: + .word infinite_loop + +infinite_loop: + b infinite_loop + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * Below are the critical initializations already taken place in BootROM. + * So, these are not taken care in Xloader + * 1. Relocation to RAM + * 2. Initializing stacks + * + ************************************************************************* + */ + +/* + * the actual reset code + */ + +reset: +/* + * Xloader has to return back to BootROM in a few cases. + * eg. Ethernet boot, UART boot, USB boot + * Saving registers for returning back + */ + stmdb sp!, {r0-r12,r14} + bl cpu_init_crit +/* + * Clearing bss area is not done in Xloader. + * BSS area lies in the DDR location which is not yet initialized + * bss is assumed to be uninitialized. + */ + bl spl_boot + ldmia sp!, {r0-r12,pc} + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * enable instruction cache + */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + stmdb sp!, {lr} + bl lowlevel_init /* go setup pll,mux,memory */ + ldmia sp!, {pc} diff --git a/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds new file mode 100644 index 00000000000..afd3381e167 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 Marek Vasut + * on behalf of DENX Software Engineering GmbH + * + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm926ejs/spear/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data) + } + + . = ALIGN(4); + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end__ = .; + } + + _end = .; + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynsym*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.hash*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h index 0012dd7e631..81509119dda 100644 --- a/arch/arm/include/asm/arch-spear/hardware.h +++ b/arch/arm/include/asm/arch-spear/hardware.h @@ -24,37 +24,54 @@ #ifndef _ASM_ARCH_HARDWARE_H #define _ASM_ARCH_HARDWARE_H -#define CONFIG_SYS_USBD_BASE (0xE1100000) -#define CONFIG_SYS_PLUG_BASE (0xE1200000) -#define CONFIG_SYS_FIFO_BASE (0xE1000800) -#define CONFIG_SYS_SMI_BASE (0xFC000000) -#define CONFIG_SPEAR_SYSCNTLBASE (0xFCA00000) -#define CONFIG_SPEAR_TIMERBASE (0xFC800000) -#define CONFIG_SPEAR_MISCBASE (0xFCA80000) +#define CONFIG_SYS_USBD_BASE 0xE1100000 +#define CONFIG_SYS_PLUG_BASE 0xE1200000 +#define CONFIG_SYS_FIFO_BASE 0xE1000800 +#define CONFIG_SYS_SMI_BASE 0xFC000000 +#define CONFIG_SPEAR_SYSCNTLBASE 0xFCA00000 +#define CONFIG_SPEAR_TIMERBASE 0xFC800000 +#define CONFIG_SPEAR_MISCBASE 0xFCA80000 #define CONFIG_SPEAR_ETHBASE 0xE0800000 +#define CONFIG_SPEAR_MPMCBASE 0xFC600000 +#define CONFIG_SSP1_BASE 0xD0100000 +#define CONFIG_SSP2_BASE 0xD0180000 +#define CONFIG_SSP3_BASE 0xD8180000 +#define CONFIG_GPIO_BASE 0xD8100000 #define CONFIG_SYS_NAND_CLE (1 << 16) #define CONFIG_SYS_NAND_ALE (1 << 17) #if defined(CONFIG_SPEAR600) -#define CONFIG_SYS_I2C_BASE (0xD0200000) -#define CONFIG_SYS_FSMC_BASE (0xD1800000) +#define CONFIG_SYS_I2C_BASE 0xD0200000 +#define CONFIG_SYS_FSMC_BASE 0xD1800000 +#define CONFIG_FSMC_NAND_BASE 0xD2000000 + +#define CONFIG_SPEAR_BOOTSTRAPCFG 0xFCA80000 +#define CONFIG_SPEAR_BOOTSTRAPSHFT 16 +#define CONFIG_SPEAR_BOOTSTRAPMASK 0xB +#define CONFIG_SPEAR_ONLYSNORBOOT 0xA +#define CONFIG_SPEAR_NORNANDBOOT 0xB +#define CONFIG_SPEAR_NORNAND8BOOT 0x8 +#define CONFIG_SPEAR_NORNAND16BOOT 0x9 +#define CONFIG_SPEAR_USBBOOT 0x8 + +#define CONFIG_SPEAR_MPMCREGS 100 #elif defined(CONFIG_SPEAR300) -#define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SYS_FSMC_BASE (0x94000000) +#define CONFIG_SYS_I2C_BASE 0xD0180000 +#define CONFIG_SYS_FSMC_BASE 0x94000000 #elif defined(CONFIG_SPEAR310) -#define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SYS_FSMC_BASE (0x44000000) +#define CONFIG_SYS_I2C_BASE 0xD0180000 +#define CONFIG_SYS_FSMC_BASE 0x44000000 #undef CONFIG_SYS_NAND_CLE #undef CONFIG_SYS_NAND_ALE #define CONFIG_SYS_NAND_CLE (1 << 17) #define CONFIG_SYS_NAND_ALE (1 << 16) -#define CONFIG_SPEAR_EMIBASE (0x4F000000) -#define CONFIG_SPEAR_RASBASE (0xB4000000) +#define CONFIG_SPEAR_EMIBASE 0x4F000000 +#define CONFIG_SPEAR_RASBASE 0xB4000000 #define CONFIG_SYS_MACB0_BASE 0xB0000000 #define CONFIG_SYS_MACB1_BASE 0xB0800000 @@ -62,11 +79,11 @@ #define CONFIG_SYS_MACB3_BASE 0xB1800000 #elif defined(CONFIG_SPEAR320) -#define CONFIG_SYS_I2C_BASE (0xD0180000) -#define CONFIG_SYS_FSMC_BASE (0x4C000000) +#define CONFIG_SYS_I2C_BASE 0xD0180000 +#define CONFIG_SYS_FSMC_BASE 0x4C000000 -#define CONFIG_SPEAR_EMIBASE (0x40000000) -#define CONFIG_SPEAR_RASBASE (0xB3000000) +#define CONFIG_SPEAR_EMIBASE 0x40000000 +#define CONFIG_SPEAR_RASBASE 0xB3000000 #define CONFIG_SYS_MACB0_BASE 0xAA000000 diff --git a/arch/arm/include/asm/arch-spear/spr_defs.h b/arch/arm/include/asm/arch-spear/spr_defs.h index 0ddce621e39..71d64a19921 100644 --- a/arch/arm/include/asm/arch-spear/spr_defs.h +++ b/arch/arm/include/asm/arch-spear/spr_defs.h @@ -28,6 +28,30 @@ extern int spear_board_init(ulong); extern void setfreq(unsigned int, unsigned int); extern unsigned int setfreq_sz; +void plat_ddr_init(void); +void soc_init(void); +void spear_late_init(void); +void plat_late_init(void); + +int snor_boot_selected(void); +int nand_boot_selected(void); +int pnor_boot_selected(void); +int usb_boot_selected(void); +int uart_boot_selected(void); +int tftp_boot_selected(void); +int i2c_boot_selected(void); +int spi_boot_selected(void); +int mmc_boot_selected(void); + +extern u32 mpmc_conf_vals[]; + +struct chip_data { + int cpufreq; + int dramfreq; + int dramtype; + uchar version[32]; +}; + /* HW mac id in i2c memory definitions */ #define MAGIC_OFF 0x0 #define MAGIC_LEN 0x2 @@ -36,4 +60,10 @@ extern unsigned int setfreq_sz; #define MAC_OFF 0x2 #define MAC_LEN 0x6 +#define PNOR_WIDTH_8 0 +#define PNOR_WIDTH_16 1 +#define PNOR_WIDTH_32 2 +#define PNOR_WIDTH_NUM 3 +#define PNOR_WIDTH_SEARCH 0xff + #endif diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h index b8fcf49febb..5f67a5fa203 100644 --- a/arch/arm/include/asm/arch-spear/spr_misc.h +++ b/arch/arm/include/asm/arch-spear/spr_misc.h @@ -46,7 +46,7 @@ struct misc_regs { u32 prsc2_clk_cfg; /* 0x48 */ u32 prsc3_clk_cfg; /* 0x4C */ u32 amem_cfg_ctrl; /* 0x50 */ - u32 port_cfg_ctrl; /* 0x54 */ + u32 expi_clk_cfg; /* 0x54 */ u32 reserved_1; /* 0x58 */ u32 clcd_synth_clk; /* 0x5C */ u32 irda_synth_clk; /* 0x60 */ @@ -101,6 +101,37 @@ struct misc_regs { u32 ras_gpp2_out; /* 0x800C */ }; +/* SYNTH_CLK value*/ +#define SYNTH23 0x00020003 + +/* PLLx_FRQ value */ +#if defined(CONFIG_SPEAR3XX) +#define FREQ_332 0xA600010C +#define FREQ_266 0x8500010C +#elif defined(CONFIG_SPEAR600) +#define FREQ_332 0xA600010F +#define FREQ_266 0x8500010F +#endif + +/* PLL_CTR_REG */ +#define MEM_CLK_SEL_MSK 0x70000000 +#define MEM_CLK_HCLK 0x00000000 +#define MEM_CLK_2HCLK 0x10000000 +#define MEM_CLK_PLL2 0x30000000 + +#define EXPI_CLK_CFG_LOW_COMPR 0x2000 +#define EXPI_CLK_CFG_CLK_EN 0x0400 +#define EXPI_CLK_CFG_RST 0x0200 +#define EXPI_CLK_SYNT_EN 0x0010 +#define EXPI_CLK_CFG_SEL_PLL2 0x0004 +#define EXPI_CLK_CFG_INT_CLK_EN 0x0001 + +#define PLL2_CNTL_6UA 0x1c00 +#define PLL2_CNTL_SAMPLE 0x0008 +#define PLL2_CNTL_ENABLE 0x0004 +#define PLL2_CNTL_RESETN 0x0002 +#define PLL2_CNTL_LOCK 0x0001 + /* AUTO_CFG_REG value */ #define MISC_SOCCFGMSK 0x0000003F #define MISC_SOCCFG30 0x0000000C @@ -131,9 +162,112 @@ struct misc_regs { #define MISC_ETHENB 0x00800000 #define MISC_SMIENB 0x00200000 #define MISC_GPT3ENB 0x00010000 +#define MISC_GPIO4ENB 0x00002000 #define MISC_GPT2ENB 0x00000800 #define MISC_FSMCENB 0x00000200 #define MISC_I2CENB 0x00000080 +#define MISC_SSP2ENB 0x00000070 #define MISC_UART0ENB 0x00000008 +/* PERIPH_CLK_CFG */ +#define XTALTIMEEN 0x00000001 +#define PLLTIMEEN 0x00000002 +#define CLCDCLK_SYNTH 0x00000000 +#define CLCDCLK_48MHZ 0x00000004 +#define CLCDCLK_EXT 0x00000008 +#define UARTCLK_MASK (0x1 << 4) +#define UARTCLK_48MHZ 0x00000000 +#define UARTCLK_SYNTH 0x00000010 +#define IRDACLK_48MHZ 0x00000000 +#define IRDACLK_SYNTH 0x00000020 +#define IRDACLK_EXT 0x00000040 +#define RTC_DISABLE 0x00000080 +#define GPT1CLK_48MHZ 0x00000000 +#define GPT1CLK_SYNTH 0x00000100 +#define GPT2CLK_48MHZ 0x00000000 +#define GPT2CLK_SYNTH 0x00000200 +#define GPT3CLK_48MHZ 0x00000000 +#define GPT3CLK_SYNTH 0x00000400 +#define GPT4CLK_48MHZ 0x00000000 +#define GPT4CLK_SYNTH 0x00000800 +#define GPT5CLK_48MHZ 0x00000000 +#define GPT5CLK_SYNTH 0x00001000 +#define GPT1_FREEZE 0x00002000 +#define GPT2_FREEZE 0x00004000 +#define GPT3_FREEZE 0x00008000 +#define GPT4_FREEZE 0x00010000 +#define GPT5_FREEZE 0x00020000 + +/* PERIPH1_CLKEN bits */ +#define PERIPH_ARM1_WE 0x00000001 +#define PERIPH_ARM1 0x00000002 +#define PERIPH_ARM2 0x00000004 +#define PERIPH_UART1 0x00000008 +#define PERIPH_UART2 0x00000010 +#define PERIPH_SSP1 0x00000020 +#define PERIPH_SSP2 0x00000040 +#define PERIPH_I2C 0x00000080 +#define PERIPH_JPEG 0x00000100 +#define PERIPH_FSMC 0x00000200 +#define PERIPH_FIRDA 0x00000400 +#define PERIPH_GPT4 0x00000800 +#define PERIPH_GPT5 0x00001000 +#define PERIPH_GPIO4 0x00002000 +#define PERIPH_SSP3 0x00004000 +#define PERIPH_ADC 0x00008000 +#define PERIPH_GPT3 0x00010000 +#define PERIPH_RTC 0x00020000 +#define PERIPH_GPIO3 0x00040000 +#define PERIPH_DMA 0x00080000 +#define PERIPH_ROM 0x00100000 +#define PERIPH_SMI 0x00200000 +#define PERIPH_CLCD 0x00400000 +#define PERIPH_GMAC 0x00800000 +#define PERIPH_USBD 0x01000000 +#define PERIPH_USBH1 0x02000000 +#define PERIPH_USBH2 0x04000000 +#define PERIPH_MPMC 0x08000000 +#define PERIPH_RAMW 0x10000000 +#define PERIPH_MPMC_EN 0x20000000 +#define PERIPH_MPMC_WE 0x40000000 +#define PERIPH_MPMCMSK 0x60000000 + +#define PERIPH_CLK_ALL 0x0FFFFFF8 +#define PERIPH_RST_ALL 0x00000004 + +/* DDR_PAD values */ +#define DDR_PAD_CNF_MSK 0x0000ffff +#define DDR_PAD_SW_CONF 0x00060000 +#define DDR_PAD_SSTL_SEL 0x00000001 +#define DDR_PAD_DRAM_TYPE 0x00008000 + +/* DDR_COMP values */ +#define DDR_COMP_ACCURATE 0x00000010 + +/* SoC revision stuff */ +#define SOC_PRI_SHFT 16 +#define SOC_SEC_SHFT 8 + +/* Revision definitions */ +#define SOC_SPEAR_NA 0 + +/* + * The definitons have started from + * 101 for SPEAr6xx + * 201 for SPEAr3xx + * 301 for SPEAr13xx + */ +#define SOC_SPEAR600_AA 101 +#define SOC_SPEAR600_AB 102 +#define SOC_SPEAR600_BA 103 +#define SOC_SPEAR600_BB 104 +#define SOC_SPEAR600_BC 105 +#define SOC_SPEAR600_BD 106 + +#define SOC_SPEAR300 201 +#define SOC_SPEAR310 202 +#define SOC_SPEAR320 203 + +extern int get_socrev(void); + #endif diff --git a/arch/arm/include/asm/arch-spear/spr_ssp.h b/arch/arm/include/asm/arch-spear/spr_ssp.h new file mode 100644 index 00000000000..4f144ee4d62 --- /dev/null +++ b/arch/arm/include/asm/arch-spear/spr_ssp.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 Stefan Roese + * + * 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 _SPR_SSP_H +#define _SPR_SSP_H + +struct ssp_regs { + u32 sspcr0; + u32 sspcr1; + u32 sspdr; + u32 sspsr; + u32 sspcpsr; + u32 sspimsc; + u32 sspicr; + u32 sspdmacr; +}; + +#define SSPCR0_FRF_MOT_SPI 0x0000 +#define SSPCR0_DSS_16BITS 0x000f + +#define SSPCR1_SSE 0x0002 + +#define SSPSR_TNF 0x2 +#define SSPSR_TFE 0x1 + +#endif diff --git a/arch/arm/include/asm/arch-spear/spr_syscntl.h b/arch/arm/include/asm/arch-spear/spr_syscntl.h index 3c92f094cf6..2393d89c0f4 100644 --- a/arch/arm/include/asm/arch-spear/spr_syscntl.h +++ b/arch/arm/include/asm/arch-spear/spr_syscntl.h @@ -21,6 +21,9 @@ * MA 02111-1307 USA */ +#ifndef __SYSCTRL_H +#define __SYSCTRL_H + struct syscntl_regs { u32 scctrl; u32 scsysstat; @@ -36,3 +39,14 @@ struct syscntl_regs { const u32 scperclken; const u32 scperstat; }; + +#define MODE_SHIFT 0x00000003 + +#define NORMAL 0x00000004 +#define SLOW 0x00000002 +#define DOZE 0x00000001 +#define SLEEP 0x00000000 + +#define PLL_TIM 0x01FFFFFF + +#endif -- cgit v1.2.3 From 5427d29c26bd980c37e449687fa8456598a57c91 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 1 Mar 2012 04:02:39 +0000 Subject: No need to define CONFIG_ARCH_CPU_INIT. All mx6 based boards should use arch_cpu_init(). Signed-off-by: Fabio Estevam Acked-by: Marek Vasut --- arch/arm/cpu/armv7/mx6/soc.c | 2 -- include/configs/mx6qarm2.h | 1 - include/configs/mx6qsabrelite.h | 1 - 3 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 90f208809ba..84b458c7eb0 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -43,7 +43,6 @@ u32 get_cpu_rev(void) return system_rev; } -#ifdef CONFIG_ARCH_CPU_INIT void init_aips(void) { struct aipstz_regs *aips1, *aips2; @@ -113,7 +112,6 @@ int arch_cpu_init(void) return 0; } -#endif #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) diff --git a/include/configs/mx6qarm2.h b/include/configs/mx6qarm2.h index a155c772341..a9c1b1545e0 100644 --- a/include/configs/mx6qarm2.h +++ b/include/configs/mx6qarm2.h @@ -37,7 +37,6 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) -#define CONFIG_ARCH_CPU_INIT #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_MXC_GPIO diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h index 5b566a8f2b7..fd25fafeabd 100644 --- a/include/configs/mx6qsabrelite.h +++ b/include/configs/mx6qsabrelite.h @@ -40,7 +40,6 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) -#define CONFIG_ARCH_CPU_INIT #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_MISC_INIT_R #define CONFIG_MXC_GPIO -- cgit v1.2.3 From c27c07b86b0a9ff71e3c4788d74cee50c7ed2283 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 1 Mar 2012 04:02:40 +0000 Subject: ARM: mx28: Remove CONFIG_ARCH_CPU_INIT No need to define CONFIG_ARCH_CPU_INIT. All mx28 based boards should use arch_cpu_init(). Signed-off-by: Fabio Estevam Acked-by: Marek Vasut --- arch/arm/cpu/arm926ejs/mx28/mx28.c | 2 -- include/configs/m28evk.h | 1 - include/configs/mx28evk.h | 1 - 3 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28.c b/arch/arm/cpu/arm926ejs/mx28/mx28.c index a82ff2564bd..ff25772099b 100644 --- a/arch/arm/cpu/arm926ejs/mx28/mx28.c +++ b/arch/arm/cpu/arm926ejs/mx28/mx28.c @@ -153,7 +153,6 @@ int arch_misc_init(void) } #endif -#ifdef CONFIG_ARCH_CPU_INIT int arch_cpu_init(void) { struct mx28_clkctrl_regs *clkctrl_regs = @@ -187,7 +186,6 @@ int arch_cpu_init(void) return 0; } -#endif #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h index a0e90ca694a..f12d927e038 100644 --- a/include/configs/m28evk.h +++ b/include/configs/m28evk.h @@ -40,7 +40,6 @@ #define CONFIG_SYS_ICACHE_OFF #define CONFIG_SYS_DCACHE_OFF #define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_ARCH_CPU_INIT #define CONFIG_ARCH_MISC_INIT /* diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h index 640dcb4be7c..8f60496d355 100644 --- a/include/configs/mx28evk.h +++ b/include/configs/mx28evk.h @@ -34,7 +34,6 @@ #define CONFIG_SYS_ICACHE_OFF #define CONFIG_SYS_DCACHE_OFF #define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_ARCH_CPU_INIT #define CONFIG_ARCH_MISC_INIT /* -- cgit v1.2.3 From d519b4bc0a1216eb273c76c129b779fa1ba2beb5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 2 Apr 2012 11:19:45 +0000 Subject: ARM: introduce arch_early_init_r() Introduce arch_early_init_r() function, which can be useful for doing early initialization after relocation has happened. Signed-off-by: Fabio Estevam --- arch/arm/include/asm/u-boot-arm.h | 1 + arch/arm/lib/board.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 4ca75f9f93d..9f3cae5ece4 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -52,6 +52,7 @@ void cpu_init_cp15(void); /* cpu/.../arch/cpu.c */ int arch_cpu_init(void); int arch_misc_init(void); +int arch_early_init_r(void); /* board/.../... */ int board_init(void); diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 024646cae5a..f21591dc6ab 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -500,6 +500,10 @@ void board_init_r(gd_t *id, ulong dest_addr) malloc_start = dest_addr - TOTAL_MALLOC_LEN; mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); +#ifdef CONFIG_ARCH_EARLY_INIT_R + arch_early_init_r(); +#endif + #if !defined(CONFIG_SYS_NO_FLASH) puts("Flash: "); -- cgit v1.2.3 From d702b0811df53a1fc2d8049e35431e4591d093c6 Mon Sep 17 00:00:00 2001 From: SRICHARAN R Date: Wed, 16 May 2012 23:52:54 +0000 Subject: ARM: cache: Move the cp15 CR register read before flushing the cache. The following is the cleanup sequence in arch/arm/cpu/armv7/cpu.c int cleanup_before_linux(void) { ... ... dcache_disable(); v7_outer_cache_disable(); invalidate_dcache_all(); } 1) invalidate_dcache_all call expects that all the caches has been flushed, invalidated and there are no dirty entries prior to its execution. In the above sequence dcache_disable() flushes, invalidates the caches and turns off the mmu. But after it cleanups the cache and before the mmu is disabled there is a cp_delay() function which has STR instruction. On certain cores like the cortex-a15, cache hit and a write can happen to a cache line even when the dcache is disabled. So the above mentioned STR instruction creates a dirty entry after cleaning. The mmu gets disabled after this. 2) invalidate_dcache_all invalidates the cache lines. Again on cores like cortex-a15, invalidate instruction flushes the dirty line as well. So some times the dirty line from sequence 1 can corrupt the memory resulting in a crash. Fixing this by moving the get_cr() and cp_delay() calls before cleaning up the cache, thus avoiding the dirty entry. Signed-off-by: R Sricharan --- arch/arm/lib/cache-cp15.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index e6c3eae6f9d..939de10e039 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -115,17 +115,17 @@ static void cache_disable(uint32_t cache_bit) { uint32_t reg; + reg = get_cr(); + cp_delay(); + if (cache_bit == CR_C) { /* if cache isn;t enabled no need to disable */ - reg = get_cr(); if ((reg & CR_C) != CR_C) return; /* if disabling data cache, disable mmu too */ cache_bit |= CR_M; flush_dcache_all(); } - reg = get_cr(); - cp_delay(); set_cr(reg & ~cache_bit); } #endif -- cgit v1.2.3