U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
January 2009
- 181 participants
- 473 discussions
should i push changes for the Blackfin on-chip network driver through Ben's
net tree or can i have you pull them straight from my repo ? obviously
changes to this driver only affect Blackfin parts, but the file itself lives
in drivers/net/ ...
-mike
2
3

[U-Boot] Strange arm9 behaviour reading long(s) not aligned to 4 bytes boundary
by dibacco@libero.it 24 Jan '09
by dibacco@libero.it 24 Jan '09
24 Jan '09
Hi,
I have something like this on a 32 bit little endian arm9 board (SAM9
L9260):
char buffer[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
long A = * ( (long*)
buffer );
long B = * ( (long*) (buffer + 2) );
printf("A: %08x B: %08x", A,
B);
I would expect that A = 0x03020100 and B = 0x05040302
instead I get the
right value for A but B is 0x01000302 or something like this but anyway not
what I expect.
Is there something wrong on the board? It seems that only 4
bytes aligned long are read correctly.
Thank you in advance,
Antonio.
2
1
2009/1/24, Jerry Zhang <jerry.scofield(a)gmail.com>:
> Obviously you know nothing about the "make".
> 1)Read the Readme of the make tool first
> 2) then figure out "How the u-boot building process works; how the
> Makefile serve the building of your .bin"
> 3) Build your bin.
Obviously, either you're responding wrong person.
--
Roman Mashak
1
0

