aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Forlin <per.forlin@linaro.org>2011-08-26 12:25:53 +0200
committerJohn Rigby <john.rigby@linaro.org>2012-01-19 17:08:45 -0700
commit5351cac1ebbce9a645c35d892a9a597846592fab (patch)
tree2db2776c825cd70e7002e19559f13270b3f365e0
parentb74c35da22d27dbffff42087b94cc9447dec2275 (diff)
snowball: igloo copy port of board specific files
TODO: remove mmc driver and use pl180_mmci. Signed-off-by: Per Forlin <per.forlin@linaro.org>
-rw-r--r--board/st-ericsson/snowball/Makefile53
-rw-r--r--board/st-ericsson/snowball/db8500_pins.h745
-rw-r--r--board/st-ericsson/snowball/mmc_fifo.S146
-rw-r--r--board/st-ericsson/snowball/mmc_fifo.h45
-rw-r--r--board/st-ericsson/snowball/mmc_host.c589
-rw-r--r--board/st-ericsson/snowball/mmc_host.h302
-rw-r--r--board/st-ericsson/snowball/mmc_utils.c180
-rw-r--r--board/st-ericsson/snowball/snowball.c481
-rw-r--r--include/configs/snowball.h297
9 files changed, 2838 insertions, 0 deletions
diff --git a/board/st-ericsson/snowball/Makefile b/board/st-ericsson/snowball/Makefile
new file mode 100644
index 000000000..560ed118c
--- /dev/null
+++ b/board/st-ericsson/snowball/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := snowball.o mmc_host.o mmc_utils.o
+SOBJS := mmc_fifo.o
+
+#prcmu.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/st-ericsson/snowball/db8500_pins.h b/board/st-ericsson/snowball/db8500_pins.h
new file mode 100644
index 000000000..9cbaff648
--- /dev/null
+++ b/board/st-ericsson/snowball/db8500_pins.h
@@ -0,0 +1,745 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Code ported from Nomadik GPIO driver in ST-Ericsson Linux kernel code.
+ * The purpose is that GPIO config found in kernel should work by simply
+ * copy-paste it to U-boot.
+ *
+ * Ported to U-boot by:
+ * Copyright (C) 2010 Joakim Axelsson <joakim.axelsson AT stericsson.com>
+ **
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __DB8500_PINS_H
+#define __DB8500_PINS_H
+
+#include <db8500_pincfg.h>
+
+#define GPIO0_GPIO PIN_CFG(0, GPIO)
+#define GPIO0_U0_CTSn PIN_CFG(0, ALT_A)
+#define GPIO0_TRIG_OUT PIN_CFG(0, ALT_B)
+#define GPIO0_IP_TDO PIN_CFG(0, ALT_C)
+
+#define GPIO1_GPIO PIN_CFG(1, GPIO)
+#define GPIO1_U0_RTSn PIN_CFG(1, ALT_A)
+#define GPIO1_TRIG_IN PIN_CFG(1, ALT_B)
+#define GPIO1_IP_TDI PIN_CFG(1, ALT_C)
+
+#define GPIO2_GPIO PIN_CFG(2, GPIO)
+#define GPIO2_U0_RXD PIN_CFG(2, ALT_A)
+#define GPIO2_NONE PIN_CFG(2, ALT_B)
+#define GPIO2_IP_TMS PIN_CFG(2, ALT_C)
+
+#define GPIO3_GPIO PIN_CFG(3, GPIO)
+#define GPIO3_U0_TXD PIN_CFG(3, ALT_A)
+#define GPIO3_NONE PIN_CFG(3, ALT_B)
+#define GPIO3_IP_TCK PIN_CFG(3, ALT_C)
+
+#define GPIO4_GPIO PIN_CFG(4, GPIO)
+#define GPIO4_U1_RXD PIN_CFG(4, ALT_A)
+#define GPIO4_I2C4_SCL PIN_CFG_PULL(4, ALT_B, UP)
+#define GPIO4_IP_TRSTn PIN_CFG(4, ALT_C)
+
+#define GPIO5_GPIO PIN_CFG(5, GPIO)
+#define GPIO5_U1_TXD PIN_CFG(5, ALT_A)
+#define GPIO5_I2C4_SDA PIN_CFG_PULL(5, ALT_B, UP)
+#define GPIO5_IP_GPIO6 PIN_CFG(5, ALT_C)
+
+#define GPIO6_GPIO PIN_CFG(6, GPIO)
+#define GPIO6_U1_CTSn PIN_CFG(6, ALT_A)
+#define GPIO6_I2C1_SCL PIN_CFG_PULL(6, ALT_B, UP)
+#define GPIO6_IP_GPIO0 PIN_CFG(6, ALT_C)
+
+#define GPIO7_GPIO PIN_CFG(7, GPIO)
+#define GPIO7_U1_RTSn PIN_CFG(7, ALT_A)
+#define GPIO7_I2C1_SDA PIN_CFG_PULL(7, ALT_B, UP)
+#define GPIO7_IP_GPIO1 PIN_CFG(7, ALT_C)
+
+#define GPIO8_GPIO PIN_CFG(8, GPIO)
+#define GPIO8_IPI2C_SDA PIN_CFG_PULL(8, ALT_A, UP)
+#define GPIO8_I2C2_SDA PIN_CFG_PULL(8, ALT_B, UP)
+
+#define GPIO9_GPIO PIN_CFG(9, GPIO)
+#define GPIO9_IPI2C_SCL PIN_CFG_PULL(9, ALT_A, UP)
+#define GPIO9_I2C2_SCL PIN_CFG_PULL(9, ALT_B, UP)
+
+#define GPIO10_GPIO PIN_CFG(10, GPIO)
+#define GPIO10_IPI2C_SDA PIN_CFG_PULL(10, ALT_A, UP)
+#define GPIO10_I2C2_SDA PIN_CFG_PULL(10, ALT_B, UP)
+#define GPIO10_IP_GPIO3 PIN_CFG(10, ALT_C)
+
+#define GPIO11_GPIO PIN_CFG(11, GPIO)
+#define GPIO11_IPI2C_SCL PIN_CFG_PULL(11, ALT_A, UP)
+#define GPIO11_I2C2_SCL PIN_CFG_PULL(11, ALT_B, UP)
+#define GPIO11_IP_GPIO2 PIN_CFG(11, ALT_C)
+
+#define GPIO12_GPIO PIN_CFG(12, GPIO)
+#define GPIO12_MSP0_TXD PIN_CFG(12, ALT_A)
+#define GPIO12_MSP0_RXD PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO PIN_CFG(13, GPIO)
+#define GPIO13_MSP0_TFS PIN_CFG(13, ALT_A)
+
+#define GPIO14_GPIO PIN_CFG(14, GPIO)
+#define GPIO14_MSP0_TCK PIN_CFG(14, ALT_A)
+
+#define GPIO15_GPIO PIN_CFG(15, GPIO)
+#define GPIO15_MSP0_RXD PIN_CFG(15, ALT_A)
+#define GPIO15_MSP0_TXD PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO PIN_CFG(16, GPIO)
+#define GPIO16_MSP0_RFS PIN_CFG(16, ALT_A)
+#define GPIO16_I2C1_SCL PIN_CFG_PULL(16, ALT_B, UP)
+#define GPIO16_SLIM0_DAT PIN_CFG(16, ALT_C)
+
+#define GPIO17_GPIO PIN_CFG(17, GPIO)
+#define GPIO17_MSP0_RCK PIN_CFG(17, ALT_A)
+#define GPIO17_I2C1_SDA PIN_CFG_PULL(17, ALT_B, UP)
+#define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C)
+
+#define GPIO18_GPIO PIN_CFG(18, GPIO)
+#define GPIO18_MC0_CMDDIR PIN_CFG(18, ALT_A)
+#define GPIO18_U2_RXD PIN_CFG(18, ALT_B)
+#define GPIO18_MS_IEP PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO PIN_CFG(19, GPIO)
+#define GPIO19_MC0_DAT0DIR PIN_CFG(19, ALT_A)
+#define GPIO19_U2_TXD PIN_CFG(19, ALT_B)
+#define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C)
+
+#define GPIO20_GPIO PIN_CFG(20, GPIO)
+#define GPIO20_MC0_DAT2DIR PIN_CFG(20, ALT_A)
+#define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B)
+#define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C)
+
+#define GPIO21_GPIO PIN_CFG(21, GPIO)
+#define GPIO21_MC0_DAT31DIR PIN_CFG(21, ALT_A)
+#define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B)
+#define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C)
+
+#define GPIO22_GPIO PIN_CFG(22, GPIO)
+#define GPIO22_MC0_FBCLK PIN_CFG(22, ALT_A)
+#define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B)
+#define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C)
+
+#define GPIO23_GPIO PIN_CFG(23, GPIO)
+#define GPIO23_MC0_CLK PIN_CFG(23, ALT_A)
+#define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B)
+#define GPIO23_MS_CLK PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO PIN_CFG(24, GPIO)
+#define GPIO24_MC0_CMD PIN_CFG(24, ALT_A)
+#define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B)
+#define GPIO24_MS_BS PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO PIN_CFG(25, GPIO)
+#define GPIO25_MC0_DAT0 PIN_CFG(25, ALT_A)
+#define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B)
+#define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO PIN_CFG(26, GPIO)
+#define GPIO26_MC0_DAT1 PIN_CFG(26, ALT_A)
+#define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B)
+#define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C)
+
+#define GPIO27_GPIO PIN_CFG(27, GPIO)
+#define GPIO27_MC0_DAT2 PIN_CFG(27, ALT_A)
+#define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B)
+#define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C)
+
+#define GPIO28_GPIO PIN_CFG(28, GPIO)
+#define GPIO28_MC0_DAT3 PIN_CFG(28, ALT_A)
+#define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B)
+#define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C)
+
+#define GPIO29_GPIO PIN_CFG(29, GPIO)
+#define GPIO29_MC0_DAT4 PIN_CFG(29, ALT_A)
+#define GPIO29_SPI3_CLK PIN_CFG(29, ALT_B)
+#define GPIO29_U2_RXD PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A)
+#define GPIO30_SPI3_RXD PIN_CFG(30, ALT_B)
+#define GPIO30_U2_TXD PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT6 PIN_CFG(31, ALT_A)
+#define GPIO31_SPI3_FRM PIN_CFG(31, ALT_B)
+#define GPIO31_U2_CTSn PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO PIN_CFG(32, GPIO)
+#define GPIO32_MC0_DAT7 PIN_CFG(32, ALT_A)
+#define GPIO32_SPI3_TXD PIN_CFG(32, ALT_B)
+#define GPIO32_U2_RTSn PIN_CFG(32, ALT_C)
+
+#define GPIO33_GPIO PIN_CFG(33, GPIO)
+#define GPIO33_MSP1_TXD PIN_CFG(33, ALT_A)
+#define GPIO33_MSP1_RXD PIN_CFG(33, ALT_B)
+#define GPIO33_U0_DTRn PIN_CFG(33, ALT_C)
+
+#define GPIO34_GPIO PIN_CFG(34, GPIO)
+#define GPIO34_MSP1_TFS PIN_CFG(34, ALT_A)
+#define GPIO34_NONE PIN_CFG(34, ALT_B)
+#define GPIO34_U0_DCDn PIN_CFG(34, ALT_C)
+
+#define GPIO35_GPIO PIN_CFG(35, GPIO)
+#define GPIO35_MSP1_TCK PIN_CFG(35, ALT_A)
+#define GPIO35_NONE PIN_CFG(35, ALT_B)
+#define GPIO35_U0_DSRn PIN_CFG(35, ALT_C)
+
+#define GPIO36_GPIO PIN_CFG(36, GPIO)
+#define GPIO36_MSP1_RXD PIN_CFG(36, ALT_A)
+#define GPIO36_MSP1_TXD PIN_CFG(36, ALT_B)
+#define GPIO36_U0_RIn PIN_CFG(36, ALT_C)
+
+#define GPIO64_GPIO PIN_CFG(64, GPIO)
+#define GPIO64_LCDB_DE PIN_CFG(64, ALT_A)
+#define GPIO64_KP_O1 PIN_CFG(64, ALT_B)
+#define GPIO64_IP_GPIO4 PIN_CFG(64, ALT_C)
+
+#define GPIO65_GPIO PIN_CFG(65, GPIO)
+#define GPIO65_LCDB_HSO PIN_CFG(65, ALT_A)
+#define GPIO65_KP_O0 PIN_CFG(65, ALT_B)
+#define GPIO65_IP_GPIO5 PIN_CFG(65, ALT_C)
+
+#define GPIO66_GPIO PIN_CFG(66, GPIO)
+#define GPIO66_LCDB_VSO PIN_CFG(66, ALT_A)
+#define GPIO66_KP_I1 PIN_CFG(66, ALT_B)
+#define GPIO66_IP_GPIO6 PIN_CFG(66, ALT_C)
+
+#define GPIO67_GPIO PIN_CFG(67, GPIO)
+#define GPIO67_LCDB_CLK PIN_CFG(67, ALT_A)
+#define GPIO67_KP_I0 PIN_CFG(67, ALT_B)
+#define GPIO67_IP_GPIO7 PIN_CFG(67, ALT_C)
+
+#define GPIO68_GPIO PIN_CFG(68, GPIO)
+#define GPIO68_LCD_VSI0 PIN_CFG(68, ALT_A)
+#define GPIO68_KP_O7 PIN_CFG(68, ALT_B)
+#define GPIO68_SM_CLE PIN_CFG(68, ALT_C)
+
+#define GPIO69_GPIO PIN_CFG(69, GPIO)
+#define GPIO69_LCD_VSI1 PIN_CFG(69, ALT_A)
+#define GPIO69_KP_I7 PIN_CFG(69, ALT_B)
+#define GPIO69_SM_ALE PIN_CFG(69, ALT_C)
+
+#define GPIO70_GPIO PIN_CFG(70, GPIO)
+#define GPIO70_LCD_D0 PIN_CFG(70, ALT_A)
+#define GPIO70_KP_O5 PIN_CFG(70, ALT_B)
+#define GPIO70_STMAPE_CLK PIN_CFG(70, ALT_C)
+
+#define GPIO71_GPIO PIN_CFG(71, GPIO)
+#define GPIO71_LCD_D1 PIN_CFG(71, ALT_A)
+#define GPIO71_KP_O4 PIN_CFG(71, ALT_B)
+#define GPIO71_STMAPE_DAT3 PIN_CFG(71, ALT_C)
+
+#define GPIO72_GPIO PIN_CFG(72, GPIO)
+#define GPIO72_LCD_D2 PIN_CFG(72, ALT_A)
+#define GPIO72_KP_O3 PIN_CFG(72, ALT_B)
+#define GPIO72_STMAPE_DAT2 PIN_CFG(72, ALT_C)
+
+#define GPIO73_GPIO PIN_CFG(73, GPIO)
+#define GPIO73_LCD_D3 PIN_CFG(73, ALT_A)
+#define GPIO73_KP_O2 PIN_CFG(73, ALT_B)
+#define GPIO73_STMAPE_DAT1 PIN_CFG(73, ALT_C)
+
+#define GPIO74_GPIO PIN_CFG(74, GPIO)
+#define GPIO74_LCD_D4 PIN_CFG(74, ALT_A)
+#define GPIO74_KP_I5 PIN_CFG(74, ALT_B)
+#define GPIO74_STMAPE_DAT0 PIN_CFG(74, ALT_C)
+
+#define GPIO75_GPIO PIN_CFG(75, GPIO)
+#define GPIO75_LCD_D5 PIN_CFG(75, ALT_A)
+#define GPIO75_KP_I4 PIN_CFG(75, ALT_B)
+#define GPIO75_U2_RXD PIN_CFG(75, ALT_C)
+
+#define GPIO76_GPIO PIN_CFG(76, GPIO)
+#define GPIO76_LCD_D6 PIN_CFG(76, ALT_A)
+#define GPIO76_KP_I3 PIN_CFG(76, ALT_B)
+#define GPIO76_U2_TXD PIN_CFG(76, ALT_C)
+
+#define GPIO77_GPIO PIN_CFG(77, GPIO)
+#define GPIO77_LCD_D7 PIN_CFG(77, ALT_A)
+#define GPIO77_KP_I2 PIN_CFG(77, ALT_B)
+#define GPIO77_NONE PIN_CFG(77, ALT_C)
+
+#define GPIO78_GPIO PIN_CFG(78, GPIO)
+#define GPIO78_LCD_D8 PIN_CFG(78, ALT_A)
+#define GPIO78_KP_O6 PIN_CFG(78, ALT_B)
+#define GPIO78_IP_GPIO2 PIN_CFG(78, ALT_C)
+
+#define GPIO79_GPIO PIN_CFG(79, GPIO)
+#define GPIO79_LCD_D9 PIN_CFG(79, ALT_A)
+#define GPIO79_KP_I6 PIN_CFG(79, ALT_B)
+#define GPIO79_IP_GPIO3 PIN_CFG(79, ALT_C)
+
+#define GPIO80_GPIO PIN_CFG(80, GPIO)
+#define GPIO80_LCD_D10 PIN_CFG(80, ALT_A)
+#define GPIO80_KP_SKA0 PIN_CFG(80, ALT_B)
+#define GPIO80_IP_GPIO4 PIN_CFG(80, ALT_C)
+
+#define GPIO81_GPIO PIN_CFG(81, GPIO)
+#define GPIO81_LCD_D11 PIN_CFG(81, ALT_A)
+#define GPIO81_KP_SKB0 PIN_CFG(81, ALT_B)
+#define GPIO81_IP_GPIO5 PIN_CFG(81, ALT_C)
+
+#define GPIO82_GPIO PIN_CFG(82, GPIO)
+#define GPIO82_LCD_D12 PIN_CFG(82, ALT_A)
+#define GPIO82_KP_O5 PIN_CFG(82, ALT_B)
+
+#define GPIO83_GPIO PIN_CFG(83, GPIO)
+#define GPIO83_LCD_D13 PIN_CFG(83, ALT_A)
+#define GPIO83_KP_O4 PIN_CFG(83, ALT_B)
+
+#define GPIO84_GPIO PIN_CFG_PULL(84, GPIO, UP)
+#define GPIO84_LCD_D14 PIN_CFG(84, ALT_A)
+#define GPIO84_KP_I5 PIN_CFG(84, ALT_B)
+
+#define GPIO85_GPIO PIN_CFG(85, GPIO)
+#define GPIO85_LCD_D15 PIN_CFG(85, ALT_A)
+#define GPIO85_KP_I4 PIN_CFG(85, ALT_B)
+
+#define GPIO86_GPIO PIN_CFG(86, GPIO)
+#define GPIO86_LCD_D16 PIN_CFG(86, ALT_A)
+#define GPIO86_SM_ADQ0 PIN_CFG(86, ALT_B)
+#define GPIO86_MC5_DAT0 PIN_CFG(86, ALT_C)
+
+#define GPIO87_GPIO PIN_CFG(87, GPIO)
+#define GPIO87_LCD_D17 PIN_CFG(87, ALT_A)
+#define GPIO87_SM_ADQ1 PIN_CFG(87, ALT_B)
+#define GPIO87_MC5_DAT1 PIN_CFG(87, ALT_C)
+
+#define GPIO88_GPIO PIN_CFG(88, GPIO)
+#define GPIO88_LCD_D18 PIN_CFG(88, ALT_A)
+#define GPIO88_SM_ADQ2 PIN_CFG(88, ALT_B)
+#define GPIO88_MC5_DAT2 PIN_CFG(88, ALT_C)
+
+#define GPIO89_GPIO PIN_CFG(89, GPIO)
+#define GPIO89_LCD_D19 PIN_CFG(89, ALT_A)
+#define GPIO89_SM_ADQ3 PIN_CFG(89, ALT_B)
+#define GPIO89_MC5_DAT3 PIN_CFG(89, ALT_C)
+
+#define GPIO90_GPIO PIN_CFG(90, GPIO)
+#define GPIO90_LCD_D20 PIN_CFG(90, ALT_A)
+#define GPIO90_SM_ADQ4 PIN_CFG(90, ALT_B)
+#define GPIO90_MC5_CMD PIN_CFG(90, ALT_C)
+
+#define GPIO91_GPIO PIN_CFG(91, GPIO)
+#define GPIO91_LCD_D21 PIN_CFG(91, ALT_A)
+#define GPIO91_SM_ADQ5 PIN_CFG(91, ALT_B)
+#define GPIO91_MC5_FBCLK PIN_CFG(91, ALT_C)
+
+#define GPIO92_GPIO PIN_CFG(92, GPIO)
+#define GPIO92_LCD_D22 PIN_CFG(92, ALT_A)
+#define GPIO92_SM_ADQ6 PIN_CFG(92, ALT_B)
+#define GPIO92_MC5_CLK PIN_CFG(92, ALT_C)
+
+#define GPIO93_GPIO PIN_CFG(93, GPIO)
+#define GPIO93_LCD_D23 PIN_CFG(93, ALT_A)
+#define GPIO93_SM_ADQ7 PIN_CFG(93, ALT_B)
+#define GPIO93_MC5_DAT4 PIN_CFG(93, ALT_C)
+
+#define GPIO94_GPIO PIN_CFG(94, GPIO)
+#define GPIO94_KP_O7 PIN_CFG(94, ALT_A)
+#define GPIO94_SM_ADVn PIN_CFG(94, ALT_B)
+#define GPIO94_MC5_DAT5 PIN_CFG(94, ALT_C)
+
+#define GPIO95_GPIO PIN_CFG(95, GPIO)
+#define GPIO95_KP_I7 PIN_CFG(95, ALT_A)
+#define GPIO95_SM_CS0n PIN_CFG(95, ALT_B)
+#define GPIO95_SM_PS0n PIN_CFG(95, ALT_C)
+
+#define GPIO96_GPIO PIN_CFG(96, GPIO)
+#define GPIO96_KP_O6 PIN_CFG(96, ALT_A)
+#define GPIO96_SM_OEn PIN_CFG(96, ALT_B)
+#define GPIO96_MC5_DAT6 PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO PIN_CFG(97, GPIO)
+#define GPIO97_KP_I6 PIN_CFG(97, ALT_A)
+#define GPIO97_SM_WEn PIN_CFG(97, ALT_B)
+#define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C)
+
+#define GPIO128_GPIO PIN_CFG(128, GPIO)
+#define GPIO128_MC2_CLK PIN_CFG(128, ALT_A)
+#define GPIO128_SM_CKO PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO PIN_CFG(129, GPIO)
+#define GPIO129_MC2_CMD PIN_CFG(129, ALT_A)
+#define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO PIN_CFG(130, GPIO)
+#define GPIO130_MC2_FBCLK PIN_CFG(130, ALT_A)
+#define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B)
+#define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C)
+
+#define GPIO131_GPIO PIN_CFG(131, GPIO)
+#define GPIO131_MC2_DAT0 PIN_CFG(131, ALT_A)
+#define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO PIN_CFG(132, GPIO)
+#define GPIO132_MC2_DAT1 PIN_CFG(132, ALT_A)
+#define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B)
+
+#define GPIO133_GPIO PIN_CFG(133, GPIO)
+#define GPIO133_MC2_DAT2 PIN_CFG(133, ALT_A)
+#define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B)
+
+#define GPIO134_GPIO PIN_CFG(134, GPIO)
+#define GPIO134_MC2_DAT3 PIN_CFG(134, ALT_A)
+#define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B)
+
+#define GPIO135_GPIO PIN_CFG(135, GPIO)
+#define GPIO135_MC2_DAT4 PIN_CFG(135, ALT_A)
+#define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B)
+
+#define GPIO136_GPIO PIN_CFG(136, GPIO)
+#define GPIO136_MC2_DAT5 PIN_CFG(136, ALT_A)
+#define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B)
+
+#define GPIO137_GPIO PIN_CFG(137, GPIO)
+#define GPIO137_MC2_DAT6 PIN_CFG(137, ALT_A)
+#define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B)
+
+#define GPIO138_GPIO PIN_CFG(138, GPIO)
+#define GPIO138_MC2_DAT7 PIN_CFG(138, ALT_A)
+#define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B)
+
+#define GPIO139_GPIO PIN_CFG(139, GPIO)
+#define GPIO139_SSP1_RXD PIN_CFG(139, ALT_A)
+#define GPIO139_SM_WAIT1n PIN_CFG(139, ALT_B)
+#define GPIO139_KP_O8 PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO PIN_CFG(140, GPIO)
+#define GPIO140_SSP1_TXD PIN_CFG(140, ALT_A)
+#define GPIO140_IP_GPIO7 PIN_CFG(140, ALT_B)
+#define GPIO140_KP_SKA1 PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO PIN_CFG(141, GPIO)
+#define GPIO141_SSP1_CLK PIN_CFG(141, ALT_A)
+#define GPIO141_IP_GPIO2 PIN_CFG(141, ALT_B)
+#define GPIO141_KP_O9 PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO PIN_CFG(142, GPIO)
+#define GPIO142_SSP1_FRM PIN_CFG(142, ALT_A)
+#define GPIO142_IP_GPIO3 PIN_CFG(142, ALT_B)
+#define GPIO142_KP_SKB1 PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO PIN_CFG(143, GPIO)
+#define GPIO143_SSP0_CLK PIN_CFG(143, ALT_A)
+
+#define GPIO144_GPIO PIN_CFG(144, GPIO)
+#define GPIO144_SSP0_FRM PIN_CFG(144, ALT_A)
+
+#define GPIO145_GPIO PIN_CFG(145, GPIO)
+#define GPIO145_SSP0_RXD PIN_CFG(145, ALT_A)
+
+#define GPIO146_GPIO PIN_CFG(146, GPIO)
+#define GPIO146_SSP0_TXD PIN_CFG(146, ALT_A)
+
+#define GPIO147_GPIO PIN_CFG(147, GPIO)
+#define GPIO147_I2C0_SCL PIN_CFG_PULL(147, ALT_A, UP)
+
+#define GPIO148_GPIO PIN_CFG(148, GPIO)
+#define GPIO148_I2C0_SDA PIN_CFG_PULL(148, ALT_A, UP)
+
+#define GPIO149_GPIO PIN_CFG(149, GPIO)
+#define GPIO149_IP_GPIO0 PIN_CFG(149, ALT_A)
+#define GPIO149_SM_CS1n PIN_CFG(149, ALT_B)
+#define GPIO149_SM_PS1n PIN_CFG(149, ALT_C)
+
+#define GPIO150_GPIO PIN_CFG(150, GPIO)
+#define GPIO150_IP_GPIO1 PIN_CFG(150, ALT_A)
+#define GPIO150_LCDA_CLK PIN_CFG(150, ALT_B)
+
+#define GPIO151_GPIO PIN_CFG(151, GPIO)
+#define GPIO151_KP_SKA0 PIN_CFG(151, ALT_A)
+#define GPIO151_LCD_VSI0 PIN_CFG(151, ALT_B)
+#define GPIO151_KP_O8 PIN_CFG(151, ALT_C)
+
+#define GPIO152_GPIO PIN_CFG(152, GPIO)
+#define GPIO152_KP_SKB0 PIN_CFG(152, ALT_A)
+#define GPIO152_LCD_VSI1 PIN_CFG(152, ALT_B)
+#define GPIO152_KP_O9 PIN_CFG(152, ALT_C)
+
+#define GPIO153_GPIO PIN_CFG(153, GPIO)
+#define GPIO153_KP_I7 PIN_CFG_PULL(153, ALT_A, DOWN)
+#define GPIO153_LCD_D24 PIN_CFG(153, ALT_B)
+#define GPIO153_U2_RXD PIN_CFG(153, ALT_C)
+
+#define GPIO154_GPIO PIN_CFG(154, GPIO)
+#define GPIO154_KP_I6 PIN_CFG_PULL(154, ALT_A, DOWN)
+#define GPIO154_LCD_D25 PIN_CFG(154, ALT_B)
+#define GPIO154_U2_TXD PIN_CFG(154, ALT_C)
+
+#define GPIO155_GPIO PIN_CFG(155, GPIO)
+#define GPIO155_KP_I5 PIN_CFG_PULL(155, ALT_A, DOWN)
+#define GPIO155_LCD_D26 PIN_CFG(155, ALT_B)
+#define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C)
+
+#define GPIO156_GPIO PIN_CFG(156, GPIO)
+#define GPIO156_KP_I4 PIN_CFG_PULL(156, ALT_A, DOWN)
+#define GPIO156_LCD_D27 PIN_CFG(156, ALT_B)
+#define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C)
+
+#define GPIO157_GPIO PIN_CFG(157, GPIO)
+#define GPIO157_KP_O7 PIN_CFG_PULL(157, ALT_A, UP)
+#define GPIO157_LCD_D28 PIN_CFG(157, ALT_B)
+#define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C)
+
+#define GPIO158_GPIO PIN_CFG(158, GPIO)
+#define GPIO158_KP_O6 PIN_CFG_PULL(158, ALT_A, UP)
+#define GPIO158_LCD_D29 PIN_CFG(158, ALT_B)
+#define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C)
+
+#define GPIO159_GPIO PIN_CFG(159, GPIO)
+#define GPIO159_KP_O5 PIN_CFG_PULL(159, ALT_A, UP)
+#define GPIO159_LCD_D30 PIN_CFG(159, ALT_B)
+#define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C)
+
+#define GPIO160_GPIO PIN_CFG(160, GPIO)
+#define GPIO160_KP_O4 PIN_CFG_PULL(160, ALT_A, UP)
+#define GPIO160_LCD_D31 PIN_CFG(160, ALT_B)
+#define GPIO160_NONE PIN_CFG(160, ALT_C)
+
+#define GPIO161_GPIO PIN_CFG(161, GPIO)
+#define GPIO161_KP_I3 PIN_CFG_PULL(161, ALT_A, DOWN)
+#define GPIO161_LCD_D32 PIN_CFG(161, ALT_B)
+#define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C)
+
+#define GPIO162_GPIO PIN_CFG(162, GPIO)
+#define GPIO162_KP_I2 PIN_CFG_PULL(162, ALT_A, DOWN)
+#define GPIO162_LCD_D33 PIN_CFG(162, ALT_B)
+#define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C)
+
+#define GPIO163_GPIO PIN_CFG(163, GPIO)
+#define GPIO163_KP_I1 PIN_CFG_PULL(163, ALT_A, DOWN)
+#define GPIO163_LCD_D34 PIN_CFG(163, ALT_B)
+#define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C)
+
+#define GPIO164_GPIO PIN_CFG(164, GPIO)
+#define GPIO164_KP_I0 PIN_CFG_PULL(164, ALT_A, UP)
+#define GPIO164_LCD_D35 PIN_CFG(164, ALT_B)
+#define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C)
+
+#define GPIO165_GPIO PIN_CFG(165, GPIO)
+#define GPIO165_KP_O3 PIN_CFG_PULL(165, ALT_A, UP)
+#define GPIO165_LCD_D36 PIN_CFG(165, ALT_B)
+#define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO PIN_CFG(166, GPIO)
+#define GPIO166_KP_O2 PIN_CFG_PULL(166, ALT_A, UP)
+#define GPIO166_LCD_D37 PIN_CFG(166, ALT_B)
+#define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO PIN_CFG(167, GPIO)
+#define GPIO167_KP_O1 PIN_CFG_PULL(167, ALT_A, UP)
+#define GPIO167_LCD_D38 PIN_CFG(167, ALT_B)
+#define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO PIN_CFG(168, GPIO)
+#define GPIO168_KP_O0 PIN_CFG_PULL(168, ALT_A, UP)
+#define GPIO168_LCD_D39 PIN_CFG(168, ALT_B)
+#define GPIO168_NONE PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO PIN_CFG(169, GPIO)
+#define GPIO169_RF_PURn PIN_CFG(169, ALT_A)
+#define GPIO169_LCDA_DE PIN_CFG(169, ALT_B)
+#define GPIO169_USBSIM_PDC PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO PIN_CFG(170, GPIO)
+#define GPIO170_MODEM_STATE PIN_CFG(170, ALT_A)
+#define GPIO170_LCDA_VSO PIN_CFG(170, ALT_B)
+#define GPIO170_KP_SKA1 PIN_CFG(170, ALT_C)
+
+#define GPIO171_GPIO PIN_CFG(171, GPIO)
+#define GPIO171_MODEM_PWREN PIN_CFG(171, ALT_A)
+#define GPIO171_LCDA_HSO PIN_CFG(171, ALT_B)
+#define GPIO171_KP_SKB1 PIN_CFG(171, ALT_C)
+
+#define GPIO192_GPIO PIN_CFG(192, GPIO)
+#define GPIO192_MSP2_SCK PIN_CFG(192, ALT_A)
+
+#define GPIO193_GPIO PIN_CFG(193, GPIO)
+#define GPIO193_MSP2_TXD PIN_CFG(193, ALT_A)
+
+#define GPIO194_GPIO PIN_CFG(194, GPIO)
+#define GPIO194_MSP2_TCK PIN_CFG(194, ALT_A)
+
+#define GPIO195_GPIO PIN_CFG(195, GPIO)
+#define GPIO195_MSP2_TFS PIN_CFG(195, ALT_A)
+
+#define GPIO196_GPIO PIN_CFG(196, GPIO)
+#define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A)
+
+#define GPIO197_GPIO PIN_CFG(197, GPIO)
+#define GPIO197_MC4_DAT3 PIN_CFG(197, ALT_A)
+
+#define GPIO198_GPIO PIN_CFG(198, GPIO)
+#define GPIO198_MC4_DAT2 PIN_CFG(198, ALT_A)
+
+#define GPIO199_GPIO PIN_CFG(199, GPIO)
+#define GPIO199_MC4_DAT1 PIN_CFG(199, ALT_A)
+
+#define GPIO200_GPIO PIN_CFG(200, GPIO)
+#define GPIO200_MC4_DAT0 PIN_CFG(200, ALT_A)
+
+#define GPIO201_GPIO PIN_CFG(201, GPIO)
+#define GPIO201_MC4_CMD PIN_CFG(201, ALT_A)
+
+#define GPIO202_GPIO PIN_CFG(202, GPIO)
+#define GPIO202_MC4_FBCLK PIN_CFG(202, ALT_A)
+#define GPIO202_PWL PIN_CFG(202, ALT_B)
+#define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C)
+
+#define GPIO203_GPIO PIN_CFG(203, GPIO)
+#define GPIO203_MC4_CLK PIN_CFG(203, ALT_A)
+
+#define GPIO204_GPIO PIN_CFG(204, GPIO)
+#define GPIO204_MC4_DAT7 PIN_CFG(204, ALT_A)
+
+#define GPIO205_GPIO PIN_CFG(205, GPIO)
+#define GPIO205_MC4_DAT6 PIN_CFG(205, ALT_A)
+
+#define GPIO206_GPIO PIN_CFG(206, GPIO)
+#define GPIO206_MC4_DAT5 PIN_CFG(206, ALT_A)
+
+#define GPIO207_GPIO PIN_CFG(207, GPIO)
+#define GPIO207_MC4_DAT4 PIN_CFG(207, ALT_A)
+
+#define GPIO208_GPIO PIN_CFG(208, GPIO)
+#define GPIO208_MC1_CLK PIN_CFG(208, ALT_A)
+
+#define GPIO209_GPIO PIN_CFG(209, GPIO)
+#define GPIO209_MC1_FBCLK PIN_CFG(209, ALT_A)
+#define GPIO209_SPI1_CLK PIN_CFG(209, ALT_B)
+
+#define GPIO210_GPIO PIN_CFG(210, GPIO)
+#define GPIO210_MC1_CMD PIN_CFG(210, ALT_A)
+
+#define GPIO211_GPIO PIN_CFG(211, GPIO)
+#define GPIO211_MC1_DAT0 PIN_CFG(211, ALT_A)
+
+#define GPIO212_GPIO PIN_CFG(212, GPIO)
+#define GPIO212_MC1_DAT1 PIN_CFG(212, ALT_A)
+#define GPIO212_SPI1_FRM PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO PIN_CFG(213, GPIO)
+#define GPIO213_MC1_DAT2 PIN_CFG(213, ALT_A)
+#define GPIO213_SPI1_TXD PIN_CFG(213, ALT_B)
+
+#define GPIO214_GPIO PIN_CFG(214, GPIO)
+#define GPIO214_MC1_DAT3 PIN_CFG(214, ALT_A)
+#define GPIO214_SPI1_RXD PIN_CFG(214, ALT_B)
+
+#define GPIO215_GPIO PIN_CFG(215, GPIO)
+#define GPIO215_MC1_CMDDIR PIN_CFG(215, ALT_A)
+#define GPIO215_MC3_DAT2DIR PIN_CFG(215, ALT_B)
+#define GPIO215_CLKOUT1 PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO PIN_CFG(216, GPIO)
+#define GPIO216_MC1_DAT2DIR PIN_CFG(216, ALT_A)
+#define GPIO216_MC3_CMDDIR PIN_CFG(216, ALT_B)
+#define GPIO216_I2C3_SDA PIN_CFG_PULL(216, ALT_C, UP)
+
+#define GPIO217_GPIO PIN_CFG(217, GPIO)
+#define GPIO217_MC1_DAT0DIR PIN_CFG(217, ALT_A)
+#define GPIO217_MC3_DAT31DIR PIN_CFG(217, ALT_B)
+#define GPIO217_CLKOUT2 PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO PIN_CFG(218, GPIO)
+#define GPIO218_MC1_DAT31DIR PIN_CFG(218, ALT_A)
+#define GPIO218_MC3_DAT0DIR PIN_CFG(218, ALT_B)
+#define GPIO218_I2C3_SCL PIN_CFG_PULL(218, ALT_C, UP)
+
+#define GPIO219_GPIO PIN_CFG(219, GPIO)
+#define GPIO219_HSIR_FLA0 PIN_CFG(219, ALT_A)
+#define GPIO219_MC3_CLK PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO PIN_CFG(220, GPIO)
+#define GPIO220_HSIR_DAT0 PIN_CFG(220, ALT_A)
+#define GPIO220_MC3_FBCLK PIN_CFG(220, ALT_B)
+#define GPIO220_SPI0_CLK PIN_CFG(220, ALT_C)
+
+#define GPIO221_GPIO PIN_CFG(221, GPIO)
+#define GPIO221_HSIR_RDY0 PIN_CFG(221, ALT_A)
+#define GPIO221_MC3_CMD PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO PIN_CFG(222, GPIO)
+#define GPIO222_HSIT_FLA0 PIN_CFG(222, ALT_A)
+#define GPIO222_MC3_DAT0 PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO PIN_CFG(223, GPIO)
+#define GPIO223_HSIT_DAT0 PIN_CFG(223, ALT_A)
+#define GPIO223_MC3_DAT1 PIN_CFG(223, ALT_B)
+#define GPIO223_SPI0_FRM PIN_CFG(223, ALT_C)
+
+#define GPIO224_GPIO PIN_CFG(224, GPIO)
+#define GPIO224_HSIT_RDY0 PIN_CFG(224, ALT_A)
+#define GPIO224_MC3_DAT2 PIN_CFG(224, ALT_B)
+#define GPIO224_SPI0_TXD PIN_CFG(224, ALT_C)
+
+#define GPIO225_GPIO PIN_CFG(225, GPIO)
+#define GPIO225_HSIT_CAWAKE0 PIN_CFG(225, ALT_A)
+#define GPIO225_MC3_DAT3 PIN_CFG(225, ALT_B)
+#define GPIO225_SPI0_RXD PIN_CFG(225, ALT_C)
+
+#define GPIO226_GPIO PIN_CFG(226, GPIO)
+#define GPIO226_HSIT_ACWAKE0 PIN_CFG(226, ALT_A)
+#define GPIO226_PWL PIN_CFG(226, ALT_B)
+#define GPIO226_USBSIM_PDC PIN_CFG(226, ALT_C)
+
+#define GPIO227_GPIO PIN_CFG(227, GPIO)
+#define GPIO227_CLKOUT1 PIN_CFG(227, ALT_A)
+
+#define GPIO228_GPIO PIN_CFG(228, GPIO)
+#define GPIO228_CLKOUT2 PIN_CFG(228, ALT_A)
+
+#define GPIO229_GPIO PIN_CFG(229, GPIO)
+#define GPIO229_CLKOUT1 PIN_CFG(229, ALT_A)
+#define GPIO229_PWL PIN_CFG(229, ALT_B)
+#define GPIO229_I2C3_SDA PIN_CFG_PULL(229, ALT_C, UP)
+
+#define GPIO230_GPIO PIN_CFG(230, GPIO)
+#define GPIO230_CLKOUT2 PIN_CFG(230, ALT_A)
+#define GPIO230_PWL PIN_CFG(230, ALT_B)
+#define GPIO230_I2C3_SCL PIN_CFG_PULL(230, ALT_C, UP)
+
+#define GPIO256_GPIO PIN_CFG(256, GPIO)
+#define GPIO256_USB_NXT PIN_CFG(256, ALT_A)
+
+#define GPIO257_GPIO PIN_CFG(257, GPIO)
+#define GPIO257_USB_STP PIN_CFG(257, ALT_A)
+
+#define GPIO258_GPIO PIN_CFG(258, GPIO)
+#define GPIO258_USB_XCLK PIN_CFG(258, ALT_A)
+#define GPIO258_NONE PIN_CFG(258, ALT_B)
+#define GPIO258_DDR_TRIG PIN_CFG(258, ALT_C)
+
+#define GPIO259_GPIO PIN_CFG(259, GPIO)
+#define GPIO259_USB_DIR PIN_CFG(259, ALT_A)
+
+#define GPIO260_GPIO PIN_CFG(260, GPIO)
+#define GPIO260_USB_DAT7 PIN_CFG(260, ALT_A)
+
+#define GPIO261_GPIO PIN_CFG(261, GPIO)
+#define GPIO261_USB_DAT6 PIN_CFG(261, ALT_A)
+
+#define GPIO262_GPIO PIN_CFG(262, GPIO)
+#define GPIO262_USB_DAT5 PIN_CFG(262, ALT_A)
+
+#define GPIO263_GPIO PIN_CFG(263, GPIO)
+#define GPIO263_USB_DAT4 PIN_CFG(263, ALT_A)
+
+#define GPIO264_GPIO PIN_CFG(264, GPIO)
+#define GPIO264_USB_DAT3 PIN_CFG(264, ALT_A)
+
+#define GPIO265_GPIO PIN_CFG(265, GPIO)
+#define GPIO265_USB_DAT2 PIN_CFG(265, ALT_A)
+
+#define GPIO266_GPIO PIN_CFG(266, GPIO)
+#define GPIO266_USB_DAT1 PIN_CFG(266, ALT_A)
+
+#define GPIO267_GPIO PIN_CFG(267, GPIO)
+#define GPIO267_USB_DAT0 PIN_CFG(267, ALT_A)
+
+#endif
diff --git a/board/st-ericsson/snowball/mmc_fifo.S b/board/st-ericsson/snowball/mmc_fifo.S
new file mode 100644
index 000000000..44911a8d5
--- /dev/null
+++ b/board/st-ericsson/snowball/mmc_fifo.S
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include "mmc_fifo.h"
+#include "mmc_host.h"
+
+/*
+ * Function: mmc_fifo_read()
+ *
+ * int mmc_fifo_read(u32 *fifo, u32 *buf, unsigned int count, u32 *status_reg)
+ *
+ * Info: Reads data from an MMC (ARM PL180) FIFO
+ *
+ * Parameters:
+ * fifo - pointer to the first PL180 FIFO register
+ * buf - pointer to a read buffer (32-bit aligned)
+ * count - number of bytes to be read (32-bit aligned)
+ * status_reg - pointer to the PL180 status register
+ *
+ * Returns '0' if success and PL180 status on failure.
+ *
+ */
+
+ .globl mmc_fifo_read
+mmc_fifo_read:
+ push {r4-r10,lr}
+mmc_fifo_read_loop_32_1:
+ /* If count is <32B read word-wise */
+ cmp r2,#32
+ blo mmc_fifo_read_loop_4_1
+mmc_fifo_read_loop_32_2:
+ /* Load SDI_STA to r4 */
+ ldr r4,[r3]
+ /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_read_fail
+ /* Wait until SDI_STA_RXFIFOBR is set */
+ tst r4,#SDI_STA_RXFIFOBR
+ beq mmc_fifo_read_loop_32_2
+ /* Load and store 8 words */
+ ldmia r0,{r4-r10,lr}
+ stmia r1!,{r4-r10,lr}
+ subs r2,r2,#32
+ b mmc_fifo_read_loop_32_1
+mmc_fifo_read_loop_4_1:
+ /* Read word wise */
+ cmp r2,#4
+ blo mmc_fifo_read_ok
+mmc_fifo_read_loop_4_2:
+ /* Load SDI_STA to r4 */
+ ldr r4,[r3]
+ /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_read_fail
+ /* Wait until SDI_STA_RXDAVL is set */
+ tst r4,#SDI_STA_RXDAVL
+ beq mmc_fifo_read_loop_4_2
+ /* Load and store 1 word */
+ ldmia r0,{r4}
+ stmia r1!,{r4}
+ subs r2,r2,#4
+ b mmc_fifo_read_loop_4_1
+mmc_fifo_read_ok:
+ /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */
+ ldr r4,[r3]
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_read_fail
+ and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
+ cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
+ bne mmc_fifo_read_ok
+mmc_fifo_read_fail:
+ mov r0,r4
+ pop {r4-r10,pc}
+
+/*
+ * Function: mmc_fifo_write()
+ *
+ * int mmc_fifo_write(u32 *buf, u32 *fifo, unsigned int count, u32 *status_reg)
+ *
+ * Info: Writes data to an MMC (ARM PL180) FIFO
+ *
+ * Parameters:
+ * buf - pointer to a write buffer (32-bit aligned)
+ * fifo - pointer to the first PL180 FIFO register
+ * count - number of bytes to be written (32-bit aligned)
+ * status_reg - pointer to the PL180 status register
+ *
+ * Returns '0' if success and PL180 status on failure.
+ *
+ */
+
+ .globl mmc_fifo_write
+mmc_fifo_write:
+ push {r4-r10,lr}
+mmc_fifo_write_loop_32_1:
+ /* If count is <32B read word-wise */
+ cmp r2,#32
+ blo mmc_fifo_write_loop_4_1
+mmc_fifo_write_loop_32_2:
+ /* Load SDI_STA to r4 */
+ ldr r4,[r3]
+ /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_write_fail
+ /* Wait until SDI_STA_TXFIFOBW is set */
+ tst r4,#SDI_STA_TXFIFOBW
+ beq mmc_fifo_write_loop_32_2
+ /* Load and store 8 words */
+ ldmia r0!,{r4-r10,lr}
+ stmia r1,{r4-r10,lr}
+ subs r2,r2,#32
+ b mmc_fifo_write_loop_32_1
+mmc_fifo_write_loop_4_1:
+ /* Read word wise */
+ cmp r2,#4
+ blo mmc_fifo_write_ok
+mmc_fifo_write_loop_4_2:
+ /* Load SDI_STA to r4 */
+ ldr r4,[r3]
+ /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_write_fail
+ /* Wait until SDI_STA_TXFIFOBW is set */
+ tst r4,#SDI_STA_TXFIFOBW
+ beq mmc_fifo_write_loop_4_2
+ /* Load and store 1 word */
+ ldmia r0!,{r4}
+ stmia r1,{r4}
+ subs r2,r2,#4
+ b mmc_fifo_write_loop_4_1
+mmc_fifo_write_ok:
+ /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */
+ ldr r4,[r3]
+ ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
+ bne mmc_fifo_write_fail
+ and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
+ cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
+ bne mmc_fifo_write_ok
+mmc_fifo_write_fail:
+ mov r0,r4
+ pop {r4-r10,pc}
diff --git a/board/st-ericsson/snowball/mmc_fifo.h b/board/st-ericsson/snowball/mmc_fifo.h
new file mode 100644
index 000000000..e2fb0a53b
--- /dev/null
+++ b/board/st-ericsson/snowball/mmc_fifo.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <common.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Function: mmc_fifo_read()
+ *
+ * Info: Reads data from an MMC (ARM PL180) FIFO
+ *
+ * Parameters:
+ * fifo - pointer to the first PL180 FIFO register
+ * buf - pointer to a read buffer (32-bit aligned)
+ * count - number of bytes to be read (32-bit aligned)
+ * status_reg - pointer to the PL180 status register
+ *
+ * Returns '0' if success and PL180 status on failure.
+ *
+ */
+int mmc_fifo_read(u32 *fifo, u32 *buf, unsigned int count, u32 *status_reg);
+
+/*
+ * Function: mmc_fifo_write()
+ *
+ * Info: Writes data to an MMC (ARM PL180) FIFO
+ *
+ * Parameters:
+ * buf - pointer to a write buffer (32-bit aligned)
+ * fifo - pointer to the first PL180 FIFO register
+ * count - number of bytes to be written (32-bit aligned)
+ * status_reg - pointer to the PL180 status register
+ *
+ * Returns '0' if success and PL180 status on failure.
+ *
+ */
+int mmc_fifo_write(u32 *buf, u32 *fifo, unsigned int count, u32 *status_reg);
+
+#endif /* __ASSEMBLY__ */
diff --git a/board/st-ericsson/snowball/mmc_host.c b/board/st-ericsson/snowball/mmc_host.c
new file mode 100644
index 000000000..4e5c0e39a
--- /dev/null
+++ b/board/st-ericsson/snowball/mmc_host.c
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+/*
+ * There are two levels of debug printouts in this file. The macro DEBUG can be
+ * set to either DBG_LVL_INFO (1) or DBG_LVL_VERBOSE (2).
+ */
+#define DBG_LVL_INFO (1)
+#define DBG_LVL_VERBOSE (2)
+
+#include <asm/io.h>
+#include <asm/arch/common.h>
+#include <asm/arch/cpu.h>
+#include <mmc.h>
+#include "mmc_host.h"
+#include <malloc.h>
+#include <div64.h>
+#include "mmc_fifo.h"
+
+
+struct mmc_host {
+ struct sdi_registers *base;
+};
+
+/*
+ * wait_for_command_end() - waiting for the command completion
+ * this function will wait until the command completion has happened or
+ * any error generated by reading the status register
+ */
+static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
+{
+ u32 hoststatus, statusmask;
+ struct mmc_host *host = dev->priv;
+
+ statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL;
+ if ((cmd->resp_type & MMC_RSP_PRESENT))
+ statusmask |= SDI_STA_CMDREND;
+ else
+ statusmask |= SDI_STA_CMDSENT;
+
+ do
+ hoststatus = readl(&host->base->status) & statusmask;
+ while (!hoststatus);
+
+ debugX(DBG_LVL_VERBOSE, "SDI_ICR <= 0x%08X\n", statusmask);
+ writel(statusmask, &host->base->status_clear);
+
+ if (hoststatus & SDI_STA_CTIMEOUT) {
+ debugX(DBG_LVL_VERBOSE, "CMD%d time out\n", cmd->cmdidx);
+ return TIMEOUT;
+ } else if ((hoststatus & SDI_STA_CCRCFAIL) &&
+ (cmd->flags & MMC_RSP_CRC)) {
+ debugX(DBG_LVL_VERBOSE, "CMD%d CRC error\n", cmd->cmdidx);
+ return MMC_CMD_CRC_FAIL;
+ }
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ cmd->response[0] = readl(&host->base->response0);
+ cmd->response[1] = readl(&host->base->response1);
+ cmd->response[2] = readl(&host->base->response2);
+ cmd->response[3] = readl(&host->base->response3);
+ debugX(DBG_LVL_VERBOSE,
+ "CMD%d response[0]:0x%08X, response[1]:0x%08X, "
+ "response[2]:0x%08X, response[3]:0x%08X\n",
+ cmd->cmdidx, cmd->response[0], cmd->response[1],
+ cmd->response[2], cmd->response[3]);
+ }
+ return MMC_OK;
+}
+
+/*
+ * do_command - sends command to card, and waits for its result.
+ */
+static int do_command(struct mmc *dev, struct mmc_cmd *cmd)
+{
+ int result;
+ u32 sdi_cmd = 0;
+ struct mmc_host *host = dev->priv;
+ u32 lap = 0;
+
+ debugX(DBG_LVL_VERBOSE, "Request to do CMD%d on %s\n", cmd->cmdidx,
+ dev->name);
+
+ sdi_cmd = (cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN;
+
+ if (cmd->resp_type) {
+ sdi_cmd |= SDI_CMD_WAITRESP;
+ if (cmd->resp_type & MMC_RSP_136)
+ sdi_cmd |= SDI_CMD_LONGRESP;
+ }
+
+ debugX(DBG_LVL_VERBOSE, "SDI_ARG <= 0x%08X\n", cmd->cmdarg);
+ writel((u32)cmd->cmdarg, &host->base->argument);
+ udelay(COMMAND_REG_DELAY); /* DONT REMOVE */
+ debugX(DBG_LVL_VERBOSE, "SDI_CMD <= 0x%08X\n", sdi_cmd);
+
+ /*
+ * It has been noticed that after a write operation some cards does
+ * not respond to a new command for a few milliseconds. So here we
+ * retry the command a couple of times if we get a timeout.
+ */
+ do {
+ writel(sdi_cmd, &host->base->command);
+ result = wait_for_command_end(dev, cmd);
+ if ((result != TIMEOUT) || (lap >= 10))
+ break;
+ udelay(1000);
+ lap++;
+ } while (1);
+
+ /* After CMD2 set RCA to a none zero value. */
+ if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID))
+ dev->rca = 10;
+
+ /* After CMD3 open drain is switched off and push pull is used. */
+ if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) {
+ u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD;
+ debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_pwr);
+ writel(sdi_pwr, &host->base->power);
+ }
+
+ return result;
+}
+
+static int convert_from_bytes_to_power_of_two(unsigned int x)
+{
+ int y = 0;
+ y = (x & 0xAAAA) ? 1 : 0;
+ y |= ((x & 0xCCCC) ? 1 : 0)<<1;
+ y |= ((x & 0xF0F0) ? 1 : 0)<<2;
+ y |= ((x & 0xFF00) ? 1 : 0)<<3;
+
+ return y;
+}
+
+/*
+ * read_bytes - reads bytes from the card, part of data transfer.
+ */
+static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize)
+{
+ u64 xfercount = blkcount * blksize;
+ struct mmc_host *host = dev->priv;
+ u32 status;
+
+ debugX(DBG_LVL_VERBOSE, "read_bytes: blkcount=%u blksize=%u\n",
+ blkcount, blksize);
+
+ status = mmc_fifo_read(&host->base->fifo, dest, xfercount,
+ &host->base->status);
+
+ if (status & (SDI_STA_DTIMEOUT | SDI_STA_DCRCFAIL)) {
+ printf("Reading data failed: status:0x%08X\n", status);
+ if (status & SDI_STA_DTIMEOUT)
+ return MMC_DATA_TIMEOUT;
+ else if (status & SDI_STA_DCRCFAIL)
+ return MMC_DATA_CRC_FAIL;
+ }
+
+ debugX(DBG_LVL_VERBOSE, "SDI_ICR <= 0x%08X\n", SDI_ICR_MASK);
+ writel(SDI_ICR_MASK, &host->base->status_clear);
+ debugX(DBG_LVL_VERBOSE, "Reading data completed status:0x%08X\n",
+ status);
+
+ return MMC_OK;
+}
+
+/*
+ * write_bytes - writes byte to the card, part of data transfer.
+ */
+static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize)
+{
+ u64 xfercount = blkcount * blksize;
+ struct mmc_host *host = dev->priv;
+ u32 status;
+ u32 status_busy;
+
+ debugX(DBG_LVL_VERBOSE, "write_bytes: blkcount=%u blksize=%u\n",
+ blkcount, blksize);
+
+ status = mmc_fifo_write(src, &host->base->fifo, xfercount,
+ &host->base->status);
+
+ if (status & (SDI_STA_DTIMEOUT | SDI_STA_DCRCFAIL)) {
+ printf("Writing data failed: status=0x%08X\n", status);
+ if (status & SDI_STA_DTIMEOUT)
+ return MMC_DATA_TIMEOUT;
+ else if (status & SDI_STA_DCRCFAIL)
+ return MMC_DATA_CRC_FAIL;
+ }
+
+ /* Wait if busy */
+ status_busy = status & SDI_STA_CARDBUSY;
+ while (status_busy)
+ status_busy = readl(&host->base->status) & SDI_STA_CARDBUSY;
+
+ writel(SDI_ICR_MASK, &host->base->status_clear);
+ debugX(DBG_LVL_VERBOSE, "Writing data completed status:0x%08X\n",
+ status);
+
+ return MMC_OK;
+}
+
+/*
+ * do_data_transfer - for doing any data transfer operation.
+ *
+ * dev: mmc device for doing the operation on.
+ * cmd: cmd to do.
+ * data: if cmd warrants any data transfer.
+ */
+static int do_data_transfer(struct mmc *dev,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+#if (DEBUG >= DBG_LVL_INFO)
+ u32 start_time = 0;
+#endif
+ int error = MMC_DATA_TIMEOUT;
+ struct mmc_host *host = dev->priv;
+ u32 blksz = 0;
+ u32 data_ctrl = 0;
+ u32 data_len = (u32) (data->blocks * data->blocksize);
+
+ debugX(DBG_LVL_VERBOSE, "Request to do data xfer on %s\n", dev->name);
+ debugX(DBG_LVL_VERBOSE, "do_data_transfer(%u) start\n", data->blocks);
+
+#if (DEBUG >= DBG_LVL_INFO)
+ // if (data->blocks > 1)
+ // start_time = (u32) get_timer_us();
+#endif
+
+ if (cpu_is_u8500v1() || u8500_is_earlydrop()) {
+ blksz = convert_from_bytes_to_power_of_two(data->blocksize);
+ data_ctrl |= (blksz << INDEX(SDI_DCTRL_DBLOCKSIZE_MASK));
+ } else {
+ blksz = data->blocksize;
+ data_ctrl |= (blksz << INDEX(SDI_DCTRL_DBLOCKSIZE_V2_MASK));
+ }
+ data_ctrl |= SDI_DCTRL_DTEN | SDI_DCTRL_BUSYMODE;
+ if (dev->ddr_en &&
+ ((cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) ||
+ (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
+ (cmd->cmdidx == MMC_CMD_WRITE_SINGLE_BLOCK) ||
+ (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK) ||
+ (cmd->cmdidx == MMC_CMD_SEND_EXT_CSD)))
+ data_ctrl |= SDI_DCTRL_DDR_MODE;
+
+#if (DEBUG >= DBG_LVL_VERBOSE)
+ if (data_ctrl & SDI_DCTRL_DDR_MODE)
+ printf("SDI_DCTRL_DDR_MODE\n");
+#endif
+
+ debugX(DBG_LVL_VERBOSE, "SDI_DTIMER <= 0x%08X\n", dev->data_timeout);
+ writel(dev->data_timeout, &host->base->datatimer);
+ debugX(DBG_LVL_VERBOSE, "SDI_DLEN <= 0x%08X\n", data_len);
+ writel(data_len, &host->base->datalength);
+ udelay(DATA_REG_DELAY); /* DONT REMOVE */
+
+ if (data->flags & (MMC_DATA_READ)) {
+ debugX(DBG_LVL_VERBOSE, "It is a read operation\n");
+
+ data_ctrl |= SDI_DCTRL_DTDIR_IN;
+ debugX(DBG_LVL_VERBOSE, "SDI_DCTRL <= 0x%08X\n", data_ctrl);
+ writel(data_ctrl, &host->base->datactrl);
+
+ error = do_command(dev, cmd);
+ if (error)
+ return error;
+
+ error = read_bytes(dev,
+ (u32 *)data->dest,
+ (u32)data->blocks,
+ (u32)data->blocksize);
+ } else if (data->flags & (MMC_DATA_WRITE)) {
+ debugX(DBG_LVL_VERBOSE, "It is a write operation\n");
+
+ error = do_command(dev, cmd);
+ if (error)
+ return error;
+
+ debugX(DBG_LVL_VERBOSE, "SDI_DCTRL <= 0x%08X\n", data_ctrl);
+ writel(data_ctrl, &host->base->datactrl);
+
+ error = write_bytes(dev,
+ (u32 *)data->src,
+ (u32)data->blocks,
+ (u32)data->blocksize);
+ }
+
+#if (DEBUG >= DBG_LVL_INFO)
+#if 0
+ if (data->blocks > 1) {
+ u32 transfer_time = (u32) get_timer_us() - start_time;
+ u64 throughput = lldiv((u64) 1000 * 1000 * data->blocks *
+ data->blocksize, transfer_time);
+ printf("MMC %s: %u bytes in %u [us] => %llu [B/s] = "
+ "%llu [kB/s] = %llu.%02u [MB/s] = %llu [Mbits/s]\n",
+ (data->flags & (MMC_DATA_READ)) ? "read" : "write",
+ data->blocks * data->blocksize,
+ transfer_time,
+ throughput, throughput / 1024,
+ throughput / (1024 * 1024),
+ (u32)((100 * throughput) / (1024 * 1024) -
+ (throughput / (1024 * 1024)) * 100),
+ throughput * 8 / (1024 * 1024));
+ }
+#endif
+#endif
+ debugX(DBG_LVL_VERBOSE, "do_data_transfer() end\n");
+
+ return error;
+}
+
+/*
+ * host_request - For all operations on cards.
+ *
+ * dev: mmc device for doing the operation on.
+ * cmd: cmd to do.
+ * data: if cmd warrants any data transfer.
+ */
+static int host_request(struct mmc *dev,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ int result;
+
+ if (data)
+ result = do_data_transfer(dev, cmd, data);
+ else
+ result = do_command(dev, cmd);
+
+ return result;
+}
+
+/*
+ * This is to initialize card specific things just before enumerating
+ * them. MMC cards uses open drain drivers in enumeration phase.
+ */
+static int mmc_host_reset(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+
+ debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ return MMC_OK;
+}
+
+/*
+ * This is to initialize card specific things just before enumerating
+ * them. SD cards does not need to be initialized.
+ */
+static int sd_host_reset(struct mmc *dev)
+{
+ (void) dev; /* Parameter not used! */
+
+ return MMC_OK;
+}
+/*
+ * host_set_ios:to configure host parameters.
+ *
+ * dev: the pointer to the host structure for MMC.
+ */
+static void host_set_ios(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_clkcr;
+
+ /* First read out the contents of clock control register. */
+ sdi_clkcr = readl(&host->base->clock);
+
+ /* Set the clock rate and bus width */
+ if (dev->clock) {
+ u32 clkdiv = 0;
+ u32 tmp_clock;
+
+ debugX(DBG_LVL_VERBOSE,
+ "setting clock and bus width in the host:");
+ if (dev->clock >= dev->f_max) {
+ clkdiv = 0;
+ dev->clock = dev->f_max;
+ } else {
+ clkdiv = (MCLK / dev->clock) - 2;
+ }
+ tmp_clock = MCLK / (clkdiv + 2);
+ while (tmp_clock > dev->clock) {
+ clkdiv++;
+ tmp_clock = MCLK / (clkdiv + 2);
+ }
+ if (clkdiv > SDI_CLKCR_CLKDIV_MASK)
+ clkdiv = SDI_CLKCR_CLKDIV_MASK;
+ tmp_clock = MCLK / (clkdiv + 2);
+ dev->clock = tmp_clock;
+ sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK);
+ sdi_clkcr |= clkdiv;
+ }
+
+ if (dev->bus_width) {
+ u32 buswidth = 0;
+
+ switch (dev->bus_width) {
+ case 1:
+ buswidth |= SDI_CLKCR_WIDBUS_1;
+ break;
+ case 4:
+ buswidth |= SDI_CLKCR_WIDBUS_4;
+ break;
+ case 8:
+ buswidth |= SDI_CLKCR_WIDBUS_8;
+ break;
+ default:
+ printf("wrong bus width, so ignoring");
+ break;
+ }
+ sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK);
+ sdi_clkcr |= buswidth;
+ }
+
+
+ dev->data_timeout = MMC_DATA_TIMEOUT * dev->clock;
+
+ debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_clkcr);
+ writel(sdi_clkcr, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+}
+
+struct mmc *alloc_mmc_struct(void)
+{
+ struct mmc_host *host = NULL;
+ struct mmc *mmc_device = NULL;
+
+ host = malloc(sizeof(struct mmc_host));
+ if (!host)
+ return NULL;
+
+ mmc_device = malloc(sizeof(struct mmc));
+ if (!mmc_device)
+ goto err;
+
+ memset(mmc_device, 0x00, sizeof(struct mmc));
+
+ mmc_device->priv = host;
+ return mmc_device;
+ err:
+ free(host);
+ return NULL;
+}
+
+/*
+ * emmc_host_init - initialize the emmc controller.
+ * Configure GPIO settings, set initial clock and power for emmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int emmc_host_init(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_u32;
+
+ /* TODO: Investigate what is actually needed of the below. */
+
+ if (u8500_is_earlydrop() || u8500_is_snowball()) {
+ debugX(DBG_LVL_VERBOSE, "configuring EMMC for ED\n");
+ host->base = (struct sdi_registers *)CFG_EMMC_BASE_ED;
+ } else {
+ debugX(DBG_LVL_VERBOSE, "configuring EMMC for V1\n");
+ host->base = (struct sdi_registers *)CFG_EMMC_BASE_V1;
+ }
+
+ sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+ debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ /* setting clk freq less than 400KHz */
+ sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+ sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
+ debugX(DBG_LVL_VERBOSE, "SDI_MASK0 <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->mask0);
+ dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ sprintf(dev->name, "EMMC");
+ dev->send_cmd = host_request;
+ dev->set_ios = host_set_ios;
+ dev->init = mmc_host_reset;
+ dev->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
+ MMC_MODE_HS_52MHz /* | MMC_MODE_REL_WR | MMC_MODE_DDR */;
+ dev->voltages = VOLTAGE_WINDOW_MMC;
+ dev->f_min = dev->clock;
+ dev->f_max = MCLK / 2;
+ dev->ddr_en = 0;
+ return 0;
+}
+
+/*
+ * mmc_host_init - initialize the external mmc controller.
+ * Configure GPIO settings, set initial clock and power for mmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int mmc_host_init(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_u32;
+
+ host->base = (struct sdi_registers *)CFG_MMC_BASE;
+ sdi_u32 = 0xBF;
+ debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ /* setting clk freq just less than 400KHz */
+ sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+ sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
+ debugX(DBG_LVL_VERBOSE, "SDI_MASK0 <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->mask0);
+ dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ sprintf(dev->name, "MMC");
+ dev->send_cmd = host_request;
+ dev->set_ios = host_set_ios;
+ dev->init = sd_host_reset;
+ dev->host_caps = /* MMC_MODE_4BIT */ 0; /* Some SD cards do not work in
+ 4 bit mode! */
+ dev->voltages = VOLTAGE_WINDOW_SD;
+ dev->f_min = dev->clock;
+ dev->f_max = MCLK / 2;
+ dev->ddr_en = 0;
+ return 0;
+}
+
+/*
+ * board_mmc_init - initialize all the mmc/sd host controllers.
+ * Called by generic mmc framework.
+ */
+int board_mmc_init(bd_t *bis)
+{
+ int error;
+ struct mmc *dev;
+
+ debugX(DBG_LVL_VERBOSE, "[%s] mmc_host - board_mmc_init board ed %d, snow %d\n",
+ __func__,u8500_is_earlydrop(), u8500_is_snowball());
+
+ (void) bis; /* Parameter not used! */
+
+ dev = alloc_mmc_struct();
+ if (!dev)
+ return -1;
+
+ error = emmc_host_init(dev);
+ if (error) {
+ printf("emmc_host_init() %d \n", error);
+ return -1;
+ }
+ mmc_register(dev);
+ debugX(DBG_LVL_VERBOSE, "registered emmc interface number is:%d\n",
+ dev->block_dev.dev);
+
+
+ mmc_init(dev);
+
+ /*
+ * In a perfect world board_early_access shouldn't be here but we want
+ * some functionality to be loaded as quickly as possible and putting it
+ * here will get the shortest time to start that functionality. Time
+ * saved by putting it here compared to later is somewhere between
+ * 0.3-0.7s. That is enough to be able to justify putting it here.
+ */
+
+ board_early_access(&dev->block_dev);
+
+ dev = alloc_mmc_struct();
+ if (!dev)
+ return -1;
+
+ error = mmc_host_init(dev);
+ if (error) {
+ printf("mmc_host_init() %d \n", error);
+ return -1;
+ }
+ mmc_register(dev);
+ debugX(DBG_LVL_VERBOSE, "registered mmc/sd interface number is:%d\n",
+ dev->block_dev.dev);
+
+ return 0;
+}
diff --git a/board/st-ericsson/snowball/mmc_host.h b/board/st-ericsson/snowball/mmc_host.h
new file mode 100644
index 000000000..3b5e1c589
--- /dev/null
+++ b/board/st-ericsson/snowball/mmc_host.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __MMC_NOMADIK_H__
+#define __MMC_NOMADIK_H__
+
+/* See SDI (SD card host interface) documentation in U8500 sw specification. */
+
+#define COMMAND_REG_DELAY 300
+#define DATA_REG_DELAY 10000
+#define CLK_CHANGE_DELAY 2000
+
+#define MAX_ERROR_VALUE -65
+#ifndef __ASSEMBLY__
+enum mmc_result {
+ /* MMC specific error defines */
+ MMC_CMD_CRC_FAIL = (MAX_ERROR_VALUE - 1),/* Command response received
+ (but CRC check failed) */
+ MMC_DATA_CRC_FAIL = (MAX_ERROR_VALUE - 2),/* Data bock sent/received
+ (CRC check Failed) */
+ MMC_CMD_RSP_TIMEOUT = (MAX_ERROR_VALUE - 3),/*Command response timeout
+ */
+ MMC_DATA_TIMEOUT = (MAX_ERROR_VALUE - 4),/* Data time out*/
+ MMC_TX_UNDERRUN = (MAX_ERROR_VALUE - 5),/* Transmit FIFO under-run */
+ MMC_RX_OVERRUN = (MAX_ERROR_VALUE - 6), /* Receive FIFO over-run */
+ MMC_START_BIT_ERR = (MAX_ERROR_VALUE - 7),/* Start bit not detected on
+ all data signals in widE bus mode */
+ MMC_CMD_OUT_OF_RANGE = (MAX_ERROR_VALUE - 8),/* CMD's argument was out
+ of range.*/
+ MMC_ADDR_MISALIGNED = (MAX_ERROR_VALUE - 9),/* Misaligned address */
+ MMC_BLOCK_LEN_ERR = (MAX_ERROR_VALUE - 10),/* Transferred block length
+ is not allowed for the card or the number of
+ transferred bytes does not match the block length*/
+ MMC_ERASE_SEQ_ERR = (MAX_ERROR_VALUE - 11),/* An error in the sequence
+ of erase command occurs.*/
+ MMC_BAD_ERASE_PARAM = (MAX_ERROR_VALUE - 12),/* An Invalid selection
+ for erase groups */
+ MMC_WRITE_PROT_VIOLATION = (MAX_ERROR_VALUE - 13),/* Attempt to program
+ a write protect block */
+ MMC_LOCK_UNLOCK_FAILED = (MAX_ERROR_VALUE - 14),/* Sequence or password
+ error has been detected in unlock command or
+ if there was an attempt to access a locked card */
+ MMC_COM_CRC_FAILED = (MAX_ERROR_VALUE - 15),/* CRC check of the
+ previous command failed*/
+ MMC_ILLEGAL_CMD = (MAX_ERROR_VALUE - 16),/* Command is not legal for
+ the card state */
+ MMC_CARD_ECC_FAILED = (MAX_ERROR_VALUE - 17),/* Card internal ECC was
+ applied but failed to correct the data */
+ MMC_CC_ERROR = (MAX_ERROR_VALUE - 18),/*Internal card controller error
+ */
+ MMC_GENERAL_UNKNOWN_ERROR = (MAX_ERROR_VALUE - 19),/* General or
+ Unknown error */
+ MMC_STREAM_READ_UNDERRUN = (MAX_ERROR_VALUE - 20),/* The card could not
+ sustain data transfer in stream read
+ operation. */
+ MMC_STREAM_WRITE_OVERRUN = (MAX_ERROR_VALUE - 21),/* The card could not
+ sustain data programming in stream mode */
+ MMC_CID_CSD_OVERWRITE = (MAX_ERROR_VALUE - 22), /* CID/CSD overwrite
+ error */
+ MMC_WP_ERASE_SKIP = (MAX_ERROR_VALUE - 23),/* only partial address
+ space was erased */
+ MMC_CARD_ECC_DISABLED = (MAX_ERROR_VALUE - 24),/* Command has been
+ executed without using internal ECC */
+ MMC_ERASE_RESET = (MAX_ERROR_VALUE - 25),/* Erase sequence was cleared
+ before executing because an out of erase sequence
+ command was received */
+ MMC_AKE_SEQ_ERROR = (MAX_ERROR_VALUE - 26),/* Error in sequence of
+ authentication. */
+ MMC_INVALID_VOLTRANGE = (MAX_ERROR_VALUE - 27),
+ MMC_ADDR_OUT_OF_RANGE = (MAX_ERROR_VALUE - 28),
+ MMC_SWITCH_ERROR = (MAX_ERROR_VALUE - 29),
+ MMC_SDIO_DISABLED = (MAX_ERROR_VALUE - 30),
+ MMC_SDIO_FUNCTION_BUSY = (MAX_ERROR_VALUE - 31),
+ MMC_SDIO_FUNCTION_FAILED = (MAX_ERROR_VALUE - 32),
+ MMC_SDIO_UNKNOWN_FUNCTION = MAX_ERROR_VALUE,
+ /* standard error defines */
+ MMC_INTERNAL_ERROR = -8,
+ MMC_NOT_CONFIGURED = -7,
+ MMC_REQUEST_PENDING = -6,
+ MMC_REQUEST_NOT_APPLICABLE = -5,
+ MMC_INVALID_PARAMETER = -4,
+ MMC_UNSUPPORTED_FEATURE = -3,
+ MMC_UNSUPPORTED_HW = -2,
+ MMC_ERROR = -1,
+ MMC_OK = 0,
+ MMC_INTERNAL_EVENT = 1,
+ MMC_REMAINING_PENDING_EVENTS = 2,
+ MMC_REMAINING_FILTER_PENDING_EVENTS = 3,
+ MMC_NO_MORE_PENDING_EVENT = 4,
+ MMC_NO_MORE_FILTER_PENDING_EVENT = 5,
+ MMC_NO_PENDING_EVENT_ERROR = 7,
+};
+#endif
+
+#define MCLK (100*1000*1000)
+
+#define INDEX(mask) ( \
+ ((mask & 0x00000001) ? 0 : \
+ ((mask & 0x00000002) ? 1 : \
+ ((mask & 0x00000004) ? 2 : \
+ ((mask & 0x00000008) ? 3 : \
+ ((mask & 0x00000010) ? 4 : \
+ ((mask & 0x00000020) ? 5 : \
+ ((mask & 0x00000040) ? 6 : \
+ ((mask & 0x00000080) ? 7 : \
+ ((mask & 0x00000100) ? 8 : \
+ ((mask & 0x00000200) ? 9 : \
+ ((mask & 0x00000400) ? 10 : \
+ ((mask & 0x00000800) ? 11 : \
+ ((mask & 0x00001000) ? 12 : \
+ ((mask & 0x00002000) ? 13 : \
+ ((mask & 0x00004000) ? 14 : \
+ ((mask & 0x00008000) ? 15 : \
+ ((mask & 0x00010000) ? 16 : \
+ ((mask & 0x00020000) ? 17 : \
+ ((mask & 0x00040000) ? 18 : \
+ ((mask & 0x00080000) ? 19 : \
+ ((mask & 0x00100000) ? 20 : \
+ ((mask & 0x00200000) ? 21 : \
+ ((mask & 0x00400000) ? 22 : \
+ ((mask & 0x00800000) ? 23 : \
+ ((mask & 0x01000000) ? 24 : \
+ ((mask & 0x02000000) ? 25 : \
+ ((mask & 0x04000000) ? 26 : \
+ ((mask & 0x08000000) ? 27 : \
+ ((mask & 0x10000000) ? 28 : \
+ ((mask & 0x20000000) ? 29 : \
+ ((mask & 0x40000000) ? 30 : \
+ ((mask & 0x80000000) ? 31 : 0) \
+ ))))))))))))))))))))))))))))))) \
+)
+
+#define MMC_PERIPHERAL_ID0 0x81
+#define MMC_PERIPHERAL_ID1 0x11
+#define MMC_PERIPHERAL_ID2 0x04
+#define MMC_PERIPHERAL_ID3 0x00
+
+/* SDI Power Control register bits */
+
+#define SDI_PWR_PWRCTRL_MASK (0x00000003)
+#define SDI_PWR_PWRCTRL_ON (0x00000003)
+#define SDI_PWR_PWRCTRL_OFF (0x00000000)
+#define SDI_PWR_DAT2DIREN (0x00000004)
+#define SDI_PWR_CMDDIREN (0x00000008)
+#define SDI_PWR_DAT0DIREN (0x00000010)
+#define SDI_PWR_DAT31DIREN (0x00000020)
+#define SDI_PWR_OPD (0x00000040)
+#define SDI_PWR_FBCLKEN (0x00000080)
+#define SDI_PWR_DAT74DIREN (0x00000100)
+#define SDI_PWR_RSTEN (0x00000200)
+
+#define VOLTAGE_WINDOW_MMC (0x00FF8080)
+#define VOLTAGE_WINDOW_SD (0x80010000)
+
+/* SDI clock control register bits */
+
+#define SDI_CLKCR_CLKDIV_MASK (0x000000FF)
+#define SDI_CLKCR_CLKEN (0x00000100)
+#define SDI_CLKCR_PWRSAV (0x00000200)
+#define SDI_CLKCR_BYPASS (0x00000400)
+#define SDI_CLKCR_WIDBUS_MASK (0x00001800)
+#define SDI_CLKCR_WIDBUS_1 (0x00000000)
+#define SDI_CLKCR_WIDBUS_4 (0x00000800)
+#define SDI_CLKCR_WIDBUS_8 (0x00001000)
+#define SDI_CLKCR_NEGEDGE (0x00002000)
+#define SDI_CLKCR_HWFC_EN (0x00004000)
+
+#define SDI_CLKCR_CLKDIV_INIT (0x000000FD)
+
+/* SDI command register bits */
+
+#define SDI_CMD_CMDINDEX_MASK (0x000000FF)
+#define SDI_CMD_WAITRESP (0x00000040)
+#define SDI_CMD_LONGRESP (0x00000080)
+#define SDI_CMD_WAITINT (0x00000100)
+#define SDI_CMD_WAITPEND (0x00000200)
+#define SDI_CMD_CPSMEN (0x00000400)
+#define SDI_CMD_SDIOSUSPEND (0x00000800)
+#define SDI_CMD_ENDCMDCOMPL (0x00001000)
+#define SDI_CMD_NIEN (0x00002000)
+#define SDI_CMD_CE_ATACMD (0x00004000)
+#define SDI_CMD_CBOOTMODEEN (0x00008000)
+
+/* MMC_DATA_TIMEOUT sets the data timeout in seconds */
+#define MMC_DATA_TIMEOUT (30)
+
+/* SDI Status register bits */
+
+#define SDI_STA_CCRCFAIL (0x00000001) /* (1 << 0) */
+#define SDI_STA_DCRCFAIL (0x00000002) /* (1 << 1) */
+#define SDI_STA_CTIMEOUT (0x00000004) /* (1 << 2) */
+#define SDI_STA_DTIMEOUT (0x00000008) /* (1 << 3) */
+#define SDI_STA_TXUNDERR (0x00000010) /* (1 << 4) */
+#define SDI_STA_RXOVERR (0x00000020) /* (1 << 5) */
+#define SDI_STA_CMDREND (0x00000040) /* (1 << 6) */
+#define SDI_STA_CMDSENT (0x00000080) /* (1 << 7) */
+#define SDI_STA_DATAEND (0x00000100) /* (1 << 8) */
+#define SDI_STA_STBITERR (0x00000200) /* (1 << 9) */
+#define SDI_STA_DBCKEND (0x00000400) /* (1 << 10) */
+#define SDI_STA_CMDACT (0x00000800) /* (1 << 11) */
+#define SDI_STA_TXACT (0x00001000) /* (1 << 12) */
+#define SDI_STA_RXACT (0x00002000) /* (1 << 13) */
+#define SDI_STA_TXFIFOBW (0x00004000) /* (1 << 14) */
+#define SDI_STA_RXFIFOBR (0x00008000) /* (1 << 15) */
+#define SDI_STA_TXFIFOF (0x00010000) /* (1 << 16) */
+#define SDI_STA_RXFIFOF (0x00020000) /* (1 << 17) */
+#define SDI_STA_TXFIFOE (0x00040000) /* (1 << 18) */
+#define SDI_STA_RXFIFOE (0x00080000) /* (1 << 19) */
+#define SDI_STA_TXDAVL (0x00100000) /* (1 << 20) */
+#define SDI_STA_RXDAVL (0x00200000) /* (1 << 21) */
+#define SDI_STA_SDIOIT (0x00400000) /* (1 << 22) */
+#define SDI_STA_CEATAEND (0x00800000) /* (1 << 23) */
+#define SDI_STA_CARDBUSY (0x01000000) /* (1 << 24) */
+#define SDI_STA_BOOTMODE (0x02000000) /* (1 << 25) */
+#define SDI_STA_BOOTACKERR (0x04000000) /* (1 << 26) */
+#define SDI_STA_BOOTACKTIMEOUT (0x08000000) /* (1 << 27) */
+#define SDI_STA_RSTNEND (0x10000000) /* (1 << 28) */
+
+/* SDI Interrupt Clear register bits */
+
+#define SDI_ICR_MASK (0x1DC007FF)
+#define SDI_ICR_CCRCFAILC (0x00000001) /* (1 << 0) */
+#define SDI_ICR_DCRCFAILC (0x00000002) /* (1 << 1) */
+#define SDI_ICR_CTIMEOUTC (0x00000004) /* (1 << 2) */
+#define SDI_ICR_DTIMEOUTC (0x00000008) /* (1 << 3) */
+#define SDI_ICR_TXUNDERRC (0x00000010) /* (1 << 4) */
+#define SDI_ICR_RXOVERRC (0x00000020) /* (1 << 5) */
+#define SDI_ICR_CMDRENDC (0x00000040) /* (1 << 6) */
+#define SDI_ICR_CMDSENTC (0x00000080) /* (1 << 7) */
+#define SDI_ICR_DATAENDC (0x00000100) /* (1 << 8) */
+#define SDI_ICR_STBITERRC (0x00000200) /* (1 << 9) */
+#define SDI_ICR_DBCKENDC (0x00000400) /* (1 << 10) */
+#define SDI_ICR_SDIOITC (0x00400000) /* (1 << 22) */
+#define SDI_ICR_CEATAENDC (0x00800000) /* (1 << 23) */
+#define SDI_ICR_BUSYENDC (0x01000000) /* (1 << 24) */
+#define SDI_ICR_BOOTACKERRC (0x04000000) /* (1 << 26) */
+#define SDI_ICR_BOOTACKTIMEOUTC (0x08000000) /* (1 << 27) */
+#define SDI_ICR_RSTNENDC (0x10000000) /* (1 << 28) */
+
+#define SDI_MASK0_MASK (0x1FFFFFFF)
+
+/* SDI Data control register bits */
+
+#define SDI_DCTRL_DTEN (0x00000001) /* (1 << 0) */
+#define SDI_DCTRL_DTDIR_IN (0x00000002) /* (1 << 1) */
+#define SDI_DCTRL_DTMODE_STREAM (0x00000004) /* (1 << 2) */
+#define SDI_DCTRL_DMAEN (0x00000008) /* (1 << 3) */
+#define SDI_DCTRL_DBLOCKSIZE_MASK (0x000000F0)
+#define SDI_DCTRL_RWSTART (0x00000100) /* (1 << 8) */
+#define SDI_DCTRL_RWSTOP (0x00000200) /* (1 << 9) */
+#define SDI_DCTRL_RWMOD (0x00000200) /* (1 << 10) */
+#define SDI_DCTRL_SDIOEN (0x00000800) /* (1 << 11) */
+#define SDI_DCTRL_DMAREQCTL (0x00001000) /* (1 << 12) */
+#define SDI_DCTRL_DBOOTMODEEN (0x00002000) /* (1 << 13) */
+#define SDI_DCTRL_BUSYMODE (0x00004000) /* (1 << 14) */
+#define SDI_DCTRL_DDR_MODE (0x00008000) /* (1 << 15) */
+#define SDI_DCTRL_DBLOCKSIZE_V2_MASK (0x7fff0000)
+
+#define SDI_FIFO_BURST_SIZE (8)
+
+#ifndef __ASSEMBLY__
+struct sdi_registers {
+ u32 power; /* 0x00*/
+ u32 clock; /* 0x04*/
+ u32 argument; /* 0x08*/
+ u32 command; /* 0x0c*/
+ u32 respcommand; /* 0x10*/
+ u32 response0; /* 0x14*/
+ u32 response1; /* 0x18*/
+ u32 response2; /* 0x1c*/
+ u32 response3; /* 0x20*/
+ u32 datatimer; /* 0x24*/
+ u32 datalength; /* 0x28*/
+ u32 datactrl; /* 0x2c*/
+ u32 datacount; /* 0x30*/
+ u32 status; /* 0x34*/
+ u32 status_clear; /* 0x38*/
+ u32 mask0; /* 0x3c*/
+ u32 mask1; /* 0x40*/
+ u32 card_select; /* 0x44*/
+ u32 fifo_count; /* 0x48*/
+ u32 padding1[(0x80-0x4C)>>2];
+ u32 fifo; /* 0x80*/
+ u32 padding2[(0xFE0-0x84)>>2];
+ u32 periph_id0; /* 0xFE0 mmc Peripheral Identi.cation Register*/
+ u32 periph_id1; /* 0xFE4*/
+ u32 periph_id2; /* 0xFE8*/
+ u32 periph_id3; /* 0xFEC*/
+ u32 pcell_id0; /* 0xFF0*/
+ u32 pcell_id1; /* 0xFF4*/
+ u32 pcell_id2; /* 0xFF8*/
+ u32 pcell_id3; /* 0xFFC*/
+};
+#endif
+
+#endif
diff --git a/board/st-ericsson/snowball/mmc_utils.c b/board/st-ericsson/snowball/mmc_utils.c
new file mode 100644
index 000000000..6c5a8150d
--- /dev/null
+++ b/board/st-ericsson/snowball/mmc_utils.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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 <linux/ctype.h>
+
+#include <asm/arch/common.h>
+#include <asm/arch/cpu.h>
+#include <command.h>
+#include <mmc.h>
+#include <fat.h>
+
+#define PIB_EMMC_ADDR 0x00
+
+struct partition {
+ unsigned char boot_ind; /* 0x80 - active */
+ unsigned char head; /* starting head */
+ unsigned char sector; /* starting sector */
+ unsigned char cyl; /* starting cylinder */
+ unsigned char sys_ind; /* What partition type */
+ unsigned char end_head; /* end head */
+ unsigned char end_sector; /* end sector */
+ unsigned char end_cyl; /* end cylinder */
+ u32 start_sect; /* starting sector counting from 0 */
+ u32 nr_sects; /* nr of sectors in partition */
+} __attribute__((packed));
+
+#define PART(type, start, num) \
+ { \
+ .boot_ind = 0x00, \
+ .head = 0x03, \
+ .sector = 0xD0, \
+ .cyl = 0xff, \
+ .sys_ind = type, \
+ .end_head = 0x03, \
+ .end_sector = 0xd0, \
+ .end_cyl = 0xff, \
+ .start_sect = start, \
+ .nr_sects = num, \
+ }
+
+static struct partition partitions_ed[] = {
+ [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
+ [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
+ [2] = PART(0x83, 0x00124000, 0x0022c000),
+ [3] = PART(0x0c, 0x00350000, 0x00b9a000),
+};
+
+static struct partition partitions_v1[] = {
+ [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
+ [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
+ [2] = PART(0x83, 0x00000400, 0x00000800), /* Modem parameters */
+ [3] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
+
+#undef PART
+
+int write_partition_block(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int err;
+ u32 offset = PIB_EMMC_ADDR;
+ u8 mbr[512];
+ u8 emmc_existing_partition[512];
+ struct mmc *boot_dev = NULL;
+
+ (void) cmdtp; /* Parameter not used! */
+ (void) flag; /* Parameter not used! */
+ (void) argc; /* Parameter not used! */
+ (void) argv; /* Parameter not used! */
+
+ memset(mbr, 0, 0x1be);
+ if (u8500_is_earlydrop())
+ memcpy(mbr + 0x1be, partitions_ed, sizeof(partitions_ed));
+ else
+ memcpy(mbr + 0x1be, partitions_v1, sizeof(partitions_v1));
+
+ /* magic */
+ mbr[0x1fe] = 0x55;
+ mbr[0x1ff] = 0xAA;
+
+ printf("Writing partition block (if needed)...\n");
+
+ boot_dev = find_mmc_device(CONFIG_EMMC_DEV_NUM);
+ if (!boot_dev) {
+ printf(" Error: eMMC device not found\n");
+ return 1;
+ }
+
+ err = boot_dev->block_dev.block_read(CONFIG_EMMC_DEV_NUM,
+ offset,
+ 1,
+ (void *) emmc_existing_partition);
+ if (err != 1) {
+ printf(" Error: eMMC read failed\n");
+ return 1;
+ }
+
+ if (memcmp((void *)emmc_existing_partition, (void *)mbr, 512)) {
+ err = boot_dev->block_dev.block_write(CONFIG_EMMC_DEV_NUM,
+ offset,
+ 1,
+ (void *) mbr);
+ if (err != 1) {
+ printf(" Error: eMMC write failed\n");
+ return 1;
+ }
+ }
+ printf(" eMMC partition block exists now\n");
+ return 0;
+}
+
+U_BOOT_CMD(
+ write_partition_block, 1, 0, write_partition_block,
+ "- write partition block on emmc device\n",
+ NULL
+);
+
+/*
+ * command line commands
+ */
+#ifdef CONFIG_CMD_FAT
+static int mmc_read_cmd_file(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *argv[])
+{
+ long sz;
+ char mmc_cmdbuffer[1024];
+ struct mmc *mmc_dev;
+ (void) cmdtp; /* Parameter not used! */
+ (void) flag; /* Parameter not used! */
+ (void) argc; /* Parameter not used! */
+ (void) argv; /* Parameter not used! */
+
+ mmc_dev = find_mmc_device(CONFIG_MMC_DEV_NUM);
+ if (mmc_dev == NULL) {
+ printf("mmc_read_cmd_file: find_mmc_device failed\n");
+ return 1;
+ }
+
+ if (fat_register_device(&mmc_dev->block_dev, 1) != 0) {
+ printf("mmc_read_cmd_file: fat_register_device failed\n");
+ return 1;
+ }
+
+ sz = file_fat_read("/command.txt", &mmc_cmdbuffer,
+ sizeof(mmc_cmdbuffer) - 1);
+ if (sz == -1) {
+ printf("No command.txt found in the MMC/SD card\n");
+ return 1;
+ }
+
+ mmc_cmdbuffer[sz] = '\0';
+ setenv("bootcmd", mmc_cmdbuffer);
+ return 0;
+}
+
+U_BOOT_CMD(
+ mmc_read_cmd_file, 1, 0, mmc_read_cmd_file,
+ "setup bootcmd env from command.txt on SD",
+ NULL
+);
+#endif
+
+/* ------------------------------- End of file ---------------------------- */
diff --git a/board/st-ericsson/snowball/snowball.c b/board/st-ericsson/snowball/snowball.c
new file mode 100644
index 000000000..4379b2cb9
--- /dev/null
+++ b/board/st-ericsson/snowball/snowball.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/ab8500.h>
+#include <asm/arch/prcmu.h>
+#include <asm/arch/common.h>
+
+#include <db8500_pincfg.h>
+
+#include "db8500_pins.h"
+
+#define NOMADIK_PER4_BASE (0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR 0x80156000
+#define DMC_CTL_97 (DMC_BASE_ADDR + 0x184)
+
+/*
+ * GPIO pin config common for MOP500/HREF boards
+ */
+pin_cfg_t gpio_cfg_common[] = {
+ /* I2C */
+ GPIO147_I2C0_SCL,
+ GPIO148_I2C0_SDA,
+ GPIO16_I2C1_SCL,
+ GPIO17_I2C1_SDA,
+ GPIO10_I2C2_SDA,
+ GPIO11_I2C2_SCL,
+ GPIO229_I2C3_SDA,
+ GPIO230_I2C3_SCL,
+
+ /* SSP0, to AB8500 */
+ GPIO143_SSP0_CLK,
+ GPIO144_SSP0_FRM,
+ GPIO145_SSP0_RXD | PIN_PULL_DOWN,
+ GPIO146_SSP0_TXD,
+
+ /* MMC0 (MicroSD card) */
+ GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH,
+ GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH,
+ GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH,
+ GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH,
+ GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL,
+ GPIO23_MC0_CLK | PIN_OUTPUT_LOW,
+ GPIO24_MC0_CMD | PIN_INPUT_PULLUP,
+ GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP,
+ GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP,
+ GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP,
+ GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP,
+
+ /* MMC4 (On-board eMMC) */
+ GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP,
+ GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP,
+ GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP,
+ GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP,
+ GPIO201_MC4_CMD | PIN_INPUT_PULLUP,
+ GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL,
+ GPIO203_MC4_CLK | PIN_OUTPUT_LOW,
+ GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP,
+ GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP,
+ GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP,
+ GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP,
+
+ /* UART2, console */
+ GPIO29_U2_RXD | PIN_INPUT_PULLUP,
+ GPIO30_U2_TXD | PIN_OUTPUT_HIGH,
+ GPIO31_U2_CTSn | PIN_INPUT_PULLUP,
+ GPIO32_U2_RTSn | PIN_OUTPUT_HIGH,
+
+ /*
+ * USB, pin 256-267 USB, Is probably already setup correctly from
+ * BootROM/boot stages, but we don't trust that and set it up anyway
+ */
+ GPIO256_USB_NXT,
+ GPIO257_USB_STP,
+ GPIO258_USB_XCLK,
+ GPIO259_USB_DIR,
+ GPIO260_USB_DAT7,
+ GPIO261_USB_DAT6,
+ GPIO262_USB_DAT5,
+ GPIO263_USB_DAT4,
+ GPIO264_USB_DAT3,
+ GPIO265_USB_DAT2,
+ GPIO266_USB_DAT1,
+ GPIO267_USB_DAT0,
+};
+
+pin_cfg_t gpio_cfg_snowball[] = {
+ /* MMC0 (MicroSD card) */
+ GPIO217_GPIO | PIN_OUTPUT_HIGH, /* MMC_EN */
+ GPIO218_GPIO | PIN_INPUT_NOPULL, /* MMC_CD */
+ GPIO228_GPIO | PIN_OUTPUT_HIGH, /* SD_SEL */
+
+ /* eMMC */
+ GPIO167_GPIO | PIN_OUTPUT_HIGH, /* RSTn_MLC */
+
+ /* LAN */
+ GPIO131_SM_ADQ8,
+ GPIO132_SM_ADQ9,
+ GPIO133_SM_ADQ10,
+ GPIO134_SM_ADQ11,
+ GPIO135_SM_ADQ12,
+ GPIO136_SM_ADQ13,
+ GPIO137_SM_ADQ14,
+ GPIO138_SM_ADQ15,
+
+ /* RSTn_LAN */
+ GPIO141_GPIO | PIN_OUTPUT_HIGH,
+};
+
+#define BOARD_ID_MOP500 0
+#define BOARD_ID_HREF 1
+#define BOARD_ID_HREFV60 2
+#define BOARD_ID_SNOWBALL 3
+int board_id; /* set in probe_href() */
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+ printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init(void)
+{
+ /*
+ * Setup board (bd) and board-info (bi).
+ * bi_arch_number: Unique id for this board. It will passed in r1 to
+ * Linux startup code and is the machine_id.
+ * bi_boot_params: Where this board expects params.
+ */
+ gd->bd->bi_arch_number = MACH_TYPE_SNOWBALL;
+ gd->bd->bi_boot_params = 0x00000100;
+
+ /* Configure GPIO pins needed by U-boot */
+ db8500_gpio_config_pins(gpio_cfg_common, ARRAY_SIZE(gpio_cfg_common));
+
+ db8500_gpio_config_pins(gpio_cfg_snowball, ARRAY_SIZE(gpio_cfg_snowball));
+
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ uint32_t unused_cols_rows;
+ unsigned int nrows;
+ unsigned int ncols;
+
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+ /*
+ * Assumption: 2 CS active, both CS have same layout.
+ * 15 rows max, 11 cols max (controller spec).
+ * memory chip has 8 banks, I/O width 32 bit.
+ * The correct way would be to read MR#8: I/O width and density,
+ * but this requires locking against the PRCMU firmware.
+ * Simplified approach:
+ * Read number of unused rows and columns from mem controller.
+ * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+ */
+ unused_cols_rows = readl(DMC_CTL_97);
+ nrows = 15 - (unused_cols_rows & 0x07);
+ ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+ gd->ram_size = gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+ return 0;
+}
+
+/*
+ * probe_href - set board_id according to HREF version
+ *
+ * side-effect: configures additional GPIO pins if necessary.
+ */
+static void probe_href(void)
+{
+ uchar byte;
+
+ gd->bd->bi_arch_number = MACH_TYPE_SNOWBALL;
+ board_id = BOARD_ID_SNOWBALL;
+}
+
+#define BATT_OK_SEL1_TH_F_MASK 0xF0
+#define BATT_OK_SEL1_TH_F_2V71 0x70
+/*
+ * board_early_access - for functionality that needs to run before
+ * board_late_init but after board_init and emmc init.
+ */
+int board_early_access(block_dev_desc_t *block_dev)
+{
+ int ret;
+ int battok_regval;
+
+ /* set board_id according to HREF version */
+ probe_href();
+
+ /*
+ * In AB8500 rev2.0, the cut-off voltage threshold is set too low
+ * and the AB will power-off when we start with a drained battery
+ * and a charger connected when the backlight is turned on.
+ * Here we will lower the cut-off voltage threshold before
+ * power consumption goes up
+ */
+ ret = ab8500_read(AB8500_SYS_CTRL2_BLOCK, AB8500_BATT_OK_REG);
+ if (ret < 0)
+ return -EINVAL;
+
+ battok_regval = ret;
+
+ /* Mask and set BattOkSel1ThF */
+ ret = ab8500_write(AB8500_SYS_CTRL2_BLOCK, AB8500_BATT_OK_REG,
+ (battok_regval & ~BATT_OK_SEL1_TH_F_MASK) |
+ BATT_OK_SEL1_TH_F_2V71);
+ if (ret < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_ENABLE_MASK 0x3
+#define LDO_VAUX3_ENABLE_VAL 0x1
+#define LDO_VAUX3_SEL_MASK 0xf
+#define LDO_VAUX3_SEL_2V9 0xd
+#define LDO_VAUX3_V2_SEL_MASK 0x7
+#define LDO_VAUX3_V2_SEL_2V91 0x7
+
+static int hrefplus_mmc_power_init(void)
+{
+ int ret;
+ int voltage_regval;
+ int enable_regval;
+ int ab8500_revision;
+
+ if (!cpu_is_u8500v11() && !cpu_is_u8500v2())
+ return 0;
+
+ /* Get AB8500 revision */
+ ret = ab8500_read(AB8500_MISC, AB8500_REV_REG);
+ if (ret < 0)
+ goto out;
+
+ ab8500_revision = ret;
+
+ /*
+ * On v1.1 HREF boards (HREF+) and v2 boards, Vaux3 needs to be
+ * enabled for the SD card to work. This is done by enabling
+ * the regulators in the AB8500 via PRCMU I2C transactions.
+ *
+ * This code is derived from the handling of AB8500_LDO_VAUX3 in
+ * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+ *
+ * Turn off and delay is required to have it work across soft reboots.
+ */
+
+ /* Turn off (read-modify-write) */
+ ret = ab8500_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+ if (ret < 0)
+ goto out;
+
+ enable_regval = ret;
+
+ ret = ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+ enable_regval & ~LDO_VAUX3_ENABLE_MASK);
+ if (ret < 0)
+ goto out;
+
+ /* Delay */
+ udelay(10 * 1000);
+
+ /* Set the voltage to 2.91 V or 2.9 V without overriding VRF1 value */
+ ret = ab8500_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_SEL_REG);
+ if (ret < 0)
+ goto out;
+
+ voltage_regval = ret;
+
+ if (ab8500_revision < 0x20) {
+ voltage_regval &= ~LDO_VAUX3_SEL_MASK;
+ voltage_regval |= LDO_VAUX3_SEL_2V9;
+ } else {
+ voltage_regval &= ~LDO_VAUX3_V2_SEL_MASK;
+ voltage_regval |= LDO_VAUX3_V2_SEL_2V91;
+ }
+
+ ret = ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_SEL_REG,
+ voltage_regval);
+ if (ret < 0)
+ goto out;
+
+ /* Turn on the supply */
+ enable_regval &= ~LDO_VAUX3_ENABLE_MASK;
+ enable_regval |= LDO_VAUX3_ENABLE_VAL;
+
+ ret = ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+ enable_regval);
+
+out:
+ return ret;
+}
+#endif
+
+static int snowball_raise_ab8500_gpio26(void)
+{
+ int ret;
+
+ /* For snowball (aka "minikit") we need to raise AB8500's GPIO26 */
+ ret = ab8500_read(AB8500_MISC, AB8500_GPIO_DIR4_REG);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret |= 0x2;
+ ret = ab8500_write(AB8500_MISC, AB8500_GPIO_DIR4_REG, ret);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret = ab8500_read(AB8500_MISC, AB8500_GPIO_OUT4_REG);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret |= 0x2;
+ ret = ab8500_write(AB8500_MISC, AB8500_GPIO_OUT4_REG, ret);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ }
+
+out:
+ return ret;
+}
+
+
+static int snowball_raise_ab8500_gpio16(void)
+{
+ int ret;
+
+ /* selection */
+ ret = ab8500_read(AB8500_MISC, AB8500_GPIO_SEL2_REG);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret |= 0x80;
+ ret = ab8500_write(AB8500_MISC, AB8500_GPIO_SEL2_REG, ret);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ /* direction */
+ ret = ab8500_read(AB8500_MISC, AB8500_GPIO_DIR2_REG);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret |= 0x80;
+ ret = ab8500_write(AB8500_MISC, AB8500_GPIO_DIR2_REG, ret);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ /* out */
+ ret = ab8500_read(AB8500_MISC, AB8500_GPIO_OUT2_REG);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+ ret |= 0x80;
+ ret = ab8500_write(AB8500_MISC, AB8500_GPIO_OUT2_REG, ret);
+ if (ret < 0) {
+ printf("error at %s:%i\n", __func__, __LINE__);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+ uchar byte;
+#ifdef CONFIG_MMC
+ uchar byte_array[] = {0x06, 0x06};
+#endif
+ char strbuf[80];
+
+ /*
+ * The board_id environment variable is needed for the Linux bootargs.
+ */
+ if (board_id == 0)
+ setenv("board_id", "0");
+ else
+ setenv("board_id", "1");
+
+ if (u8500_is_snowball()) {
+ /* enable 3V3 for LAN controller */
+ if(snowball_raise_ab8500_gpio26() >= 0) {
+
+ /* Turn on FSMC device */
+ writel(0x1, 0x8000f000);
+ writel(0x1, 0x8000f008);
+
+ /* setup FSMC for LAN controler */
+ writel(0x305b, 0x80000000);
+ /* the default is too slow */
+ writel(0x01010110, 0x80000004);
+ }
+
+ /* enable 3V6 for GBF chip */
+ snowball_raise_ab8500_gpio16();
+ }
+
+#ifdef CONFIG_MMC
+ hrefplus_mmc_power_init();
+
+ /*
+ * config extended GPIO pins for level shifter and
+ * SDMMC_ENABLE
+ */
+ /* HREF V60 and later */
+ /* enable SDMMC */
+ db8500_gpio_set_output(GPIO169_GPIO, 1);
+#endif /* CONFIG_MMC */
+
+ return (0);
+}
+#endif /* BOARD_LATE_INIT */
+
diff --git a/include/configs/snowball.h b/include/configs/snowball.h
new file mode 100644
index 000000000..aa0a69ec6
--- /dev/null
+++ b/include/configs/snowball.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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 __CONFIG_H
+#define __CONFIG_H
+
+//#define CONFIG_SKIP_LOWLEVEL_INIT 1
+#define CONFIG_SNOWBALL 1
+//#define DEBUG 100
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_U8500
+#define CONFIG_L2_OFF
+
+#define CONFIG_SYS_MEMTEST_START 0x00000000
+#define CONFIG_SYS_MEMTEST_END 0x1FFFFFFF
+#define CONFIG_SYS_HZ 1000 /* must be 1000 */
+
+//#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_CPU_INIT 1
+
+#define CONFIG_DISPLAY_CPUINFO 1
+#define BOARD_LATE_INIT 1
+
+
+/*-----------------------------------------------------------------------
+ * Size of environment and malloc() pool
+ */
+/*
+ * If you use U-Boot as crash kernel, make sure that it does not overwrite
+ * information saved by kexec during panic. Kexec expects the start
+ * address of the executable 32K above "crashkernel" address.
+ */
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE (32*1024)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE (128*1024)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */
+
+//#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_CMD_ENV
+#define CONFIG_ENV_OFFSET 0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV 0 /* SLOT2: eMMC */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL_RLCR
+#define CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE 0x80120000
+#define CFG_UART1_BASE 0x80121000
+#define CFG_UART2_BASE 0x80007000
+#define CFG_SERIAL0 CFG_UART0_BASE
+#define CFG_SERIAL1 CFG_UART1_BASE
+#define CFG_SERIAL2 CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK 38400000
+#define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+ (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX 2
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+//#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+//#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY 1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND \
+ "mmc rescan 0; mmc rescan 1; " \
+ "if run loadbootscript; " \
+ "then run bootscript; " \
+ "else " \
+ "if run mmcload; " \
+ "then run mmcboot; " \
+ "else " \
+ "if run emmcload; " \
+ "then run emmcboot; " \
+ "else " \
+ "echo No media to boot from; " \
+ "fi; " \
+ "fi; " \
+ "fi; "
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "verify=n\0" \
+ "loadaddr=0x00100000\0" \
+ "console=ttyAMA2,115200n8\0" \
+ "loadbootscript=fatload mmc 1:1 ${loadaddr} boot.scr\0" \
+ "bootscript=echo Running bootscript " \
+ "from mmc ...; source ${loadaddr}\0" \
+ "memargs256=mem=96M@0 mem_modem=32M@96M mem=32M@128M " \
+ "hwmem=22M@160M pmem_hwb=42M@182M mem_mali=32@224M\0" \
+ "memargs512=mem=96M@0 mem_modem=32M@96M hwmem=32M@128M " \
+ "mem=64M@160M mem_mali=32M@224M " \
+ "pmem_hwb=128M@256M mem=128M@384M\0" \
+ "memargs1024=mem=128M@0 mali.mali_mem=32M@128M " \
+ "hwmem=168M@M160M mem=48M@328M " \
+ "mem_issw=1M@383M mem=640M@384M\0" \
+ "memargs=setenv bootargs ${bootargs} ${memargs1024}\0" \
+ "emmcload=fatload mmc 0:2 ${loadaddr} /uImage\0" \
+ "mmcload=fatload mmc 1:1 ${loadaddr} /uImage\0" \
+ "commonargs=setenv bootargs console=${console} " \
+ "ip=dhcp vmalloc=256M\0" \
+ "emmcargs=setenv bootargs ${bootargs} " \
+ "root=/dev/mmcblk0p3 " \
+ "rootwait\0" \
+ "addcons=setenv bootargs ${bootargs} " \
+ "console=${console}\0" \
+ "emmcboot=echo Booting from eMMC ...; " \
+ "run commonargs emmcargs memargs; " \
+ "bootm ${loadaddr}\0" \
+ "mmcargs=setenv bootargs ${bootargs} " \
+ "root=/dev/mmcblk1p2 " \
+ "rootwait earlyprintk\0" \
+ "mmcboot=echo Booting from external MMC ...; " \
+ "run commonargs mmcargs memargs; " \
+ "bootm ${loadaddr}\0" \
+ "stdout=serial,usbtty\0" \
+ "stdin=serial,usbtty\0" \
+ "stderr=serial,usbtty\0"
+
+/*-----------------------------------------------------------------------
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_PROMPT "U8500 $ " /* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
+ + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 32 /* max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR 0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE 1
+
+#define CONFIG_SYS_HUSH_PARSER 1
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS 2
+#define CONFIG_INITRD_TAG 1
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS 1
+#define PHYS_SDRAM_1 0x00000000 /* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1 0x10000000 /* 256 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE 0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_SDRAM_BASE + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE 0x0
+#endif
+
+/*-----------------------------------------------------------------------
+ * MMC related configs
+ */
+#define MMC_BLOCK_SIZE 512
+#define CFG_MMC_BASE 0x80126000 /* MMC base for 8500 */
+#define CONFIG_MMC_DEV_NUM 1
+
+/*-----------------------------------------------------------------------
+ * EMMC related configs
+ */
+#define CFG_EMMC_BASE_V1 0x80005000 /*POP EMMC base of size 256MB for 8500 cut1.0 */
+#define CFG_EMMC_BASE_ED 0x80114000 /* EMMC base of size 2GB for 8500 */
+#define CONFIG_EMMC_DEV_NUM 0
+
+/*-----------------------------------------------------------------------
+ * USB related configs
+ */
+#define CONFIG_USB_BASE 0xA03E0000
+#define UDC_BASE 0xA03E0000
+#ifdef CONFIG_USB_TTY
+/* Allow console in serial and USB at the same time */
+#define CONFIG_CONSOLE_MUX 1
+//#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
+//#define CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+#endif
+
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE 0x80157000 /* Power, reset and clock */
+
+
+/*
+ * U8500 GPIO register base for 9 banks
+ */
+#define CONFIG_DB8500_GPIO
+#define CFG_GPIO_0_BASE 0x8012E000
+#define CFG_GPIO_1_BASE 0x8012E080
+#define CFG_GPIO_2_BASE 0x8000E000
+#define CFG_GPIO_3_BASE 0x8000E080
+#define CFG_GPIO_4_BASE 0x8000E100
+#define CFG_GPIO_5_BASE 0x8000E180
+#define CFG_GPIO_6_BASE 0x8011E000
+#define CFG_GPIO_7_BASE 0x8011E080
+#define CFG_GPIO_8_BASE 0xA03FE000
+
+#define CFG_FSMC_BASE 0x80000000 /* FSMC Controller */
+
+#endif /* __CONFIG_H */