24 Jan '09
From: Alessandro Rubini <rubini(a)unipv.it>
Subject: Initial support for Nomadik 8815 development board
The NMDK8815 board is distributed by ST Microelectornics.
Other (proprietary) code must be run to unlock the CPU before
U-Boot runs. doc/README.nmdk8815 outlines the boot sequence.
This is the initial port, with basic infrastructure and
a working serial port.
Signed-off-by: Alessandro Rubini <rubini(a)unipv.it>
Acked-by: Andrea Gallo <andrea.gallo(a)stnwireless.com>
---
changes since v2:
- added doc/README.nmdk8815 to explain the boot process
- moved code to a vendor dir
- fixed Makefiles as suggested (and removed unused CFLAGS)
- added copyright where missing (u-boot.lds is copied, so no new copyright)
- fixed remaining whitespace issues and comment style
- other detais JC noted
MAINTAINERS | 5 +
MAKEALL | 1 +
Makefile | 11 ++
board/st/nmdk8815/Makefile | 55 +++++++
board/st/nmdk8815/config.mk | 26 +++
board/st/nmdk8815/nmdk8815.c | 73 +++++++++
board/st/nmdk8815/platform.S | 345 ++++++++++++++++++++++++++++++++++++++++
board/st/nmdk8815/u-boot.lds | 51 ++++++
cpu/arm926ejs/nomadik/Makefile | 46 ++++++
cpu/arm926ejs/nomadik/reset.S | 27 +++
cpu/arm926ejs/nomadik/timer.c | 180 +++++++++++++++++++++
doc/README.nmdk8815 | 22 +++
include/configs/nmdk8815.h | 188 ++++++++++++++++++++++
13 files changed, 1030 insertions(+), 0 deletions(-)
create mode 100644 board/st/nmdk8815/Makefile
create mode 100644 board/st/nmdk8815/config.mk
create mode 100644 board/st/nmdk8815/nmdk8815.c
create mode 100644 board/st/nmdk8815/platform.S
create mode 100644 board/st/nmdk8815/u-boot.lds
create mode 100644 cpu/arm926ejs/nomadik/Makefile
create mode 100644 cpu/arm926ejs/nomadik/reset.S
create mode 100644 cpu/arm926ejs/nomadik/timer.c
create mode 100644 doc/README.nmdk8815
create mode 100644 include/configs/nmdk8815.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 127604b..e2a90d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -581,6 +581,11 @@ Stefan Roese <sr(a)denx.de>
pdnb3 xscale
scpu xscale
+Alessandro Rubini <rubini(a)unipv.it>
+Nomadik Linux Team <STN_WMM_nomadik_linux(a)list.st.com>
+
+ nmdk8815 ARM926EJS (Nomadik 8815 Soc)
+
Robert Schwebel <r.schwebel(a)pengutronix.de>
csb226 xscale
diff --git a/MAKEALL b/MAKEALL
index dbed268..a209a4d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -487,6 +487,7 @@ LIST_ARM9=" \
mx1ads \
mx1fs2 \
netstar \
+ nmdk8815 \
omap1510inn \
omap1610h2 \
omap1610inn \
diff --git a/Makefile b/Makefile
index fd521b6..de6e6ab 100644
--- a/Makefile
+++ b/Makefile
@@ -2644,6 +2644,17 @@ mx1fs2_config : unconfig
netstar_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm925t netstar
+nmdk8815_config \
+nmdk8815_onenand_config: unconfig
+ @ > $(obj)include/config.h
+ @if [ "$(findstring _onenand, $@)" ] ; then \
+ echo "#define CONFIG_BOOT_ONENAND" >> $(obj)include/config.h; \
+ $(XECHO) "... configured for OneNand Flash"; \
+ else \
+ $(XECHO) "... configured for Nand Flash"; \
+ fi
+ @$(MKCONFIG) -a nmdk8815 arm arm926ejs nmdk8815 st nomadik
+
omap1510inn_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm925t omap1510inn
diff --git a/board/st/nmdk8815/Makefile b/board/st/nmdk8815/Makefile
new file mode 100644
index 0000000..be9a424
--- /dev/null
+++ b/board/st/nmdk8815/Makefile
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# (C) Copyright 2004
+# ARM Ltd.
+# Philippe Robin, <philippe.robin(a)arm.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 $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := nmdk8815.o
+SOBJS := platform.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(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/nmdk8815/config.mk b/board/st/nmdk8815/config.mk
new file mode 100644
index 0000000..590393b
--- /dev/null
+++ b/board/st/nmdk8815/config.mk
@@ -0,0 +1,26 @@
+# (C) Copyright 2007
+# STMicroelectronics, <www.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
+#
+#
+# image should be loaded at 0x01000000
+#
+
+TEXT_BASE = 0x03F80000
diff --git a/board/st/nmdk8815/nmdk8815.c b/board/st/nmdk8815/nmdk8815.c
new file mode 100644
index 0000000..5536d97
--- /dev/null
+++ b/board/st/nmdk8815/nmdk8815.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2005
+ * STMicrolelctronics, <www.st.com>
+ *
+ * (C) Copyright 2004
+ * ARM Ltd.
+ * Philippe Robin, <philippe.robin(a)arm.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 <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress(int progress)
+{
+ printf("%i\n", progress);
+}
+#endif
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+int board_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ gd->bd->bi_arch_number = MACH_TYPE_NOMADIK;
+ gd->bd->bi_boot_params = 0x00000100;
+ writel(0xC37800F0, NOMADIK_GPIO1_BASE + 0x20);
+ writel(0x00000000, NOMADIK_GPIO1_BASE + 0x24);
+ writel(0x00000000, NOMADIK_GPIO1_BASE + 0x28);
+ writel(readl(NOMADIK_SRC_BASE) | 0x8000, NOMADIK_SRC_BASE);
+
+ icache_enable();
+
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ setenv("verify", "n");
+ return 0;
+}
+
+int dram_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* set dram bank start addr and size */
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+ return 0;
+}
diff --git a/board/st/nmdk8815/platform.S b/board/st/nmdk8815/platform.S
new file mode 100644
index 0000000..d4b0f0b
--- /dev/null
+++ b/board/st/nmdk8815/platform.S
@@ -0,0 +1,345 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2005
+ * STMicrolelctronics, <www.st.com>
+ *
+ * (C) Copyright 2004, ARM Ltd.
+ * Philippe Robin, <philippe.robin(a)arm.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 <config.h>
+#include <version.h>
+
+.globl lowlevel_init
+lowlevel_init:
+ /* Jump to the flash address */
+ ldr r0, =CFG_ONENAND_BASE
+
+ /*
+ * Make it independent whether we boot from 0x0 or 0x30000000.
+ * Non-portable: it relies on the knowledge that ip has to be updated
+ */
+ orr ip, ip, r0 /* adjust return address of cpu_init_crit */
+ orr lr, lr, r0 /* adjust return address */
+ orr pc, pc, r0 /* jump to the normal address */
+ nop
+
+ /* Initialize PLL, Remap clear, FSMC, MPMC here! */
+ /* What about GPIO, CLCD and UART */
+
+ /* PLL Initialization */
+ /* Prog the PLL1 @ 266 MHz ==> SDRAM Clock = 100.8 MHz */
+ ldr r0, =NOMADIK_SRC_BASE
+
+ ldr r1, =0x2B013502
+
+ str r1, [r0, #0x14]
+
+
+ /* Used to set all the timers clock to 2.4MHZ */
+ ldr r1, =0x2AAAA004
+ str r1, [r0]
+
+ ldr r1, =0x10000000
+ str r1, [r0, #0x10]
+
+ /* FSMC setup ---- */
+ ldr r0, =NOMADIK_FSMC_BASE
+
+ ldr r1, =0x10DB /* For 16-bit NOR flash */
+ str r1, [r0,#0x08]
+
+ ldr r1, =0x03333333 /* For 16-bit NOR flash */
+ str r1, [r0, #0xc]
+
+ /* oneNAND setting */
+ ldr r1, =0x0000105B /* BCR0 Prog control register */
+ str r1, [r0]
+
+ ldr r1, =0x0A200551 /* BTR0 Prog timing register */
+ str r1, [r0, #0x04]
+
+ /* preload the instructions into icache */
+ add r0, pc, #0x1F
+ bic r0, r0, #0x1F
+ mcr p15, 0, r0, c7, c13, 1
+ add r0, r0, #0x20
+ mcr p15, 0, r0, c7, c13, 1
+
+ /* Now Clear Remap */
+ ldr r0, =NOMADIK_SRC_BASE
+
+ ldr r1, =0x2004
+ str r1, [r0]
+
+ ldr r1, =0x10000000
+ str r1, [r0,#0x10]
+
+ ldr r0,=0x101E9000
+ ldr r1, =0x2004
+ str r1, [r0]
+
+ ldr r0, =NOMADIK_SRC_BASE
+ ldr r1, =0x2104
+ str r1, [r0]
+
+ /* FSMC setup -- */
+ mov r0, #(NOMADIK_FSMC_BASE & 0x10000000)
+ orr r0, r0, #(NOMADIK_FSMC_BASE & 0x0FFFFFFF)
+
+ ldr r1, =0x10DB /* For 16-bit NOR flash */
+ str r1, [r0, #0x8]
+
+ ldr r1, =0x03333333 /* For 16-bit NOR flash */
+ str r1, [r0, #0xc]
+
+
+
+ /* MPMC Setup */
+ ldr r0, =NOMADIK_MPMC_BASE
+
+ ldr r1, =0xF00003
+ str r1, [r0] /* Enable the MPMC and the DLL */
+
+ ldr r1, =0x183
+ str r1, [r0, #0x20]
+
+ ldr r2, =NOMADIK_PMU_BASE
+
+ ldr r1, =0x1111
+ str r1, [r2]
+
+ ldr r1, =0x1111 /* Prog the, mand delay strategy */
+ str r1, [r0, #0x28]
+
+ ldr r1, =0x103 /* NOP ,mand */
+ str r1, [r0, #0x20]
+
+ /* FIXME -- Wait required here */
+
+ ldr r1, =0x103 /* PALL ,mand*/
+ str r1, [r0, #0x20]
+
+ ldr r1, =0x1
+ str r1, [r0, #0x24] /* To do at least two auto-refresh */
+
+ /* FIXME -- Wait required here */
+
+ /* Auto-refresh period = 7.8us @ SDRAM Clock = 100.8 MHz */
+ ldr r1, =0x31
+ str r1, [r0, #0x24]
+
+ /* Prog Little Endian, Not defined in 8800 board */
+ ldr r1, =0x0
+ str r1, [r0, #0x8]
+
+
+ ldr r1, =0x2
+ str r1, [r0, #0x30] /* Prog tRP timing */
+
+ ldr r1, =0x4 /* Change for 8815 */
+ str r1, [r0, #0x34] /* Prog tRAS timing */
+
+ ldr r1, =0xB
+ str r1, [r0, #0x38] /* Prog tSREX timing */
+
+
+ ldr r1, =0x1
+ str r1, [r0, #0x44] /* Prog tWR timing */
+
+ ldr r1, =0x8
+ str r1, [r0, #0x48] /* Prog tRC timing */
+
+ ldr r1, =0xA
+ str r1, [r0, #0x4C] /* Prog tRFC timing */
+
+ ldr r1, =0xB
+ str r1, [r0, #0x50] /* Prog tXSR timing */
+
+ ldr r1, =0x1
+ str r1, [r0, #0x54] /* Prog tRRD timing */
+
+ ldr r1, =0x1
+ str r1, [r0, #0x58] /* Prog tMRD timing */
+
+ ldr r1, =0x1
+ str r1, [r0, #0x5C] /* Prog tCDLR timing */
+
+ /* DDR-SDRAM MEMORY IS ON BANK0 8815 */
+ ldr r1, =0x304 /* Prog RAS and CAS for CS 0 */
+ str r1, [r0, #0x104]
+
+ /* SDR-SDRAM MEMORY IS ON BANK1 8815 */
+ ldr r1, =0x304 /* Prog RAS and CAS for CS 1 */
+ str r1, [r0, #0x124]
+ /* THE DATA BUS WIDE IS PROGRAM FOR 16-BITS */
+ /* DDR-SDRAM MEMORY IS ON BANK0*/
+
+ ldr r1, =0x884 /* 8815 : config reg in BRC for CS0 */
+ str r1, [r0, #0x100]
+
+ /*SDR-SDRAM MEMORY IS ON BANK1*/
+
+ ldr r1, =0x884 /* 8815 : config reg in BRC for CS1 */
+ str r1, [r0, #0x120]
+
+ ldr r1, =0x83 /*MODE Mand*/
+ str r1, [r0, #0x20]
+
+ /* LOAD MODE REGISTER FOR 2 bursts of 16b, with DDR mem ON BANK0 */
+
+ ldr r1, =0x62000 /*Data in*/
+ ldr r1, [r1]
+
+ /* LOAD MODE REGISTER FOR 2 bursts of 16b, with DDR mem ON BANK1 */
+
+ ldr r1, =0x8062000
+ ldr r1, [r1]
+
+ ldr r1, =0x003
+ str r1, [r0, #0x20]
+
+ /* ENABLE ALL THE BUFFER FOR EACH AHB PORT*/
+
+ ldr r1, =0x01 /* Enable buffer 0 */
+ str r1, [r0, #0x400]
+
+ ldr r1, =0x01 /* Enable buffer 1 */
+ str r1, [r0, #0x420]
+
+ ldr r1, =0x01 /* Enable buffer 2 */
+ str r1, [r0, #0x440]
+
+ ldr r1, =0x01 /* Enable buffer 3 */
+ str r1, [r0, #0x460]
+
+ ldr r1, =0x01 /* Enable buffer 4 */
+ str r1, [r0, #0x480]
+
+ ldr r1, =0x01 /* Enable buffer 5 */
+ str r1, [r0, #0x4A0]
+
+ /* GPIO settings */
+
+ ldr r0, =NOMADIK_GPIO1_BASE
+
+ ldr r1, =0xC0600000
+ str r1, [r0, #0x20]
+
+ ldr r1, =0x3F9FFFFF /* ABHI change this for uart1 */
+ str r1, [r0, #0x24]
+
+ ldr r1, =0x3F9FFFFF /* ABHI change this for uart1 */
+ str r1, [r0, #0x28]
+
+ ldr r0, =NOMADIK_GPIO0_BASE
+
+ ldr r1, =0xFFFFFFFF
+ str r1, [r0, #0x20]
+
+ ldr r1, =0x00
+ str r1, [r0, #0x24]
+
+ ldr r1, =0x00
+ str r1, [r0, #0x28]
+
+/* Configure CPLD_CTRL register for enabling MUX logic for UART0/UART2 */
+
+ ldr r0, =NOMADIK_FSMC_BASE
+
+ ldr r1,=0x10DB /* INIT FSMC bank 0 */
+ str r1, [r0, #0x00]
+
+ ldr r1,=0x0FFFFFFF
+ str r1, [r0, #0x04]
+
+ ldr r1,=0x010DB /* INIT FSMC bank 1 */
+ str r1, [r0, #0x08]
+
+ ldr r1,=0x00FFFFFFF
+ str r1, [r0, #0x0C]
+
+ ldr r0,=NOMADIK_UART0_BASE
+
+ ldr r1,=0x00000000
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x0000004e
+ str r1,[r0,#0x24]
+
+ ldr r1,=0x00000008
+ str r1,[r0,#0x28]
+
+ ldr r1,=0x00000060
+ str r1,[r0,#0x2C]
+
+ ldr r1,=0x00000301
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x00000066
+ str r1,[r0]
+
+
+ ldr r0,=NOMADIK_UART1_BASE
+
+ ldr r1,=0x00000000
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x0000004e
+ str r1,[r0,#0x24]
+
+ ldr r1,=0x00000008
+ str r1,[r0,#0x28]
+
+ ldr r1,=0x00000060
+ str r1,[r0,#0x2C]
+
+ ldr r1,=0x00000301
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x00000066
+ str r1,[r0]
+
+ ldr r0,=NOMADIK_UART2_BASE
+
+ ldr r1,=0x00000000
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x0000004e
+ str r1,[r0,#0x24]
+
+ ldr r1,=0x00000008
+ str r1,[r0,#0x28]
+
+ ldr r1,=0x00000060
+ str r1,[r0,#0x2C]
+
+ ldr r1,=0x00000301
+ str r1,[r0,#0x30]
+
+ ldr r1,=0x00000066
+ str r1,[r0]
+
+ /* Configure CPLD to enable UART0 */
+
+
+ mov pc, lr
diff --git a/board/st/nmdk8815/u-boot.lds b/board/st/nmdk8815/u-boot.lds
new file mode 100644
index 0000000..6d6481b
--- /dev/null
+++ b/board/st/nmdk8815/u-boot.lds
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm926ejs/start.o (.text)
+ *(.text)
+ }
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+ . = ALIGN(4);
+ .data : { *(.data) }
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
+ _end = .;
+}
diff --git a/cpu/arm926ejs/nomadik/Makefile b/cpu/arm926ejs/nomadik/Makefile
new file mode 100644
index 0000000..e3bd2ee
--- /dev/null
+++ b/cpu/arm926ejs/nomadik/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+COBJS = timer.o
+SOBJS = reset.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/nomadik/reset.S b/cpu/arm926ejs/nomadik/reset.S
new file mode 100644
index 0000000..522a817
--- /dev/null
+++ b/cpu/arm926ejs/nomadik/reset.S
@@ -0,0 +1,27 @@
+#include <config.h>
+/*
+ * Processor reset for Nomadik
+ */
+
+ .align 5
+.globl reset_cpu
+reset_cpu:
+#if defined CONFIG_NOMADIK_8815
+ ldr r0, =NOMADIK_SRC_BASE
+ ldr r1, =0x1
+ str r1, [r0, #0x18]
+#else
+ ldr r1, rstctl1 /* get clkm1 reset ctl */
+ mov r3, #0x0
+ strh r3, [r1] /* clear it */
+ mov r3, #0x8
+ strh r3, [r1] /* force dsp+arm reset */
+#endif
+_loop_forever:
+ b _loop_forever
+
+
+rstctl1:
+ .word 0xfffece10
+
+
diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c
new file mode 100644
index 0000000..3598fb8
--- /dev/null
+++ b/cpu/arm926ejs/nomadik/timer.c
@@ -0,0 +1,180 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger(a)sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu(a)sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj(a)denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin(a)arm.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 <common.h>
+#include <asm/io.h>
+#include <arm926ejs.h>
+
+
+extern void reset_cpu(ulong addr);
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the 32 bit timer */
+#define READ_TIMER readl(CONFIG_SYS_TIMERBASE+20)
+
+static ulong timestamp;
+static ulong lastdec;
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+ /* Load timer with initial value */
+ writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + 16);
+ /* Set timer to be enabled, free-running, no interrupts, 256 divider,
+ 32-bit, wrap-mode */
+ writel(0x8a, CONFIG_SYS_TIMERBASE + 24);
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ if (usec >= 1000) {
+ /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize */
+ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" */
+ tmo /= 1000; /* finish normalize. */
+ } else {
+ /* small number, don't kill it prior to HZ multiply */
+ tmo = usec * CONFIG_SYS_HZ;
+ tmo /= (1000*1000);
+ }
+
+ tmp = get_timer(0); /* get current timestamp */
+ if ((tmo + tmp + 1) < tmp) /* will roll time stamp? */
+ reset_timer_masked(); /* reset to 0, set lastdec value */
+ else
+ tmo += tmp;
+
+ while (get_timer_masked() < tmo)
+ /* nothing */ ;
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastdec = READ_TIMER; /* capure current decrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER; /* current tick value */
+
+ if (lastdec >= now) { /* normal mode (non roll) */
+ /* move stamp fordward */
+ timestamp += lastdec - now;
+ } else {
+ /*
+ * An overflow is expected.
+ * nts = ts + ld + (TLV - now)
+ * ts=old stamp, ld=time that passed before passing through -1
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll
+ */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked(unsigned long usec)
+{
+ ulong tmo;
+
+ if (usec >= 1000) {
+ /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize */
+ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" */
+ tmo /= 1000; /* finish normalize. */
+ } else {
+ /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CONFIG_SYS_HZ;
+ tmo /= (1000*1000);
+ }
+
+ reset_timer_masked();
+ /* set "advancing" timestamp to 0, set lastdec vaule */
+
+ while (get_timer_masked() < tmo)
+ /* nothing */ ;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ ulong tbclk;
+
+ tbclk = CONFIG_SYS_HZ;
+ return tbclk;
+}
diff --git a/doc/README.nmdk8815 b/doc/README.nmdk8815
new file mode 100644
index 0000000..453cfae
--- /dev/null
+++ b/doc/README.nmdk8815
@@ -0,0 +1,22 @@
+
+The Nomadik 8815 CPU has a "secure" boot mode where no external access
+(not even JTAG) is allowed. The "remap" bits in the evaluation board
+are configured in order to boot from the internal ROM memory (in
+secure mode).
+
+The boot process as defined by the manufacturer executes external code
+(loaded from NAND or OneNAND) that that disables such "security" in
+order to run u-boot and later the kernel without constraints. Such
+code is a proprietary initial boot loader, called "X-Loader" (in case
+anyone wonders, it has no relations with other loaders with the same
+name and there is no GPL code inside the ST X-Loader).
+
+SDRAM configuration, PLL setup and initial loading from NAND is
+implemented in the X-Loader, so U-Boot is already running in SDRAM
+when control is handed over to it.
+
+
+On www.st.com/nomadik and on www.stnwireless.com there are documents,
+summary data and white papers on Nomadik. The full datasheet for
+STn8815 is not currently available on line but under specific request
+to the local ST sales offices.
diff --git a/include/configs/nmdk8815.h b/include/configs/nmdk8815.h
new file mode 100644
index 0000000..a6badae
--- /dev/null
+++ b/include/configs/nmdk8815.h
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright 2005
+ * STMicroelectronics.
+ * Configuration settings for the STn8815 nomadik board.
+ *
+ * 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_ARM926EJS
+#define CONFIG_NOMADIK
+#define CONFIG_NOMADIK_8815
+#define CONFIG_NOMADIK_NDK15
+#define CONFIG_NOMADIK_NHK15
+
+#define CONFIG_SKIP_LOWLEVEL_INIT /* we have already been loaded to RAM */
+
+/* commands */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+/* At this point there is no flash driver, so remove some commands */
+#undef CONFIG_CMD_ENV
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+
+/* user interface */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT "Nomadik> "
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
+ + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_LOAD_ADDR 0x800000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+/* boot config */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_BOOTDELAY 1
+#define CONFIG_BOOTARGS "root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
+#define CONFIG_BOOTCOMMAND "fsload 0x100000 kernel.uimg;" \
+ " fsload 0x800000 initrd.gz.uimg;" \
+ " bootm 0x100000 0x800000"
+
+/* memory-related information */
+#define CONFIG_NR_DRAM_BANKS 2
+#define PHYS_SDRAM_1 0x00000000 /* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */
+#define PHYS_SDRAM_2 0x08000000 /* SDR-SDRAM BANK #2*/
+#define PHYS_SDRAM_2_SIZE 0x04000000 /* 64 MB */
+
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#ifdef CONFIG_USE_IRQ
+# define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+# define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+#define CONFIG_SYS_MEMTEST_START 0x00000000
+#define CONFIG_SYS_MEMTEST_END 0x0FFFFFFF
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 256*1024)
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */
+
+#define CONFIG_MISC_INIT_R /* call misc_init_r during start up */
+
+/* timing informazion */
+#define CONFIG_SYS_HZ (2400000 / 256) /* Timer0: 2.4Mhz + divider */
+#define CONFIG_SYS_TIMERBASE 0x101E2000
+#undef CONFIG_SYS_CLKS_IN_HZ
+
+/* serial port (PL011) configuration */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#define CFG_SERIAL0 0x101FD000
+#define CFG_SERIAL1 0x101FB000
+
+#define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 }
+#define CONFIG_PL011_CLOCK 48000000
+
+/* Ethernet */
+#define PCI_MEMORY_VADDR 0xe8000000
+#define PCI_IO_VADDR 0xee000000
+#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
+#define __mem_isa(a) ((a) + PCI_MEMORY_VADDR)
+
+#define CONFIG_DRIVER_SMC91111 /* Using SMC91c111*/
+#define CONFIG_SMC91111_BASE 0x34000300
+#undef CONFIG_SMC91111_EXT_PHY /* Internal PHY */
+#define CONFIG_SMC_USE_32_BIT
+#define CONFIG_BOOTFILE "uImage"
+
+/* flash memory and filesystem information */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MTD_ONENAND_VERIFY_WRITE
+#define CONFIG_SYS_ONENAND_BASE 0x30000000
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE 0x40000000
+
+#define CONFIG_SYS_NO_FLASH
+
+#ifdef CONFIG_BOOT_ONENAND
+
+# undef CONFIG_CMD_NAND /* Temporary: nand and onenand can't coexist */
+ /* Partition Size Start
+ * XloaderTOC + X-Loader 256KB 0x00000000
+ * Memory init function 256KB 0x00040000
+ * U-Boot 2MB 0x00080000
+ * Sysimage (kernel + ramdisk) 4MB 0x00280000
+ * JFFS2 Root filesystem 22MB 0x00680000
+ * JFFS2 User Data 227.5MB 0x01C80000
+ */
+# define CONFIG_JFFS2_PART_SIZE 0x400000
+# define CONFIG_JFFS2_PART_OFFSET 0x280000
+
+# define CONFIG_ENV_IS_IN_ONENAND
+# define CONFIG_ENV_SIZE (256*1024)
+# define CONFIG_ENV_ADDR 0x30300000
+
+#else /* ! CONFIG_BOOT_ONENAND */
+
+# undef CONFIG_CMD_ONENAND /* Temporary: nand and onenand can't coexist */
+
+# define CONFIG_JFFS2_DEV "nand0"
+# define CONFIG_JFFS2_NAND 1 /* For the jffs2 support*/
+# define CONFIG_JFFS2_PART_SIZE 0x00300000
+# define CONFIG_JFFS2_PART_OFFSET 0x00280000
+
+# define CONFIG_ENV_IS_IN_NAND
+# define CONFIG_ENV_SIZE 0x20000 /*128 Kb*/
+# define CONFIG_ENV_OFFSET (0x8000000 - 0x20000)
+
+#endif /* CONFIG_BOOT_ONENAND */
+
+/* Temporarily, until we have no driver, env is not in nand */
+#undef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_IS_NOWHERE
+
+/* this is needed to make hello_world.c and other stuff happy */
+#define CONFIG_SYS_MAX_FLASH_SECT 512
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+
+/* base addresses of our peripherals */
+#define NOMADIK_SRC_BASE 0x101E0000 /* System and Reset Cnt */
+#define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */
+#define NOMADIK_MPMC_BASE 0x10110000 /* SDRAM Controller */
+#define NOMADIK_FSMC_BASE 0x10100000 /* FSMC Controller */
+#define NOMADIK_1NAND_BASE 0x30000000
+#define NOMADIK_GPIO0_BASE 0x101E4000
+#define NOMADIK_GPIO1_BASE 0x101E5000
+#define NOMADIK_GPIO2_BASE 0x101E6000
+#define NOMADIK_GPIO3_BASE 0x101E7000
+#define NOMADIK_CPLD_BASE 0x36000000
+#define NOMADIK_UART0_BASE 0x101FD000
+#define NOMADIK_UART1_BASE 0x101FB000
+#define NOMADIK_UART2_BASE 0x101F2000
+
+#define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */
+#define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */
+
+#define NOMADIK_RTC_BASE 0x101E8000
+#define NOMADIK_ETH0_BASE 0x36800300
+#define NOMADIK_CPLD_UART_BASE 0x36480000
+
+#endif /* __CONFIG_H */
--
1.6.0.2
3
3
Added support for a second memory bank to DDR autodetection for 440
platforms.
Made hardcoded values configurable.
Signed-off-by: Dirk Eibach <eibach(a)gdsys.de>
---
cpu/ppc4xx/sdram.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
index 6d5f8d6..c785414 100644
--- a/cpu/ppc4xx/sdram.c
+++ b/cpu/ppc4xx/sdram.c
@@ -259,6 +259,7 @@ phys_size_t initdram(int board_type)
#ifndef CONFIG_SYS_SDRAM_TABLE
sdram_conf_t mb0cf[] = {
{(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
+ {(128 << 20), 13, 0x000A4001}, /* 128MB mode 3, 13x10(4) */
{(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
};
#else
@@ -269,6 +270,18 @@ sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
#define CONFIG_SYS_SDRAM0_TR0 0x41094012
#endif
+#ifndef CONFIG_SYS_SDRAM0_WDDCTR
+#define CONFIG_SYS_SDRAM0_WDDCTR 0x00000000 /* wrcp=0 dcd=0 */
+#endif
+
+#ifndef CONFIG_SYS_SDRAM0_RTR
+#define CONFIG_SYS_SDRAM0_RTR 0x04100000 /* 7.8µs @ 133MHz PLB */
+#endif
+
+#ifndef CONFIG_SYS_SDRAM0_CFG0
+#define CONFIG_SYS_SDRAM0_CFG0 0x82000000 /* DCEN=1, PMUD=0, 64-bit */
+#endif
+
#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
#define NUM_TRIES 64
@@ -378,7 +391,7 @@ phys_size_t initdram(int board_type)
mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
- mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
+ mtsdram(mem_wddctr, CONFIG_SYS_SDRAM0_WDDCTR);
mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
/*
@@ -387,31 +400,63 @@ phys_size_t initdram(int board_type)
mtsdram(mem_b0cr, mb0cf[i].reg);
mtsdram(mem_tr0, CONFIG_SYS_SDRAM0_TR0);
mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
- mtsdram(mem_rtr, 0x04100000); /* Interval 7.8µs @ 133MHz PLB */
+ mtsdram(mem_rtr, CONFIG_SYS_SDRAM0_RTR);
mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM*/
udelay(400); /* Delay 200 usecs (min) */
/*
* Enable the controller, then wait for DCEN to complete
*/
- mtsdram(mem_cfg0, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */
+ mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
udelay(10000);
if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
+ phys_size_t size = mb0cf[i].size;
/*
* Optimize TR1 to current hardware environment
*/
sdram_tr1_set(0x00000000, &tr1_bank1);
mtsdram(mem_tr1, (tr1_bank1 | 0x80800800));
+
+ /*
+ * OK, size detected. Enable second bank if
+ * defined (assumes same type as bank 0)
+ */
+#ifdef CONFIG_SDRAM_BANK1
+ mtsdram(mem_cfg0, 0);
+ mtsdram(mem_b1cr, mb0cf[i].size | mb0cf[i].reg);
+ mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
+ udelay(10000);
+
+ /*
+ * Check if 2nd bank is really available.
+ * If the size not equal to the size of the first
+ * bank, then disable the 2nd bank completely.
+ */
+ if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
+ mb0cf[i].size) {
+ mtsdram(mem_cfg0, 0);
+ mtsdram(mem_b1cr, 0);
+ mtsdram(mem_cfg0, CONFIG_SYS_SDRAM0_CFG0);
+ udelay(10000);
+ } else {
+ /*
+ * We have two identical banks, so the size
+ * is twice the bank size
+ */
+ size = 2 * size;
+ }
+#endif
+
#ifdef CONFIG_SDRAM_ECC
- ecc_init(0, mb0cf[i].size);
+ ecc_init(0, size);
#endif
/*
* OK, size detected -> all done
*/
- return mb0cf[i].size;
+ return size;
}
}
--
1.5.6.5
3
2
The following changes since commit 4d0b54685c5c656023b826089ef8cc0ea1c5cd9e:
Haavard Skinnemoen (1):
Merge branch 'fixes'
are available in the git repository at:
git://www.denx.de/git/u-boot-blackfin.git master
Brad Bozarth (1):
spi flash: fix crash due to spi flash miscommunication
Bryan Wu (1):
fat: fix unaligned errors
Mike Frysinger (2):
easylogo: add optional gzip support
Blackfin: use common strmhz() in system output
common/cmd_bdinfo.c | 10 +++--
drivers/mtd/spi/atmel.c | 3 +-
drivers/mtd/spi/stmicro.c | 3 +-
fs/fat/fat.c | 8 ++-
lib_blackfin/board.c | 6 ++-
tools/easylogo/easylogo.c | 98 ++++++++++++++++++++++++++++++++++++++++++---
6 files changed, 111 insertions(+), 17 deletions(-)
2
6

24 Jan '09
--- On Fri, 1/23/09, Ron Madrid <ron_madrid(a)sbcglobal.net> wrote:
> From: Ron Madrid <ron_madrid(a)sbcglobal.net>
> Subject: Re: [U-Boot] [PATCH v5] mpc83xx: New board support for SIMPC8313
> To: "Kim Phillips" <kim.phillips(a)freescale.com>
> Cc: u-boot(a)lists.denx.de
> Date: Friday, January 23, 2009, 2:29 PM
> --- On Fri, 1/23/09, Kim Phillips
> <kim.phillips(a)freescale.com> wrote:
> > > >
> > > > > +ENTRY(_start)
> > > > > +ASSERT(_end <= 0xfff01000,
> "NAND
> > bootstrap
> > > > too big");
> > > >
> > > > Ron, the above gets asserted when building
> for
> > large page
> > > > nand with a
> > > > gcc 4.1.2 based toolchain:
> > >
> > > Please forgive my ignorance, but how can I go
> about
> > fixing this? How do I
> > > determine my toolchain and how can I use the same
> one
> > you are referring to?
> > > Are there any documents that can point me in the
> right
> > direction?
> >
> > I'm just using what Fedora brought to me on my G5
> box
> > (native
> > compiler). I still use it because it's close to
> what
> > the ELDK version
> > is (or used to be - I can't immediately tell which
> > version the ELDK is
> > using right now). Where/when did you get your
> toolchain?
>
> I am using the one that came with FC4. I'm guessing
> that I should go ahead
> an update my gcc. I'm in the middle of doing that.
> I'll get back to you
> if I discover anything and then of course I'll
> resubmit.
I upgraded my gcc and did not see any difference in the builds. I'm not sure where to go from here.
Ron
3
3
WD,
u-boot-mpc83xx added support for two new boards - the keymile1 and the
SIMPC8313 - plus PCI-E support and mostly nand-related fixes. Please
pull:
The following changes since commit 6dadc9195ad642cc662632f4d92f92d3d71e8bf2:
Mike Frysinger (1):
Blackfin: use common strmhz() in system output
are available in the git repository at:
git://git.denx.de/u-boot-mpc83xx.git master
Anton Vorontsov (3):
mpc83xx: Add support for MPC83xx PCI-E controllers
mpc83xx: Add PCI-E support for MPC8315ERDB boards
mpc83xx: Add PCI-E support for MPC837XEMDS boards
Heiko Schocher (3):
powerpc: 83xx: add support for the kmeter1 board
powerpc: keymile: Add a check for the PIGGY debug board
powerpc, keymile boards: extract identical config options
Ira Snyder (2):
83xx: PCI agent mode fixes for multi-board systems
MPC8349EMDS: do not setup unused PCI clock outputs in PCI agent mode
Ron Madrid (2):
mpc83xx: Size optimization of start.S
mpc83xx: New board support for SIMPC8313
Scott Wood (1):
83xx: Use the proper sequence for updating IMMR.
MAINTAINERS | 5 +
MAKEALL | 2 +
Makefile | 18 +
board/freescale/mpc8315erdb/mpc8315erdb.c | 52 +++
board/freescale/mpc8349emds/pci.c | 7 -
board/freescale/mpc837xemds/mpc837xemds.c | 6 +-
board/freescale/mpc837xemds/pci.c | 89 +++++-
board/freescale/mpc837xemds/pci.h | 6 +
board/keymile/common/common.c | 23 +-
board/keymile/common/common.h | 20 +
board/keymile/kmeter1/Makefile | 53 +++
board/keymile/kmeter1/config.mk | 24 ++
board/keymile/kmeter1/kmeter1.c | 158 ++++++++
board/keymile/mgcoge/mgcoge.c | 10 +-
board/keymile/mgsuvd/mgsuvd.c | 8 +-
board/sheldon/simpc8313/Makefile | 50 +++
board/sheldon/simpc8313/config.mk | 13 +
board/sheldon/simpc8313/sdram.c | 193 ++++++++++
board/sheldon/simpc8313/simpc8313.c | 134 +++++++
cpu/mpc83xx/Makefile | 1 +
cpu/mpc83xx/pci.c | 5 +
cpu/mpc83xx/pcie.c | 314 +++++++++++++++
cpu/mpc83xx/speed.c | 4 +-
cpu/mpc83xx/start.S | 95 +++--
doc/README.kmeter1 | 91 +++++
doc/README.simpc8313 | 80 ++++
include/asm-ppc/global_data.h | 2 +-
include/asm-ppc/immap_83xx.h | 119 ++++++-
include/configs/MPC8315ERDB.h | 21 +
include/configs/MPC837XEMDS.h | 21 +
include/configs/SIMPC8313.h | 544 +++++++++++++++++++++++++++
include/configs/keymile-common.h | 113 ++++++
include/configs/kmeter1.h | 457 ++++++++++++++++++++++
include/configs/mgcoge.h | 51 +---
include/configs/mgsuvd.h | 72 +----
include/mpc83xx.h | 68 +++-
include/pci.h | 4 +
nand_spl/board/sheldon/simpc8313/Makefile | 100 +++++
nand_spl/board/sheldon/simpc8313/u-boot.lds | 52 +++
39 files changed, 2883 insertions(+), 202 deletions(-)
create mode 100644 board/freescale/mpc837xemds/pci.h
create mode 100644 board/keymile/common/common.h
create mode 100644 board/keymile/kmeter1/Makefile
create mode 100644 board/keymile/kmeter1/config.mk
create mode 100644 board/keymile/kmeter1/kmeter1.c
create mode 100644 board/sheldon/simpc8313/Makefile
create mode 100644 board/sheldon/simpc8313/config.mk
create mode 100644 board/sheldon/simpc8313/sdram.c
create mode 100644 board/sheldon/simpc8313/simpc8313.c
create mode 100644 cpu/mpc83xx/pcie.c
create mode 100644 doc/README.kmeter1
create mode 100644 doc/README.simpc8313
create mode 100644 include/configs/SIMPC8313.h
create mode 100644 include/configs/keymile-common.h
create mode 100644 include/configs/kmeter1.h
create mode 100644 nand_spl/board/sheldon/simpc8313/Makefile
create mode 100644 nand_spl/board/sheldon/simpc8313/u-boot.lds
Thanks,
Kim
2
1
diff -purN u-boot.orig/drivers/i2c/fsl_uni_i2c.c u-boot/drivers/i2c/fsl_uni_i2c.c
--- u-boot.orig/drivers/i2c/fsl_uni_i2c.c 1969-12-31 16:00:00.000000000 -0800
+++ u-boot/drivers/i2c/fsl_uni_i2c.c 2009-01-23 16:01:48.000000000 -0800
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
+ * Copyright 2006 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_FSL_UNI_I2C
+
+#include <command.h>
+#include <i2c.h> /* Functional interface */
+
+#include <asm/io.h>
+#include <asm/fsl_i2c.h> /* HW definitions */
+
+#define I2C_TIMEOUT (CONFIG_SYS_HZ / 4)
+
+#define I2C_READ_BIT 1
+#define I2C_WRITE_BIT 0
+
+#define FSL_NAME(arg) "fsl_i2c@" MK_NAME(arg)
+#define MK_NAME(arg) #arg
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct fsl_i2c *i2c_dev[2] = {
+ (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
+#ifdef CONFIG_SYS_FSL_I2C2_OFFSET
+ (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET)
+#endif
+};
+
+/* I2C speed map for a DFSR value of 1 */
+
+/*
+ * Map I2C frequency dividers to FDR and DFSR values
+ *
+ * This structure is used to define the elements of a table that maps I2C
+ * frequency divider (I2C clock rate divided by I2C bus speed) to a value to be
+ * programmed into the Frequency Divider Ratio (FDR) and Digital Filter
+ * Sampling Rate (DFSR) registers.
+ *
+ * The actual table should be defined in the board file, and it must be called
+ * fsl_i2c_speed_map[].
+ *
+ * The last entry of the table must have a value of {-1, X}, where X is same
+ * FDR/DFSR values as the second-to-last entry. This guarantees that any
+ * search through the array will always find a match.
+ *
+ * The values of the divider must be in increasing numerical order, i.e.
+ * fsl_i2c_speed_map[x+1].divider > fsl_i2c_speed_map[x].divider.
+ *
+ * For this table, the values are based on a value of 1 for the DFSR
+ * register. See the application note AN2919 "Determining the I2C Frequency
+ * Divider Ratio for SCL"
+ *
+ * ColdFire I2C frequency dividers for FDR values are different from
+ * PowerPC. The protocol to use the I2C module is still the same.
+ * A different table is defined and are based on MCF5xxx user manual.
+ *
+ */
+static const struct {
+ unsigned short divider;
+#ifdef __PPC__
+ u8 dfsr;
+#endif
+ u8 fdr;
+} fsl_i2c_speed_map[] = {
+#ifdef __PPC__
+ {160, 1, 32}, {192, 1, 33}, {224, 1, 34}, {256, 1, 35},
+ {288, 1, 0}, {320, 1, 1}, {352, 6, 1}, {384, 1, 2}, {416, 6, 2},
+ {448, 1, 38}, {480, 1, 3}, {512, 1, 39}, {544, 11, 3}, {576, 1, 4},
+ {608, 22, 3}, {640, 1, 5}, {672, 32, 3}, {704, 11, 5}, {736, 43, 3},
+ {768, 1, 6}, {800, 54, 3}, {832, 11, 6}, {896, 1, 42}, {960, 1, 7},
+ {1024, 1, 43}, {1088, 22, 7}, {1152, 1, 8}, {1216, 43, 7}, {1280, 1, 9},
+ {1408, 22, 9}, {1536, 1, 10}, {1664, 22, 10}, {1792, 1, 46},
+ {1920, 1, 11}, {2048, 1, 47}, {2176, 43, 11}, {2304, 1, 12},
+ {2560, 1, 13}, {2816, 43, 13}, {3072, 1, 14}, {3328, 43, 14},
+ {3584, 1, 50}, {3840, 1, 15}, {4096, 1, 51}, {4608, 1, 16},
+ {5120, 1, 17}, {6144, 1, 18}, {7168, 1, 54}, {7680, 1, 19},
+ {8192, 1, 55}, {9216, 1, 20}, {10240, 1, 21}, {12288, 1, 22},
+ {14336, 1, 58}, {15360, 1, 23}, {16384, 1, 59}, {18432, 1, 24},
+ {20480, 1, 25}, {24576, 1, 26}, {28672, 1, 62}, {30720, 1, 27},
+ {32768, 1, 63}, {36864, 1, 28}, {40960, 1, 29}, {49152, 1, 30},
+ {61440, 1, 31}, {-1, 1, 31}
+#elif defined(__M68K__)
+ {20, 32}, {22, 33}, {24, 34}, {26, 35},
+ {28, 0}, {28, 36}, {30, 1}, {32, 37},
+ {34, 2}, {36, 38}, {40, 3}, {40, 39},
+ {44, 4}, {48, 5}, {48, 40}, {56, 6},
+ {56, 41}, {64, 42}, {68, 7}, {72, 43},
+ {80, 8}, {80, 44}, {88, 9}, {96, 41},
+ {104, 10}, {112, 42}, {128, 11}, {128, 43},
+ {144, 12}, {160, 13}, {160, 48}, {192, 14},
+ {192, 49}, {224, 50}, {240, 15}, {256, 51},
+ {288, 16}, {320, 17}, {320, 52}, {384, 18},
+ {384, 53}, {448, 54}, {480, 19}, {512, 55},
+ {576, 20}, {640, 21}, {640, 56}, {768, 22},
+ {768, 57}, {960, 23}, {896, 58}, {1024, 59},
+ {1152, 24}, {1280, 25}, {1280, 60}, {1536, 26},
+ {1536, 61}, {1792, 62}, {1920, 27}, {2048, 63},
+ {2304, 28}, {2560, 29}, {3072, 30}, {3840, 31},
+ {-1, 31}
+#endif
+};
+
+i2c_adap_t fsl_i2c_adap[];
+
+/**
+ * Set the I2C bus speed for a given I2C device
+ *
+ * @param dev: the I2C device
+ * @i2c_clk: I2C bus clock frequency
+ * @speed: the desired speed of the bus
+ *
+ * The I2C device must be stopped before calling this function.
+ *
+ * The return value is the actual bus speed that is set.
+ */
+static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
+ unsigned int i2c_clk, unsigned int speed)
+{
+ unsigned short divider = min(i2c_clk / speed, (unsigned short) -1);
+ unsigned int i;
+
+ /*
+ * We want to choose an FDR/DFSR that generates an I2C bus speed that
+ * is equal to or lower than the requested speed. That means that we
+ * want the first divider that is equal to or greater than the
+ * calculated divider.
+ */
+
+ for (i = 0; i < ARRAY_SIZE(fsl_i2c_speed_map); i++)
+ if (fsl_i2c_speed_map[i].divider >= divider) {
+ u8 fdr;
+#ifdef __PPC__
+ u8 dfsr;
+ dfsr = fsl_i2c_speed_map[i].dfsr;
+#endif
+ fdr = fsl_i2c_speed_map[i].fdr;
+ speed = i2c_clk / fsl_i2c_speed_map[i].divider;
+ writeb(fdr, &dev->fdr); /* set bus speed */
+#ifdef __PPC__
+ writeb(dfsr, &dev->dfsrr); /* set default filter */
+#endif
+ break;
+ }
+
+ return speed;
+}
+
+
+static void __i2c_init(int adap_no, int speed, int slaveadd)
+{
+ unsigned int temp;
+
+ writeb(0, &i2c_dev[adap_no]->cr); /* stop I2C controller */
+ udelay(5); /* let it shutdown in peace */
+ temp = set_i2c_bus_speed(i2c_dev[adap_no], gd->i2c1_clk, speed);
+ if (gd->flags & GD_FLG_RELOC) {
+ fsl_i2c_adap[adap_no].speed = temp;
+ fsl_i2c_adap[adap_no].slaveaddr = slaveadd;
+ }
+ writeb(slaveadd << 1, &i2c_dev[adap_no]->adr); /* write slave address */
+ writeb(0x0, &i2c_dev[adap_no]->sr); /* clear status register */
+ writeb(I2C_CR_MEN, &i2c_dev[adap_no]->cr); /* start I2C controller */
+}
+
+
+static __inline__ int i2c_wait4bus(int adap_no)
+{
+ unsigned long long timeval = get_ticks();
+
+ while (readb(&i2c_dev[adap_no]->sr) & I2C_SR_MBB) {
+ if ((get_ticks() - timeval) > usec2ticks(I2C_TIMEOUT))
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static __inline__ int i2c_wait(int adap_no, int write)
+{
+ u32 csr;
+ unsigned long long timeval = get_ticks();
+
+ do {
+ csr = readb(&i2c_dev[adap_no]->sr);
+ if (!(csr & I2C_SR_MIF))
+ continue;
+
+ writeb(0x0, &i2c_dev[adap_no]->sr);
+
+ if (csr & I2C_SR_MAL) {
+ debug("i2c_wait: MAL\n");
+ return -1;
+ }
+
+ if (!(csr & I2C_SR_MCF)) {
+ debug("i2c_wait: unfinished\n");
+ return -1;
+ }
+
+ if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
+ debug("i2c_wait: No RXACK\n");
+ return -1;
+ }
+
+ return 0;
+ } while ((get_ticks() - timeval) < usec2ticks(I2C_TIMEOUT));
+
+ debug("i2c_wait: timed out\n");
+ return -1;
+}
+
+
+static __inline__ int i2c_write_addr (int adap_no, u8 dev, u8 dir, int rsta)
+{
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
+ | (rsta ? I2C_CR_RSTA : 0),
+ &i2c_dev[adap_no]->cr);
+
+ writeb((dev << 1) | dir, &i2c_dev[adap_no]->dr);
+
+ if (i2c_wait(adap_no, I2C_WRITE_BIT) < 0)
+ return 0;
+
+ return 1;
+}
+
+
+static __inline__ int i2c_write_data(int adap_no, u8 *data, int length)
+{
+ int i;
+
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
+ &i2c_dev[adap_no]->cr);
+
+ for (i = 0; i < length; i++) {
+ writeb(data[i], &i2c_dev[adap_no]->dr);
+
+ if (i2c_wait(adap_no, I2C_WRITE_BIT) < 0)
+ break;
+ }
+
+ return i;
+}
+
+
+static __inline__ int i2c_read_data(int adap_no, u8 *data, int length)
+{
+ int i;
+
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
+ &i2c_dev[adap_no]->cr);
+
+ /* dummy read */
+ readb(&i2c_dev[adap_no]->dr);
+
+ for (i = 0; i < length; i++) {
+ if (i2c_wait(adap_no, I2C_READ_BIT) < 0)
+ break;
+
+ /* Generate ack on last next to last byte */
+ if (i == length - 2)
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
+ &i2c_dev[adap_no]->cr);
+
+ /* Generate stop on last byte */
+ if (i == length - 1)
+ writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[adap_no]->cr);
+
+ data[i] = readb(&i2c_dev[adap_no]->dr);
+ }
+
+ return i;
+}
+
+
+static int __i2c_read(int adap_no, u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ int i = -1; /* signal error */
+ u8 *a = (u8*)&addr;
+
+ if (i2c_wait4bus(adap_no) >= 0
+ && i2c_write_addr(adap_no, dev, I2C_WRITE_BIT, 0) != 0
+ && i2c_write_data(adap_no, &a[4 - alen], alen) == alen)
+ i = 0; /* No error so far */
+
+ if (length
+ && i2c_write_addr(adap_no, dev, I2C_READ_BIT, 1) != 0)
+ i = i2c_read_data(adap_no, data, length);
+
+ writeb(I2C_CR_MEN, &i2c_dev[adap_no]->cr);
+
+ if (i == length)
+ return 0;
+
+ return -1;
+}
+
+
+static int __i2c_write(int adap_no, u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ int i = -1; /* signal error */
+ u8 *a = (u8*)&addr;
+
+ if (i2c_wait4bus(adap_no) >= 0
+ && i2c_write_addr(adap_no, dev, I2C_WRITE_BIT, 0) != 0
+ && i2c_write_data(adap_no, &a[4 - alen], alen) == alen) {
+ i = i2c_write_data(adap_no, data, length);
+ }
+
+ writeb(I2C_CR_MEN, &i2c_dev[adap_no]->cr);
+
+ if (i == length)
+ return 0;
+
+ return -1;
+}
+
+
+static int __i2c_probe(int adap_no, uchar chip)
+{
+ /* For unknow reason the controller will ACK when
+ * probing for a slave with the same address, so skip
+ * it.
+ */
+ if (chip == (readb(&i2c_dev[adap_no]->adr) >> 1))
+ return -1;
+
+ return __i2c_read(adap_no, chip, 0, 0, NULL, 0);
+}
+
+
+static int __i2c_set_bus_speed(int adap_no, unsigned int speed)
+{
+ unsigned int i2c_clk = (adap_no == 1) ? gd->i2c2_clk : gd->i2c1_clk;
+
+ writeb(0, &i2c_dev[adap_no]->cr); /* stop controller */
+ fsl_i2c_adap[adap_no].speed =
+ set_i2c_bus_speed(i2c_dev[adap_no], i2c_clk, speed);
+ writeb(I2C_CR_MEN, &i2c_dev[adap_no]->cr); /* start controller */
+
+ return 0;
+}
+
+
+/* Wrappers for the first controller */
+static void fsl_i2c1_init(int speed, int slaveadd)
+{
+ __i2c_init(0, speed, slaveadd);
+}
+
+static int fsl_i2c1_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ return(__i2c_read(0, dev, addr, alen, data, length));
+}
+
+static int fsl_i2c1_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ return(__i2c_write(0, dev, addr, alen, data, length));
+}
+
+static int fsl_i2c1_probe(uchar chip)
+{
+ return(__i2c_probe(0, chip));
+}
+
+static unsigned int fsl_i2c1_set_bus_speed(unsigned int speed)
+{
+ return(__i2c_set_bus_speed(0, speed));
+}
+
+static unsigned int fsl_i2c1_get_bus_speed(void)
+{
+ return(fsl_i2c_adap[0].speed);
+}
+
+
+/* Second controller */
+#ifdef CONFIG_SYS_FSL_I2C2_OFFSET
+static void fsl_i2c2_init(int speed, int slaveadd)
+{
+ __i2c_init(1, speed, slaveadd);
+}
+
+static int fsl_i2c2_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ return(__i2c_read(1, dev, addr, alen, data, length));
+}
+
+static int fsl_i2c2_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ return(__i2c_write(1, dev, addr, alen, data, length));
+}
+
+static int fsl_i2c2_probe(uchar chip)
+{
+ return(__i2c_probe(1, chip));
+}
+
+static unsigned int fsl_i2c2_set_bus_speed(unsigned int speed)
+{
+ return(__i2c_set_bus_speed(1, speed));
+}
+
+static unsigned int fsl_i2c2_get_bus_speed(void)
+{
+ return(fsl_i2c_adap[1].speed);
+}
+#endif
+
+i2c_adap_t fsl_i2c_adap[2] = {
+ {
+ .init = fsl_i2c1_init,
+ .probe = fsl_i2c1_probe,
+ .read = fsl_i2c1_read,
+ .write = fsl_i2c1_write,
+ .set_bus_speed = fsl_i2c1_set_bus_speed,
+ .get_bus_speed = fsl_i2c1_get_bus_speed,
+ .speed = CONFIG_SYS_FSL_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_FSL_I2C_SLAVE,
+ .init_done = 0,
+ .name = FSL_NAME(CONFIG_SYS_FSL_I2C_OFFSET)
+ },
+#ifdef CONFIG_SYS_FSL_I2C2_OFFSET
+ {
+ .init = fsl_i2c2_init,
+ .probe = fsl_i2c2_probe,
+ .read = fsl_i2c2_read,
+ .write = fsl_i2c2_write,
+ .set_bus_speed = fsl_i2c2_set_bus_speed,
+ .get_bus_speed = fsl_i2c2_get_bus_speed,
+ .speed = CONFIG_SYS_FSL_I2C2_SPEED,
+ .slaveaddr = CONFIG_SYS_FSL_I2C2_SLAVE,
+ .init_done = 0,
+ .name = FSL_NAME(CONFIG_SYS_FSL_I2C2_OFFSET)
+ }
+#endif
+};
+
+#endif /* CONFIG_FSL_UNI_I2C */
diff -purN u-boot.orig/drivers/i2c/sm502_i2c.c u-boot/drivers/i2c/sm502_i2c.c
--- u-boot.orig/drivers/i2c/sm502_i2c.c 1969-12-31 16:00:00.000000000 -0800
+++ u-boot/drivers/i2c/sm502_i2c.c 2009-01-23 16:01:48.000000000 -0800
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Driver for Silicon Motion SM501/SM502 I2C interface.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_SM502_I2C
+
+#include <command.h>
+#include <i2c.h>
+
+#include <sm501-regs.h>
+#include <asm/io.h>
+
+/* I2C registers field definitions */
+/* --------------------------------*/
+/* I2C_CONTROL (R/W) */
+#define SM501_I2C_ENABLE (1<<0)
+#define SM501_I2C_SPEED (1<<1)
+#define SM501_I2C_START (1<<2)
+#define SM501_I2C_IRQ_ENA (1<<4)
+#define SM501_I2C_IRQ_ACK (1<<5)
+#define SM501_I2C_RPT_START_ENA (1<<6)
+/* I2C_STATUS (R/O) */
+#define SM501_I2C_BUS_BUSY (1<<0)
+#define SM501_I2C_NACK (1<<1)
+#define SM501_I2C_BUS_ERROR (1<<2)
+#define SM501_I2C_XFER_DONE (1<<3)
+/* I2C_RESET (W/O) */
+#define SM501_I2C_CLEAR (1<<2)
+
+#define SM501_I2C_MAX_COUNT 16
+
+#define SM501_I2C_READ 1
+#define SM501_I2C_WRITE 0
+
+#define SM501_I2C_TIMEOUT (1<<7)
+
+#define SM501_CHECK_NACK() \
+ do {\
+ if (tmp & (SM501_I2C_NACK | SM501_I2C_BUS_ERROR)) {\
+ tmp = read_i2c_reg(SM501_I2C_CONTROL) & SM501_I2C_SPEED;\
+ write_i2c_reg(SM501_I2C_CONTROL, tmp);\
+ return(1);\
+ }\
+ } while (0)
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+i2c_adap_t sm501_i2c_adap;
+
+static __inline__ u_int8_t read_i2c_reg(unsigned long offset)
+{
+ return(readb(sm501_iomem_base + SM501_I2C + offset));
+}
+
+static __inline__ void write_i2c_reg(unsigned long offset, u_int8_t data)
+{
+ writeb(data, sm501_iomem_base + SM501_I2C + offset);
+ __asm__("sync;isync;msync");
+#ifndef CONFIG_SYS_SM501_BASEADDR
+ /* Dummy read to push it through PCI */
+ readb(sm501_iomem_base + SM501_I2C + offset);
+#endif
+}
+
+static int poll_i2c_status(u_int8_t mask, int timeout)
+{
+ u_int8_t stat;
+ int i;
+
+ i = 0;
+
+ do {
+ stat = read_i2c_reg(SM501_I2C_STATUS);
+ if (stat & mask) {
+ return(stat);
+ }
+ udelay(1000);
+
+ } while (i++ < timeout);
+
+ return(stat | SM501_I2C_TIMEOUT);
+}
+
+static int wait_for_bus(void)
+{
+ int timeout = 10;
+
+ while ((read_i2c_reg(SM501_I2C_STATUS) & SM501_I2C_BUS_BUSY) && timeout--) {
+ udelay (1000);
+ }
+
+ if (timeout <= 0) {
+ printf ("SM501_I2C timed out in wait_for_bb: I2C_STAT=%x\n",
+ read_i2c_reg(SM501_I2C_STATUS));
+ return(1);
+ }
+
+ return(0);
+}
+
+static void sm501_i2c_init(int speed, int slaveadd)
+{
+ unsigned long tmpl;
+
+ /* Set GPIO pins for hardware I2C */
+ tmpl = readl(sm501_iomem_base + SM501_GPIO + SM501_GPIO_DATA_HIGH);
+ tmpl |= 0x0000c000;
+ writel(tmpl, sm501_iomem_base + SM501_GPIO + SM501_GPIO_DATA_HIGH);
+ __asm__("sync;isync;msync");
+#ifndef CONFIG_SYS_SM501_BASEADDR
+ /* Dummy read to push is through PCI */
+ readl(sm501_iomem_base + SM501_GPIO + SM501_GPIO_DATA_HIGH);
+#endif
+
+ /* SM501/502 only allows 100 or 400 KHz speed (standard or fast) */
+ if (speed <= 100000)
+ write_i2c_reg(SM501_I2C_CONTROL, SM501_I2C_ENABLE);
+ else
+ write_i2c_reg(SM501_I2C_CONTROL, SM501_I2C_ENABLE | SM501_I2C_SPEED);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ sm501_i2c_adap.speed = speed <= 100000 ? 100000 : 400000;
+ sm501_i2c_adap.init_done = 1;
+ }
+}
+
+
+static int sm501_i2c_probe(u_int8_t chip)
+{
+ u_int8_t tmp;
+
+ /* Fail if I2C address is invalid */
+ if (chip > 0x7f) {return(1);}
+
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ write_i2c_reg(SM501_I2C_CONTROL, tmp & ~(SM501_I2C_START | SM501_I2C_ENABLE));
+ if (wait_for_bus()) {return(1);}
+
+ /* try to read one byte from current (or only) address */
+ write_i2c_reg(SM501_I2C_CONTROL, tmp | SM501_I2C_ENABLE);
+ write_i2c_reg(SM501_I2C_BYTE_COUNT, 0);
+ write_i2c_reg(SM501_I2C_SLAVE_ADDRESS, (chip << 1) | SM501_I2C_READ);
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ write_i2c_reg(SM501_I2C_CONTROL, tmp | SM501_I2C_START);
+ udelay (1000);
+
+ if (!(read_i2c_reg(SM501_I2C_STATUS) & (SM501_I2C_NACK | SM501_I2C_BUS_ERROR))) {
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ write_i2c_reg(SM501_I2C_CONTROL, tmp & ~(SM501_I2C_START | SM501_I2C_ENABLE));
+ if (wait_for_bus()) {return(1);}
+ return(0);
+ }
+
+ return(1);
+}
+
+
+static int sm501_i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+ u_int8_t tmp;
+ u_int8_t *ptr = buf;
+ int i, bytes_read = 0;
+
+ if ((alen < 0) || (alen > 2)) {
+ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+ return(1);
+ }
+
+ if (len < 0) {
+ printf("%s(): bogus length %x\n", __FUNCTION__, len);
+ return(1);
+ }
+
+ if (wait_for_bus()) {return(1);}
+
+ if (alen != 0) {
+ /* Start address phase */
+ if (alen == 2) {
+ /* MSB goes first... */
+ write_i2c_reg(SM501_I2C_DATA, (addr >> 8) & 0xff);
+ write_i2c_reg(SM501_I2C_DATA + 1, addr & 0xff);
+ } else {
+ write_i2c_reg(SM501_I2C_DATA, addr & 0xff);
+ }
+
+ /* Now write it out without STOP condition */
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ tmp |= SM501_I2C_ENABLE | SM501_I2C_START | SM501_I2C_RPT_START_ENA;
+ write_i2c_reg(SM501_I2C_SLAVE_ADDRESS, (chip << 1) | SM501_I2C_WRITE);
+ write_i2c_reg(SM501_I2C_BYTE_COUNT, (u_int8_t)(alen - 1));
+ write_i2c_reg(SM501_I2C_CONTROL, tmp);
+
+ tmp = poll_i2c_status(SM501_I2C_NACK | SM501_I2C_BUS_ERROR | SM501_I2C_XFER_DONE, 2);
+
+ SM501_CHECK_NACK();
+ }
+
+ /*
+ * Address phase is over, now read 'len' bytes.
+ * SM502 can read up to 16 bytes per transaction so
+ * we will be reading in 16-bytes batches if len > 16.
+ */
+ do {
+ i = (len - bytes_read) > 16 ? 16 : len - bytes_read;
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ tmp |= SM501_I2C_ENABLE | SM501_I2C_START;
+ write_i2c_reg(SM501_I2C_SLAVE_ADDRESS, (chip << 1) | SM501_I2C_READ);
+ write_i2c_reg(SM501_I2C_BYTE_COUNT, (u_int8_t)(i - 1));
+ write_i2c_reg(SM501_I2C_CONTROL, tmp);
+
+ tmp = poll_i2c_status(SM501_I2C_NACK | SM501_I2C_BUS_ERROR | SM501_I2C_XFER_DONE, 100);
+
+ SM501_CHECK_NACK();
+
+ bytes_read += i;
+
+ for (; i > 0; i--) {
+ *ptr++ = read_i2c_reg(SM501_I2C_DATA + 16 - i);
+ }
+
+ } while (len > bytes_read);
+
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ write_i2c_reg(SM501_I2C_CONTROL, tmp & ~(SM501_I2C_START | SM501_I2C_ENABLE));
+
+ return(0);
+}
+
+
+static int sm501_i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+ u_int8_t tmp;
+ u_int8_t *ptr = buf;
+ int i, bytes_written = 0;
+
+ if ((alen < 0) || (alen > 2)) {
+ printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+ return(1);
+ }
+
+ if (len < 0) {
+ printf("%s(): bogus length %x\n", __FUNCTION__, len);
+ return(1);
+ }
+
+ if (wait_for_bus()) {return(1);}
+
+ /*
+ * SM502 can write up to 16 bytes per transaction so we will be
+ * writing in 16-bytes batches if len > (16 - alen). Address is
+ * sent first, then data hence (16 - alen)...
+ */
+ do {
+ i = (len - bytes_written) > (16 - alen) ? 16 - alen : len - bytes_written;
+
+ /* Prepend address */
+ if (alen == 2) {
+ /* MSB goes first... */
+ write_i2c_reg(SM501_I2C_DATA, ((addr + bytes_written) >> 8) & 0xff);
+ write_i2c_reg(SM501_I2C_DATA + 1, (addr + bytes_written) & 0xff);
+ }
+
+ if (alen == 1) {
+ write_i2c_reg(SM501_I2C_DATA, (addr + bytes_written) & 0xff);
+ }
+
+
+ for (; i > 0; i--) {
+ write_i2c_reg(SM501_I2C_DATA + 16 + alen - i, *ptr++);
+ }
+
+ /* Push it down the bus */
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ tmp |= SM501_I2C_ENABLE | SM501_I2C_START;
+ write_i2c_reg(SM501_I2C_SLAVE_ADDRESS, (chip << 1) | SM501_I2C_WRITE);
+ write_i2c_reg(SM501_I2C_BYTE_COUNT, (u_int8_t)(i + alen - 1));
+ write_i2c_reg(SM501_I2C_CONTROL, tmp);
+
+ tmp = poll_i2c_status(SM501_I2C_NACK | SM501_I2C_BUS_ERROR | SM501_I2C_XFER_DONE, 100);
+
+ SM501_CHECK_NACK();
+
+ bytes_written += i;
+
+ } while (len > bytes_written);
+
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+ write_i2c_reg(SM501_I2C_CONTROL, tmp & ~(SM501_I2C_START | SM501_I2C_ENABLE));
+
+ return(0);
+}
+
+
+static unsigned int sm501_i2c_set_bus_speed(unsigned int speed)
+{
+ u_int8_t tmp;
+
+ tmp = read_i2c_reg(SM501_I2C_CONTROL);
+
+ /* SM501/502 only allows 100 or 400 KHz speed (standard or fast) */
+ if (speed <= 100000)
+ tmp &= ~SM501_I2C_SPEED;
+ else
+ tmp |= SM501_I2C_SPEED;
+
+ write_i2c_reg(SM501_I2C_CONTROL, tmp);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ sm501_i2c_adap.speed = speed <= 100000 ? 100000 : 400000;
+ }
+
+ return(speed <= 100000 ? 100000 : 400000);
+}
+
+
+static unsigned int sm501_i2c_get_bus_speed(void)
+{
+ return(sm501_i2c_adap.speed);
+}
+
+
+i2c_adap_t sm501_i2c_adap = {
+ .init = sm501_i2c_init,
+ .probe = sm501_i2c_probe,
+ .read = sm501_i2c_read,
+ .write = sm501_i2c_write,
+ .set_bus_speed = sm501_i2c_set_bus_speed,
+ .get_bus_speed = sm501_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SM501_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_SM501_I2C_SLAVE,
+ .init_done = 0,
+ .name = "sm501_i2c"
+};
+#endif /* CONFIG_SM502_I2C */
diff -purN u-boot.orig/include/sm501-regs.h u-boot/include/sm501-regs.h
--- u-boot.orig/include/sm501-regs.h 1969-12-31 16:00:00.000000000 -0800
+++ u-boot/include/sm501-regs.h 2009-01-23 16:01:48.000000000 -0800
@@ -0,0 +1,394 @@
+/* sm501-regs.h
+ *
+ * Copyright 2006 Simtec Electronics
+ *
+ * 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.
+ *
+ * Silicon Motion SM501 register definitions
+*/
+
+#ifndef CONFIG_SYS_SM501_BASEADDR
+/* SM501/502 on PCI bus, resides and initialized in $(BOARD).c */
+extern unsigned long sm501_iomem_base;
+#else
+/* SM501/502 on processor bus, preassigned address */
+#define sm501_iomem_base CONFIG_SYS_SM501_BASEADDR
+#endif
+
+/* System Configuration area */
+/* System config base */
+#define SM501_SYS_CONFIG (0x000000)
+
+/* config 1 */
+#define SM501_SYSTEM_CONTROL (0x000000)
+
+#define SM501_SYSCTRL_PANEL_TRISTATE (1<<0)
+#define SM501_SYSCTRL_MEM_TRISTATE (1<<1)
+#define SM501_SYSCTRL_CRT_TRISTATE (1<<2)
+
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3<<4)
+
+#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
+#define SM501_SYSCTRL_PCI_RETRY_DISABLE (1<<7)
+#define SM501_SYSCTRL_PCI_SUBSYS_LOCK (1<<11)
+#define SM501_SYSCTRL_PCI_BURST_READ_EN (1<<15)
+
+/* miscellaneous control */
+
+#define SM501_MISC_CONTROL (0x000004)
+
+#define SM501_MISC_BUS_SH (0x0)
+#define SM501_MISC_BUS_PCI (0x1)
+#define SM501_MISC_BUS_XSCALE (0x2)
+#define SM501_MISC_BUS_NEC (0x6)
+#define SM501_MISC_BUS_MASK (0x7)
+
+#define SM501_MISC_VR_62MB (1<<3)
+#define SM501_MISC_CDR_RESET (1<<7)
+#define SM501_MISC_USB_LB (1<<8)
+#define SM501_MISC_USB_SLAVE (1<<9)
+#define SM501_MISC_BL_1 (1<<10)
+#define SM501_MISC_MC (1<<11)
+#define SM501_MISC_DAC_POWER (1<<12)
+#define SM501_MISC_IRQ_INVERT (1<<16)
+#define SM501_MISC_SH (1<<17)
+
+#define SM501_MISC_HOLD_EMPTY (0<<18)
+#define SM501_MISC_HOLD_8 (1<<18)
+#define SM501_MISC_HOLD_16 (2<<18)
+#define SM501_MISC_HOLD_24 (3<<18)
+#define SM501_MISC_HOLD_32 (4<<18)
+#define SM501_MISC_HOLD_MASK (7<<18)
+
+#define SM501_MISC_FREQ_12 (1<<24)
+#define SM501_MISC_PNL_24BIT (1<<25)
+#define SM501_MISC_8051_LE (1<<26)
+
+
+
+#define SM501_GPIO31_0_CONTROL (0x000008)
+#define SM501_GPIO63_32_CONTROL (0x00000C)
+#define SM501_DRAM_CONTROL (0x000010)
+
+/* command list */
+#define SM501_ARBTRTN_CONTROL (0x000014)
+
+/* command list */
+#define SM501_COMMAND_LIST_STATUS (0x000024)
+
+/* interrupt debug */
+#define SM501_RAW_IRQ_STATUS (0x000028)
+#define SM501_RAW_IRQ_CLEAR (0x000028)
+#define SM501_IRQ_STATUS (0x00002C)
+#define SM501_IRQ_MASK (0x000030)
+#define SM501_DEBUG_CONTROL (0x000034)
+
+/* power management */
+#define SM501_POWERMODE_P2X_SRC (1<<29)
+#define SM501_POWERMODE_V2X_SRC (1<<20)
+#define SM501_POWERMODE_M_SRC (1<<12)
+#define SM501_POWERMODE_M1_SRC (1<<4)
+
+#define SM501_CURRENT_GATE (0x000038)
+#define SM501_CURRENT_CLOCK (0x00003C)
+#define SM501_POWER_MODE_0_GATE (0x000040)
+#define SM501_POWER_MODE_0_CLOCK (0x000044)
+#define SM501_POWER_MODE_1_GATE (0x000048)
+#define SM501_POWER_MODE_1_CLOCK (0x00004C)
+#define SM501_SLEEP_MODE_GATE (0x000050)
+#define SM501_POWER_MODE_CONTROL (0x000054)
+
+/* power gates for units within the 501 */
+#define SM501_GATE_HOST (0)
+#define SM501_GATE_MEMORY (1)
+#define SM501_GATE_DISPLAY (2)
+#define SM501_GATE_2D_ENGINE (3)
+#define SM501_GATE_CSC (4)
+#define SM501_GATE_ZVPORT (5)
+#define SM501_GATE_GPIO (6)
+#define SM501_GATE_UART0 (7)
+#define SM501_GATE_UART1 (8)
+#define SM501_GATE_SSP (10)
+#define SM501_GATE_USB_HOST (11)
+#define SM501_GATE_USB_GADGET (12)
+#define SM501_GATE_UCONTROLLER (17)
+#define SM501_GATE_AC97 (18)
+
+/* panel clock */
+#define SM501_CLOCK_P2XCLK (24)
+/* crt clock */
+#define SM501_CLOCK_V2XCLK (16)
+/* main clock */
+#define SM501_CLOCK_MCLK (8)
+/* SDRAM controller clock */
+#define SM501_CLOCK_M1XCLK (0)
+
+/* config 2 */
+#define SM501_PCI_MASTER_BASE (0x000058)
+#define SM501_ENDIAN_CONTROL (0x00005C)
+#define SM501_DEVICEID (0x000060)
+/* 0x050100A0 */
+
+#define SM501_DEVICEID_SM501 (0x05010000)
+#define SM501_DEVICEID_IDMASK (0xffff0000)
+#define SM501_DEVICEID_REVMASK (0x000000ff)
+
+#define SM501_PLLCLOCK_COUNT (0x000064)
+#define SM501_MISC_TIMING (0x000068)
+#define SM501_CURRENT_SDRAM_CLOCK (0x00006C)
+
+#define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074)
+
+/* GPIO base */
+#define SM501_GPIO (0x010000)
+#define SM501_GPIO_DATA_LOW (0x00)
+#define SM501_GPIO_DATA_HIGH (0x04)
+#define SM501_GPIO_DDR_LOW (0x08)
+#define SM501_GPIO_DDR_HIGH (0x0C)
+#define SM501_GPIO_IRQ_SETUP (0x10)
+#define SM501_GPIO_IRQ_STATUS (0x14)
+#define SM501_GPIO_IRQ_RESET (0x14)
+
+/* I2C controller base */
+#define SM501_I2C (0x010040)
+#define SM501_I2C_BYTE_COUNT (0x00)
+#define SM501_I2C_CONTROL (0x01)
+#define SM501_I2C_STATUS (0x02)
+#define SM501_I2C_RESET (0x02)
+#define SM501_I2C_SLAVE_ADDRESS (0x03)
+#define SM501_I2C_DATA (0x04)
+
+/* SSP base */
+#define SM501_SSP (0x020000)
+
+/* Uart 0 base */
+#define SM501_UART0 (0x030000)
+
+/* Uart 1 base */
+#define SM501_UART1 (0x030020)
+
+/* USB host port base */
+#define SM501_USB_HOST (0x040000)
+
+/* USB slave/gadget base */
+#define SM501_USB_GADGET (0x060000)
+
+/* USB slave/gadget data port base */
+#define SM501_USB_GADGET_DATA (0x070000)
+
+/* Display controller/video engine base */
+#define SM501_DC (0x080000)
+
+/* common defines for the SM501 address registers */
+#define SM501_ADDR_FLIP (1<<31)
+#define SM501_ADDR_EXT (1<<27)
+#define SM501_ADDR_CS1 (1<<26)
+#define SM501_ADDR_MASK (0x3f << 26)
+
+#define SM501_FIFO_MASK (0x3 << 16)
+#define SM501_FIFO_1 (0x0 << 16)
+#define SM501_FIFO_3 (0x1 << 16)
+#define SM501_FIFO_7 (0x2 << 16)
+#define SM501_FIFO_11 (0x3 << 16)
+
+/* common registers for panel and the crt */
+#define SM501_OFF_DC_H_TOT (0x000)
+#define SM501_OFF_DC_V_TOT (0x008)
+#define SM501_OFF_DC_H_SYNC (0x004)
+#define SM501_OFF_DC_V_SYNC (0x00C)
+
+#define SM501_DC_PANEL_CONTROL (0x000)
+
+#define SM501_DC_PANEL_CONTROL_FPEN (1<<27)
+#define SM501_DC_PANEL_CONTROL_BIAS (1<<26)
+#define SM501_DC_PANEL_CONTROL_DATA (1<<25)
+#define SM501_DC_PANEL_CONTROL_VDD (1<<24)
+#define SM501_DC_PANEL_CONTROL_DP (1<<23)
+
+#define SM501_DC_PANEL_CONTROL_TFT_888 (0<<21)
+#define SM501_DC_PANEL_CONTROL_TFT_333 (1<<21)
+#define SM501_DC_PANEL_CONTROL_TFT_444 (2<<21)
+
+#define SM501_DC_PANEL_CONTROL_DE (1<<20)
+
+#define SM501_DC_PANEL_CONTROL_LCD_TFT (0<<18)
+#define SM501_DC_PANEL_CONTROL_LCD_STN8 (1<<18)
+#define SM501_DC_PANEL_CONTROL_LCD_STN12 (2<<18)
+
+#define SM501_DC_PANEL_CONTROL_CP (1<<14)
+#define SM501_DC_PANEL_CONTROL_VSP (1<<13)
+#define SM501_DC_PANEL_CONTROL_HSP (1<<12)
+#define SM501_DC_PANEL_CONTROL_CK (1<<9)
+#define SM501_DC_PANEL_CONTROL_TE (1<<8)
+#define SM501_DC_PANEL_CONTROL_VPD (1<<7)
+#define SM501_DC_PANEL_CONTROL_VP (1<<6)
+#define SM501_DC_PANEL_CONTROL_HPD (1<<5)
+#define SM501_DC_PANEL_CONTROL_HP (1<<4)
+#define SM501_DC_PANEL_CONTROL_GAMMA (1<<3)
+#define SM501_DC_PANEL_CONTROL_EN (1<<2)
+
+#define SM501_DC_PANEL_CONTROL_8BPP (0<<0)
+#define SM501_DC_PANEL_CONTROL_16BPP (1<<0)
+#define SM501_DC_PANEL_CONTROL_32BPP (2<<0)
+
+
+#define SM501_DC_PANEL_PANNING_CONTROL (0x004)
+#define SM501_DC_PANEL_COLOR_KEY (0x008)
+#define SM501_DC_PANEL_FB_ADDR (0x00C)
+#define SM501_DC_PANEL_FB_OFFSET (0x010)
+#define SM501_DC_PANEL_FB_WIDTH (0x014)
+#define SM501_DC_PANEL_FB_HEIGHT (0x018)
+#define SM501_DC_PANEL_TL_LOC (0x01C)
+#define SM501_DC_PANEL_BR_LOC (0x020)
+#define SM501_DC_PANEL_H_TOT (0x024)
+#define SM501_DC_PANEL_H_SYNC (0x028)
+#define SM501_DC_PANEL_V_TOT (0x02C)
+#define SM501_DC_PANEL_V_SYNC (0x030)
+#define SM501_DC_PANEL_CUR_LINE (0x034)
+
+#define SM501_DC_VIDEO_CONTROL (0x040)
+#define SM501_DC_VIDEO_FB0_ADDR (0x044)
+#define SM501_DC_VIDEO_FB_WIDTH (0x048)
+#define SM501_DC_VIDEO_FB0_LAST_ADDR (0x04C)
+#define SM501_DC_VIDEO_TL_LOC (0x050)
+#define SM501_DC_VIDEO_BR_LOC (0x054)
+#define SM501_DC_VIDEO_SCALE (0x058)
+#define SM501_DC_VIDEO_INIT_SCALE (0x05C)
+#define SM501_DC_VIDEO_YUV_CONSTANTS (0x060)
+#define SM501_DC_VIDEO_FB1_ADDR (0x064)
+#define SM501_DC_VIDEO_FB1_LAST_ADDR (0x068)
+
+#define SM501_DC_VIDEO_ALPHA_CONTROL (0x080)
+#define SM501_DC_VIDEO_ALPHA_FB_ADDR (0x084)
+#define SM501_DC_VIDEO_ALPHA_FB_OFFSET (0x088)
+#define SM501_DC_VIDEO_ALPHA_FB_LAST_ADDR (0x08C)
+#define SM501_DC_VIDEO_ALPHA_TL_LOC (0x090)
+#define SM501_DC_VIDEO_ALPHA_BR_LOC (0x094)
+#define SM501_DC_VIDEO_ALPHA_SCALE (0x098)
+#define SM501_DC_VIDEO_ALPHA_INIT_SCALE (0x09C)
+#define SM501_DC_VIDEO_ALPHA_CHROMA_KEY (0x0A0)
+#define SM501_DC_VIDEO_ALPHA_COLOR_LOOKUP (0x0A4)
+
+#define SM501_DC_PANEL_HWC_BASE (0x0F0)
+#define SM501_DC_PANEL_HWC_ADDR (0x0F0)
+#define SM501_DC_PANEL_HWC_LOC (0x0F4)
+#define SM501_DC_PANEL_HWC_COLOR_1_2 (0x0F8)
+#define SM501_DC_PANEL_HWC_COLOR_3 (0x0FC)
+
+#define SM501_HWC_EN (1<<31)
+
+#define SM501_OFF_HWC_ADDR (0x00)
+#define SM501_OFF_HWC_LOC (0x04)
+#define SM501_OFF_HWC_COLOR_1_2 (0x08)
+#define SM501_OFF_HWC_COLOR_3 (0x0C)
+
+#define SM501_DC_ALPHA_CONTROL (0x100)
+#define SM501_DC_ALPHA_FB_ADDR (0x104)
+#define SM501_DC_ALPHA_FB_OFFSET (0x108)
+#define SM501_DC_ALPHA_TL_LOC (0x10C)
+#define SM501_DC_ALPHA_BR_LOC (0x110)
+#define SM501_DC_ALPHA_CHROMA_KEY (0x114)
+#define SM501_DC_ALPHA_COLOR_LOOKUP (0x118)
+
+#define SM501_DC_CRT_CONTROL (0x200)
+
+#define SM501_DC_CRT_CONTROL_TVP (1<<15)
+#define SM501_DC_CRT_CONTROL_CP (1<<14)
+#define SM501_DC_CRT_CONTROL_VSP (1<<13)
+#define SM501_DC_CRT_CONTROL_HSP (1<<12)
+#define SM501_DC_CRT_CONTROL_VS (1<<11)
+#define SM501_DC_CRT_CONTROL_BLANK (1<<10)
+#define SM501_DC_CRT_CONTROL_SEL (1<<9)
+#define SM501_DC_CRT_CONTROL_TE (1<<8)
+#define SM501_DC_CRT_CONTROL_PIXEL_MASK (0xF << 4)
+#define SM501_DC_CRT_CONTROL_GAMMA (1<<3)
+#define SM501_DC_CRT_CONTROL_ENABLE (1<<2)
+
+#define SM501_DC_CRT_CONTROL_8BPP (0<<0)
+#define SM501_DC_CRT_CONTROL_16BPP (1<<0)
+#define SM501_DC_CRT_CONTROL_32BPP (2<<0)
+
+#define SM501_DC_CRT_FB_ADDR (0x204)
+#define SM501_DC_CRT_FB_OFFSET (0x208)
+#define SM501_DC_CRT_H_TOT (0x20C)
+#define SM501_DC_CRT_H_SYNC (0x210)
+#define SM501_DC_CRT_V_TOT (0x214)
+#define SM501_DC_CRT_V_SYNC (0x218)
+#define SM501_DC_CRT_SIGNATURE_ANALYZER (0x21C)
+#define SM501_DC_CRT_CUR_LINE (0x220)
+#define SM501_DC_CRT_MONITOR_DETECT (0x224)
+
+#define SM501_DC_CRT_HWC_BASE (0x230)
+#define SM501_DC_CRT_HWC_ADDR (0x230)
+#define SM501_DC_CRT_HWC_LOC (0x234)
+#define SM501_DC_CRT_HWC_COLOR_1_2 (0x238)
+#define SM501_DC_CRT_HWC_COLOR_3 (0x23C)
+
+#define SM501_DC_PANEL_PALETTE (0x400)
+
+#define SM501_DC_VIDEO_PALETTE (0x800)
+
+#define SM501_DC_CRT_PALETTE (0xC00)
+
+/* Zoom Video port base */
+#define SM501_ZVPORT (0x090000)
+
+/* AC97/I2S base */
+#define SM501_AC97 (0x0A0000)
+
+/* 8051 micro controller base */
+#define SM501_UCONTROLLER (0x0B0000)
+
+/* 8051 micro controller SRAM base */
+#define SM501_UCONTROLLER_SRAM (0x0C0000)
+
+/* DMA base */
+#define SM501_DMA (0x0D0000)
+
+/* 2d engine base */
+#define SM501_2D_ENGINE (0x100000)
+#define SM501_2D_SOURCE (0x00)
+#define SM501_2D_DESTINATION (0x04)
+#define SM501_2D_DIMENSION (0x08)
+#define SM501_2D_CONTROL (0x0C)
+#define SM501_2D_PITCH (0x10)
+#define SM501_2D_FOREGROUND (0x14)
+#define SM501_2D_BACKGROUND (0x18)
+#define SM501_2D_STRETCH (0x1C)
+#define SM501_2D_COLOR_COMPARE (0x20)
+#define SM501_2D_COLOR_COMPARE_MASK (0x24)
+#define SM501_2D_MASK (0x28)
+#define SM501_2D_CLIP_TL (0x2C)
+#define SM501_2D_CLIP_BR (0x30)
+#define SM501_2D_MONO_PATTERN_LOW (0x34)
+#define SM501_2D_MONO_PATTERN_HIGH (0x38)
+#define SM501_2D_WINDOW_WIDTH (0x3C)
+#define SM501_2D_SOURCE_BASE (0x40)
+#define SM501_2D_DESTINATION_BASE (0x44)
+#define SM501_2D_ALPHA (0x48)
+#define SM501_2D_WRAP (0x4C)
+#define SM501_2D_STATUS (0x50)
+
+#define SM501_CSC_Y_SOURCE_BASE (0xC8)
+#define SM501_CSC_CONSTANTS (0xCC)
+#define SM501_CSC_Y_SOURCE_X (0xD0)
+#define SM501_CSC_Y_SOURCE_Y (0xD4)
+#define SM501_CSC_U_SOURCE_BASE (0xD8)
+#define SM501_CSC_V_SOURCE_BASE (0xDC)
+#define SM501_CSC_SOURCE_DIMENSION (0xE0)
+#define SM501_CSC_SOURCE_PITCH (0xE4)
+#define SM501_CSC_DESTINATION (0xE8)
+#define SM501_CSC_DESTINATION_DIMENSION (0xEC)
+#define SM501_CSC_DESTINATION_PITCH (0xF0)
+#define SM501_CSC_SCALE_FACTOR (0xF4)
+#define SM501_CSC_DESTINATION_BASE (0xF8)
+#define SM501_CSC_CONTROL (0xFC)
+
+/* 2d engine data port base */
+#define SM501_2D_ENGINE_DATA (0x110000)
---
******************************************************************
* KSI@home KOI8 Net < > The impossible we do immediately. *
* Las Vegas NV, USA < > Miracles require 24-hour notice. *
******************************************************************
1
0
diff -purN u-boot.orig/common/cmd_i2c.c u-boot/common/cmd_i2c.c
--- u-boot.orig/common/cmd_i2c.c 2008-11-25 16:41:07.000000000 -0800
+++ u-boot/common/cmd_i2c.c 2009-01-23 16:01:48.000000000 -0800
@@ -1,4 +1,9 @@
/*
+ * (C) Copyright 2009
+ * Sergey Kubushyn, himself, ksi(a)koi8.net
+ *
+ * Changes for unified multibus/multiadapter I2C support.
+ *
* (C) Copyright 2001
* Gerald Van Baren, Custom IDEAS, vanbaren(a)cideas.com.
*
@@ -106,7 +111,7 @@ static uint i2c_mm_last_alen;
* pairs. The following macros take care of this */
#if defined(CONFIG_SYS_I2C_NOPROBES)
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
static struct
{
uchar bus;
@@ -122,19 +127,11 @@ static uchar i2c_no_probes[] = CONFIG_SY
#define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */
#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a))
#define NO_PROBE_ADDR(i) i2c_no_probes[(i)]
-#endif /* CONFIG_MULTI_BUS */
+#endif /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
#endif
-#if defined(CONFIG_I2C_MUX)
-static I2C_MUX_DEVICE *i2c_mux_devices = NULL;
-static int i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS;
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#endif
-
static int
mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]);
@@ -548,10 +545,10 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrfl
*/
int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- int j;
+ int j;
#if defined(CONFIG_SYS_I2C_NOPROBES)
- int k, skip;
- uchar bus = GET_BUS_NUM;
+ int k, skip;
+ unsigned int bus = GET_BUS_NUM;
#endif /* NOPROBES */
puts ("Valid chip addresses:");
@@ -1189,59 +1186,79 @@ int do_sdram (cmd_tbl_t * cmdtp, int fla
#if defined(CONFIG_I2C_CMD_TREE)
int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ i2c_init (ADAP(i2c_get_bus_num())->speed, ADAP(i2c_get_bus_num())->slaveaddr);
return 0;
}
-#if defined(CONFIG_I2C_MUX)
-int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_i2c_show_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- int ret=0;
+ int i;
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+ int j;
+#endif
if (argc == 1) {
/* show all busses */
- I2C_MUX *mux;
- I2C_MUX_DEVICE *device = i2c_mux_devices;
-
- printf ("Busses reached over muxes:\n");
- while (device != NULL) {
- printf ("Bus ID: %x\n", device->busid);
- printf (" reached over Mux(es):\n");
- mux = device->mux;
- while (mux != NULL) {
- printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel);
- mux = mux->next;
+ for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSSES; i++) {
+ printf("Bus %d:\t%s", i, ADAP(i)->name);
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+ for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
+ if (i2c_bus[i].next_hop[j].chip == 0) break;
+ printf("->%s@0x%2x:%d",
+ i2c_bus[i].next_hop[j].mux.name,
+ i2c_bus[i].next_hop[j].chip,
+ i2c_bus[i].next_hop[j].channel);
}
- device = device->next;
+#endif
+ printf("\n");
}
- } else {
- I2C_MUX_DEVICE *dev;
- dev = i2c_mux_ident_muxstring ((uchar *)argv[1]);
- ret = 0;
+ } else {
+ /* show specific bus */
+ i = simple_strtoul(argv[1], NULL, 10);
+ if (i >= CONFIG_SYS_NUM_I2C_BUSSES) {
+ printf("Invalid bus %d\n", i);
+ return(-1);
+ }
+ printf("Bus %d:\t%s", i, ADAP(i)->name);
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+ for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
+ if (i2c_bus[i].next_hop[j].chip == 0) break;
+ printf("->%s@0x%2x:%d",
+ i2c_bus[i].next_hop[j].mux.name,
+ i2c_bus[i].next_hop[j].chip,
+ i2c_bus[i].next_hop[j].channel);
+ }
+#endif
+ printf("\n");
}
- return ret;
+
+ return(0);
}
-#endif /* CONFIG_I2C_MUX */
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- int bus_idx, ret=0;
+ int ret=0;
+ unsigned int bus_no;
if (argc == 1)
/* querying current setting */
printf("Current bus is %d\n", i2c_get_bus_num());
else {
- bus_idx = simple_strtoul(argv[1], NULL, 10);
- printf("Setting bus to %d\n", bus_idx);
- ret = i2c_set_bus_num(bus_idx);
+ bus_no = simple_strtoul(argv[1], NULL, 10);
+ if (bus_no >= CONFIG_SYS_NUM_I2C_BUSSES) {
+ printf("Invalid bus %d\n", bus_no);
+ return(-1);
+ }
+ printf("Setting bus to %d\n", bus_no);
+ ret = i2c_set_bus_num(bus_no);
if (ret)
printf("Failure changing bus number (%d)\n", ret);
}
return ret;
}
-#endif /* CONFIG_I2C_MULTI_BUS */
+#endif /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
@@ -1262,16 +1279,16 @@ int do_i2c_bus_speed(cmd_tbl_t * cmdtp,
int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
-#if defined(CONFIG_I2C_MUX)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
if (!strncmp(argv[1], "bu", 2))
- return do_i2c_add_bus(cmdtp, flag, --argc, ++argv);
-#endif /* CONFIG_I2C_MUX */
+ return do_i2c_show_bus(cmdtp, flag, --argc, ++argv);
+#endif /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
if (!strncmp(argv[1], "sp", 2))
return do_i2c_bus_speed(cmdtp, flag, --argc, ++argv);
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
if (!strncmp(argv[1], "de", 2))
return do_i2c_bus_num(cmdtp, flag, --argc, ++argv);
-#endif /* CONFIG_I2C_MULTI_BUS */
+#endif /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
if (!strncmp(argv[1], "md", 2))
return do_i2c_md(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "mm", 2))
@@ -1304,13 +1321,11 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag,
U_BOOT_CMD(
i2c, 6, 1, do_i2c,
"i2c - I2C sub-system\n",
-#if defined(CONFIG_I2C_MUX)
- "bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes.\n"
-#endif /* CONFIG_I2C_MUX */
- "speed [speed] - show or set I2C bus speed\n"
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
+ "bus [bus_no] - show I2C bus info.\n"
"i2c dev [dev] - show or set current I2C bus\n"
-#endif /* CONFIG_I2C_MULTI_BUS */
+#endif /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
+ "i2c speed [speed] - show or set I2C bus speed\n"
"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
@@ -1323,7 +1338,7 @@ U_BOOT_CMD(
"i2c sdram chip - print SDRAM configuration information\n"
#endif
);
-#endif /* CONFIG_I2C_CMD_TREE */
+#else /* CONFIG_I2C_CMD_TREE */
U_BOOT_CMD(
imd, 4, 1, do_i2c_md, \
"imd - i2c memory display\n", \
@@ -1378,221 +1393,4 @@ U_BOOT_CMD(
" (valid chip values 50..57)\n"
);
#endif
-
-#if defined(CONFIG_I2C_MUX)
-
-int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
-{
- I2C_MUX_DEVICE *devtmp = i2c_mux_devices;
-
- if (i2c_mux_devices == NULL) {
- i2c_mux_devices = dev;
- return 0;
- }
- while (devtmp->next != NULL)
- devtmp = devtmp->next;
-
- devtmp->next = dev;
- return 0;
-}
-
-I2C_MUX_DEVICE *i2c_mux_search_device(int id)
-{
- I2C_MUX_DEVICE *device = i2c_mux_devices;
-
- while (device != NULL) {
- if (device->busid == id)
- return device;
- device = device->next;
- }
- return NULL;
-}
-
-/* searches in the buf from *pos the next ':'.
- * returns:
- * 0 if found (with *pos = where)
- * < 0 if an error occured
- * > 0 if the end of buf is reached
- */
-static int i2c_mux_search_next (int *pos, uchar *buf, int len)
-{
- while ((buf[*pos] != ':') && (*pos < len)) {
- *pos += 1;
- }
- if (*pos >= len)
- return 1;
- if (buf[*pos] != ':')
- return -1;
- return 0;
-}
-
-static int i2c_mux_get_busid (void)
-{
- int tmp = i2c_mux_busid;
-
- i2c_mux_busid ++;
- return tmp;
-}
-
-/* Analyses a Muxstring and sends immediately the
- Commands to the Muxes. Runs from Flash.
- */
-int i2c_mux_ident_muxstring_f (uchar *buf)
-{
- int pos = 0;
- int oldpos;
- int ret = 0;
- int len = strlen((char *)buf);
- int chip;
- uchar channel;
- int was = 0;
-
- while (ret == 0) {
- oldpos = pos;
- /* search name */
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret != 0)
- printf ("ERROR\n");
- /* search address */
- pos ++;
- oldpos = pos;
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret != 0)
- printf ("ERROR\n");
- buf[pos] = 0;
- chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
- buf[pos] = ':';
- /* search channel */
- pos ++;
- oldpos = pos;
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret < 0)
- printf ("ERROR\n");
- was = 0;
- if (buf[pos] != 0) {
- buf[pos] = 0;
- was = 1;
- }
- channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
- if (was)
- buf[pos] = ':';
- if (i2c_write(chip, 0, 0, &channel, 1) != 0) {
- printf ("Error setting Mux: chip:%x channel: \
- %x\n", chip, channel);
- return -1;
- }
- pos ++;
- oldpos = pos;
-
- }
-
- return 0;
-}
-
-/* Analyses a Muxstring and if this String is correct
- * adds a new I2C Bus.
- */
-I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf)
-{
- I2C_MUX_DEVICE *device;
- I2C_MUX *mux;
- int pos = 0;
- int oldpos;
- int ret = 0;
- int len = strlen((char *)buf);
- int was = 0;
-
- device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE));
- device->mux = NULL;
- device->busid = i2c_mux_get_busid ();
- device->next = NULL;
- while (ret == 0) {
- mux = (I2C_MUX *)malloc (sizeof(I2C_MUX));
- mux->next = NULL;
- /* search name of mux */
- oldpos = pos;
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret != 0)
- printf ("%s no name.\n", __FUNCTION__);
- mux->name = (char *)malloc (pos - oldpos + 1);
- memcpy (mux->name, &buf[oldpos], pos - oldpos);
- mux->name[pos - oldpos] = 0;
- /* search address */
- pos ++;
- oldpos = pos;
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret != 0)
- printf ("%s no mux address.\n", __FUNCTION__);
- buf[pos] = 0;
- mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
- buf[pos] = ':';
- /* search channel */
- pos ++;
- oldpos = pos;
- ret = i2c_mux_search_next(&pos, buf, len);
- if (ret < 0)
- printf ("%s no mux channel.\n", __FUNCTION__);
- was = 0;
- if (buf[pos] != 0) {
- buf[pos] = 0;
- was = 1;
- }
- mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
- if (was)
- buf[pos] = ':';
- if (device->mux == NULL)
- device->mux = mux;
- else {
- I2C_MUX *muxtmp = device->mux;
- while (muxtmp->next != NULL) {
- muxtmp = muxtmp->next;
- }
- muxtmp->next = mux;
- }
- pos ++;
- oldpos = pos;
- }
- if (ret > 0) {
- /* Add Device */
- i2c_mux_add_device (device);
- return device;
- }
-
- return NULL;
-}
-
-int i2x_mux_select_mux(int bus)
-{
- I2C_MUX_DEVICE *dev;
- I2C_MUX *mux;
-
- if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) {
- /* select Default Mux Bus */
-#if defined(CONFIG_SYS_I2C_IVM_BUS)
- i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
-#else
- {
- unsigned char *buf;
- buf = (unsigned char *) getenv("EEprom_ivm");
- if (buf != NULL)
- i2c_mux_ident_muxstring_f (buf);
- }
-#endif
- return 0;
- }
- dev = i2c_mux_search_device(bus);
- if (dev == NULL)
- return -1;
-
- mux = dev->mux;
- while (mux != NULL) {
- if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
- printf ("Error setting Mux: chip:%x channel: \
- %x\n", mux->chip, mux->channel);
- return -1;
- }
- mux = mux->next;
- }
- return 0;
-}
-#endif /* CONFIG_I2C_MUX */
+#endif /* CONFIG_I2C_CMD_TREE */
diff -purN u-boot.orig/common/devices.c u-boot/common/devices.c
--- u-boot.orig/common/devices.c 2008-10-20 13:59:38.000000000 -0700
+++ u-boot/common/devices.c 2009-01-23 16:01:48.000000000 -0800
@@ -1,4 +1,8 @@
/*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio(a)tin.it
*
@@ -30,7 +34,7 @@
#ifdef CONFIG_LOGBUFFER
#include <logbuff.h>
#endif
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) || defined(CONFIG_SYS_I2C_ADAPTERS)
#include <i2c.h>
#endif
@@ -215,9 +219,15 @@ int devices_init (void)
/* Initialize the list */
INIT_LIST_HEAD(&(devs.list));
+#ifdef CONFIG_NEW_I2C
+#ifdef CONFIG_SYS_I2C_ADAPTERS
+ i2c_init_all();
+#endif
+#else
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
+#endif
#ifdef CONFIG_LCD
drv_lcd_init ();
#endif
diff -purN u-boot.orig/drivers/i2c/i2c_core.c u-boot/drivers/i2c/i2c_core.c
--- u-boot.orig/drivers/i2c/i2c_core.c 1969-12-31 16:00:00.000000000 -0800
+++ u-boot/drivers/i2c/i2c_core.c 2009-01-23 16:01:48.000000000 -0800
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Multibus/multiadapter I2C core functions (wrappers)
+ */
+#include <common.h>
+#include <i2c.h>
+
+#ifdef CONFIG_FSL_UNI_I2C
+extern i2c_adap_t fsl_i2c_adap[];
+#endif
+
+#ifdef CONFIG_SM502_I2C
+extern i2c_adap_t sm501_i2c_adap;
+#endif
+
+i2c_adap_t *i2c_adap[CONFIG_SYS_NUM_I2C_ADAPTERS] = CONFIG_SYS_I2C_ADAPTERS;
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+i2c_bus_t i2c_bus[CONFIG_SYS_NUM_I2C_BUSSES] = CONFIG_SYS_I2C_BUSSES;
+#endif
+
+static unsigned int i2c_cur_bus __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void i2c_reloc_fixup(void)
+{
+ int i;
+ unsigned long addr;
+
+ /* Adapters */
+ for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
+ /* Adapter itself */
+ addr = (unsigned long)i2c_adap[i];
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i] = (i2c_adap_t *)addr;
+ /* i2c_init() */
+ addr = (unsigned long)i2c_adap[i]->init;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->init = (void (*)(int, int))addr;
+ /* i2c_probe() */
+ addr = (unsigned long)i2c_adap[i]->probe;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->probe = (int (*)(u_int8_t))addr;
+ /* i2c_read() */
+ addr = (unsigned long)i2c_adap[i]->read;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->read = (int (*)(u_int8_t, uint, int, u_int8_t *, int))addr;
+ /* i2c_write() */
+ addr = (unsigned long)i2c_adap[i]->write;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->write = (int (*)(u_int8_t, uint, int, u_int8_t *, int))addr;
+ /* i2c_set_bus_speed() */
+ addr = (unsigned long)i2c_adap[i]->set_bus_speed;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->set_bus_speed = (uint (*)(uint))addr;
+ /* i2c_get_bus_speed() */
+ addr = (unsigned long)i2c_adap[i]->get_bus_speed;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->get_bus_speed = (uint (*)(void))addr;
+ /* name */
+ addr = (unsigned long)i2c_adap[i]->name;
+ if (addr != 0) addr += gd->reloc_off;
+ i2c_adap[i]->name = (char *)addr;
+ }
+}
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+/*
+ * i2c_mux_set()
+ * -------------
+ *
+ * This turns on the given channel on I2C multiplexer chip connected to
+ * a given I2C adapter directly or via other multiplexers. In the latter
+ * case the entire multiplexer chain must be initialized first starting
+ * with the one connected directly to the adapter. When disabling a chain
+ * muxes must be programmed in reverse order, starting with the one
+ * farthest from the adapter.
+ *
+ * mux_id is the multiplexer chip type from defined in i2c.h. So far only
+ * NXP (Philips) PCA954x multiplexers are supported. Switches are NOT
+ * supported (anybody uses them?)
+ */
+
+static int i2c_mux_set(int adapter, int mux_id, int chip, int channel)
+{
+ u_int8_t buf;
+
+ /* channel < 0 - turn off the mux */
+ if (channel < 0) {
+ buf = 0;
+ return(i2c_adap[adapter]->write(chip, 0, 0, &buf, 1));
+ }
+
+ switch (mux_id) {
+ case I2C_MUX_PCA9540_ID:
+ case I2C_MUX_PCA9542_ID:
+ if (channel > 1) return(-1);
+ buf = (u_int8_t)((channel & 0x01) | (1 << 2));
+ break;
+ case I2C_MUX_PCA9544_ID:
+ if (channel > 3) return(-1);
+ buf = (u_int8_t)((channel & 0x03) | (1 << 2));
+ break;
+ case I2C_MUX_PCA9547_ID:
+ if (channel > 7) return(-1);
+ buf = (u_int8_t)((channel & 0x07) | (1 << 3));
+ break;
+ default:
+ return(-1);
+ }
+
+ return(i2c_adap[adapter]->write(chip, 0, 0, &buf, 1));
+}
+#endif
+
+/*
+ * i2c_get_bus_num():
+ * ------------------
+ *
+ * Returns index of currently active I2C bus. Zero-based.
+ */
+unsigned int i2c_get_bus_num(void)
+{
+ return(i2c_cur_bus);
+}
+
+/*
+ * i2c_set_bus_num():
+ * ------------------
+ *
+ * Change the active I2C bus. Subsequent read/write calls will
+ * go to this one. Sets all of the muxes in a proper condition
+ * if that bus is behind muxes. Fails if called before relocation.
+ * If previously selected bus is behind the muxes turns off all the
+ * muxes along the path to that bus.
+ *
+ * bus - bus index, zero based
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int i2c_set_bus_num(unsigned int bus)
+{
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+ int i;
+ u_int8_t buf;
+#endif
+
+ if ((bus >= CONFIG_SYS_NUM_I2C_BUSSES) || !(gd->flags & GD_FLG_RELOC))
+ return(-1);
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+ /* Disconnect current bus (turn off muxes if any) */
+ if ((i2c_bus[i2c_cur_bus].next_hop[0].chip != 0) &&
+ (ADAP(i2c_cur_bus)->init_done != 0)) {
+
+ i = CONFIG_SYS_I2C_MAX_HOPS;
+
+ do {
+ u_int8_t chip;
+
+ if ((chip = i2c_bus[i2c_cur_bus].next_hop[--i].chip) == 0)
+ continue;
+
+ ADAP(i2c_cur_bus)->write(chip, 0, 0, &buf, 1);
+
+ } while (i > 0);
+ }
+
+ /* Connect requested bus if behind muxes */
+ if ((i2c_bus[bus].next_hop[0].chip != 0) &&
+ (ADAP(bus)->init_done != 0)) {
+
+ /* Set all muxes along the path to that bus */
+ for (i = 0; i < CONFIG_SYS_I2C_MAX_HOPS; i++) {
+
+ if (i2c_bus[bus].next_hop[i].chip == 0) break;
+
+ i2c_mux_set(i2c_bus[bus].adapter,
+ i2c_bus[bus].next_hop[i].mux.id,
+ i2c_bus[bus].next_hop[i].chip,
+ i2c_bus[bus].next_hop[i].channel);
+ }
+ }
+#endif
+
+ i2c_cur_bus = bus;
+ return(0);
+}
+
+
+/*
+ * i2c_init_bus():
+ * ---------------
+ *
+ * Initializes one bus. Will initialize the parent adapter. No current bus
+ * changes, no mux (if any) setup.
+ */
+static void i2c_init_bus(unsigned int bus_no, int speed, int slaveaddr)
+{
+ if (bus_no >= CONFIG_SYS_NUM_I2C_BUSSES)
+ return;
+
+ ADAP(bus_no)->init(speed, slaveaddr);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ ADAP(bus_no)->init_done = 1;
+ ADAP(bus_no)->speed = speed;
+ ADAP(bus_no)->slaveaddr = slaveaddr;
+ }
+}
+
+
+/*
+ * i2c_init_all():
+ *
+ * Initializes all I2C adapters in the system. All i2c_adap_t structures in
+ * i2c_adap[] must be initialized beforehead with function pointers and
+ * data, including speed and slaveaddr.
+ */
+void i2c_init_all(void)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
+ if ((i2c_adap[i]->speed != 0) && (i2c_adap[i]->init != NULL)) {
+ i2c_adap[i]->init(i2c_adap[i]->speed, i2c_adap[i]->slaveaddr);
+ if (gd->flags & GD_FLG_RELOC)
+ i2c_adap[i]->init_done = 1;
+ }
+ }
+}
+
+
+/*
+ * Probe the given I2C chip address. Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(u_int8_t chip)
+{
+ return(ADAP(i2c_cur_bus)->probe(chip));
+}
+
+/*
+ * Read/Write interface:
+ * chip: I2C chip address, range 0..127
+ * addr: Memory (register) address within the chip
+ * alen: Number of bytes to use for addr (typically 1, 2 for larger
+ * memories, 0 for register type devices with only one
+ * register)
+ * buffer: Where to read/write the data
+ * len: How many bytes to read/write
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(u_int8_t chip, unsigned int addr, int alen,
+ u_int8_t *buffer, int len)
+{
+ return(ADAP(i2c_cur_bus)->read(chip, addr, alen, buffer, len));
+}
+
+int i2c_write(u_int8_t chip, unsigned int addr, int alen,
+ u_int8_t *buffer, int len)
+{
+ return(ADAP(i2c_cur_bus)->write(chip, addr, alen, buffer, len));
+}
+
+
+unsigned int i2c_set_bus_speed(unsigned int speed)
+{
+ return(ADAP(i2c_cur_bus)->set_bus_speed(speed));
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+ return(ADAP(i2c_cur_bus)->get_bus_speed());
+}
+
+
+u_int8_t i2c_reg_read(u_int8_t addr, u_int8_t reg)
+{
+ u_int8_t buf;
+
+#ifdef CONFIG_8xx
+ /* MPC8xx needs this. Maybe one day we can get rid of it. */
+ i2c_init_bus(i2c_cur_bus, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+
+#ifdef CONFIG_BLACKFIN
+ /* This ifdef will become unneccessary in a future version of the
+ * blackfin I2C driver.
+ */
+ i2c_read(addr, reg, 0, &buf, 1);
+#else
+ i2c_read(addr, reg, 1, &buf, 1);
+#endif
+
+#ifdef DEBUG
+ printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
+ __func__, i2c_cur_bus, addr, reg, buf);
+#endif
+
+ return buf;
+}
+
+void i2c_reg_write(u_int8_t addr, u_int8_t reg, u_int8_t val)
+{
+#ifdef CONFIG_8xx
+ /* MPC8xx needs this. Maybe one day we can get rid of it. */
+ i2c_init_bus(i2c_cur_bus, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+
+#ifdef DEBUG
+ printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
+ __func__, i2c_cur_bus, addr, reg, val);
+#endif
+
+#ifdef CONFIG_BLACKFIN
+ /* This ifdef will become unneccessary in a future version of the
+ * blackfin I2C driver.
+ */
+ i2c_write(addr, reg, 0, &val, 1);
+#else
+ i2c_write(addr, reg, 1, &val, 1);
+#endif
+}
+
+
+void inline __i2c_init(unsigned int speed, int slaveaddr)
+{
+ i2c_init_bus(i2c_cur_bus, speed, slaveaddr);
+}
+
+void inline i2c_init(unsigned int speed, int slaveaddr)
+ __attribute__((weak, alias("__i2c_init")));
diff -purN u-boot.orig/drivers/i2c/Makefile u-boot/drivers/i2c/Makefile
--- u-boot.orig/drivers/i2c/Makefile 2008-09-12 10:10:35.000000000 -0700
+++ u-boot/drivers/i2c/Makefile 2009-01-23 16:01:48.000000000 -0800
@@ -26,13 +26,15 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libi2c.a
COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_FSL_UNI_I2C) += fsl_uni_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_SM502_I2C) += sm502_i2c.o
-COBJS := $(COBJS-y)
+COBJS := i2c_core.o $(COBJS-y)
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff -purN u-boot.orig/include/i2c.h u-boot/include/i2c.h
--- u-boot.orig/include/i2c.h 2008-12-16 15:32:13.000000000 -0800
+++ u-boot/include/i2c.h 2009-01-23 16:01:48.000000000 -0800
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2001
* Gerald Van Baren, Custom IDEAS, vanbaren(a)cideas.com.
*
@@ -46,14 +49,20 @@
*/
#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
-#if defined(CONFIG_I2C_MULTI_BUS)
-#define CONFIG_SYS_MAX_I2C_BUS 2
-#define I2C_GET_BUS() i2c_get_bus_num()
-#define I2C_SET_BUS(a) i2c_set_bus_num(a)
+#ifndef CONFIG_SYS_NUM_I2C_ADAPTERS
+#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
+#endif
+
+#if !defined(CONFIG_SYS_I2C_MAX_HOPS) || (CONFIG_SYS_I2C_MAX_HOPS == 0)
+#define CONFIG_SYS_I2C_DIRECT_BUS 1
+#if !defined(CONFIG_SYS_NUM_I2C_BUSSES) || (CONFIG_SYS_NUM_I2C_BUSSES != CONFIG_SYS_NUM_I2C_ADAPTERS)
+#define CONFIG_SYS_NUM_I2C_BUSSES CONFIG_SYS_NUM_I2C_ADAPTERS
+#endif
#else
-#define CONFIG_SYS_MAX_I2C_BUS 1
-#define I2C_GET_BUS() 0
-#define I2C_SET_BUS(a)
+#undef CONFIG_SYS_I2C_DIRECT_BUS
+#ifndef CONFIG_SYS_NUM_I2C_BUSSES
+#define CONFIG_SYS_NUM_I2C_BUSSES 1
+#endif
#endif
/* define the I2C bus number for RTC and DTT if not already done */
@@ -67,66 +76,111 @@
#define CONFIG_SYS_SPD_BUS_NUM 0
#endif
-#ifndef I2C_SOFT_DECLARATIONS
-# if defined(CONFIG_MPC8260)
-# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT);
-# elif defined(CONFIG_8xx)
-# define I2C_SOFT_DECLARATIONS volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-# else
-# define I2C_SOFT_DECLARATIONS
-# endif
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+#define ADAP(bus) i2c_adap[i2c_bus[(bus)].adapter]
+#else
+#define ADAP(bus) i2c_adap[(bus)]
#endif
-#ifdef CONFIG_8xx
-/* Set default values for the I2C bus speed and slave address on 8xx. In the
- * future, we'll define these in all 8xx board config files.
- */
-#ifndef CONFIG_SYS_I2C_SPEED
-#define CONFIG_SYS_I2C_SPEED 50000
-#endif
+typedef struct i2c_adapter {
+ void (*init)(int speed, int slaveaddr);
+ int (*probe)(u_int8_t chip);
+ int (*read)(u_int8_t chip, uint addr, int alen,
+ u_int8_t *buffer, int len);
+ int (*write)(u_int8_t chip, uint addr, int alen,
+ u_int8_t *buffer, int len);
+ uint (*set_bus_speed)(uint speed);
+ uint (*get_bus_speed)(void);
+
+ int speed;
+ int slaveaddr;
+ int init_done;
+ char *name;
+} i2c_adap_t;
+
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+#define I2C_MUX_PCA9540_ID 1
+#define I2C_MUX_PCA9540 {I2C_MUX_PCA9540_ID, "PCA9540B"}
+#define I2C_MUX_PCA9542_ID 2
+#define I2C_MUX_PCA9542 {I2C_MUX_PCA9542_ID, "PCA9542A"}
+#define I2C_MUX_PCA9544_ID 3
+#define I2C_MUX_PCA9544 {I2C_MUX_PCA9544_ID, "PCA9544A"}
+#define I2C_MUX_PCA9547_ID 4
+#define I2C_MUX_PCA9547 {I2C_MUX_PCA9547_ID, "PCA9547A"}
+
+typedef struct i2c_mux {
+ int id;
+ char name[16];
+} i2c_mux_t;
+
+typedef struct i2c_next_hop {
+ i2c_mux_t mux;
+ u_int8_t chip;
+ u_int8_t channel;
+} i2c_next_hop_t;
+
+
+typedef struct i2c_bus_hose {
+ int adapter;
+ i2c_next_hop_t next_hop[CONFIG_SYS_I2C_MAX_HOPS];
+} i2c_bus_t;
-#ifndef CONFIG_SYS_I2C_SLAVE
-#define CONFIG_SYS_I2C_SLAVE 0xFE
-#endif
+#define I2C_NULL_HOP {{-1, ""}, 0, 0}
+
+extern i2c_bus_t i2c_bus[];
#endif
+extern i2c_adap_t *i2c_adap[];
+
+/*
+ * i2c_get_bus_num:
+ *
+ * Returns index of currently active I2C bus. Zero-based.
+ */
+unsigned int i2c_get_bus_num(void);
+
+
/*
+ * i2c_set_bus_num:
+ *
+ * Change the active I2C bus. Subsequent read/write calls will
+ * go to this one.
+ *
+ * bus - bus index, zero based
+ *
+ * Returns: 0 on success, not 0 on failure
+ *
+ */
+int i2c_set_bus_num(unsigned int bus);
+
+
+/*
+ * i2c_init_bus()
+ *
* Initialization, must be called once on start up, may be called
- * repeatedly to change the speed and slave addresses.
+ * repeatedly to change the speed and slave addresses. This initializes
+ * a single current i2c bus.
*/
-void i2c_init(int speed, int slaveaddr);
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-void i2c_init_board(void);
-#endif
+/* void i2c_init_bus(int speed, int slaveaddr); */
-#if defined(CONFIG_I2C_MUX)
-typedef struct _mux {
- uchar chip;
- uchar channel;
- char *name;
- struct _mux *next;
-} I2C_MUX;
-
-typedef struct _mux_device {
- int busid;
- I2C_MUX *mux; /* List of muxes, to reach the device */
- struct _mux_device *next;
-} I2C_MUX_DEVICE;
-
-int i2c_mux_add_device(I2C_MUX_DEVICE *dev);
-
-I2C_MUX_DEVICE *i2c_mux_search_device(int id);
-I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf);
-int i2x_mux_select_mux(int bus);
-int i2c_mux_ident_muxstring_f (uchar *buf);
-#endif
+/*
+ * i2c_init_all():
+ *
+ * Initializes all I2C adapters in the system. All i2c_adap structures must
+ * be initialized beforehead with function pointers and data, including
+ * speed and slaveaddr. Returns 0 on success, non-0 on failure.
+ */
+void i2c_init_all(void);
+
/*
* Probe the given I2C chip address. Returns 0 if a chip responded,
* not 0 on failure.
*/
-int i2c_probe(uchar chip);
+int i2c_probe(u_int8_t chip);
+
/*
* Read/Write interface:
@@ -140,83 +194,25 @@ int i2c_probe(uchar chip);
*
* Returns: 0 on success, not 0 on failure
*/
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
+int i2c_read(u_int8_t chip, unsigned int addr, int alen,
+ u_int8_t *buffer, int len);
+
+int i2c_write(u_int8_t chip, unsigned int addr, int alen,
+ u_int8_t *buffer, int len);
+
/*
* Utility routines to read/write registers.
*/
-static inline u8 i2c_reg_read(u8 addr, u8 reg)
-{
- u8 buf;
-
-#ifdef CONFIG_8xx
- /* MPC8xx needs this. Maybe one day we can get rid of it. */
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
+u_int8_t i2c_reg_read(u_int8_t addr, u_int8_t reg);
-#ifdef DEBUG
- printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg);
-#endif
+void i2c_reg_write(u_int8_t addr, u_int8_t reg, u_int8_t val);
-#ifdef CONFIG_BLACKFIN
- /* This ifdef will become unneccessary in a future version of the
- * blackfin I2C driver.
- */
- i2c_read(addr, reg, 0, &buf, 1);
-#else
- i2c_read(addr, reg, 1, &buf, 1);
-#endif
-
- return buf;
-}
-
-static inline void i2c_reg_write(u8 addr, u8 reg, u8 val)
-{
-#ifdef CONFIG_8xx
- /* MPC8xx needs this. Maybe one day we can get rid of it. */
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
-
-#ifdef DEBUG
- printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n",
- __func__, addr, reg, val);
-#endif
-
-#ifdef CONFIG_BLACKFIN
- /* This ifdef will become unneccessary in a future version of the
- * blackfin I2C driver.
- */
- i2c_write(addr, reg, 0, &val, 1);
-#else
- i2c_write(addr, reg, 1, &val, 1);
-#endif
-}
/*
* Functions for setting the current I2C bus and its speed
*/
-/*
- * i2c_set_bus_num:
- *
- * Change the active I2C bus. Subsequent read/write calls will
- * go to this one.
- *
- * bus - bus index, zero based
- *
- * Returns: 0 on success, not 0 on failure
- *
- */
-int i2c_set_bus_num(unsigned int bus);
-
-/*
- * i2c_get_bus_num:
- *
- * Returns index of currently active I2C bus. Zero-based.
- */
-
-unsigned int i2c_get_bus_num(void);
/*
* i2c_set_bus_speed:
@@ -225,10 +221,10 @@ unsigned int i2c_get_bus_num(void);
*
* speed - bus speed in Hz
*
- * Returns: 0 on success, not 0 on failure
+ * Returns: new bus speed
*
*/
-int i2c_set_bus_speed(unsigned int);
+unsigned int i2c_set_bus_speed(unsigned int speed);
/*
* i2c_get_bus_speed:
@@ -238,4 +234,44 @@ int i2c_set_bus_speed(unsigned int);
unsigned int i2c_get_bus_speed(void);
+/*
+ * i2c_reloc_fixup:
+ *
+ * Adjusts I2C pointers after U-Boot is relocated to DRAM
+ */
+void i2c_reloc_fixup(void);
+
+
+#ifndef I2C_SOFT_DECLARATIONS
+# if defined(CONFIG_MPC8260)
+# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT);
+# elif defined(CONFIG_8xx)
+# define I2C_SOFT_DECLARATIONS volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+# else
+# define I2C_SOFT_DECLARATIONS
+# endif
+#endif
+
+#ifdef CONFIG_8xx
+/* Set default values for the I2C bus speed and slave address on 8xx. In the
+ * future, we'll define these in all 8xx board config files.
+ */
+#ifndef CONFIG_SYS_I2C_SPEED
+#define CONFIG_SYS_I2C_SPEED 50000
+#endif
+
+#ifndef CONFIG_SYS_I2C_SLAVE
+#define CONFIG_SYS_I2C_SLAVE 0xFE
+#endif
+#endif
+
+/*
+ * Initialization, must be called once on start up, may be called
+ * repeatedly to change the speed and slave addresses.
+ */
+void i2c_init(unsigned int speed, int slaveaddr);
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+void i2c_init_board(void);
+#endif
+
#endif /* _I2C_H_ */
diff -purN u-boot.orig/lib_ppc/board.c u-boot/lib_ppc/board.c
--- u-boot.orig/lib_ppc/board.c 2009-01-23 10:39:27.000000000 -0800
+++ u-boot/lib_ppc/board.c 2009-01-23 16:01:48.000000000 -0800
@@ -91,7 +91,8 @@ extern void sc3_read_eeprom(void);
void doc_init (void);
#endif
#if defined(CONFIG_HARD_I2C) || \
- defined(CONFIG_SOFT_I2C)
+ defined(CONFIG_SOFT_I2C) || \
+ defined(CONFIG_SYS_I2C_ADAPTERS)
#include <i2c.h>
#endif
#include <spi.h>
@@ -234,11 +235,15 @@ static int init_func_ram (void)
/***********************************************************************/
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) || defined(CONFIG_SYS_I2C_ADAPTERS)
static int init_func_i2c (void)
{
puts ("I2C: ");
+#ifdef CONFIG_NEW_I2C
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
puts ("ready\n");
return (0);
}
@@ -333,7 +338,7 @@ init_fnc_t *init_sequence[] = {
misc_init_f,
#endif
INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) || defined(CONFIG_SYS_I2C_ADAPTERS)
init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)
@@ -863,6 +868,11 @@ void board_init_r (gd_t *id, ulong dest_
* the environment is in EEPROM.
*/
+#if defined(CONFIG_NEW_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+ /* Adjust I2C subsystem pointers after relocation */
+ i2c_reloc_fixup();
+#endif
+
#if defined(CONFIG_SYS_EXTBDINFO)
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
#if defined(CONFIG_I2CFAST)
diff -purN u-boot.orig/include/configs/MPC8548CDS.h u-boot/include/configs/MPC8548CDS.h
--- u-boot.orig/include/configs/MPC8548CDS.h 2008-12-16 15:32:13.000000000 -0800
+++ u-boot/include/configs/MPC8548CDS.h 2009-01-23 16:01:48.000000000 -0800
@@ -52,6 +52,8 @@
#define CONFIG_FSL_VIA
+#define CONFIG_NEW_I2C
+
/*
* When initializing flash, if we cannot find the manufacturer ID,
* assume this is the AMD flash associated with the CDS board.
@@ -343,6 +345,8 @@ extern unsigned long get_clock_freq(void
#define CONFIG_SYS_64BIT_VSPRINTF 1
#define CONFIG_SYS_64BIT_STRTOUL 1
+
+#ifndef CONFIG_NEW_I2C
/*
* I2C
*/
@@ -353,6 +357,57 @@ extern unsigned long get_clock_freq(void
#define CONFIG_SYS_I2C_SLAVE 0x7F
#define CONFIG_SYS_I2C_NOPROBES {0x69} /* Don't probe these addrs */
#define CONFIG_SYS_I2C_OFFSET 0x3000
+#else /* CONFIG_NEW_I2C */
+#if 0
+/*
+ * Illustrative example with 3 I2C adapters and 5 I2C busses.
+ *
+ * Adapters: 2x FSL_I2C (0 and 1) and SM502 adapter (3)
+ *
+ * Busses:
+ *
+ * 0: Direct off of FSL_I2C[0]
+ * 1: FSL_I2C[1]->PCA9542(0)->PCA9542(0)
+ * 2: FSL_I2C[1]->PCA9542(0)->PCA9542(1)
+ * 3: FSL_I2C[1]->PCA9542(1)
+ * 4: SM502_I2C
+ *
+ * This might not have sense (it is much more logical to use a single
+ * PCA9544 for 3 busses off of FSL_I2C[1]) but it is just an illustrative
+ * example.
+ */
+#define CONFIG_SYS_NUM_I2C_ADAPTERS 3
+#define CONFIG_SYS_NUM_I2C_BUSSES 5
+#define CONFIG_SYS_I2C_MAX_HOPS 2
+#define CONFIG_SM502_I2C /* Use SM502 I2C driver */
+#define CONFIG_SYS_SM501_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CONFIG_SYS_SM501_I2C_SLAVE 0x7F /* Adapter #1 */
+#define CONFIG_SYS_SM501_BASEADDR 0x80000000 /* Bogus */
+#define CONFIG_FSL_UNI_I2C /* Use FSL common I2C driver */
+#define CONFIG_SYS_FSL_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F /* Adapter #1 */
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000
+#define CONFIG_SYS_FSL_I2C2_SPEED 400000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C2_SLAVE 0x7F /* Adapter #2 */
+#define CONFIG_SYS_FSL_I2C2_OFFSET 0x3100
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0], &fsl_i2c_adap[1], &sm501_i2c_adap}
+#define CONFIG_SYS_I2C_BUSSES { {0, {I2C_NULL_HOP, I2C_NULL_HOP}}, \
+ {1, {{I2C_MUX_PCA9542, 0x70, 0}, {I2C_MUX_PCA9542, 0x71, 0}}}, \
+ {1, {{I2C_MUX_PCA9542, 0x70, 0}, {I2C_MUX_PCA9542, 0x71, 1}}}, \
+ {1, {{I2C_MUX_PCA9542, 0x70, 1}, I2C_NULL_HOP}}, \
+ {2, {I2C_NULL_HOP, I2C_NULL_HOP}}}
+#define CONFIG_SYS_I2C_NOPROBES {{0,0x69},{1,0x69}} /* Don't probe these addrs */
+#else
+#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
+#define CONFIG_SYS_NUM_I2C_BUSSES 1
+#define CONFIG_FSL_UNI_I2C /* Use FSL common I2C driver */
+#define CONFIG_SYS_FSL_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F /* Adapter #1 */
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000
+#define CONFIG_SYS_I2C_NOPROBES {0x69} /* Don't probe these addrs */
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
+#endif
+#endif /* CONFIG_NEW_I2C */
/* EEPROM */
#define CONFIG_ID_EEPROM
@@ -482,8 +537,11 @@ extern unsigned long get_clock_freq(void
*/
#include <config_cmd_default.h>
+#define CONFIG_I2C_CMD_TREE
+
#define CONFIG_CMD_PING
#define CONFIG_CMD_I2C
+#define CONFIG_CMD_SDRAM
#define CONFIG_CMD_MII
#define CONFIG_CMD_ELF
#define CONFIG_CMD_IRQ
---
******************************************************************
* KSI@home KOI8 Net < > The impossible we do immediately. *
* Las Vegas NV, USA < > Miracles require 24-hour notice. *
******************************************************************
1
0