Browse Source

Merge with /home/wd/git/u-boot/master
(Conflicts between Jon Loeliger's and Matthew McClintock's tree
were resolved by in favour of Jon's version.)

Wolfgang Denk 18 năm trước cách đây
mục cha
commit
d97370feca
100 tập tin đã thay đổi với 12389 bổ sung657 xóa
  1. 2 0
      CHANGELOG
  2. 13 0
      MAINTAINERS
  3. 8 1
      MAKEALL
  4. 40 14
      Makefile
  5. 16 2
      README
  6. 25 0
      avr32_config.mk
  7. 0 1
      board/amcc/sequoia/Makefile
  8. 1 1
      board/amcc/sequoia/config.mk
  9. 44 0
      board/atmel/atstk1000/Makefile
  10. 52 0
      board/atmel/atstk1000/atstk1000.c
  11. 4 0
      board/atmel/atstk1000/config.mk
  12. 223 0
      board/atmel/atstk1000/flash.c
  13. 79 0
      board/atmel/atstk1000/u-boot.lds.S
  14. 27 1
      board/cds/common/ft_board.c
  15. 12 7
      board/cds/common/via.c
  16. 32 0
      board/cds/mpc8548cds/mpc8548cds.c
  17. 4 0
      board/mpc8560ads/mpc8560ads.c
  18. 0 1
      board/mpc8560ads/u-boot.lds
  19. 52 0
      board/mpc8641hpcn/Makefile
  20. 31 0
      board/mpc8641hpcn/config.mk
  21. 179 0
      board/mpc8641hpcn/init.S
  22. 426 0
      board/mpc8641hpcn/mpc8641hpcn.c
  23. 321 0
      board/mpc8641hpcn/pixis.c
  24. 33 0
      board/mpc8641hpcn/pixis.h
  25. 256 0
      board/mpc8641hpcn/sys_eeprom.c
  26. 148 0
      board/mpc8641hpcn/u-boot.lds
  27. 0 1
      board/sbc8560/u-boot.lds
  28. 0 1
      board/stxgp3/u-boot.lds
  29. 1 1
      common/Makefile
  30. 1 1
      common/cmd_boot.c
  31. 7 5
      common/cmd_bootm.c
  32. 66 0
      common/cmd_mac.c
  33. 6 1
      common/cmd_scsi.c
  34. 1 1
      config.mk
  35. 50 0
      cpu/at32ap/Makefile
  36. 43 0
      cpu/at32ap/at32ap7000/Makefile
  37. 448 0
      cpu/at32ap/at32ap7000/devices.c
  38. 38 0
      cpu/at32ap/at32ap7000/hebi.c
  39. 97 0
      cpu/at32ap/cache.c
  40. 22 0
      cpu/at32ap/config.mk
  41. 83 0
      cpu/at32ap/cpu.c
  42. 126 0
      cpu/at32ap/device.c
  43. 65 0
      cpu/at32ap/entry.S
  44. 119 0
      cpu/at32ap/exception.c
  45. 155 0
      cpu/at32ap/hsdramc.c
  46. 143 0
      cpu/at32ap/hsdramc1.h
  47. 126 0
      cpu/at32ap/hsmc3.h
  48. 154 0
      cpu/at32ap/interrupts.c
  49. 94 0
      cpu/at32ap/pio.c
  50. 44 0
      cpu/at32ap/pio2.h
  51. 163 0
      cpu/at32ap/pm.c
  52. 204 0
      cpu/at32ap/sm.h
  53. 113 0
      cpu/at32ap/start.S
  54. 1 1
      cpu/mpc85xx/Makefile
  55. 0 265
      cpu/mpc85xx/i2c.c
  56. 63 69
      cpu/mpc85xx/spd_sdram.c
  57. 51 0
      cpu/mpc86xx/Makefile
  58. 374 0
      cpu/mpc86xx/cache.S
  59. 26 0
      cpu/mpc86xx/config.mk
  60. 308 0
      cpu/mpc86xx/cpu.c
  61. 117 0
      cpu/mpc86xx/cpu_init.c
  62. 204 0
      cpu/mpc86xx/interrupts.c
  63. 146 0
      cpu/mpc86xx/pci.c
  64. 199 0
      cpu/mpc86xx/pcie_indirect.c
  65. 2 0
      cpu/mpc86xx/resetvec.S
  66. 1324 0
      cpu/mpc86xx/spd_sdram.c
  67. 127 0
      cpu/mpc86xx/speed.c
  68. 1226 0
      cpu/mpc86xx/start.S
  69. 226 0
      cpu/mpc86xx/traps.c
  70. 33 0
      doc/README.AVR32
  71. 123 0
      doc/README.mpc8641hpcn
  72. 4 3
      drivers/Makefile
  73. 702 0
      drivers/ahci.c
  74. 88 0
      drivers/atmel_usart.c
  75. 314 0
      drivers/atmel_usart.h
  76. 241 0
      drivers/fsl_i2c.c
  77. 2 1
      drivers/pci_auto.c
  78. 1 0
      drivers/rtl8139.c
  79. 346 262
      drivers/tsec.c
  80. 36 1
      drivers/tsec.h
  81. 34 16
      examples/Makefile
  82. 13 0
      examples/stubs.c
  83. 190 0
      include/ahci.h
  84. 46 0
      include/asm-avr32/addrspace.h
  85. 232 0
      include/asm-avr32/arch-at32ap7000/hmatrix2.h
  86. 61 0
      include/asm-avr32/arch-at32ap7000/memory-map.h
  87. 146 0
      include/asm-avr32/arch-at32ap7000/platform.h
  88. 25 0
      include/asm-avr32/bitops.h
  89. 37 0
      include/asm-avr32/byteorder.h
  90. 83 0
      include/asm-avr32/cacheflush.h
  91. 39 0
      include/asm-avr32/div64.h
  92. 64 0
      include/asm-avr32/dma-mapping.h
  93. 132 0
      include/asm-avr32/errno.h
  94. 59 0
      include/asm-avr32/global_data.h
  95. 33 0
      include/asm-avr32/initcalls.h
  96. 92 0
      include/asm-avr32/io.h
  97. 144 0
      include/asm-avr32/posix_types.h
  98. 97 0
      include/asm-avr32/processor.h
  99. 148 0
      include/asm-avr32/ptrace.h
  100. 33 0
      include/asm-avr32/sdram.h

+ 2 - 0
CHANGELOG

@@ -2,6 +2,8 @@
 Changes for U-Boot 1.1.5:
 ======================================================================
 
+* Fix sequoia separate object direcory building problems.
+
 * Cleanup compile warnings. Prepare for release 1.1.5
 
 * Fix compile problem in include/configs/ep82xxm.h

+ 13 - 0
MAINTAINERS

@@ -218,6 +218,8 @@ Jon Loeliger <jdl@freescale.com>
 	MPC8541CDS		MPC8541
 	MPC8555CDS		MPC8555
 
+	MPC8641HPCN		MPC8641D
+
 Dan Malek <dan@embeddededge.com>
 
 	STxGP3			MPC85xx
@@ -554,6 +556,17 @@ Zachary P. Landau <zachary.landau@labxtechnologies.com>
 
 	r5200			mcf52x2
 
+#########################################################################
+# AVR32 Systems:							#
+#									#
+# Maintainer Name, Email Address					#
+#	Board			CPU					#
+#########################################################################
+
+Haavard Skinnemoen <hskinnemoen@atmel.com>
+
+	ATSTK1000		AT32AP7000
+
 #########################################################################
 # End of MAINTAINERS list						#
 #########################################################################

+ 8 - 1
MAKEALL

@@ -302,6 +302,12 @@ LIST_coldfire="	\
 	r5200		M5271EVB					\
 "
 
+#########################################################################
+## AVR32 Systems
+#########################################################################
+
+LIST_avr32="atstk1002"
+
 #-----------------------------------------------------------------------
 
 #----- for now, just run PPC by default -----
@@ -334,7 +340,8 @@ do
 	mips|mips_el| \
 	nios|nios2| \
 	x86|I486| \
-	coldfire)
+	coldfire| \
+	avr32)
 			for target in `eval echo '$LIST_'${arg}`
 			do
 				build_target ${target}

+ 40 - 14
Makefile

@@ -152,6 +152,9 @@ endif
 ifeq ($(ARCH),blackfin)
 CROSS_COMPILE = bfin-elf-
 endif
+ifeq ($(ARCH),avr32)
+CROSS_COMPILE = avr32-
+endif
 endif
 endif
 
@@ -177,6 +180,9 @@ endif
 ifeq ($(CPU),mpc85xx)
 OBJS += cpu/$(CPU)/resetvec.o
 endif
+ifeq ($(CPU),mpc86xx)
+OBJS += cpu/$(CPU)/resetvec.o
+endif
 ifeq ($(CPU),bf533)
 OBJS += cpu/$(CPU)/start1.o	cpu/$(CPU)/interrupt.o	cpu/$(CPU)/cache.o
 OBJS += cpu/$(CPU)/cplbhdlr.o	cpu/$(CPU)/cplbmgr.o	cpu/$(CPU)/flush.o
@@ -269,10 +275,10 @@ $(SUBDIRS):
 		$(MAKE) -C $@ all
 
 $(NAND_SPL):	version
-		$(MAKE) -C nand_spl all
+		$(MAKE) -C nand_spl/board/$(BOARDDIR) all
 
 $(U_BOOT_NAND):	$(NAND_SPL) $(obj)u-boot.bin
-		cat nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
+		cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
 
 version:
 		@echo -n "#define U_BOOT_VERSION \"U-Boot " > $(VERSION_FILE); \
@@ -1146,19 +1152,22 @@ PPChameleonEVB_HI_33_config:	unconfig
 	@$(MKCONFIG) -a $(call xtract_4xx,$@) ppc ppc4xx PPChameleonEVB dave
 
 rainier_config:	unconfig
-	@echo "#define CONFIG_RAINIER" > include/config.h
+	@mkdir -p $(obj)include
+	@echo "#define CONFIG_RAINIER" > $(obj)include/config.h
 	@echo "Configuring for rainier board as subset of sequoia..."
 	@$(MKCONFIG) -a sequoia ppc ppc4xx sequoia amcc
 
 rainier_nand_config:	unconfig
-	@echo "#define CONFIG_RAINIER" > include/config.h
+	@mkdir -p $(obj)include
+	@mkdir -p $(obj)nand_spl
+	@mkdir -p $(obj)board/amcc/sequoia
+	@echo "#define CONFIG_RAINIER" > $(obj)include/config.h
 	@echo "Configuring for rainier board as subset of sequoia..."
-	@ln -s board/amcc/sequoia/Makefile nand_spl/Makefile
-	@echo "#define CONFIG_NAND_U_BOOT" >> include/config.h
+	@echo "#define CONFIG_NAND_U_BOOT" >> $(obj)include/config.h
 	@echo "Compile NAND boot image for sequoia"
 	@$(MKCONFIG) -a sequoia ppc ppc4xx sequoia amcc
-	@echo "TEXT_BASE = 0x01000000" >board/amcc/sequoia/config.tmp
-	@echo "CONFIG_NAND_U_BOOT = y" >> include/config.mk
+	@echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/sequoia/config.tmp
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 
 sbc405_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx sbc405
@@ -1167,12 +1176,14 @@ sequoia_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx sequoia amcc
 
 sequoia_nand_config:	unconfig
-	@ln -s board/amcc/sequoia/Makefile nand_spl/Makefile
-	@echo "#define CONFIG_NAND_U_BOOT" >include/config.h
+	@mkdir -p $(obj)include
+	@mkdir -p $(obj)nand_spl
+	@mkdir -p $(obj)board/amcc/sequoia
+	@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 	@echo "Compile NAND boot image for sequoia"
 	@$(MKCONFIG) -a sequoia ppc ppc4xx sequoia amcc
-	@echo "TEXT_BASE = 0x01000000" >board/amcc/sequoia/config.tmp
-	@echo "CONFIG_NAND_U_BOOT = y" >> include/config.mk
+	@echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/sequoia/config.tmp
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 
 sycamore_config:	unconfig
 	@echo "Configuring for sycamore board as subset of walnut..."
@@ -1668,6 +1679,14 @@ TQM8560_config:		unconfig
 	echo "#define CFG_BOOTFILE \"bootfile=/tftpboot/tqm$${CTYPE}/uImage\0\"">>$(obj)include/config.h
 	@$(MKCONFIG) -a TQM85xx ppc mpc85xx tqm85xx
 
+#########################################################################
+## MPC86xx Systems
+#########################################################################
+
+MPC8641HPCN_config:    unconfig
+	@./mkconfig $(@:_config=) ppc mpc86xx mpc8641hpcn
+
+
 #########################################################################
 ## 74xx/7xx Systems
 #########################################################################
@@ -2099,6 +2118,13 @@ pb1000_config		: 	unconfig
 	@echo "#define CONFIG_PB1000 1" >>$(obj)include/config.h
 	@$(MKCONFIG) -a pb1x00 mips mips pb1x00
 
+#========================================================================
+# AVR32
+#========================================================================
+#########################################################################
+## AT32AP7xxx
+#########################################################################
+
 #########################################################################
 ## MIPS64 5Kc
 #########################################################################
@@ -2244,8 +2270,7 @@ clean:
 	rm -f $(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom
 	rm -f $(obj)board/integratorap/u-boot.lds $(obj)board/integratorcp/u-boot.lds
 	rm -f $(obj)include/bmp_logo.h
-	find nand_spl -lname "*" -print | xargs rm -f
-	rm -f nand_spl/u-boot-spl nand_spl/u-boot-spl.map
+	rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
 
 clobber:	clean
 	find $(OBJTREE) -type f \( -name .depend \
@@ -2258,6 +2283,7 @@ clobber:	clean
 	rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c
 	rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
 	rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
+	[ ! -d $(OBJTREE)/nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
 
 ifeq ($(OBJTREE),$(SRCTREE))
 mrproper \

+ 16 - 2
README

@@ -132,6 +132,7 @@ Directory Hierarchy:
   - arm925t	Files specific to ARM 925 CPUs
   - arm926ejs	Files specific to ARM 926 CPUs
   - arm1136	Files specific to ARM 1136 CPUs
+  - at32ap	Files specific to Atmel AVR32 AP CPUs
   - i386	Files specific to i386 CPUs
   - ixp		Files specific to Intel XScale IXP CPUs
   - mcf52x2	Files specific to Freescale ColdFire MCF52x2 CPUs
@@ -156,6 +157,7 @@ Directory Hierarchy:
 - examples	Example code for standalone applications, etc.
 - include	Header Files
 - lib_arm	Files generic to ARM	 architecture
+- lib_avr32	Files generic to AVR32	 architecture
 - lib_generic	Files generic to all	 architectures
 - lib_i386	Files generic to i386	 architecture
 - lib_m68k	Files generic to m68k	 architecture
@@ -256,6 +258,9 @@ The following options need to be configured:
 		----------------------
 		CONFIG_NIOS2
 
+		AVR32 based CPUs:
+		----------------------
+		CONFIG_AT32AP
 
 - Board Type:	Define exactly one of
 
@@ -325,6 +330,15 @@ The following options need to be configured:
 		CONFIG_PCI5441 CONFIG_PK1C20
 		CONFIG_EP1C20 CONFIG_EP1S10 CONFIG_EP1S40
 
+		AVR32 based boards:
+		-------------------
+
+		CONFIG_ATSTK1000
+
+- CPU Daughterboard Type: (if CONFIG_ATSTK1000 is defined)
+		Define exactly one of
+		CONFIG_ATSTK1002
+
 
 - CPU Module Type: (if CONFIG_COGENT is defined)
 		Define exactly one of
@@ -2727,9 +2741,9 @@ defines the following image properties:
   4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
   LynxOS, pSOS, QNX, RTEMS, ARTOS;
   Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS).
-* Target CPU Architecture (Provisions for Alpha, ARM, Intel x86,
+* Target CPU Architecture (Provisions for Alpha, ARM, AVR32, Intel x86,
   IA64, MIPS, NIOS, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit;
-  Currently supported: ARM, Intel x86, MIPS, NIOS, PowerPC).
+  Currently supported: ARM, AVR32, Intel x86, MIPS, NIOS, PowerPC).
 * Compression Type (uncompressed, gzip, bzip2)
 * Load Address
 * Entry Point

+ 25 - 0
avr32_config.mk

@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2000-2002
+# Wolfgang Denk, DENX Software Engineering, wd@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
+#
+
+PLATFORM_RELFLAGS	+= -ffixed-r5 -mno-pic -mrelax
+PLATFORM_LDFLAGS	+= --relax

+ 0 - 1
board/amcc/sequoia/Makefile

@@ -22,7 +22,6 @@
 #
 
 include $(TOPDIR)/config.mk
-include $(TOPDIR)/include/config.mk
 
 LIB	= $(obj)lib$(BOARD).a
 

+ 1 - 1
board/amcc/sequoia/config.mk

@@ -24,7 +24,7 @@
 # AMCC 440EPx Reference Platform (Sequoia) board
 #
 
-sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
 
 ifndef TEXT_BASE
 TEXT_BASE = 0xFFFA0000

+ 44 - 0
board/atmel/atstk1000/Makefile

@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2001-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o flash.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 52 - 0
board/atmel/atstk1000/atstk1000.c

@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/sdram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct sdram_info sdram = {
+	.phys_addr	= CFG_SDRAM_BASE,
+	.row_bits	= 11,
+	.col_bits	= 8,
+	.bank_bits	= 2,
+	.cas		= 3,
+	.twr		= 2,
+	.trc		= 7,
+	.trp		= 2,
+	.trcd		= 2,
+	.tras		= 5,
+	.txsr		= 5,
+};
+
+void board_init_memories(void)
+{
+	gd->sdram_size = sdram_init(&sdram);
+}
+
+void board_init_info(void)
+{
+	gd->bd->bi_phy_id[0] = 0x10;
+	gd->bd->bi_phy_id[1] = 0x11;
+}

+ 4 - 0
board/atmel/atstk1000/config.mk

@@ -0,0 +1,4 @@
+PLATFORM_RELFLAGS	+= -ffunction-sections -fdata-sections
+PLATFORM_LDFLAGS	+= --gc-sections
+TEXT_BASE		= 0x00000000
+LDSCRIPT		= $(obj)board/atmel/atstk1000/u-boot.lds

+ 223 - 0
board/atmel/atstk1000/flash.c

@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#ifdef CONFIG_ATSTK1000_EXT_FLASH
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/sections.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+flash_info_t flash_info[1];
+
+static void __flashprog flash_identify(uint16_t *flash, flash_info_t *info)
+{
+	unsigned long flags;
+
+	flags = disable_interrupts();
+
+	dcache_flush_unlocked();
+
+	writew(0xaa, flash + 0x555);
+	writew(0x55, flash + 0xaaa);
+	writew(0x90, flash + 0x555);
+	info->flash_id = readl(flash);
+	writew(0xff, flash);
+
+	readw(flash);
+
+	if (flags)
+		enable_interrupts();
+}
+
+unsigned long flash_init(void)
+{
+	unsigned long addr;
+	unsigned int i;
+
+	gd->bd->bi_flashstart = CFG_FLASH_BASE;
+	gd->bd->bi_flashsize = CFG_FLASH_SIZE;
+	gd->bd->bi_flashoffset = __edata_lma - _text;
+
+	flash_info[0].size = CFG_FLASH_SIZE;
+	flash_info[0].sector_count = 135;
+
+	flash_identify(uncached((void *)CFG_FLASH_BASE), &flash_info[0]);
+
+	for (i = 0, addr = 0; i < 8; i++, addr += 0x2000)
+		flash_info[0].start[i] = addr;
+	for (; i < flash_info[0].sector_count; i++, addr += 0x10000)
+		flash_info[0].start[i] = addr;
+
+	return CFG_FLASH_SIZE;
+}
+
+void flash_print_info(flash_info_t *info)
+{
+	printf("Flash: Vendor ID: 0x%02x, Product ID: 0x%02x\n",
+	       info->flash_id >> 16, info->flash_id & 0xffff);
+	printf("Size: %ld MB in %d sectors\n",
+	       info->size >> 10, info->sector_count);
+}
+
+int __flashprog flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+	unsigned long flags;
+	unsigned long start_time;
+	uint16_t *fb, *sb;
+	unsigned int i;
+	int ret;
+	uint16_t status;
+
+	if ((s_first < 0) || (s_first > s_last)
+	    || (s_last >= info->sector_count)) {
+		puts("Error: first and/or last sector out of range\n");
+		return ERR_INVAL;
+	}
+
+	for (i = s_first; i < s_last; i++)
+		if (info->protect[i]) {
+			printf("Error: sector %d is protected\n", i);
+			return ERR_PROTECTED;
+		}
+
+	fb = (uint16_t *)uncached(info->start[0]);
+
+	dcache_flush_unlocked();
+
+	for (i = s_first; (i <= s_last) && !ctrlc(); i++) {
+		printf("Erasing sector %3d...", i);
+
+		sb = (uint16_t *)uncached(info->start[i]);
+
+		flags = disable_interrupts();
+
+		start_time = get_timer(0);
+
+		/* Unlock sector */
+		writew(0xaa, fb + 0x555);
+		writew(0x70, sb);
+
+		/* Erase sector */
+		writew(0xaa, fb + 0x555);
+		writew(0x55, fb + 0xaaa);
+		writew(0x80, fb + 0x555);
+		writew(0xaa, fb + 0x555);
+		writew(0x55, fb + 0xaaa);
+		writew(0x30, sb);
+
+		/* Wait for completion */
+		ret = ERR_OK;
+		do {
+			/* TODO: Timeout */
+			status = readw(sb);
+		} while ((status != 0xffff) && !(status & 0x28));
+
+		writew(0xf0, fb);
+
+		/*
+		 * Make sure the command actually makes it to the bus
+		 * before we re-enable interrupts.
+		 */
+		readw(fb);
+
+		if (flags)
+			enable_interrupts();
+
+		if (status != 0xffff) {
+			printf("Flash erase error at address 0x%p: 0x%02x\n",
+			       sb, status);
+			ret = ERR_PROG_ERROR;
+			break;
+		}
+	}
+
+	if (ctrlc())
+		printf("User interrupt!\n");
+
+	return ERR_OK;
+}
+
+int __flashprog write_buff(flash_info_t *info, uchar *src,
+			   ulong addr, ulong count)
+{
+	unsigned long flags;
+	uint16_t *base, *p, *s, *end;
+	uint16_t word, status;
+	int ret = ERR_OK;
+
+	if (addr < info->start[0]
+	    || (addr + count) > (info->start[0] + info->size)
+	    || (addr + count) < addr) {
+		puts("Error: invalid address range\n");
+		return ERR_INVAL;
+	}
+
+	if (addr & 1 || count & 1 || (unsigned int)src & 1) {
+		puts("Error: misaligned source, destination or count\n");
+		return ERR_ALIGN;
+	}
+
+	base = (uint16_t *)uncached(info->start[0]);
+	end = (uint16_t *)uncached(addr + count);
+
+	flags = disable_interrupts();
+
+	dcache_flush_unlocked();
+	sync_write_buffer();
+
+	for (p = (uint16_t *)uncached(addr), s = (uint16_t *)src;
+	     p < end && !ctrlc(); p++, s++) {
+		word = *s;
+
+		writew(0xaa, base + 0x555);
+		writew(0x55, base + 0xaaa);
+		writew(0xa0, base + 0x555);
+		writew(word, p);
+
+		sync_write_buffer();
+
+		/* Wait for completion */
+		do {
+			/* TODO: Timeout */
+			status = readw(p);
+		} while ((status != word) && !(status & 0x28));
+
+		writew(0xf0, base);
+		readw(base);
+
+		if (status != word) {
+			printf("Flash write error at address 0x%p: 0x%02x\n",
+			       p, status);
+			ret = ERR_PROG_ERROR;
+			break;
+		}
+	}
+
+	if (flags)
+		enable_interrupts();
+
+	return ret;
+}
+
+#endif /* CONFIG_ATSTK1000_EXT_FLASH */

+ 79 - 0
board/atmel/atstk1000/u-boot.lds.S

@@ -0,0 +1,79 @@
+/* -*- Fundamental -*-
+ *
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+
+OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
+OUTPUT_ARCH(avr32)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = CFG_FLASH_BASE;
+	_text = .;
+	.text : {
+		*(.text)
+		*(.text.*)
+	}
+
+	. = ALIGN(CFG_ICACHE_LINESZ);
+	__flashprog_start = .;
+	.flashprog : {
+		*(.flashprog)
+	}
+	. = ALIGN(CFG_ICACHE_LINESZ);
+	__flashprog_end = .;
+
+	. = ALIGN(8);
+	.rodata : {
+		*(.rodata)
+		*(.rodata.*)
+	}
+	_etext = .;
+
+	__data_lma = ALIGN(8);
+	. = CFG_INTRAM_BASE;
+	_data = .;
+	.data : AT(__data_lma) {
+		*(.data)
+		*(.data.*)
+	}
+
+	. = ALIGN(4);
+	__u_boot_cmd_start = .;
+	__u_boot_cmd_lma = __data_lma + (__u_boot_cmd_start - _data);
+	.u_boot_cmd : AT(__u_boot_cmd_lma) {
+		KEEP(*(.u_boot_cmd))
+	}
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(8);
+	_edata = .;
+	__edata_lma = __u_boot_cmd_lma + (_edata - __u_boot_cmd_start);
+
+	.bss : AT(__edata_lma) {
+		*(.bss)
+		*(.bss.*)
+	}
+	. = ALIGN(8);
+	_end = .;
+}

+ 27 - 1
board/cds/common/ft_board.c

@@ -24,9 +24,33 @@
 
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
+#include "cadmus.h"
+
 extern void ft_cpu_setup(void *blob, bd_t *bd);
-#endif
 
+static void cds_pci_fixup(void *blob)
+{
+	int len;
+	u32 *map;
+	int slot;
+	int i;
+
+	map = ft_get_prop(blob, "/" OF_SOC "/pci@8000/interrupt-map", &len);
+
+	len /= sizeof(u32);
+
+	slot = get_pci_slot();
+
+	for (i=0;i<len;i+=7) {
+		/* We rotate the interrupt pins so that the mapping
+		 * changes depending on the slot the carrier card is in.
+		 */
+		map[3] = ((map[3] + slot - 2) % 4) + 1;
+
+		map+=7;
+	}
+}
+#endif
 
 #if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
 void
@@ -45,5 +69,7 @@ ft_board_setup(void *blob, bd_t *bd)
 		*p++ = cpu_to_be32(bd->bi_memstart);
 		*p = cpu_to_be32(bd->bi_memsize);
 	}
+
+	cds_pci_fixup(blob);
 }
 #endif

+ 12 - 7
board/cds/common/via.c

@@ -24,7 +24,8 @@
 #include <pci.h>
 
 /* Config the VIA chip */
-void mpc85xx_config_via(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via(struct pci_controller *hose,
+			pci_dev_t dev, struct pci_config_table *tab)
 {
 	pci_dev_t bridge;
 
@@ -47,7 +48,8 @@ void mpc85xx_config_via(struct pci_controller* hose, pci_dev_t dev, struct pci_c
 }
 
 /* Function 1, IDE */
-void mpc85xx_config_via_usbide(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via_usbide(struct pci_controller *hose,
+			       pci_dev_t dev, struct pci_config_table *tab)
 {
 	pciauto_config_device(hose, dev);
 	/*
@@ -64,7 +66,8 @@ void mpc85xx_config_via_usbide(struct pci_controller* hose, pci_dev_t dev, struc
 }
 
 /* Function 2, USB ports 0-1 */
-void mpc85xx_config_via_usb(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via_usb(struct pci_controller *hose,
+			    pci_dev_t dev, struct pci_config_table *tab)
 {
 	pciauto_config_device(hose, dev);
 
@@ -72,7 +75,8 @@ void mpc85xx_config_via_usb(struct pci_controller* hose, pci_dev_t dev, struct p
 }
 
 /* Function 3, USB ports 2-3 */
-void mpc85xx_config_via_usb2(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via_usb2(struct pci_controller *hose,
+			     pci_dev_t dev, struct pci_config_table *tab)
 {
 	pciauto_config_device(hose, dev);
 
@@ -80,7 +84,8 @@ void mpc85xx_config_via_usb2(struct pci_controller* hose, pci_dev_t dev, struct
 }
 
 /* Function 5, Power Management */
-void mpc85xx_config_via_power(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via_power(struct pci_controller *hose,
+			      pci_dev_t dev, struct pci_config_table *tab)
 {
 	pciauto_config_device(hose, dev);
 
@@ -90,10 +95,10 @@ void mpc85xx_config_via_power(struct pci_controller* hose, pci_dev_t dev, struct
 }
 
 /* Function 6, AC97 Interface */
-void mpc85xx_config_via_ac97(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab)
+void mpc85xx_config_via_ac97(struct pci_controller *hose,
+			     pci_dev_t dev, struct pci_config_table *tab)
 {
 	pciauto_config_device(hose, dev);
 
 	pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1c00);
 }
-

+ 32 - 0
board/cds/mpc8548cds/mpc8548cds.c

@@ -27,6 +27,7 @@
 #include <asm/processor.h>
 #include <asm/immap_85xx.h>
 #include <spd.h>
+#include <miiphy.h>
 
 #include "../common/cadmus.h"
 #include "../common/eeprom.h"
@@ -325,3 +326,34 @@ pci_init_board(void)
 	pci_mpc85xx_init(&hose);
 #endif
 }
+
+int last_stage_init(void)
+{
+	unsigned short temp;
+
+	/* Change the resistors for the PHY */
+	/* This is needed to get the RGMII working for the 1.3+
+	 * CDS cards */
+	if (get_board_version() ==  0x13) {
+		miiphy_write(CONFIG_MPC85XX_TSEC1_NAME,
+				TSEC1_PHY_ADDR, 29, 18);
+
+		miiphy_read(CONFIG_MPC85XX_TSEC1_NAME,
+				TSEC1_PHY_ADDR, 30, &temp);
+
+		temp = (temp & 0xf03f);
+		temp |= 2 << 9;		/* 36 ohm */
+		temp |= 2 << 6;		/* 39 ohm */
+
+		miiphy_write(CONFIG_MPC85XX_TSEC1_NAME,
+				TSEC1_PHY_ADDR, 30, temp);
+
+		miiphy_write(CONFIG_MPC85XX_TSEC1_NAME,
+				TSEC1_PHY_ADDR, 29, 3);
+
+		miiphy_write(CONFIG_MPC85XX_TSEC1_NAME,
+				TSEC1_PHY_ADDR, 30, 0x8000);
+	}
+
+	return 0;
+}

+ 4 - 0
board/mpc8560ads/mpc8560ads.c

@@ -33,6 +33,10 @@
 #include <spd.h>
 #include <miiphy.h>
 
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 extern void ddr_enable_ecc(unsigned int dram_size);
 #endif

+ 0 - 1
board/mpc8560ads/u-boot.lds

@@ -74,7 +74,6 @@ SECTIONS
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
     cpu/mpc85xx/speed.o (.text)
-    cpu/mpc85xx/i2c.o (.text)
     cpu/mpc85xx/spd_sdram.o (.text)
     common/dlmalloc.o (.text)
     lib_generic/crc32.o (.text)

+ 52 - 0
board/mpc8641hpcn/Makefile

@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2001
+# Wolfgang Denk, DENX Software Engineering, wd@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$(BOARD).a
+
+COBJS	:= $(BOARD).o pixis.o sys_eeprom.o
+SOBJS	:= init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(OBJS) $(SOBJS)
+
+.PHONY: distclean
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude ($obj).depend
+
+#########################################################################

+ 31 - 0
board/mpc8641hpcn/config.mk

@@ -0,0 +1,31 @@
+# Copyright 2004 Freescale Semiconductor.
+# Modified by Jeff Brown
+#
+# 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
+#
+
+#
+# mpc8641hpcn board
+# default CCSRBAR is at 0xff700000
+# assume U-Boot is less than 0.5MB
+#
+TEXT_BASE = 0xfff01000
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx=1
+PLATFORM_CPPFLAGS += -DCONFIG_MPC8641=1 -maltivec -mabi=altivec -msoft-float

+ 179 - 0
board/mpc8641hpcn/init.S

@@ -0,0 +1,179 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <config.h>
+#include <mpc86xx.h>
+
+/*
+ * LAW(Local Access Window) configuration:
+ *
+ * 0x0000_0000     0x7fff_ffff     DDR                     2G
+ * 0x8000_0000     0x9fff_ffff     PCI1 MEM                512M
+ * 0xa000_0000     0xbfff_ffff     PCI2 MEM                512M
+ * 0xc000_0000     0xdfff_ffff     RapidIO                 512M
+ * 0xe200_0000     0xe2ff_ffff     PCI1 IO                 16M
+ * 0xe300_0000     0xe3ff_ffff     PCI2 IO                 16M
+ * 0xf800_0000     0xf80f_ffff     CCSRBAR                 1M
+ * 0xf810_0000     0xf81f_ffff     PIXIS                   1M
+ * 0xfe00_0000     0xffff_ffff     FLASH (boot bank)       32M
+ *
+ * Notes:
+ *    CCSRBAR don't need a configured Local Access Window.
+ *    If flash is 8M at default position (last 8M), no LAW needed.
+ */
+
+#if !defined(CONFIG_SPD_EEPROM)
+#define LAWBAR1 ((CFG_DDR_SDRAM_BASE>>12) & 0xffffff)
+#define LAWAR1	(LAWAR_EN | LAWAR_TRGT_IF_DDR1 | (LAWAR_SIZE & LAWAR_SIZE_256M))
+#else
+#define LAWBAR1 0
+#define LAWAR1  ((LAWAR_TRGT_IF_DDR1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) & ~LAWAR_EN)
+#endif
+
+#define LAWBAR2 ((CFG_PCI1_MEM_BASE>>12) & 0xffffff)
+#define LAWAR2	(LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M))
+
+#define LAWBAR3 ((CFG_PCI2_MEM_BASE>>12) & 0xffffff)
+#define LAWAR3	(~LAWAR_EN & (LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M)))
+
+/*
+ * This is not so much the SDRAM map as it is the whole localbus map.
+ */
+#define LAWBAR4 ((0xf8100000>>12) & 0xffffff)
+#define LAWAR4	(LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_2M))
+
+#define LAWBAR5 ((CFG_PCI1_IO_BASE>>12) & 0xffffff)
+#define LAWAR5	(LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M))
+
+#define LAWBAR6 ((CFG_PCI2_IO_BASE>>12) & 0xffffff)
+#define LAWAR6	(~LAWAR_EN &( LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M)))
+
+#define LAWBAR7 ((0xfe000000 >>12) & 0xffffff)
+#define LAWAR7	(LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_32M))
+
+#if !defined(CONFIG_SPD_EEPROM)
+#define LAWBAR8 ((CFG_DDR_SDRAM_BASE>>12) & 0xffffff)
+#define LAWAR8 (LAWAR_EN | LAWAR_TRGT_IF_DDR2 | (LAWAR_SIZE & LAWAR_SIZE_256M))
+#else
+#define LAWBAR8 0
+#define LAWAR8  ((LAWAR_TRGT_IF_DDR2 | (LAWAR_SIZE & LAWAR_SIZE_512M)) & ~LAWAR_EN)
+#endif
+
+#define LAWBAR9 ((CFG_RIO_MEM_BASE>>12) & 0xfffff)
+#define LAWAR9  (LAWAR_EN | LAWAR_TRGT_IF_RIO | (LAWAR_SIZE & LAWAR_SIZE_512M))
+
+	.section .bootpg, "ax"
+	.globl	law_entry
+law_entry:
+	lis	r7,CFG_CCSRBAR@h
+	ori	r7,r7,CFG_CCSRBAR@l
+
+	addi    r4,r7,0
+	addi    r5,r7,0
+
+	/* Skip LAWAR0, start at LAWAR1 */
+	lis     r6,LAWBAR1@h
+	ori     r6,r6,LAWBAR1@l
+	stwu    r6, 0xc28(r4)
+
+	lis     r6,LAWAR1@h
+	ori     r6,r6,LAWAR1@l
+	stwu    r6, 0xc30(r5)
+
+	/* LAWBAR2, LAWAR2 */
+	lis     r6,LAWBAR2@h
+	ori     r6,r6,LAWBAR2@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR2@h
+	ori     r6,r6,LAWAR2@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR3, LAWAR3 */
+	lis     r6,LAWBAR3@h
+	ori     r6,r6,LAWBAR3@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR3@h
+	ori     r6,r6,LAWAR3@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR4, LAWAR4 */
+	lis     r6,LAWBAR4@h
+	ori     r6,r6,LAWBAR4@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR4@h
+	ori     r6,r6,LAWAR4@l
+	stwu    r6, 0x20(r5)
+	/* LAWBAR5, LAWAR5 */
+	lis     r6,LAWBAR5@h
+	ori     r6,r6,LAWBAR5@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR5@h
+	ori     r6,r6,LAWAR5@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR6, LAWAR6 */
+	lis     r6,LAWBAR6@h
+	ori     r6,r6,LAWBAR6@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR6@h
+	ori     r6,r6,LAWAR6@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR7, LAWAR7 */
+	lis     r6,LAWBAR7@h
+	ori     r6,r6,LAWBAR7@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR7@h
+	ori     r6,r6,LAWAR7@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR8, LAWAR8 */
+	lis     r6,LAWBAR8@h
+	ori     r6,r6,LAWBAR8@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR8@h
+	ori     r6,r6,LAWAR8@l
+	stwu    r6, 0x20(r5)
+
+	/* LAWBAR9, LAWAR9 */
+	lis     r6,LAWBAR9@h
+	ori     r6,r6,LAWBAR9@l
+	stwu    r6, 0x20(r4)
+
+	lis     r6,LAWAR9@h
+	ori     r6,r6,LAWAR9@l
+	stwu    r6, 0x20(r5)
+
+	blr

+ 426 - 0
board/mpc8641hpcn/mpc8641hpcn.c

@@ -0,0 +1,426 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.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 <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/immap_86xx.h>
+#include <spd.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+extern void ft_cpu_setup(void *blob, bd_t *bd);
+#endif
+
+#include "pixis.h"
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void ddr_enable_ecc(unsigned int dram_size);
+#endif
+
+#if defined(CONFIG_SPD_EEPROM)
+#include "spd_sdram.h"
+#endif
+
+void sdram_init(void);
+long int fixed_sdram(void);
+
+
+int board_early_init_f(void)
+{
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: MPC8641HPCN\n");
+
+#ifdef CONFIG_PCI
+
+	volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	volatile ccsr_pex_t *pex1 = &immap->im_pex1;
+
+	uint devdisr = gur->devdisr;
+	uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
+	uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
+	uint pex1_agent = (host1_agent == 0) || (host1_agent == 1);
+
+	if ((io_sel == 2 || io_sel == 3 || io_sel == 5
+	     || io_sel == 6 || io_sel == 7 || io_sel == 0xF)
+	    && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
+		debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host");
+		debug("0x%08x=0x%08x ", &pex1->pme_msg_det, pex1->pme_msg_det);
+		if (pex1->pme_msg_det) {
+			pex1->pme_msg_det = 0xffffffff;
+			debug(" with errors.  Clearing.  Now 0x%08x",
+			      pex1->pme_msg_det);
+		}
+		debug("\n");
+	} else {
+		puts("PCI-EXPRESS 1: Disabled\n");
+	}
+
+#else
+	puts("PCI-EXPRESS1: Disabled\n");
+#endif
+
+	return 0;
+}
+
+
+long int
+initdram(int board_type)
+{
+	long dram_size = 0;
+
+#if defined(CONFIG_SPD_EEPROM)
+	dram_size = spd_sdram();
+#else
+	dram_size = fixed_sdram();
+#endif
+
+#if defined(CFG_RAMBOOT)
+	puts("    DDR: ");
+	return dram_size;
+#endif
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	/*
+	 * Initialize and enable DDR ECC.
+	 */
+	ddr_enable_ecc(dram_size);
+#endif
+
+	puts("    DDR: ");
+	return dram_size;
+}
+
+
+#if defined(CFG_DRAM_TEST)
+int
+testdram(void)
+{
+	uint *pstart = (uint *) CFG_MEMTEST_START;
+	uint *pend = (uint *) CFG_MEMTEST_END;
+	uint *p;
+
+	puts("SDRAM test phase 1:\n");
+	for (p = pstart; p < pend; p++)
+		*p = 0xaaaaaaaa;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0xaaaaaaaa) {
+			printf("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+
+	puts("SDRAM test phase 2:\n");
+	for (p = pstart; p < pend; p++)
+		*p = 0x55555555;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0x55555555) {
+			printf("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+
+	puts("SDRAM test passed.\n");
+	return 0;
+}
+#endif
+
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*
+ * Fixed sdram init -- doesn't use serial presence detect.
+ */
+long int
+fixed_sdram(void)
+{
+#if !defined(CFG_RAMBOOT)
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_ddr_t *ddr = &immap->im_ddr1;
+
+	ddr->cs0_bnds = CFG_DDR_CS0_BNDS;
+	ddr->cs0_config = CFG_DDR_CS0_CONFIG;
+	ddr->ext_refrec = CFG_DDR_EXT_REFRESH;
+	ddr->timing_cfg_0 = CFG_DDR_TIMING_0;
+	ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
+	ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
+	ddr->sdram_mode_1 = CFG_DDR_MODE_1;
+	ddr->sdram_mode_2 = CFG_DDR_MODE_2;
+	ddr->sdram_interval = CFG_DDR_INTERVAL;
+	ddr->sdram_data_init = CFG_DDR_DATA_INIT;
+	ddr->sdram_clk_cntl = CFG_DDR_CLK_CTRL;
+	ddr->sdram_ocd_cntl = CFG_DDR_OCD_CTRL;
+	ddr->sdram_ocd_status = CFG_DDR_OCD_STATUS;
+
+#if defined (CONFIG_DDR_ECC)
+	ddr->err_disable = 0x0000008D;
+	ddr->err_sbe = 0x00ff0000;
+#endif
+	asm("sync;isync");
+
+	udelay(500);
+
+#if defined (CONFIG_DDR_ECC)
+	/* Enable ECC checking */
+	ddr->sdram_cfg_1 = (CFG_DDR_CONTROL | 0x20000000);
+#else
+	ddr->sdram_cfg_1 = CFG_DDR_CONTROL;
+	ddr->sdram_cfg_2 = CFG_DDR_CONTROL2;
+#endif
+	asm("sync; isync");
+
+	udelay(500);
+#endif
+	return CFG_SDRAM_SIZE * 1024 * 1024;
+}
+#endif	/* !defined(CONFIG_SPD_EEPROM) */
+
+
+#if defined(CONFIG_PCI)
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_fsl86xxads_config_table[] = {
+	{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 PCI_IDSEL_NUMBER, PCI_ANY_ID,
+	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
+				     PCI_ENET0_MEMADDR,
+				     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}},
+	{}
+};
+#endif
+
+
+static struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+      config_table:pci_mpc86xxcts_config_table,
+#endif
+};
+
+#endif /* CONFIG_PCI */
+
+void pci_init_board(void)
+{
+#ifdef CONFIG_PCI
+	extern void pci_mpc86xx_init(struct pci_controller *hose);
+
+	pci_mpc86xx_init(&hose);
+#endif /* CONFIG_PCI */
+}
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+	u32 *p;
+	int len;
+
+	ft_cpu_setup(blob, bd);
+
+	p = ft_get_prop(blob, "/memory/reg", &len);
+	if (p != NULL) {
+		*p++ = cpu_to_be32(bd->bi_memstart);
+		*p = cpu_to_be32(bd->bi_memsize);
+	}
+}
+#endif
+
+
+void
+mpc8641_reset_board(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	char cmd;
+	ulong val;
+	ulong corepll;
+
+	/*
+	 * No args is a simple reset request.
+	 */
+	if (argc <= 1) {
+		out8(PIXIS_BASE + PIXIS_RST, 0);
+		/* not reached */
+	}
+
+	cmd = argv[1][1];
+	switch (cmd) {
+	case 'f':		/* reset with frequency changed */
+		if (argc < 5)
+			goto my_usage;
+		read_from_px_regs(0);
+
+		val = set_px_sysclk(simple_strtoul(argv[2], NULL, 10));
+
+		corepll = strfractoint(argv[3]);
+		val = val + set_px_corepll(corepll);
+		val = val + set_px_mpxpll(simple_strtoul(argv[4], NULL, 10));
+		if (val == 3) {
+			puts("Setting registers VCFGEN0 and VCTL\n");
+			read_from_px_regs(1);
+			puts("Resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL ....\n");
+			set_px_go();
+		} else
+			goto my_usage;
+
+		while (1) ;	/* Not reached */
+
+	case 'l':
+		if (argv[2][1] == 'f') {
+			read_from_px_regs(0);
+			read_from_px_regs_altbank(0);
+			/* reset with frequency changed */
+			val = set_px_sysclk(simple_strtoul(argv[3], NULL, 10));
+
+			corepll = strfractoint(argv[4]);
+			val = val + set_px_corepll(corepll);
+			val = val + set_px_mpxpll(simple_strtoul(argv[5],
+								 NULL, 10));
+			if (val == 3) {
+				puts("Setting registers VCFGEN0, VCFGEN1, VBOOT, and VCTL\n");
+				set_altbank();
+				read_from_px_regs(1);
+				read_from_px_regs_altbank(1);
+				puts("Enabling watchdog timer on the FPGA and resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL to boot from the other bank ....\n");
+				set_px_go_with_watchdog();
+			} else
+				goto my_usage;
+
+			while (1) ;	/* Not reached */
+
+		} else if (argv[2][1] == 'd') {
+			/*
+			 * Reset from alternate bank without changing
+			 * frequencies but with watchdog timer enabled.
+			 */
+			read_from_px_regs(0);
+			read_from_px_regs_altbank(0);
+			puts("Setting registers VCFGEN1, VBOOT, and VCTL\n");
+			set_altbank();
+			read_from_px_regs_altbank(1);
+			puts("Enabling watchdog timer on the FPGA and resetting board to boot from the other bank....\n");
+			set_px_go_with_watchdog();
+			while (1) ;	/* Not reached */
+
+		} else {
+			/*
+			 * Reset from next bank without changing
+			 * frequency and without watchdog timer enabled.
+			 */
+			read_from_px_regs(0);
+			read_from_px_regs_altbank(0);
+			if (argc > 2)
+				goto my_usage;
+			puts("Setting registers VCFGNE1, VBOOT, and VCTL\n");
+			set_altbank();
+			read_from_px_regs_altbank(1);
+			puts("Resetting board to boot from the other bank....\n");
+			set_px_go();
+		}
+
+	default:
+		goto my_usage;
+	}
+
+my_usage:
+	puts("\nUsage: reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n");
+	puts("       reset altbank [cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>]\n");
+	puts("       reset altbank [wd]\n");
+	puts("For example:   reset cf 40 2.5 10\n");
+	puts("See MPC8641HPCN Design Workbook for valid values of command line parameters.\n");
+}
+
+
+/*
+ * get_board_sys_clk
+ *      Reads the FPGA on board for CONFIG_SYS_CLK_FREQ
+ */
+
+unsigned long
+get_board_sys_clk(ulong dummy)
+{
+	u8 i, go_bit, rd_clks;
+	ulong val = 0;
+
+	go_bit = in8(PIXIS_BASE + PIXIS_VCTL);
+	go_bit &= 0x01;
+
+	rd_clks = in8(PIXIS_BASE + PIXIS_VCFGEN0);
+	rd_clks &= 0x1C;
+
+	/*
+	 * Only if both go bit and the SCLK bit in VCFGEN0 are set
+	 * should we be using the AUX register. Remember, we also set the
+	 * GO bit to boot from the alternate bank on the on-board flash
+	 */
+
+	if (go_bit) {
+		if (rd_clks == 0x1c)
+			i = in8(PIXIS_BASE + PIXIS_AUX);
+		else
+			i = in8(PIXIS_BASE + PIXIS_SPD);
+	} else {
+		i = in8(PIXIS_BASE + PIXIS_SPD);
+	}
+
+	i &= 0x07;
+
+	switch (i) {
+	case 0:
+		val = 33000000;
+		break;
+	case 1:
+		val = 40000000;
+		break;
+	case 2:
+		val = 50000000;
+		break;
+	case 3:
+		val = 66000000;
+		break;
+	case 4:
+		val = 83000000;
+		break;
+	case 5:
+		val = 100000000;
+		break;
+	case 6:
+		val = 134000000;
+		break;
+	case 7:
+		val = 166000000;
+		break;
+	}
+
+	return val;
+}

+ 321 - 0
board/mpc8641hpcn/pixis.c

@@ -0,0 +1,321 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <mpc86xx.h>
+
+#include "pixis.h"
+
+
+/*
+ * Per table 27, page 58 of MPC8641HPCN spec.
+ */
+int set_px_sysclk(ulong sysclk)
+{
+	u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
+
+	switch (sysclk) {
+	case 33:
+		sysclk_s = 0x04;
+		sysclk_r = 0x04;
+		sysclk_v = 0x07;
+		sysclk_aux = 0x00;
+		break;
+	case 40:
+		sysclk_s = 0x01;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x20;
+		sysclk_aux = 0x01;
+		break;
+	case 50:
+		sysclk_s = 0x01;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x2A;
+		sysclk_aux = 0x02;
+		break;
+	case 66:
+		sysclk_s = 0x01;
+		sysclk_r = 0x04;
+		sysclk_v = 0x04;
+		sysclk_aux = 0x03;
+		break;
+	case 83:
+		sysclk_s = 0x01;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x4B;
+		sysclk_aux = 0x04;
+		break;
+	case 100:
+		sysclk_s = 0x01;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x5C;
+		sysclk_aux = 0x05;
+		break;
+	case 134:
+		sysclk_s = 0x06;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x3B;
+		sysclk_aux = 0x06;
+		break;
+	case 166:
+		sysclk_s = 0x06;
+		sysclk_r = 0x1F;
+		sysclk_v = 0x4B;
+		sysclk_aux = 0x07;
+		break;
+	default:
+		printf("Unsupported SYSCLK frequency.\n");
+		return 0;
+	}
+
+	vclkh = (sysclk_s << 5) | sysclk_r;
+	vclkl = sysclk_v;
+
+	out8(PIXIS_BASE + PIXIS_VCLKH, vclkh);
+	out8(PIXIS_BASE + PIXIS_VCLKL, vclkl);
+
+	out8(PIXIS_BASE + PIXIS_AUX, sysclk_aux);
+
+	return 1;
+}
+
+
+int set_px_mpxpll(ulong mpxpll)
+{
+	u8 tmp;
+	u8 val;
+
+	switch (mpxpll) {
+	case 2:
+	case 4:
+	case 6:
+	case 8:
+	case 10:
+	case 12:
+	case 14:
+	case 16:
+		val = (u8) mpxpll;
+		break;
+	default:
+		printf("Unsupported MPXPLL ratio.\n");
+		return 0;
+	}
+
+	tmp = in8(PIXIS_BASE + PIXIS_VSPEED1);
+	tmp = (tmp & 0xF0) | (val & 0x0F);
+	out8(PIXIS_BASE + PIXIS_VSPEED1, tmp);
+
+	return 1;
+}
+
+
+int set_px_corepll(ulong corepll)
+{
+	u8 tmp;
+	u8 val;
+
+	switch ((int)corepll) {
+	case 20:
+		val = 0x08;
+		break;
+	case 25:
+		val = 0x0C;
+		break;
+	case 30:
+		val = 0x10;
+		break;
+	case 35:
+		val = 0x1C;
+		break;
+	case 40:
+		val = 0x14;
+		break;
+	case 45:
+		val = 0x0E;
+		break;
+	default:
+		printf("Unsupported COREPLL ratio.\n");
+		return 0;
+	}
+
+	tmp = in8(PIXIS_BASE + PIXIS_VSPEED0);
+	tmp = (tmp & 0xE0) | (val & 0x1F);
+	out8(PIXIS_BASE + PIXIS_VSPEED0, tmp);
+
+	return 1;
+}
+
+
+void read_from_px_regs(int set)
+{
+	u8 mask = 0x1C;
+	u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0);
+
+	if (set)
+		tmp = tmp | mask;
+	else
+		tmp = tmp & ~mask;
+	out8(PIXIS_BASE + PIXIS_VCFGEN0, tmp);
+}
+
+
+void read_from_px_regs_altbank(int set)
+{
+	u8 mask = 0x04;
+	u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1);
+
+	if (set)
+		tmp = tmp | mask;
+	else
+		tmp = tmp & ~mask;
+	out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp);
+}
+
+
+void set_altbank(void)
+{
+	u8 tmp;
+
+	tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
+	tmp ^= 0x40;
+
+	out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
+}
+
+
+void set_px_go(void)
+{
+	u8 tmp;
+
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp = tmp & 0x1E;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp = tmp | 0x01;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+}
+
+
+void set_px_go_with_watchdog(void)
+{
+	u8 tmp;
+
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp = tmp & 0x1E;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp = tmp | 0x09;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+}
+
+
+int disable_watchdog(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	u8 tmp;
+
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp = tmp & 0x1E;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+
+	/* setting VCTL[WDEN] to 0 to disable watch dog */
+	tmp = in8(PIXIS_BASE + PIXIS_VCTL);
+	tmp &= ~0x08;
+	out8(PIXIS_BASE + PIXIS_VCTL, tmp);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	   diswd, 1, 0, disable_watchdog,
+	   "diswd	- Disable watchdog timer \n",
+	   NULL);
+
+/*
+ * This function takes the non-integral cpu:mpx pll ratio
+ * and converts it to an integer that can be used to assign
+ * FPGA register values.
+ * input: strptr i.e. argv[2]
+ */
+
+ulong strfractoint(uchar *strptr)
+{
+	int i, j, retval;
+	int mulconst;
+	int intarr_len = 0, decarr_len = 0, no_dec = 0;
+	ulong intval = 0, decval = 0;
+	uchar intarr[3], decarr[3];
+
+	/* Assign the integer part to intarr[]
+	 * If there is no decimal point i.e.
+	 * if the ratio is an integral value
+	 * simply create the intarr.
+	 */
+	i = 0;
+	while (strptr[i] != 46) {
+		if (strptr[i] == 0) {
+			no_dec = 1;
+			break;
+		}
+		intarr[i] = strptr[i];
+		i++;
+	}
+
+	/* Assign length of integer part to intarr_len. */
+	intarr_len = i;
+	intarr[i] = '\0';
+
+	if (no_dec) {
+		/* Currently needed only for single digit corepll ratios */
+		mulconst = 10;
+		decval = 0;
+	} else {
+		j = 0;
+		i++;		/* Skipping the decimal point */
+		while ((strptr[i] > 47) && (strptr[i] < 58)) {
+			decarr[j] = strptr[i];
+			i++;
+			j++;
+		}
+
+		decarr_len = j;
+		decarr[j] = '\0';
+
+		mulconst = 1;
+		for (i = 0; i < decarr_len; i++)
+			mulconst *= 10;
+		decval = simple_strtoul(decarr, NULL, 10);
+	}
+
+	intval = simple_strtoul(intarr, NULL, 10);
+	intval = intval * mulconst;
+
+	retval = intval + decval;
+
+	return retval;
+}

+ 33 - 0
board/mpc8641hpcn/pixis.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ *
+ * 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
+ */
+
+extern int set_px_sysclk(ulong sysclk);
+extern int set_px_mpxpll(ulong mpxpll);
+extern int set_px_corepll(ulong corepll);
+extern void read_from_px_regs(int set);
+extern void read_from_px_regs_altbank(int set);
+extern void set_altbank(void);
+extern void set_px_go(void);
+extern void set_px_go_with_watchdog(void);
+extern int disable_watchdog(cmd_tbl_t *cmdtp,
+			    int flag, int argc, char *argv[]);
+extern ulong strfractoint(uchar *strptr);

+ 256 - 0
board/mpc8641hpcn/sys_eeprom.c

@@ -0,0 +1,256 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * York Sun (yorksun@freescale.com)
+ * Haiying Wang (haiying.wang@freescale.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 <command.h>
+#include <i2c.h>
+#include <linux/ctype.h>
+
+#ifdef CFG_ID_EEPROM
+typedef struct {
+	unsigned char id[4];		/* 0x0000 - 0x0003 */
+	unsigned char sn[12];		/* 0x0004 - 0x000F */
+	unsigned char errata[5];	/* 0x0010 - 0x0014 */
+	unsigned char date[7];		/* 0x0015 - 0x001a */
+	unsigned char res_1[37];	/* 0x001b - 0x003f */
+	unsigned char tab_size;		/* 0x0040 */
+	unsigned char tab_flag;		/* 0x0041 */
+	unsigned char mac[8][6];	/* 0x0042 - 0x0071 */
+	unsigned char res_2[126];	/* 0x0072 - 0x00ef */
+	unsigned int crc;		/* 0x00f0 - 0x00f3 crc32 checksum */
+} EEPROM_data;
+
+static EEPROM_data mac_data;
+
+int mac_show(void)
+{
+	int i;
+	unsigned char ethaddr[8][18];
+
+	printf("ID %c%c%c%c\n",
+	       mac_data.id[0],
+	       mac_data.id[1],
+	       mac_data.id[2],
+	       mac_data.id[3]);
+	printf("Errata %c%c%c%c%c\n",
+	       mac_data.errata[0],
+	       mac_data.errata[1],
+	       mac_data.errata[2],
+	       mac_data.errata[3],
+	       mac_data.errata[4]);
+	printf("Date %c%c%c%c%c%c%c\n",
+	       mac_data.date[0],
+	       mac_data.date[1],
+	       mac_data.date[2],
+	       mac_data.date[3],
+	       mac_data.date[4],
+	       mac_data.date[5],
+	       mac_data.date[6]);
+	for (i = 0; i < 8; i++) {
+		sprintf(ethaddr[i],
+			"%02x:%02x:%02x:%02x:%02x:%02x",
+			mac_data.mac[i][0],
+			mac_data.mac[i][1],
+			mac_data.mac[i][2],
+			mac_data.mac[i][3],
+			mac_data.mac[i][4],
+			mac_data.mac[i][5]);
+		printf("MAC %d %s\n", i, ethaddr[i]);
+	}
+
+	setenv("ethaddr", ethaddr[0]);
+	setenv("eth1addr", ethaddr[1]);
+	setenv("eth2addr", ethaddr[2]);
+	setenv("eth3addr", ethaddr[3]);
+
+	return 0;
+}
+
+int mac_read(void)
+{
+	int ret, length;
+	unsigned int crc = 0;
+	unsigned char dev = ID_EEPROM_ADDR, *data;
+
+	length = sizeof(EEPROM_data);
+	ret = i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length);
+	if (ret) {
+		printf("Read failed.\n");
+		return -1;
+	}
+
+	data = (unsigned char *)(&mac_data);
+	printf("Check CRC on reading ...");
+	crc = crc32(crc, data, length - 4);
+	if (crc != mac_data.crc) {
+		printf("CRC checksum is invalid, in EEPROM CRC is %x, calculated CRC is %x\n",
+		     mac_data.crc, crc);
+		return -1;
+	} else {
+		printf("CRC OK\n");
+		mac_show();
+	}
+	return 0;
+}
+
+int mac_prog(void)
+{
+	int ret, i, length;
+	unsigned int crc = 0;
+	unsigned char dev = ID_EEPROM_ADDR, *ptr;
+	unsigned char *eeprom_data = (unsigned char *)(&mac_data);
+
+	for (i = 0; i < sizeof(mac_data.res_1); i++)
+		mac_data.res_1[i] = 0;
+	for (i = 0; i < sizeof(mac_data.res_2); i++)
+		mac_data.res_2[i] = 0;
+	length = sizeof(EEPROM_data);
+	crc = crc32(crc, eeprom_data, length - 4);
+	mac_data.crc = crc;
+	for (i = 0, ptr = eeprom_data; i < length; i += 8, ptr += 8) {
+		ret =
+		    i2c_write(dev, i, 1, ptr,
+			      (length - i) < 8 ? (length - i) : 8);
+		udelay(5000);	/* 5ms write cycle timing */
+		if (ret)
+			break;
+	}
+	if (ret) {
+		printf("Programming failed.\n");
+		return -1;
+	} else {
+		printf("Programming %d bytes. Reading back ...\n", length);
+		mac_read();
+	}
+	return 0;
+}
+
+int do_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	int i;
+	char cmd = 's';
+	unsigned long long mac_val;
+
+	if (i2c_probe(ID_EEPROM_ADDR) != 0)
+		return -1;
+
+	if (argc > 1) {
+		cmd = argv[1][0];
+		switch (cmd) {
+		case 'r':	/* display */
+			mac_read();
+			break;
+		case 's':	/* save */
+			mac_prog();
+			break;
+		case 'i':	/* id */
+			for (i = 0; i < 4; i++) {
+				mac_data.id[i] = argv[2][i];
+			}
+			break;
+		case 'n':	/* serial number */
+			for (i = 0; i < 12; i++) {
+				mac_data.sn[i] = argv[2][i];
+			}
+			break;
+		case 'e':	/* errata */
+			for (i = 0; i < 5; i++) {
+				mac_data.errata[i] = argv[2][i];
+			}
+			break;
+		case 'd':	/* date */
+			for (i = 0; i < 7; i++) {
+				mac_data.date[i] = argv[2][i];
+			}
+			break;
+		case 'p':	/* number of ports */
+			mac_data.tab_size =
+			    (unsigned char)simple_strtoul(argv[2], NULL, 16);
+			break;
+		case '0':	/* mac 0 */
+		case '1':	/* mac 1 */
+		case '2':	/* mac 2 */
+		case '3':	/* mac 3 */
+		case '4':	/* mac 4 */
+		case '5':	/* mac 5 */
+		case '6':	/* mac 6 */
+		case '7':	/* mac 7 */
+			mac_val = simple_strtoull(argv[2], NULL, 16);
+			for (i = 0; i < 6; i++) {
+				mac_data.mac[cmd - '0'][i] =
+				    *((unsigned char *)
+				      (((unsigned int)(&mac_val)) + i + 2));
+			}
+			break;
+		case 'h':	/* help */
+		default:
+			printf("Usage:\n%s\n", cmdtp->usage);
+			break;
+		}
+	} else {
+		mac_show();
+	}
+	return 0;
+}
+
+int mac_read_from_eeprom(void)
+{
+	int length, i;
+	unsigned char dev = ID_EEPROM_ADDR;
+	unsigned char *data;
+	unsigned char ethaddr[4][18];
+	unsigned char enetvar[32];
+	unsigned int crc = 0;
+
+	length = sizeof(EEPROM_data);
+	if (i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length)) {
+		printf("Read failed.\n");
+		return -1;
+	}
+
+	data = (unsigned char *)(&mac_data);
+	crc = crc32(crc, data, length - 4);
+	if (crc != mac_data.crc) {
+		return -1;
+	} else {
+		for (i = 0; i < 4; i++) {
+			if (memcmp(&mac_data.mac[i], "\0\0\0\0\0\0", 6)) {
+				sprintf(ethaddr[i],
+					"%02x:%02x:%02x:%02x:%02x:%02x",
+					mac_data.mac[i][0],
+					mac_data.mac[i][1],
+					mac_data.mac[i][2],
+					mac_data.mac[i][3],
+					mac_data.mac[i][4],
+					mac_data.mac[i][5]);
+				sprintf(enetvar,
+					i ? "eth%daddr" : "ethaddr",
+					i);
+				setenv(enetvar, ethaddr[i]);
+			}
+		}
+	}
+	return 0;
+}
+#endif /* CFG_ID_EEPROM */

+ 148 - 0
board/mpc8641hpcn/u-boot.lds

@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc.
+ * (C) Copyright 2002,2003, Motorola,Inc.
+ * Jeff Brown
+ *
+ * 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_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xFFF00100 :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .bootpg 0xFFF70000 :
+  {
+    cpu/mpc86xx/start.o	(.bootpg)
+    board/mpc8641hpcn/init.o (.bootpg)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + 1024;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/mpc86xx/start.o	(.text)
+    board/mpc8641hpcn/init.o (.text)
+    cpu/mpc86xx/traps.o (.text)
+    cpu/mpc86xx/interrupts.o (.text)
+    cpu/mpc86xx/cpu_init.o (.text)
+    cpu/mpc86xx/cpu.o (.text)
+    cpu/mpc86xx/speed.o (.text)
+    cpu/mpc86xx/pci.o (.text)
+    common/dlmalloc.o (.text)
+    lib_generic/crc32.o (.text)
+    lib_ppc/extable.o (.text)
+    lib_generic/zlib.o (.text)
+    *(.text)
+    *(.fixup)
+    *(.got1)
+   }
+    _etext = .;
+    PROVIDE (etext = .);
+    .rodata    :
+   {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}

+ 0 - 1
board/sbc8560/u-boot.lds

@@ -77,7 +77,6 @@ SECTIONS
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
     cpu/mpc85xx/speed.o (.text)
-    cpu/mpc85xx/i2c.o (.text)
     cpu/mpc85xx/spd_sdram.o (.text)
     common/dlmalloc.o (.text)
     lib_generic/crc32.o (.text)

+ 0 - 1
board/stxgp3/u-boot.lds

@@ -79,7 +79,6 @@ SECTIONS
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
     cpu/mpc85xx/speed.o (.text)
-    cpu/mpc85xx/i2c.o (.text)
     cpu/mpc85xx/spd_sdram.o (.text)
     common/dlmalloc.o (.text)
     lib_generic/crc32.o (.text)

+ 1 - 1
common/Makefile

@@ -51,7 +51,7 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
 	  memsize.o miiphybb.o miiphyutil.o \
 	  s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
 	  usb.o usb_kbd.o usb_storage.o \
-	  virtex2.o xilinx.o crc16.o xyzModem.o
+	  virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o
 
 SRCS	:= $(AOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(AOBJS) $(COBJS))

+ 1 - 1
common/cmd_boot.c

@@ -83,7 +83,7 @@ U_BOOT_CMD(
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 U_BOOT_CMD(
-	reset, 1, 0,	do_reset,
+	reset, CFG_MAXARGS, 1,	do_reset,
 	"reset   - Perform RESET of the CPU\n",
 	NULL
 );

+ 7 - 5
common/cmd_bootm.c

@@ -739,10 +739,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	}
 
 #ifdef CONFIG_OF_FLAT_TREE
-	if(argc > 3) {	
+	if(argc > 3) {
 		of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
 		hdr = (image_header_t *)of_flat_tree;
-		
+
 		if  (*(ulong *)of_flat_tree == OF_DT_HEADER) {
 #ifndef CFG_NO_FLASH
 			if (addr2info((ulong)of_flat_tree) != NULL) {
@@ -760,7 +760,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 				printf ("ERROR: Load address overwrites Flat Device Tree uImage\n");
 				return;
 			}
-			
+
 			printf("   Verifying Checksum ... ");
 			memmove (&header, (char *)hdr, sizeof(image_header_t));
 			checksum = ntohl(header.ih_hcrc);
@@ -793,8 +793,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 				printf ("ERROR: uImage data is not a flat device tree\n");
 				return;
 			}
-					
-			memmove((void *)ntohl(hdr->ih_load), 
+
+			memmove((void *)ntohl(hdr->ih_load),
 		       		(void *)(of_flat_tree + sizeof(image_header_t)),
 				ntohl(hdr->ih_size));
 			of_flat_tree = (char *)ntohl(hdr->ih_load);
@@ -900,6 +900,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
 
 #else
+	ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
+	/* ft_dump_blob(of_flat_tree); */
 
 #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
 	unlock_ram_in_cache();

+ 66 - 0
common/cmd_mac.c

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * York Sun (yorksun@freescale.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 <command.h>
+
+#ifdef CFG_ID_EEPROM
+
+extern int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+U_BOOT_CMD(
+	mac, 3, 1,  do_mac,
+	"mac     - display and program the system ID and MAC addresses in EEPROM\n",
+	"[read|save|id|num|errata|date|ports|0|1|2|3|4|5|6|7]\n"
+	"read\n"
+	"    - show content of mac\n"
+	"mac save\n"
+	"    - save to the EEPROM\n"
+	"mac id\n"
+	"    - program system id\n"
+	"mac num\n"
+	"    - program system serial number\n"
+	"mac errata\n"
+	"    - program errata data\n"
+	"mac date\n"
+	"    - program data date\n"
+	"mac ports\n"
+	"    - program the number of ports\n"
+	"mac 0\n"
+	"    - program the MAC address for port 0\n"
+	"mac 1\n"
+	"    - program the MAC address for port 1\n"
+	"mac 2\n"
+	"    - program the MAC address for port 2\n"
+	"mac 3\n"
+	"    - program the MAC address for port 3\n"
+	"mac 4\n"
+	"    - program the MAC address for port 4\n"
+	"mac 5\n"
+	"    - program the MAC address for port 5\n"
+	"mac 6\n"
+	"    - program the MAC address for port 6\n"
+	"mac 7\n"
+	"    - program the MAC address for port 7\n"
+);
+#endif /* CFG_ID_EEPROM */

+ 6 - 1
common/cmd_scsi.c

@@ -43,8 +43,13 @@
 #else
 #define SCSI_DEV_ID		CONFIG_SCSI_DEV_ID
 #endif
+#elif defined CONFIG_SATA_ULI5288
+
+#define SCSI_VEND_ID 0x10b9
+#define SCSI_DEV_ID  0x5288
+
 #else
-#error CONFIG_SCSI_SYM53C8XX must be defined
+#error no scsi device defined
 #endif
 
 

+ 1 - 1
config.mk

@@ -169,7 +169,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wno-trigraphs
 endif
 endif
 
-AFLAGS_DEBUG := -Wa,-gstabs
+AFLAGS_DEBUG := -Wa,-g
 
 # turn jbsr into jsr for m68k
 ifeq ($(ARCH),m68k)

+ 50 - 0
cpu/at32ap/Makefile

@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2005-2006 Atmel Corporation.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)lib$(CPU).a
+
+START	:= start.o
+SOBJS	:= entry.o
+COBJS	:= cpu.o hsdramc.o exception.o cache.o
+COBJS	+= interrupts.o device.o pm.o pio.o
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 43 - 0
cpu/at32ap/at32ap7000/Makefile

@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)lib$(SOC).a
+
+COBJS	:= hebi.o devices.o
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 448 - 0
cpu/at32ap/at32ap7000/devices.c

@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "../sm.h"
+
+#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))
+
+const struct clock_domain chip_clock[] = {
+	[CLOCK_CPU] = {
+		.reg	= SM_PM_CPU_MASK,
+		.id	= CLOCK_CPU,
+		.bridge	= NO_DEVICE,
+	},
+	[CLOCK_HSB] = {
+		.reg	= SM_PM_HSB_MASK,
+		.id	= CLOCK_HSB,
+		.bridge	= NO_DEVICE,
+	},
+	[CLOCK_PBA] = {
+		.reg	= SM_PM_PBA_MASK,
+		.id	= CLOCK_PBA,
+		.bridge	= DEVICE_PBA_BRIDGE,
+	},
+	[CLOCK_PBB] = {
+		.reg	= SM_PM_PBB_MASK,
+		.id	= CLOCK_PBB,
+		.bridge	= DEVICE_PBB_BRIDGE,
+	},
+};
+
+static const struct resource hebi_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 0 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 13 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 14 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
+		},
+	},
+};
+static const struct resource pba_bridge_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 1 },
+		}
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			/* HSB-HSB Bridge */
+			.clock	= { CLOCK_HSB, 4 },
+		},
+	},
+};
+static const struct resource pbb_bridge_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 2 },
+		},
+	},
+};
+static const struct resource hramc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 3 },
+		},
+	},
+};
+static const struct resource pioa_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 10 },
+		},
+	},
+};
+static const struct resource piob_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 11 },
+		},
+	},
+};
+static const struct resource pioc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 12 },
+		},
+	},
+};
+static const struct resource piod_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 13 },
+		},
+	},
+};
+static const struct resource pioe_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 14 },
+		},
+	},
+};
+static const struct resource sm_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 0 },
+		},
+	},
+};
+static const struct resource intc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock = { CLOCK_PBB, 1 },
+		},
+	},
+};
+static const struct resource hmatrix_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock = { CLOCK_PBB, 2 },
+		},
+	},
+};
+#if defined(CFG_HPDC)
+static const struct resource hpdc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 16 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MACB0)
+static const struct resource macb0_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 8 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 6 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MACB1)
+static const struct resource macb1_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 9 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 7 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
+		},
+	},
+};
+#endif
+#if defined(CFG_LCDC)
+static const struct resource lcdc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 7 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART0)
+static const struct resource usart0_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 3 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART1)
+static const struct resource usart1_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 4 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART2)
+static const struct resource usart2_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 5 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART3)
+static const struct resource usart3_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 6 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MMCI)
+static const struct resource mmci_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 9 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
+		},
+	},
+};
+#endif
+#if defined(CFG_DMAC)
+static const struct resource dmac_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 10 },
+		},
+	},
+};
+#endif
+
+const struct device chip_device[] = {
+	[DEVICE_HEBI] = {
+		.regs		= (void *)HSMC_BASE,
+		.nr_resources	= ARRAY_SIZE(hebi_resource),
+		.resource	= hebi_resource,
+	},
+	[DEVICE_PBA_BRIDGE] = {
+		.nr_resources	= ARRAY_SIZE(pba_bridge_resource),
+		.resource	= pba_bridge_resource,
+	},
+	[DEVICE_PBB_BRIDGE] = {
+		.nr_resources	= ARRAY_SIZE(pbb_bridge_resource),
+		.resource	= pbb_bridge_resource,
+	},
+	[DEVICE_HRAMC] = {
+		.nr_resources	= ARRAY_SIZE(hramc_resource),
+		.resource	= hramc_resource,
+	},
+	[DEVICE_PIOA] = {
+		.regs		= (void *)PIOA_BASE,
+		.nr_resources	= ARRAY_SIZE(pioa_resource),
+		.resource	= pioa_resource,
+	},
+	[DEVICE_PIOB] = {
+		.regs		= (void *)PIOB_BASE,
+		.nr_resources	= ARRAY_SIZE(piob_resource),
+		.resource	= piob_resource,
+	},
+	[DEVICE_PIOC] = {
+		.regs		= (void *)PIOC_BASE,
+		.nr_resources	= ARRAY_SIZE(pioc_resource),
+		.resource	= pioc_resource,
+	},
+	[DEVICE_PIOD] = {
+		.regs		= (void *)PIOD_BASE,
+		.nr_resources	= ARRAY_SIZE(piod_resource),
+		.resource	= piod_resource,
+	},
+	[DEVICE_PIOE] = {
+		.regs		= (void *)PIOE_BASE,
+		.nr_resources	= ARRAY_SIZE(pioe_resource),
+		.resource	= pioe_resource,
+	},
+	[DEVICE_SM] = {
+		.regs		= (void *)SM_BASE,
+		.nr_resources	= ARRAY_SIZE(sm_resource),
+		.resource	= sm_resource,
+	},
+	[DEVICE_INTC] = {
+		.regs		= (void *)INTC_BASE,
+		.nr_resources	= ARRAY_SIZE(intc_resource),
+		.resource	= intc_resource,
+	},
+	[DEVICE_HMATRIX] = {
+		.regs		= (void *)HMATRIX_BASE,
+		.nr_resources	= ARRAY_SIZE(hmatrix_resource),
+		.resource	= hmatrix_resource,
+	},
+#if defined(CFG_HPDC)
+	[DEVICE_HPDC] = {
+		.nr_resources	= ARRAY_SIZE(hpdc_resource),
+		.resource	= hpdc_resource,
+	},
+#endif
+#if defined(CFG_MACB0)
+	[DEVICE_MACB0] = {
+		.regs		= (void *)MACB0_BASE,
+		.nr_resources	= ARRAY_SIZE(macb0_resource),
+		.resource	= macb0_resource,
+	},
+#endif
+#if defined(CFG_MACB1)
+	[DEVICE_MACB1] = {
+		.regs		= (void *)MACB1_BASE,
+		.nr_resources	= ARRAY_SIZE(macb1_resource),
+		.resource	= macb1_resource,
+	},
+#endif
+#if defined(CFG_LCDC)
+	[DEVICE_LCDC] = {
+		.nr_resources	= ARRAY_SIZE(lcdc_resource),
+		.resource	= lcdc_resource,
+	},
+#endif
+#if defined(CFG_USART0)
+	[DEVICE_USART0] = {
+		.regs		= (void *)USART0_BASE,
+		.nr_resources	= ARRAY_SIZE(usart0_resource),
+		.resource	= usart0_resource,
+	},
+#endif
+#if defined(CFG_USART1)
+	[DEVICE_USART1] = {
+		.regs		= (void *)USART1_BASE,
+		.nr_resources	= ARRAY_SIZE(usart1_resource),
+		.resource	= usart1_resource,
+	},
+#endif
+#if defined(CFG_USART2)
+	[DEVICE_USART2] = {
+		.regs		= (void *)USART2_BASE,
+		.nr_resources	= ARRAY_SIZE(usart2_resource),
+		.resource	= usart2_resource,
+	},
+#endif
+#if defined(CFG_USART3)
+	[DEVICE_USART3] = {
+		.regs		= (void *)USART3_BASE,
+		.nr_resources	= ARRAY_SIZE(usart3_resource),
+		.resource	= usart3_resource,
+	},
+#endif
+#if defined(CFG_MMCI)
+	[DEVICE_MMCI] = {
+		.regs		= (void *)MMCI_BASE,
+		.nr_resources	= ARRAY_SIZE(mmci_resource),
+		.resource	= mmci_resource,
+	},
+#endif
+#if defined(CFG_DMAC)
+	[DEVICE_DMAC] = {
+		.regs		= (void *)DMAC_BASE,
+		.nr_resources	= ARRAY_SIZE(dmac_resource),
+		.resource	= dmac_resource,
+	},
+#endif
+};

+ 38 - 0
cpu/at32ap/at32ap7000/hebi.c

@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/hmatrix2.h>
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+void cpu_enable_sdram(void)
+{
+	const struct device *hmatrix;
+
+	hmatrix = get_device(DEVICE_HMATRIX);
+
+	/* Set the SDRAM_ENABLE bit in the HEBI SFR */
+	hmatrix2_writel(hmatrix, SFR4, 1 << 1);
+}

+ 97 - 0
cpu/at32ap/cache.c

@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#include <asm/cacheflush.h>
+
+void dcache_clean_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_clean_line((void *)v);
+
+	sync_write_buffer();
+}
+
+void dcache_invalidate_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_invalidate_line((void *)v);
+}
+
+void dcache_flush_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_flush_line((void *)v);
+
+	sync_write_buffer();
+}
+
+void icache_invalidate_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_ICACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		icache_invalidate_line((void *)v);
+}
+
+/*
+ * This is called after loading something into memory.  We need to
+ * make sure that everything that was loaded is actually written to
+ * RAM, and that the icache will look for it. Cleaning the dcache and
+ * invalidating the icache will do the trick.
+ */
+void  flush_cache (unsigned long start_addr, unsigned long size)
+{
+	dcache_clean_range((void *)start_addr, size);
+	icache_invalidate_range((void *)start_addr, size);
+}

+ 22 - 0
cpu/at32ap/config.mk

@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+PLATFORM_RELFLAGS       += -mcpu=ap7000

+ 83 - 0
cpu/at32ap/cpu.c

@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <command.h>
+
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "hsmc3.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int cpu_init(void)
+{
+	const struct device *hebi;
+	extern void _evba(void);
+	char *p;
+
+	gd->cpu_hz = CFG_OSC0_HZ;
+
+	/* fff03400: 00010001 04030402 00050005 10011103 */
+	hebi = get_device(DEVICE_HEBI);
+	hsmc3_writel(hebi, MODE0, 0x00031103);
+	hsmc3_writel(hebi, CYCLE0, 0x000c000d);
+	hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
+	hsmc3_writel(hebi, SETUP0, 0x00010002);
+
+	pm_init();
+
+	sysreg_write(EVBA, (unsigned long)&_evba);
+	asm volatile("csrf	%0" : : "i"(SYSREG_EM_OFFSET));
+	gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
+
+	/* Lock everything that mess with the flash in the icache */
+	for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
+	     p += CFG_ICACHE_LINESZ)
+		asm volatile("cache %0, 0x02" : "=m"(*p) :: "memory");
+
+	return 0;
+}
+
+void prepare_to_boot(void)
+{
+	/* Flush both caches and the write buffer */
+	asm volatile("cache  %0[4], 010\n\t"
+		     "cache  %0[0], 000\n\t"
+		     "sync   0" : : "r"(0) : "memory");
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	/* This will reset the CPU core, caches, MMU and all internal busses */
+	__builtin_mtdr(8, 1 << 13);	/* set DC:DBE */
+	__builtin_mtdr(8, 1 << 30);	/* set DC:RES */
+
+	/* Flush the pipeline before we declare it a failure */
+	asm volatile("sub   pc, pc, -4");
+
+	return -1;
+}

+ 126 - 0
cpu/at32ap/device.c

@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/arch/platform.h>
+
+#include "sm.h"
+
+struct device_state {
+	int refcount;
+};
+
+static struct device_state device_state[NR_DEVICES];
+
+static int claim_resource(const struct resource *res)
+{
+	int ret = 0;
+
+	switch (res->type) {
+	case RESOURCE_GPIO:
+		ret = gpio_set_func(res->u.gpio.gpio_dev,
+				    res->u.gpio.start,
+				    res->u.gpio.nr_pins,
+				    res->u.gpio.func);
+		break;
+	case RESOURCE_CLOCK:
+		ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
+		break;
+	}
+
+	return ret;
+}
+
+static void free_resource(const struct resource *res)
+{
+	switch (res->type) {
+	case RESOURCE_GPIO:
+		gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
+			  res->u.gpio.nr_pins);
+		break;
+	case RESOURCE_CLOCK:
+		pm_disable_clock(res->u.clock.id, res->u.clock.index);
+		break;
+	}
+}
+
+static int init_dev(const struct device *dev)
+{
+	unsigned int i;
+	int ret = 0;
+
+	for (i = 0; i < dev->nr_resources; i++) {
+		ret = claim_resource(&dev->resource[i]);
+		if (ret)
+			goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	while (i--)
+		free_resource(&dev->resource[i]);
+
+	return ret;
+}
+
+const struct device *get_device(enum device_id devid)
+{
+	struct device_state *devstate;
+	const struct device *dev;
+	unsigned long flags;
+	int initialized = 0;
+	int ret = 0;
+
+	devstate = &device_state[devid];
+	dev = &chip_device[devid];
+
+	flags = disable_interrupts();
+	if (devstate->refcount++)
+		initialized = 1;
+	if (flags)
+		enable_interrupts();
+
+	if (!initialized)
+		ret = init_dev(dev);
+
+	return ret ? NULL : dev;
+}
+
+void put_device(const struct device *dev)
+{
+	struct device_state *devstate;
+	unsigned long devid, flags;
+
+	devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
+	devstate = &device_state[devid];
+
+	flags = disable_interrupts();
+	devstate--;
+	if (!devstate) {
+		unsigned int i;
+		for (i = 0; i < dev->nr_resources; i++)
+			free_resource(&dev->resource[i]);
+	}
+	if (flags)
+		enable_interrupts();
+}

+ 65 - 0
cpu/at32ap/entry.S

@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <asm/sysreg.h>
+#include <asm/ptrace.h>
+
+	.section .text.exception,"ax"
+	.global	_evba
+	.type	_evba,@function
+	.align	10
+_evba:
+	.irp	x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+	.align	2
+	rjmp	unknown_exception
+	.endr
+
+	.global	timer_interrupt_handler
+	.type	timer_interrupt_handler,@function
+	.align	2
+timer_interrupt_handler:
+	/*
+	 * Increment timer_overflow and re-write COMPARE with 0xffffffff.
+	 *
+	 * We're running at interrupt level 3, so we don't need to save
+	 * r8-r12 or lr to the stack.
+	 */
+	mov	r8, lo(timer_overflow)
+	orh	r8, hi(timer_overflow)
+	ld.w	r9, r8[0]
+	mov	r10, -1
+	mtsr	SYSREG_COMPARE, r10
+	sub	r9, -1
+	st.w	r8[0], r9
+	rete
+
+	.type	unknown_exception, @function
+unknown_exception:
+	pushm	r0-r12
+	sub	r8, sp, REG_R12 - REG_R0 - 4
+	mov	r9, lr
+	mfsr	r10, SYSREG_RAR_EX
+	mfsr	r11, SYSREG_RSR_EX
+	pushm	r8-r11
+	mfsr	r12, SYSREG_ECR
+	mov	r11, sp
+	rcall	do_unknown_exception
+1:	rjmp	1b

+ 119 - 0
cpu/at32ap/exception.c

@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/sysreg.h>
+#include <asm/ptrace.h>
+
+static const char * const cpu_modes[8] = {
+	"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
+	"Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
+};
+
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+	unsigned long p;
+	int i;
+
+	printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+	for (p = bottom & ~31; p < top; ) {
+		printf("%04lx: ", p & 0xffff);
+
+		for (i = 0; i < 8; i++, p += 4) {
+			unsigned int val;
+
+			if (p < bottom || p >= top)
+				printf("         ");
+			else {
+				val = *(unsigned long *)p;
+				printf("%08x ", val);
+			}
+		}
+		printf("\n");
+	}
+}
+
+void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
+{
+	unsigned int mode;
+
+	printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc);
+
+	switch (ecr) {
+	case ECR_BUS_ERROR_WRITE:
+	case ECR_BUS_ERROR_READ:
+		printf("Bus error at address 0x%08lx\n",
+		       sysreg_read(BEAR));
+		break;
+	case ECR_TLB_MULTIPLE:
+	case ECR_ADDR_ALIGN_X:
+	case ECR_PROTECTION_X:
+	case ECR_ADDR_ALIGN_R:
+	case ECR_ADDR_ALIGN_W:
+	case ECR_PROTECTION_R:
+	case ECR_PROTECTION_W:
+	case ECR_DTLB_MODIFIED:
+	case ECR_TLB_MISS_X:
+	case ECR_TLB_MISS_R:
+	case ECR_TLB_MISS_W:
+		printf("MMU exception at address 0x%08lx\n",
+		       sysreg_read(TLBEAR));
+		break;
+	}
+
+	printf("   pc: %08lx    lr: %08lx    sp: %08lx   r12: %08lx\n",
+	       regs->pc, regs->lr, regs->sp, regs->r12);
+	printf("  r11: %08lx   r10: %08lx    r9: %08lx    r8: %08lx\n",
+	       regs->r11, regs->r10, regs->r9, regs->r8);
+	printf("   r7: %08lx    r6: %08lx    r5: %08lx    r4: %08lx\n",
+	       regs->r7, regs->r6, regs->r5, regs->r4);
+	printf("   r3: %08lx    r2: %08lx    r1: %08lx    r0: %08lx\n",
+	       regs->r3, regs->r2, regs->r1, regs->r0);
+	printf("Flags: %c%c%c%c%c\n",
+	       regs->sr & SR_Q ? 'Q' : 'q',
+	       regs->sr & SR_V ? 'V' : 'v',
+	       regs->sr & SR_N ? 'N' : 'n',
+	       regs->sr & SR_Z ? 'Z' : 'z',
+	       regs->sr & SR_C ? 'C' : 'c');
+	printf("Mode bits: %c%c%c%c%c%c%c%c%c\n",
+	       regs->sr & SR_H ? 'H' : 'h',
+	       regs->sr & SR_R ? 'R' : 'r',
+	       regs->sr & SR_J ? 'J' : 'j',
+	       regs->sr & SR_EM ? 'E' : 'e',
+	       regs->sr & SR_I3M ? '3' : '.',
+	       regs->sr & SR_I2M ? '2' : '.',
+	       regs->sr & SR_I1M ? '1' : '.',
+	       regs->sr & SR_I0M ? '0' : '.',
+	       regs->sr & SR_GM ? 'G' : 'g');
+	mode = (regs->sr >> SYSREG_M0_OFFSET) & 7;
+	printf("CPU Mode: %s\n", cpu_modes[mode]);
+
+	/* Avoid exception loops */
+	if (regs->sp >= CFG_INIT_SP_ADDR
+	    || regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE))
+		printf("\nStack pointer seems bogus, won't do stack dump\n");
+	else
+		dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR);
+
+	panic("Unhandled exception\n");
+}

+ 155 - 0
cpu/at32ap/hsdramc.c

@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#ifdef CFG_HSDRAMC
+#include <asm/io.h>
+#include <asm/sdram.h>
+
+#include <asm/arch/platform.h>
+
+#include "hsdramc1.h"
+
+struct hsdramc {
+	const struct device *hebi;
+	void *regs;
+};
+
+static struct hsdramc hsdramc;
+
+unsigned long sdram_init(const struct sdram_info *info)
+{
+	unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
+	unsigned long sdram_size;
+	unsigned long tmp;
+	unsigned long bus_hz;
+	unsigned int i;
+
+	hsdramc.hebi = get_device(DEVICE_HEBI);
+	if (!hsdramc.hebi)
+		return 0;
+
+	/* FIXME: Both of these lines are complete hacks */
+	hsdramc.regs = hsdramc.hebi->regs + 0x400;
+	bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
+
+	cpu_enable_sdram();
+
+	tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
+	       | HSDRAMC1_BF(NR, info->row_bits - 11)
+	       | HSDRAMC1_BF(NB, info->bank_bits - 1)
+	       | HSDRAMC1_BF(CAS, info->cas)
+	       | HSDRAMC1_BF(TWR, info->twr)
+	       | HSDRAMC1_BF(TRC, info->trc)
+	       | HSDRAMC1_BF(TRP, info->trp)
+	       | HSDRAMC1_BF(TRCD, info->trcd)
+	       | HSDRAMC1_BF(TRAS, info->tras)
+	       | HSDRAMC1_BF(TXSR, info->txsr));
+
+#ifdef CFG_SDRAM_16BIT
+	tmp |= HSDRAMC1_BIT(DBW);
+	sdram_size = 1 << (info->row_bits + info->col_bits
+			   + info->bank_bits + 1);
+#else
+	sdram_size = 1 << (info->row_bits + info->col_bits
+			   + info->bank_bits + 2);
+#endif
+
+	hsdramc1_writel(&hsdramc, CR, tmp);
+
+	/*
+	 * Initialization sequence for SDRAM, from the data sheet:
+	 *
+	 * 1. A minimum pause of 200 us is provided to precede any
+	 *    signal toggle.
+	 */
+	udelay(200);
+
+	/*
+	 * 2. A Precharge All command is issued to the SDRAM
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram);
+
+	/*
+	 * 3. Eight auto-refresh (CBR) cycles are provided
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
+	hsdramc1_readl(&hsdramc, MR);
+	for (i = 0; i < 8; i++)
+		writel(0, sdram);
+
+	/*
+	 * 4. A mode register set (MRS) cycle is issued to program
+	 *    SDRAM parameters, in particular CAS latency and burst
+	 *    length.
+	 *
+	 * CAS from info struct, burst length 1, serial burst type
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram + (info->cas << 4));
+
+	/*
+	 * 5. A Normal Mode command is provided, 3 clocks after tMRD
+	 *    is met.
+	 *
+	 * From the timing diagram, it looks like tMRD is 3
+	 * cycles...try a dummy read from the peripheral bus.
+	 */
+	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram);
+
+	/*
+	 * 6. Write refresh rate into SDRAMC refresh timer count
+	 *    register (refresh rate = timing between refresh cycles).
+	 *
+	 * 15.6 us is a typical value for a burst of length one
+	 */
+	hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
+
+	printf("SDRAM: %u MB at address 0x%08lx\n",
+	       sdram_size >> 20, info->phys_addr);
+
+	printf("Testing SDRAM...");
+	for (i = 0; i < sdram_size / 4; i++)
+		sdram[i] = i;
+
+	for (i = 0; i < sdram_size / 4; i++) {
+		tmp = sdram[i];
+		if (tmp != i) {
+			printf("FAILED at address 0x%08lx\n",
+			       info->phys_addr + i * 4);
+			printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
+			return 0;
+		}
+	}
+
+	puts("OK\n");
+
+	return sdram_size;
+}
+
+#endif /* CFG_HSDRAMC */

+ 143 - 0
cpu/at32ap/hsdramc1.h

@@ -0,0 +1,143 @@
+/*
+ * Register definitions for SDRAM Controller
+ */
+#ifndef __ASM_AVR32_HSDRAMC1_H__
+#define __ASM_AVR32_HSDRAMC1_H__
+
+/* HSDRAMC1 register offsets */
+#define HSDRAMC1_MR				0x0000
+#define HSDRAMC1_TR				0x0004
+#define HSDRAMC1_CR				0x0008
+#define HSDRAMC1_HSR				0x000c
+#define HSDRAMC1_LPR				0x0010
+#define HSDRAMC1_IER				0x0014
+#define HSDRAMC1_IDR				0x0018
+#define HSDRAMC1_IMR				0x001c
+#define HSDRAMC1_ISR				0x0020
+#define HSDRAMC1_MDR				0x0024
+#define HSDRAMC1_VERSION			0x00fc
+
+/* Bitfields in MR */
+#define HSDRAMC1_MODE_OFFSET			0
+#define HSDRAMC1_MODE_SIZE			3
+
+/* Bitfields in TR */
+#define HSDRAMC1_COUNT_OFFSET			0
+#define HSDRAMC1_COUNT_SIZE			12
+
+/* Bitfields in CR */
+#define HSDRAMC1_NC_OFFSET			0
+#define HSDRAMC1_NC_SIZE			2
+#define HSDRAMC1_NR_OFFSET			2
+#define HSDRAMC1_NR_SIZE			2
+#define HSDRAMC1_NB_OFFSET			4
+#define HSDRAMC1_NB_SIZE			1
+#define HSDRAMC1_CAS_OFFSET			5
+#define HSDRAMC1_CAS_SIZE			2
+#define HSDRAMC1_DBW_OFFSET			7
+#define HSDRAMC1_DBW_SIZE			1
+#define HSDRAMC1_TWR_OFFSET			8
+#define HSDRAMC1_TWR_SIZE			4
+#define HSDRAMC1_TRC_OFFSET			12
+#define HSDRAMC1_TRC_SIZE			4
+#define HSDRAMC1_TRP_OFFSET			16
+#define HSDRAMC1_TRP_SIZE			4
+#define HSDRAMC1_TRCD_OFFSET			20
+#define HSDRAMC1_TRCD_SIZE			4
+#define HSDRAMC1_TRAS_OFFSET			24
+#define HSDRAMC1_TRAS_SIZE			4
+#define HSDRAMC1_TXSR_OFFSET			28
+#define HSDRAMC1_TXSR_SIZE			4
+
+/* Bitfields in HSR */
+#define HSDRAMC1_DA_OFFSET			0
+#define HSDRAMC1_DA_SIZE			1
+
+/* Bitfields in LPR */
+#define HSDRAMC1_LPCB_OFFSET			0
+#define HSDRAMC1_LPCB_SIZE			2
+#define HSDRAMC1_PASR_OFFSET			4
+#define HSDRAMC1_PASR_SIZE			3
+#define HSDRAMC1_TCSR_OFFSET			8
+#define HSDRAMC1_TCSR_SIZE			2
+#define HSDRAMC1_DS_OFFSET			10
+#define HSDRAMC1_DS_SIZE			2
+#define HSDRAMC1_TIMEOUT_OFFSET			12
+#define HSDRAMC1_TIMEOUT_SIZE			2
+
+/* Bitfields in IDR */
+#define HSDRAMC1_RES_OFFSET			0
+#define HSDRAMC1_RES_SIZE			1
+
+/* Bitfields in MDR */
+#define HSDRAMC1_MD_OFFSET			0
+#define HSDRAMC1_MD_SIZE			2
+
+/* Bitfields in VERSION */
+#define HSDRAMC1_VERSION_OFFSET			0
+#define HSDRAMC1_VERSION_SIZE			12
+#define HSDRAMC1_MFN_OFFSET			16
+#define HSDRAMC1_MFN_SIZE			3
+
+/* Constants for MODE */
+#define HSDRAMC1_MODE_NORMAL			0
+#define HSDRAMC1_MODE_NOP			1
+#define HSDRAMC1_MODE_BANKS_PRECHARGE		2
+#define HSDRAMC1_MODE_LOAD_MODE			3
+#define HSDRAMC1_MODE_AUTO_REFRESH		4
+#define HSDRAMC1_MODE_EXT_LOAD_MODE		5
+#define HSDRAMC1_MODE_POWER_DOWN		6
+
+/* Constants for NC */
+#define HSDRAMC1_NC_8_COLUMN_BITS		0
+#define HSDRAMC1_NC_9_COLUMN_BITS		1
+#define HSDRAMC1_NC_10_COLUMN_BITS		2
+#define HSDRAMC1_NC_11_COLUMN_BITS		3
+
+/* Constants for NR */
+#define HSDRAMC1_NR_11_ROW_BITS			0
+#define HSDRAMC1_NR_12_ROW_BITS			1
+#define HSDRAMC1_NR_13_ROW_BITS			2
+
+/* Constants for NB */
+#define HSDRAMC1_NB_TWO_BANKS			0
+#define HSDRAMC1_NB_FOUR_BANKS			1
+
+/* Constants for CAS */
+#define HSDRAMC1_CAS_ONE_CYCLE			1
+#define HSDRAMC1_CAS_TWO_CYCLES			2
+
+/* Constants for DBW */
+#define HSDRAMC1_DBW_32_BITS			0
+#define HSDRAMC1_DBW_16_BITS			1
+
+/* Constants for TIMEOUT */
+#define HSDRAMC1_TIMEOUT_AFTER_END		0
+#define HSDRAMC1_TIMEOUT_64_CYC_AFTER_END	1
+#define HSDRAMC1_TIMEOUT_128_CYC_AFTER_END	2
+
+/* Constants for MD */
+#define HSDRAMC1_MD_SDRAM			0
+#define HSDRAMC1_MD_LOW_POWER_SDRAM		1
+
+/* Bit manipulation macros */
+#define HSDRAMC1_BIT(name)					\
+	(1 << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BF(name,value)					\
+	(((value) & ((1 << HSDRAMC1_##name##_SIZE) - 1))	\
+	 << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BFEXT(name,value)				\
+	(((value) >> HSDRAMC1_##name##_OFFSET)			\
+	 & ((1 << HSDRAMC1_##name##_SIZE) - 1))
+#define HSDRAMC1_BFINS(name,value,old)				\
+	(((old) & ~(((1 << HSDRAMC1_##name##_SIZE) - 1)		\
+		    << HSDRAMC1_##name##_OFFSET))		\
+	 | HSDRAMC1_BF(name,value))
+
+/* Register access macros */
+#define hsdramc1_readl(port,reg)				\
+	readl((port)->regs + HSDRAMC1_##reg)
+#define hsdramc1_writel(port,reg,value)				\
+	writel((value), (port)->regs + HSDRAMC1_##reg)
+
+#endif /* __ASM_AVR32_HSDRAMC1_H__ */

+ 126 - 0
cpu/at32ap/hsmc3.h

@@ -0,0 +1,126 @@
+/*
+ * Register definitions for Static Memory Controller
+ */
+#ifndef __CPU_AT32AP_HSMC3_H__
+#define __CPU_AT32AP_HSMC3_H__
+
+/* HSMC3 register offsets */
+#define HSMC3_SETUP0				0x0000
+#define HSMC3_PULSE0				0x0004
+#define HSMC3_CYCLE0				0x0008
+#define HSMC3_MODE0				0x000c
+#define HSMC3_SETUP1				0x0010
+#define HSMC3_PULSE1				0x0014
+#define HSMC3_CYCLE1				0x0018
+#define HSMC3_MODE1				0x001c
+#define HSMC3_SETUP2				0x0020
+#define HSMC3_PULSE2				0x0024
+#define HSMC3_CYCLE2				0x0028
+#define HSMC3_MODE2				0x002c
+#define HSMC3_SETUP3				0x0030
+#define HSMC3_PULSE3				0x0034
+#define HSMC3_CYCLE3				0x0038
+#define HSMC3_MODE3				0x003c
+#define HSMC3_SETUP4				0x0040
+#define HSMC3_PULSE4				0x0044
+#define HSMC3_CYCLE4				0x0048
+#define HSMC3_MODE4				0x004c
+#define HSMC3_SETUP5				0x0050
+#define HSMC3_PULSE5				0x0054
+#define HSMC3_CYCLE5				0x0058
+#define HSMC3_MODE5				0x005c
+
+/* Bitfields in SETUP0 */
+#define HSMC3_NWE_SETUP_OFFSET			0
+#define HSMC3_NWE_SETUP_SIZE			6
+#define HSMC3_NCS_WR_SETUP_OFFSET		8
+#define HSMC3_NCS_WR_SETUP_SIZE			6
+#define HSMC3_NRD_SETUP_OFFSET			16
+#define HSMC3_NRD_SETUP_SIZE			6
+#define HSMC3_NCS_RD_SETUP_OFFSET		24
+#define HSMC3_NCS_RD_SETUP_SIZE			6
+
+/* Bitfields in PULSE0 */
+#define HSMC3_NWE_PULSE_OFFSET			0
+#define HSMC3_NWE_PULSE_SIZE			7
+#define HSMC3_NCS_WR_PULSE_OFFSET		8
+#define HSMC3_NCS_WR_PULSE_SIZE			7
+#define HSMC3_NRD_PULSE_OFFSET			16
+#define HSMC3_NRD_PULSE_SIZE			7
+#define HSMC3_NCS_RD_PULSE_OFFSET		24
+#define HSMC3_NCS_RD_PULSE_SIZE			7
+
+/* Bitfields in CYCLE0 */
+#define HSMC3_NWE_CYCLE_OFFSET			0
+#define HSMC3_NWE_CYCLE_SIZE			9
+#define HSMC3_NRD_CYCLE_OFFSET			16
+#define HSMC3_NRD_CYCLE_SIZE			9
+
+/* Bitfields in MODE0 */
+#define HSMC3_READ_MODE_OFFSET			0
+#define HSMC3_READ_MODE_SIZE			1
+#define HSMC3_WRITE_MODE_OFFSET			1
+#define HSMC3_WRITE_MODE_SIZE			1
+#define HSMC3_EXNW_MODE_OFFSET			4
+#define HSMC3_EXNW_MODE_SIZE			2
+#define HSMC3_BAT_OFFSET			8
+#define HSMC3_BAT_SIZE				1
+#define HSMC3_DBW_OFFSET			12
+#define HSMC3_DBW_SIZE				2
+#define HSMC3_TDF_CYCLES_OFFSET			16
+#define HSMC3_TDF_CYCLES_SIZE			4
+#define HSMC3_TDF_MODE_OFFSET			20
+#define HSMC3_TDF_MODE_SIZE			1
+#define HSMC3_PMEN_OFFSET			24
+#define HSMC3_PMEN_SIZE				1
+#define HSMC3_PS_OFFSET				28
+#define HSMC3_PS_SIZE				2
+
+/* Bitfields in MODE1 */
+#define HSMC3_PD_OFFSET				28
+#define HSMC3_PD_SIZE				2
+
+/* Constants for READ_MODE */
+#define HSMC3_READ_MODE_NCS_CONTROLLED		0
+#define HSMC3_READ_MODE_NRD_CONTROLLED		1
+
+/* Constants for WRITE_MODE */
+#define HSMC3_WRITE_MODE_NCS_CONTROLLED		0
+#define HSMC3_WRITE_MODE_NWE_CONTROLLED		1
+
+/* Constants for EXNW_MODE */
+#define HSMC3_EXNW_MODE_DISABLED		0
+#define HSMC3_EXNW_MODE_RESERVED		1
+#define HSMC3_EXNW_MODE_FROZEN			2
+#define HSMC3_EXNW_MODE_READY			3
+
+/* Constants for BAT */
+#define HSMC3_BAT_BYTE_SELECT			0
+#define HSMC3_BAT_BYTE_WRITE			1
+
+/* Constants for DBW */
+#define HSMC3_DBW_8_BITS			0
+#define HSMC3_DBW_16_BITS			1
+#define HSMC3_DBW_32_BITS			2
+
+/* Bit manipulation macros */
+#define HSMC3_BIT(name)						\
+	(1 << HSMC3_##name##_OFFSET)
+#define HSMC3_BF(name,value)					\
+	(((value) & ((1 << HSMC3_##name##_SIZE) - 1))		\
+	 << HSMC3_##name##_OFFSET)
+#define HSMC3_BFEXT(name,value)					\
+	(((value) >> HSMC3_##name##_OFFSET)			\
+	 & ((1 << HSMC3_##name##_SIZE) - 1))
+#define HSMC3_BFINS(name,value,old)\
+	(((old) & ~(((1 << HSMC3_##name##_SIZE) - 1)		\
+		    << HSMC3_##name##_OFFSET))			\
+	 | HSMC3_BF(name,value))
+
+/* Register access macros */
+#define hsmc3_readl(port,reg)					\
+	readl((port)->regs + HSMC3_##reg)
+#define hsmc3_writel(port,reg,value)				\
+	writel((value), (port)->regs + HSMC3_##reg)
+
+#endif /* __CPU_AT32AP_HSMC3_H__ */

+ 154 - 0
cpu/at32ap/interrupts.c

@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/div64.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/platform.h>
+
+#define HANDLER_MASK	0x00ffffff
+#define INTLEV_SHIFT	30
+#define INTLEV_MASK	0x00000003
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */
+volatile unsigned long timer_overflow;
+
+/*
+ * Instead of dividing by get_tbclk(), multiply by this constant and
+ * right-shift the result by 32 bits.
+ */
+static unsigned long tb_factor;
+
+static const struct device *intc_dev;
+
+unsigned long get_tbclk(void)
+{
+	return gd->cpu_hz;
+}
+
+unsigned long long get_ticks(void)
+{
+	unsigned long lo, hi_now, hi_prev;
+
+	do {
+		hi_prev = timer_overflow;
+		lo = sysreg_read(COUNT);
+		hi_now = timer_overflow;
+	} while (hi_prev != hi_now);
+
+	return ((unsigned long long)hi_now << 32) | lo;
+}
+
+void reset_timer(void)
+{
+	sysreg_write(COUNT, 0);
+	cpu_sync_pipeline();	/* process any pending interrupts */
+	timer_overflow = 0;
+}
+
+unsigned long get_timer(unsigned long base)
+{
+	u64 now = get_ticks();
+
+	now *= tb_factor;
+	return (unsigned long)(now >> 32) - base;
+}
+
+void set_timer(unsigned long t)
+{
+	unsigned long long ticks = t;
+	unsigned long lo, hi, hi_new;
+
+	ticks = (ticks * get_tbclk()) / CFG_HZ;
+	hi = ticks >> 32;
+	lo = ticks & 0xffffffffUL;
+
+	do {
+		timer_overflow = hi;
+		sysreg_write(COUNT, lo);
+		hi_new = timer_overflow;
+	} while (hi_new != hi);
+}
+
+/*
+ * For short delays only. It will overflow after a few seconds.
+ */
+void udelay(unsigned long usec)
+{
+	unsigned long now, end;
+
+	now = sysreg_read(COUNT);
+
+	end = ((usec * (get_tbclk() / 10000)) + 50) / 100;
+	end += now;
+
+	while (now > end)
+		now = sysreg_read(COUNT);
+
+	while (now < end)
+		now = sysreg_read(COUNT);
+}
+
+static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
+				 unsigned int priority)
+{
+	unsigned long intpr;
+	unsigned long handler_addr = (unsigned long)handler;
+
+	if ((handler_addr & HANDLER_MASK) != handler_addr
+	    || (priority & INTLEV_MASK) != priority)
+		return -EINVAL;
+
+	intpr = (handler_addr & HANDLER_MASK);
+	intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
+	writel(intpr, intc_dev->regs + 4 * nr);
+
+	return 0;
+}
+
+void timer_init(void)
+{
+	extern void timer_interrupt_handler(void);
+	u64 tmp;
+
+	sysreg_write(COUNT, 0);
+
+	tmp = (u64)CFG_HZ << 32;
+	tmp += gd->cpu_hz / 2;
+	do_div(tmp, gd->cpu_hz);
+	tb_factor = (u32)tmp;
+
+	intc_dev = get_device(DEVICE_INTC);
+
+	if (!intc_dev
+	    || set_interrupt_handler(0, &timer_interrupt_handler, 3))
+		return;
+
+	/* For all practical purposes, this gives us an overflow interrupt */
+	sysreg_write(COMPARE, 0xffffffff);
+}

+ 94 - 0
cpu/at32ap/pio.c

@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+#include "pio2.h"
+
+struct pio_state {
+	const struct device *dev;
+	u32 alloc_mask;
+};
+
+static struct pio_state pio_state[CFG_NR_PIOS];
+
+int gpio_set_func(enum device_id gpio_devid, unsigned int start,
+		  unsigned int nr_pins, enum gpio_func func)
+{
+	const struct device *gpio;
+	struct pio_state *state;
+	u32 mask;
+
+	state = &pio_state[gpio_devid - DEVICE_PIOA];
+
+	gpio = get_device(gpio_devid);
+	if (!gpio)
+		return -EBUSY;
+
+	state->dev = gpio;
+	mask = ((1 << nr_pins) - 1) << start;
+
+	if (mask & state->alloc_mask) {
+		put_device(gpio);
+		return -EBUSY;
+	}
+	state->alloc_mask |= mask;
+
+	switch (func) {
+	case GPIO_FUNC_GPIO:
+		/* TODO */
+		return -EINVAL;
+	case GPIO_FUNC_A:
+		pio2_writel(gpio, ASR, mask);
+		pio2_writel(gpio, PDR, mask);
+		pio2_writel(gpio, PUDR, mask);
+		break;
+	case GPIO_FUNC_B:
+		pio2_writel(gpio, BSR, mask);
+		pio2_writel(gpio, PDR, mask);
+		pio2_writel(gpio, PUDR, mask);
+		break;
+	}
+
+	return 0;
+}
+
+void gpio_free(enum device_id gpio_devid, unsigned int start,
+	       unsigned int nr_pins)
+{
+	const struct device *gpio;
+	struct pio_state *state;
+	u32 mask;
+
+	state = &pio_state[gpio_devid - DEVICE_PIOA];
+	gpio = state->dev;
+	mask = ((1 << nr_pins) - 1) << start;
+
+	pio2_writel(gpio, ODR, mask);
+	pio2_writel(gpio, PER, mask);
+
+	state->alloc_mask &= ~mask;
+	put_device(gpio);
+}

+ 44 - 0
cpu/at32ap/pio2.h

@@ -0,0 +1,44 @@
+/*
+ * Register definitions for Parallel Input/Output Controller
+ */
+#ifndef __CPU_AT32AP_PIO2_H__
+#define __CPU_AT32AP_PIO2_H__
+
+/* PIO2 register offsets */
+#define PIO2_PER				0x0000
+#define PIO2_PDR				0x0004
+#define PIO2_PSR				0x0008
+#define PIO2_OER				0x0010
+#define PIO2_ODR				0x0014
+#define PIO2_OSR				0x0018
+#define PIO2_IFER				0x0020
+#define PIO2_IFDR				0x0024
+#define PIO2_ISFR				0x0028
+#define PIO2_SODR				0x0030
+#define PIO2_CODR				0x0034
+#define PIO2_ODSR				0x0038
+#define PIO2_PDSR				0x003c
+#define PIO2_IER				0x0040
+#define PIO2_IDR				0x0044
+#define PIO2_IMR				0x0048
+#define PIO2_ISR				0x004c
+#define PIO2_MDER				0x0050
+#define PIO2_MDDR				0x0054
+#define PIO2_MDSR				0x0058
+#define PIO2_PUDR				0x0060
+#define PIO2_PUER				0x0064
+#define PIO2_PUSR				0x0068
+#define PIO2_ASR				0x0070
+#define PIO2_BSR				0x0074
+#define PIO2_ABSR				0x0078
+#define PIO2_OWER				0x00a0
+#define PIO2_OWDR				0x00a4
+#define PIO2_OWSR				0x00a8
+
+/* Register access macros */
+#define pio2_readl(port,reg)				\
+	readl((port)->regs + PIO2_##reg)
+#define pio2_writel(port,reg,value)			\
+	writel((value), (port)->regs + PIO2_##reg)
+
+#endif /* __CPU_AT32AP_PIO2_H__ */

+ 163 - 0
cpu/at32ap/pm.c

@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#ifdef CFG_POWER_MANAGER
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "sm.h"
+
+/* Sanity checks */
+#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB)		\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA)	\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
+# error Constraint fCPU >= fHSB >= fPB{A,B} violated
+#endif
+#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
+# error Invalid PLL multiplier and/or divider
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clock_domain_state {
+	const struct device *bridge;
+	unsigned long freq;
+	u32 mask;
+};
+static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
+
+int pm_enable_clock(enum clock_domain_id id, unsigned int index)
+{
+	const struct clock_domain *ckd = &chip_clock[id];
+	struct clock_domain_state *state = &ckd_state[id];
+
+	if (ckd->bridge != NO_DEVICE) {
+		state->bridge = get_device(ckd->bridge);
+		if (!state->bridge)
+			return -EBUSY;
+	}
+
+	state->mask |= 1 << index;
+	if (gd->sm)
+		writel(state->mask, gd->sm->regs + ckd->reg);
+
+	return 0;
+}
+
+void pm_disable_clock(enum clock_domain_id id, unsigned int index)
+{
+	const struct clock_domain *ckd = &chip_clock[id];
+	struct clock_domain_state *state = &ckd_state[id];
+
+	state->mask &= ~(1 << index);
+	if (gd->sm)
+		writel(state->mask, gd->sm->regs + ckd->reg);
+
+	if (ckd->bridge)
+		put_device(state->bridge);
+}
+
+unsigned long pm_get_clock_freq(enum clock_domain_id domain)
+{
+	return ckd_state[domain].freq;
+}
+
+void pm_init(void)
+{
+	uint32_t cksel = 0;
+	unsigned long main_clock;
+
+	/* Make sure we don't disable any device we're already using */
+	get_device(DEVICE_HRAMC);
+	get_device(DEVICE_HEBI);
+
+	/* Enable the PICO as well */
+	ckd_state[CLOCK_CPU].mask |= 1;
+
+	gd->sm = get_device(DEVICE_SM);
+	if (!gd->sm)
+		panic("Unable to claim system manager device!\n");
+
+	/* Disable any devices that haven't been explicitly claimed */
+	sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
+	sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
+	sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
+	sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
+
+#ifdef CONFIG_PLL
+	/* Initialize the PLL */
+	main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
+
+	sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
+				    | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
+				    | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
+				    | SM_BF(PLLOPT, CFG_PLL0_OPT)
+				    | SM_BF(PLLOSC, 0)
+				    | SM_BIT(PLLEN)));
+
+	/* Wait for lock */
+	while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
+#else
+	main_clock = CFG_OSC0_HZ;
+#endif
+
+	/* Set up clocks for the CPU and all peripheral buses */
+	if (CFG_CLKDIV_CPU) {
+		cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
+		ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
+	} else {
+		ckd_state[CLOCK_CPU].freq = main_clock;
+	}
+	if (CFG_CLKDIV_HSB) {
+		cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
+		ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
+	} else {
+		ckd_state[CLOCK_HSB].freq = main_clock;
+	}
+	if (CFG_CLKDIV_PBA) {
+		cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
+		ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
+	} else {
+		ckd_state[CLOCK_PBA].freq = main_clock;
+	}
+	if (CFG_CLKDIV_PBB) {
+		cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
+		ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
+	} else {
+		ckd_state[CLOCK_PBB].freq = main_clock;
+	}
+	sm_writel(gd->sm, PM_CKSEL, cksel);
+
+	/* CFG_HZ currently depends on cpu_hz */
+	gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
+
+#ifdef CONFIG_PLL
+	/* Use PLL0 as main clock */
+	sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
+#endif
+}
+
+#endif /* CFG_POWER_MANAGER */

+ 204 - 0
cpu/at32ap/sm.h

@@ -0,0 +1,204 @@
+/*
+ * Register definitions for System Manager
+ */
+#ifndef __CPU_AT32AP_SM_H__
+#define __CPU_AT32AP_SM_H__
+
+/* SM register offsets */
+#define SM_PM_MCCTRL				0x0000
+#define SM_PM_CKSEL				0x0004
+#define SM_PM_CPU_MASK				0x0008
+#define SM_PM_HSB_MASK				0x000c
+#define SM_PM_PBA_MASK				0x0010
+#define SM_PM_PBB_MASK				0x0014
+#define SM_PM_PLL0				0x0020
+#define SM_PM_PLL1				0x0024
+#define SM_PM_VCTRL				0x0030
+#define SM_PM_VMREF				0x0034
+#define SM_PM_VMV				0x0038
+#define SM_PM_IER				0x0040
+#define SM_PM_IDR				0x0044
+#define SM_PM_IMR				0x0048
+#define SM_PM_ISR				0x004c
+#define SM_PM_ICR				0x0050
+#define SM_PM_GCCTRL				0x0060
+#define SM_RTC_CTRL				0x0080
+#define SM_RTC_VAL				0x0084
+#define SM_RTC_TOP				0x0088
+#define SM_RTC_IER				0x0090
+#define SM_RTC_IDR				0x0094
+#define SM_RTC_IMR				0x0098
+#define SM_RTC_ISR				0x009c
+#define SM_RTC_ICR				0x00a0
+#define SM_WDT_CTRL				0x00b0
+#define SM_WDT_CLR				0x00b4
+#define SM_WDT_EXT				0x00b8
+#define SM_RC_RCAUSE				0x00c0
+#define SM_EIM_IER				0x0100
+#define SM_EIM_IDR				0x0104
+#define SM_EIM_IMR				0x0108
+#define SM_EIM_ISR				0x010c
+#define SM_EIM_ICR				0x0110
+#define SM_EIM_MODE				0x0114
+#define SM_EIM_EDGE				0x0118
+#define SM_EIM_LEVEL				0x011c
+#define SM_EIM_TEST				0x0120
+#define SM_EIM_NMIC				0x0124
+
+/* Bitfields in PM_CKSEL */
+#define SM_CPUSEL_OFFSET			0
+#define SM_CPUSEL_SIZE				3
+#define SM_CPUDIV_OFFSET			7
+#define SM_CPUDIV_SIZE				1
+#define SM_HSBSEL_OFFSET			8
+#define SM_HSBSEL_SIZE				3
+#define SM_HSBDIV_OFFSET			15
+#define SM_HSBDIV_SIZE				1
+#define SM_PBASEL_OFFSET			16
+#define SM_PBASEL_SIZE				3
+#define SM_PBADIV_OFFSET			23
+#define SM_PBADIV_SIZE				1
+#define SM_PBBSEL_OFFSET			24
+#define SM_PBBSEL_SIZE				3
+#define SM_PBBDIV_OFFSET			31
+#define SM_PBBDIV_SIZE				1
+
+/* Bitfields in PM_PLL0 */
+#define SM_PLLEN_OFFSET				0
+#define SM_PLLEN_SIZE				1
+#define SM_PLLOSC_OFFSET			1
+#define SM_PLLOSC_SIZE				1
+#define SM_PLLOPT_OFFSET			2
+#define SM_PLLOPT_SIZE				3
+#define SM_PLLDIV_OFFSET			8
+#define SM_PLLDIV_SIZE				8
+#define SM_PLLMUL_OFFSET			16
+#define SM_PLLMUL_SIZE				8
+#define SM_PLLCOUNT_OFFSET			24
+#define SM_PLLCOUNT_SIZE			6
+#define SM_PLLTEST_OFFSET			31
+#define SM_PLLTEST_SIZE				1
+
+/* Bitfields in PM_VCTRL */
+#define SM_VAUTO_OFFSET				0
+#define SM_VAUTO_SIZE				1
+#define SM_PM_VCTRL_VAL_OFFSET			8
+#define SM_PM_VCTRL_VAL_SIZE			7
+
+/* Bitfields in PM_VMREF */
+#define SM_REFSEL_OFFSET			0
+#define SM_REFSEL_SIZE				4
+
+/* Bitfields in PM_VMV */
+#define SM_PM_VMV_VAL_OFFSET			0
+#define SM_PM_VMV_VAL_SIZE			8
+
+/* Bitfields in PM_ICR */
+#define SM_LOCK0_OFFSET				0
+#define SM_LOCK0_SIZE				1
+#define SM_LOCK1_OFFSET				1
+#define SM_LOCK1_SIZE				1
+#define SM_WAKE_OFFSET				2
+#define SM_WAKE_SIZE				1
+#define SM_VOK_OFFSET				3
+#define SM_VOK_SIZE				1
+#define SM_VMRDY_OFFSET				4
+#define SM_VMRDY_SIZE				1
+#define SM_CKRDY_OFFSET				5
+#define SM_CKRDY_SIZE				1
+
+/* Bitfields in PM_GCCTRL */
+#define SM_OSCSEL_OFFSET			0
+#define SM_OSCSEL_SIZE				1
+#define SM_PLLSEL_OFFSET			1
+#define SM_PLLSEL_SIZE				1
+#define SM_CEN_OFFSET				2
+#define SM_CEN_SIZE				1
+#define SM_CPC_OFFSET				3
+#define SM_CPC_SIZE				1
+#define SM_DIVEN_OFFSET				4
+#define SM_DIVEN_SIZE				1
+#define SM_DIV_OFFSET				8
+#define SM_DIV_SIZE				8
+
+/* Bitfields in RTC_CTRL */
+#define SM_PCLR_OFFSET				1
+#define SM_PCLR_SIZE				1
+#define SM_TOPEN_OFFSET				2
+#define SM_TOPEN_SIZE				1
+#define SM_CLKEN_OFFSET				3
+#define SM_CLKEN_SIZE				1
+#define SM_PSEL_OFFSET				8
+#define SM_PSEL_SIZE				16
+
+/* Bitfields in RTC_VAL */
+#define SM_RTC_VAL_VAL_OFFSET			0
+#define SM_RTC_VAL_VAL_SIZE			31
+
+/* Bitfields in RTC_TOP */
+#define SM_RTC_TOP_VAL_OFFSET			0
+#define SM_RTC_TOP_VAL_SIZE			32
+
+/* Bitfields in RTC_ICR */
+#define SM_TOPI_OFFSET				0
+#define SM_TOPI_SIZE				1
+
+/* Bitfields in WDT_CTRL */
+#define SM_KEY_OFFSET				24
+#define SM_KEY_SIZE				8
+
+/* Bitfields in RC_RCAUSE */
+#define SM_POR_OFFSET				0
+#define SM_POR_SIZE				1
+#define SM_BOD_OFFSET				1
+#define SM_BOD_SIZE				1
+#define SM_EXT_OFFSET				2
+#define SM_EXT_SIZE				1
+#define SM_WDT_OFFSET				3
+#define SM_WDT_SIZE				1
+#define SM_NTAE_OFFSET				4
+#define SM_NTAE_SIZE				1
+#define SM_SERP_OFFSET				5
+#define SM_SERP_SIZE				1
+
+/* Bitfields in EIM_EDGE */
+#define SM_INT0_OFFSET				0
+#define SM_INT0_SIZE				1
+#define SM_INT1_OFFSET				1
+#define SM_INT1_SIZE				1
+#define SM_INT2_OFFSET				2
+#define SM_INT2_SIZE				1
+#define SM_INT3_OFFSET				3
+#define SM_INT3_SIZE				1
+
+/* Bitfields in EIM_LEVEL */
+
+/* Bitfields in EIM_TEST */
+#define SM_TESTEN_OFFSET			31
+#define SM_TESTEN_SIZE				1
+
+/* Bitfields in EIM_NMIC */
+#define SM_EN_OFFSET				0
+#define SM_EN_SIZE				1
+
+/* Bit manipulation macros */
+#define SM_BIT(name)					\
+	(1 << SM_##name##_OFFSET)
+#define SM_BF(name,value)				\
+	(((value) & ((1 << SM_##name##_SIZE) - 1))	\
+	 << SM_##name##_OFFSET)
+#define SM_BFEXT(name,value)				\
+	(((value) >> SM_##name##_OFFSET)		\
+	 & ((1 << SM_##name##_SIZE) - 1))
+#define SM_BFINS(name,value,old)			\
+	(((old) & ~(((1 << SM_##name##_SIZE) - 1)	\
+		    << SM_##name##_OFFSET))		\
+	 | SM_BF(name,value))
+
+/* Register access macros */
+#define sm_readl(port,reg)				\
+	readl((port)->regs + SM_##reg)
+#define sm_writel(port,reg,value)			\
+	writel((value), (port)->regs + SM_##reg)
+
+#endif /* __CPU_AT32AP_SM_H__ */

+ 113 - 0
cpu/at32ap/start.S

@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+#include <asm/sysreg.h>
+
+#ifndef PART_SPECIFIC_BOOTSTRAP
+# define PART_SPECIFIC_BOOTSTRAP
+#endif
+
+#define SYSREG_MMUCR_I_OFFSET	2
+#define SYSREG_MMUCR_S_OFFSET	4
+
+#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
+#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE)		\
+		    | SYSREG_BIT(FE) | SYSREG_BIT(RE)		\
+		    | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
+
+	.text
+	.global	_start
+_start:
+	PART_SPECIFIC_BOOTSTRAP
+
+	/* Reset the Status Register */
+	mov	r0, lo(SR_INIT)
+	orh	r0, hi(SR_INIT)
+	mtsr	SYSREG_SR, r0
+
+	/* Reset CPUCR and invalidate the BTB */
+	mov	r2, CPUCR_INIT
+	mtsr	SYSREG_CPUCR, r2
+
+	/* Flush the caches */
+	mov	r1, 0
+	cache	r1[4], 8
+	cache	r1[0], 0
+	sync	0
+
+	/* Reset the MMU to default settings */
+	mov	r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
+	mtsr	SYSREG_MMUCR, r0
+
+	/* Internal RAM should not need any initialization.  We might
+	   have to initialize external RAM here if the part doesn't
+	   have internal RAM (or we may use the data cache) */
+
+	/* Jump to cacheable segment */
+	lddpc	pc, 1f
+
+	.align	2
+1:	.long	2f
+
+2:	lddpc	sp, sp_init
+
+	/*
+	 * Relocate the data section and initialize .bss.  Everything
+	 * is guaranteed to be at least doubleword aligned by the
+	 * linker script.
+	 */
+	lddpc	r12, .Ldata_vma
+	lddpc	r11, .Ldata_lma
+	lddpc	r10, .Ldata_end
+	sub	r10, r12
+4:	ld.d	r8, r11++
+	sub	r10, 8
+	st.d	r12++, r8
+	brne	4b
+
+	mov	r8, 0
+	mov	r9, 0
+	lddpc	r10, .Lbss_end
+	sub	r10, r12
+4:	sub	r10, 8
+	st.d	r12++, r8
+	brne	4b
+
+	/* Initialize the GOT pointer */
+	lddpc	r6, got_init
+3:	rsub	r6, pc
+	ld.w	pc, r6[start_u_boot@got]
+
+	.align	2
+	.type	sp_init,@object
+sp_init:
+	.long	CFG_INIT_SP_ADDR
+got_init:
+	.long	3b - _GLOBAL_OFFSET_TABLE_
+.Ldata_lma:
+	.long	__data_lma
+.Ldata_vma:
+	.long	_data
+.Ldata_end:
+	.long	_edata
+.Lbss_end:
+	.long	_end

+ 1 - 1
cpu/mpc85xx/Makefile

@@ -30,7 +30,7 @@ LIB	= $(obj)lib$(CPU).a
 
 START	= start.o resetvec.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
-	  pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
+	  pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))

+ 0 - 265
cpu/mpc85xx/i2c.c

@@ -1,265 +0,0 @@
-/*
- * (C) Copyright 2003,Motorola Inc.
- * Xianghua Xiao <x.xiao@motorola.com>
- * Adapted for Motorola 85xx chip.
- *
- * (C) Copyright 2003
- * Gleb Natapov <gnatapov@mrv.com>
- * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
- *
- * Hardware I2C driver for MPC107 PCI bridge.
- *
- * 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 <command.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-
-#define TIMEOUT (CFG_HZ/4)
-
-#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3000))
-
-#define I2CADR  &I2C_Addr[0]
-#define I2CFDR  &I2C_Addr[4]
-#define I2CCCR  &I2C_Addr[8]
-#define I2CCSR  &I2C_Addr[12]
-#define I2CCDR  &I2C_Addr[16]
-#define I2CDFSRR &I2C_Addr[20]
-
-#define I2C_READ  1
-#define I2C_WRITE 0
-
-void
-i2c_init(int speed, int slaveadd)
-{
-	/* stop I2C controller */
-	writeb(0x0, I2CCCR);
-
-	/* set clock */
-	writeb(0x3f, I2CFDR);
-
-	/* set default filter */
-	writeb(0x10,I2CDFSRR);
-
-	/* write slave address */
-	writeb(slaveadd, I2CADR);
-
-	/* clear status register */
-	writeb(0x0, I2CCSR);
-
-	/* start I2C controller */
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-}
-
-static __inline__ int
-i2c_wait4bus (void)
-{
-	ulong timeval = get_timer (0);
-
-	while (readb(I2CCSR) & MPC85xx_I2CSR_MBB) {
-		if (get_timer (timeval) > TIMEOUT) {
-			return -1;
-		}
-	}
-
-  return 0;
-}
-
-static __inline__ int
-i2c_wait (int write)
-{
-	u32 csr;
-	ulong timeval = get_timer (0);
-
-	do {
-		csr = readb(I2CCSR);
-
-		if (!(csr & MPC85xx_I2CSR_MIF))
-			continue;
-
-		writeb(0x0, I2CCSR);
-
-		if (csr & MPC85xx_I2CSR_MAL) {
-			debug("i2c_wait: MAL\n");
-			return -1;
-		}
-
-		if (!(csr & MPC85xx_I2CSR_MCF))	{
-			debug("i2c_wait: unfinished\n");
-			return -1;
-		}
-
-		if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK)) {
-			debug("i2c_wait: No RXACK\n");
-			return -1;
-		}
-
-		return 0;
-	} while (get_timer (timeval) < TIMEOUT);
-
-	debug("i2c_wait: timed out\n");
-	return -1;
-}
-
-static __inline__ int
-i2c_write_addr (u8 dev, u8 dir, int rsta)
-{
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
-	       (rsta?MPC85xx_I2CCR_RSTA:0),
-	       I2CCCR);
-
-	writeb((dev << 1) | dir, I2CCDR);
-
-	if (i2c_wait (I2C_WRITE) < 0)
-		return 0;
-
-	return 1;
-}
-
-static __inline__ int
-__i2c_write (u8 *data, int length)
-{
-	int i;
-
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX,
-	       I2CCCR);
-
-	for (i=0; i < length; i++) {
-		writeb(data[i], I2CCDR);
-
-		if (i2c_wait (I2C_WRITE) < 0)
-			break;
-	}
-
-	return i;
-}
-
-static __inline__ int
-__i2c_read (u8 *data, int length)
-{
-	int i;
-
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
-	       ((length == 1) ? MPC85xx_I2CCR_TXAK : 0),
-	       I2CCCR);
-
-	/* dummy read */
-	readb(I2CCDR);
-
-	for (i=0; i < length; i++) {
-		if (i2c_wait (I2C_READ) < 0)
-			break;
-
-		/* Generate ack on last next to last byte */
-		if (i == length - 2)
-			writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
-			       MPC85xx_I2CCR_TXAK,
-			       I2CCCR);
-
-		/* Generate stop on last byte */
-		if (i == length - 1)
-			writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
-
-		data[i] = readb(I2CCDR);
-	}
-
-	return i;
-}
-
-int
-i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
-{
-	int i = 0;
-	u8 *a = (u8*)&addr;
-
-	if (i2c_wait4bus () < 0)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
-		goto exit;
-
-	if (__i2c_write (&a[4 - alen], alen) != alen)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_READ, 1) == 0)
-		goto exit;
-
-	i = __i2c_read (data, length);
-
- exit:
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
-	return !(i == length);
-}
-
-int
-i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
-{
-	int i = 0;
-	u8 *a = (u8*)&addr;
-
-	if (i2c_wait4bus () < 0)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
-		goto exit;
-
-	if (__i2c_write (&a[4 - alen], alen) != alen)
-		goto exit;
-
-	i = __i2c_write (data, length);
-
- exit:
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
-	return !(i == length);
-}
-
-int i2c_probe (uchar chip)
-{
-	int tmp;
-
-	/*
-	 * Try to read the first location of the chip.  The underlying
-	 * driver doesn't appear to support sending just the chip address
-	 * and looking for an <ACK> back.
-	 */
-	udelay(10000);
-	return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
-	uchar buf[1];
-
-	i2c_read (i2c_addr, reg, 1, buf, 1);
-
-	return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif /* CONFIG_HARD_I2C */

+ 63 - 69
cpu/mpc85xx/spd_sdram.c

@@ -131,8 +131,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
 		800,
 		900,
 		250,
-		330,	/* FIXME: Is 333 better/valid? */
-		660,	/* FIXME: Is 667 better/valid? */
+		330,
+		660,
 		750,
 		0,	/* undefined */
 		0	/* undefined */
@@ -146,6 +146,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
 }
 
 
+/*
+ * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+	unsigned int refresh_time_ns[8] = {
+		15625000,	/* 0 Normal    1.00x */
+		3900000,	/* 1 Reduced    .25x */
+		7800000,	/* 2 Extended   .50x */
+		31300000,	/* 3 Extended  2.00x */
+		62500000,	/* 4 Extended  4.00x */
+		125000000,	/* 5 Extended  8.00x */
+		15625000,	/* 6 Normal    1.00x  filler */
+		15625000,	/* 7 Normal    1.00x  filler */
+	};
+
+	return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
 long int
 spd_sdram(void)
 {
@@ -157,6 +179,10 @@ spd_sdram(void)
 	unsigned int rank_density;
 	unsigned int odt_rd_cfg, odt_wr_cfg;
 	unsigned int odt_cfg, mode_odt_enable;
+	unsigned int refresh_clk;
+#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
+	unsigned char clk_adjust;
+#endif
 	unsigned int dqs_cfg;
 	unsigned char twr_clk, twtr_clk, twr_auto_clk;
 	unsigned int tCKmin_ps, tCKmax_ps;
@@ -740,38 +766,21 @@ spd_sdram(void)
 	ddr->sdram_mode_2 = 0;
 	debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
 
-
 	/*
-	 * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
-	 * Table from SPD Spec, Byte 12, converted to picoseconds and
-	 * filled in with "default" normal values.
+	 * Determine Refresh Rate.
 	 */
-	{
-		unsigned int refresh_clk;
-		unsigned int refresh_time_ns[8] = {
-			15625000,	/* 0 Normal    1.00x */
-			3900000,	/* 1 Reduced    .25x */
-			7800000,	/* 2 Extended   .50x */
-			31300000,	/* 3 Extended  2.00x */
-			62500000,	/* 4 Extended  4.00x */
-			125000000,	/* 5 Extended  8.00x */
-			15625000,	/* 6 Normal    1.00x  filler */
-			15625000,	/* 7 Normal    1.00x  filler */
-		};
-
-		refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
+	refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
 
-		/*
-		 * Set BSTOPRE to 0x100 for page mode
-		 * If auto-charge is used, set BSTOPRE = 0
-		 */
-		ddr->sdram_interval =
-			(0
-			 | (refresh_clk & 0x3fff) << 16
-			 | 0x100
-			 );
-		debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
-	}
+	/*
+	 * Set BSTOPRE to 0x100 for page mode
+	 * If auto-charge is used, set BSTOPRE = 0
+	 */
+	ddr->sdram_interval =
+	    (0
+	     | (refresh_clk & 0x3fff) << 16
+	     | 0x100
+	     );
+	debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
 
 	/*
 	 * Is this an ECC DDR chip?
@@ -835,28 +844,23 @@ spd_sdram(void)
 
 
 #ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
-	{
-		unsigned char clk_adjust;
-
-		/*
-		 * Setup the clock control.
-		 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
-		 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
-		 *	0110	3/4 cycle late
-		 *	0111	7/8 cycle late
-		 */
-		if (spd.mem_type == SPD_MEMTYPE_DDR) {
-			clk_adjust = 0x6;
-		} else {
-			clk_adjust = 0x7;
-		}
+	/*
+	 * Setup the clock control.
+	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+	 *	0110	3/4 cycle late
+	 *	0111	7/8 cycle late
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		clk_adjust = 0x6;
+	else
+		clk_adjust = 0x7;
 
-		ddr->sdram_clk_cntl = (0
+	ddr->sdram_clk_cntl = (0
 			       | 0x80000000
 			       | (clk_adjust << 23)
 			       );
-		debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
-	}
+	debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
 #endif
 
 	/*
@@ -1081,26 +1085,16 @@ ddr_enable_ecc(unsigned int dram_size)
 		}
 	}
 
-	/* 8K */
-	dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
-	/* 16K */
-	dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
-	/* 32K */
-	dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
-	/* 64K */
-	dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
-	/* 128k */
-	dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
-	/* 256k */
-	dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
-	/* 512k */
-	dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
-	/* 1M */
-	dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
-	/* 2M */
-	dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
-	/* 4M */
-	dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
+	dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+	dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+	dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+	dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+	dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+	dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+	dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
 
 	for (i = 1; i < dram_size / 0x800000; i++) {
 		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);

+ 51 - 0
cpu/mpc86xx/Makefile

@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2002,2003 Motorola Inc.
+# Xianghua Xiao,X.Xiao@motorola.com
+#
+# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port)
+# Jeff Brown
+# 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$(CPU).a
+
+START	= start.o #resetvec.o
+SOBJS	= cache.o
+COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
+	  pci.o pcie_indirect.o spd_sdram.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(ASOBJS) $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 374 - 0
cpu/mpc86xx/cache.S

@@ -0,0 +1,374 @@
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CACHE_LINE_SIZE
+# define CACHE_LINE_SIZE L1_CACHE_BYTES
+#endif
+
+#if CACHE_LINE_SIZE == 128
+#define LG_CACHE_LINE_SIZE 7
+#elif CACHE_LINE_SIZE == 32
+#define LG_CACHE_LINE_SIZE 5
+#elif CACHE_LINE_SIZE == 16
+#define LG_CACHE_LINE_SIZE 4
+#elif CACHE_LINE_SIZE == 8
+#define LG_CACHE_LINE_SIZE 3
+#else
+# error "Invalid cache line size!"
+#endif
+
+/*
+ * Most of this code is taken from 74xx_7xx/cache.S
+ * and then cleaned up a bit
+ */
+
+/*
+ * Invalidate L1 instruction cache.
+ */
+_GLOBAL(invalidate_l1_instruction_cache)
+	/* use invalidate-all bit in HID0 */
+	mfspr	r3,HID0
+	ori	r3,r3,HID0_ICFI
+	mtspr	HID0,r3
+	isync
+	blr
+
+/*
+ * Invalidate L1 data cache.
+ */
+_GLOBAL(invalidate_l1_data_cache)
+	mfspr	r3,HID0
+	ori	r3,r3,HID0_DCFI
+	mtspr	HID0,r3
+	isync
+	blr
+
+/*
+ * Flush data cache.
+ */
+_GLOBAL(flush_data_cache)
+	lis	r3,0
+	lis	r5,CACHE_LINE_SIZE
+flush:
+	cmp	0,1,r3,r5
+	bge	done
+	lwz	r5,0(r3)
+	lis	r5,CACHE_LINE_SIZE
+	addi	r3,r3,0x4
+	b	flush
+done:
+	blr
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_icache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+	mr	r6,r3
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	mtctr	r4
+2:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	2b
+	sync				/* additional sync needed on g4 */
+	isync
+	blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5	/* align r3 down to cache line */
+	subf	r4,r3,r4	/* r4 = offset of stop from start of cache line */
+	add	r4,r4,r5	/* r4 += cache_line_size-1 */
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */
+	beqlr				  /* if r4 == 0 return */
+	mtctr	r4			  /* ctr = r4 */
+
+	sync
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+	sync
+1:	dcbf	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbf's to get to ram */
+	blr
+
+/*
+ * Like above, but invalidate the D-cache.  This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+	sync
+1:	dcbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbi's to get to ram */
+	blr
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ *	void __flush_page_to_ram(void *page)
+ */
+_GLOBAL(__flush_page_to_ram)
+	rlwinm	r3,r3,0,0,19		/* Get page base address */
+	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
+	mtctr	r4
+	mr	r6,r3
+0:	dcbst	0,r3			/* Write line to ram */
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	0b
+	sync
+	mtctr	r4
+1:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	1b
+	sync
+	isync
+	blr
+
+/*
+ * Flush a particular page from the instruction cache.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ *	void __flush_icache_page(void *page)
+ */
+_GLOBAL(__flush_icache_page)
+	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
+	mtctr	r4
+1:	icbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync
+	isync
+	blr
+
+/*
+ * Clear a page using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced).  This only works on cacheable memory.
+ */
+_GLOBAL(clear_page)
+	li	r0,4096/CACHE_LINE_SIZE
+	mtctr	r0
+1:	dcbz	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	blr
+
+/*
+ * Enable L1 Instruction cache
+ */
+_GLOBAL(icache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_ICFI|HID0_ILOCK
+	andc	r3, r3, r5
+	ori	r3, r3, HID0_ICE
+	ori	r5, r3, HID0_ICFI
+	mtspr	HID0, r5
+	mtspr	HID0, r3
+	isync
+	blr
+
+/*
+ * Disable L1 Instruction cache
+ */
+_GLOBAL(icache_disable)
+	mfspr	r3, HID0
+	li	r5, 0
+	ori	r5, r5, HID0_ICE
+	andc	r3, r3, r5
+	mtspr	HID0, r3
+	isync
+	blr
+
+/*
+ * Is instruction cache enabled?
+ */
+_GLOBAL(icache_status)
+	mfspr	r3, HID0
+	andi.	r3, r3, HID0_ICE
+	blr
+
+
+_GLOBAL(l1dcache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	ori	r3, r3, HID0_DCE
+	ori	r5, r3, HID0_DCFI
+	mtspr	HID0, r5		/* enable + invalidate */
+	mtspr	HID0, r3		/* enable */
+	sync
+	blr
+
+/*
+ * Enable data cache(s) - L1 and optionally L2
+ * Calls l2cache_enable. LR saved in r5
+ */
+_GLOBAL(dcache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	ori	r3, r3, HID0_DCE
+	ori	r5, r3, HID0_DCFI
+	mtspr	HID0, r5		/* enable + invalidate */
+	mtspr	HID0, r3		/* enable */
+	sync
+#ifdef CFG_L2
+	mflr	r5
+	bl	l2cache_enable		/* uses r3 and r4 */
+	sync
+	mtlr	r5
+#endif
+	blr
+
+
+/*
+ * Disable data cache(s) - L1 and optionally L2
+ * Calls flush_data_cache and l2cache_disable_no_flush.
+ * LR saved in r4
+ */
+_GLOBAL(dcache_disable)
+	mflr	r4			/* save link register */
+	bl	flush_data_cache	/* uses r3 and r5 */
+	sync
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	li	r5, HID0_DCE|HID0_DCFI
+	andc	r3, r3, r5		/* no enable, no invalidate */
+	mtspr	HID0, r3
+	sync
+#ifdef CFG_L2
+	bl	l2cache_disable_no_flush /* uses r3 */
+#endif
+	mtlr	r4			/* restore link register */
+	blr
+
+/*
+ * Is data cache enabled?
+ */
+_GLOBAL(dcache_status)
+	mfspr	r3, HID0
+	andi.	r3, r3, HID0_DCE
+	blr
+
+/*
+ * Invalidate L2 cache using L2I, assume L2 is enabled
+ */
+_GLOBAL(l2cache_invalidate)
+	mfspr	r3, l2cr
+	rlwinm.	r3, r3, 0, 0, 0
+	beq	1f
+
+	mfspr	r3, l2cr
+	rlwinm	r3, r3, 0, 1, 31
+
+#ifdef	CONFIG_ALTIVEC
+	dssall
+#endif
+	sync
+	mtspr	l2cr, r3
+	sync
+1:	mfspr	r3, l2cr
+	oris	r3, r3, L2CR_L2I@h
+	mtspr	l2cr, r3
+
+invl2:
+	mfspr	r3, l2cr
+	andi.	r3, r3, L2CR_L2I@h
+	bne	invl2
+	blr
+
+/*
+ * Enable L2 cache
+ * Calls l2cache_invalidate. LR is saved in r4
+ */
+_GLOBAL(l2cache_enable)
+	mflr	r4			/* save link register */
+	bl	l2cache_invalidate	/* uses r3 */
+	sync
+	lis	r3, L2_ENABLE@h
+	ori	r3, r3, L2_ENABLE@l
+	mtspr	l2cr, r3
+	isync
+	mtlr	r4			/* restore link register */
+	blr
+
+/*
+ * Disable L2 cache
+ * Calls flush_data_cache. LR is saved in r4
+ */
+_GLOBAL(l2cache_disable)
+	mflr	r4			/* save link register */
+	bl	flush_data_cache	/* uses r3 and r5 */
+	sync
+	mtlr	r4			/* restore link register */
+l2cache_disable_no_flush:		/* provide way to disable L2 w/o flushing */
+	lis	r3, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	mtspr	l2cr, r3
+	isync
+	blr

+ 26 - 0
cpu/mpc86xx/config.mk

@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2004 Freescale Semiconductor.
+# Jeff Brown
+#
+# 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
+#
+
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx -ffixed-r2 -ffixed-r29 -mstring

+ 308 - 0
cpu/mpc86xx/cpu.c

@@ -0,0 +1,308 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <mpc86xx.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#ifdef CONFIG_MPC8641HPCN
+extern void mpc8641_reset_board(cmd_tbl_t *cmdtp, int flag,
+				int argc, char *argv[]);
+#endif
+
+
+int
+checkcpu(void)
+{
+	sys_info_t sysinfo;
+	uint pvr, svr;
+	uint ver;
+	uint major, minor;
+	uint lcrr;		/* local bus clock ratio register */
+	uint clkdiv;		/* clock divider portion of lcrr */
+
+	puts("Freescale PowerPC\n");
+
+	pvr = get_pvr();
+	ver = PVR_VER(pvr);
+	major = PVR_MAJ(pvr);
+	minor = PVR_MIN(pvr);
+
+	puts("CPU:\n");
+	puts("    Core: ");
+
+	switch (ver) {
+	case PVR_VER(PVR_86xx):
+		puts("E600");
+		break;
+	default:
+		puts("Unknown");
+		break;
+	}
+	printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
+
+	svr = get_svr();
+	ver = SVR_VER(svr);
+	major = SVR_MAJ(svr);
+	minor = SVR_MIN(svr);
+
+	puts("    System: ");
+	switch (ver) {
+	case SVR_8641:
+	    if (SVR_SUBVER(svr) == 1) {
+		puts("8641D");
+	    } else {
+		puts("8641");
+	    }
+	    break;
+	default:
+		puts("Unknown");
+		break;
+	}
+	printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+
+	get_sys_info(&sysinfo);
+
+	puts("    Clocks: ");
+	printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
+	printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
+	printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
+
+#if defined(CFG_LBC_LCRR)
+	lcrr = CFG_LBC_LCRR;
+#else
+	{
+		volatile immap_t *immap = (immap_t *) CFG_IMMR;
+		volatile ccsr_lbc_t *lbc = &immap->im_lbc;
+
+		lcrr = lbc->lcrr;
+	}
+#endif
+	clkdiv = lcrr & 0x0f;
+	if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
+		printf("LBC:%4lu MHz\n",
+		       sysinfo.freqSystemBus / 1000000 / clkdiv);
+	} else {
+		printf("    LBC: unknown (lcrr: 0x%08x)\n", lcrr);
+	}
+
+	puts("    L2: ");
+	if (get_l2cr() & 0x80000000)
+		puts("Enabled\n");
+	else
+		puts("Disabled\n");
+
+	return 0;
+}
+
+
+static inline void
+soft_restart(unsigned long addr)
+{
+#ifndef CONFIG_MPC8641HPCN
+
+	/*
+	 * SRR0 has system reset vector, SRR1 has default MSR value
+	 * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
+	 */
+
+	__asm__ __volatile__ ("mtspr	26, %0"		:: "r" (addr));
+	__asm__ __volatile__ ("li	4, (1 << 6)"	::: "r4");
+	__asm__ __volatile__ ("mtspr	27, 4");
+	__asm__ __volatile__ ("rfi");
+
+#else /* CONFIG_MPC8641HPCN */
+
+	out8(PIXIS_BASE + PIXIS_RST, 0);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+	while (1) ;		/* not reached */
+}
+
+
+/*
+ * No generic way to do board reset. Simply call soft_reset.
+ */
+void
+do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#ifndef CONFIG_MPC8641HPCN
+
+#ifdef CFG_RESET_ADDRESS
+	ulong addr = CFG_RESET_ADDRESS;
+#else
+	/*
+	 * note: when CFG_MONITOR_BASE points to a RAM address,
+	 * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
+	 * address. Better pick an address known to be invalid on your
+	 * system and assign it to CFG_RESET_ADDRESS.
+	 */
+	ulong addr = CFG_MONITOR_BASE - sizeof(ulong);
+#endif
+
+	/* flush and disable I/D cache */
+	__asm__ __volatile__ ("mfspr	3, 1008"	::: "r3");
+	__asm__ __volatile__ ("ori	5, 5, 0xcc00"	::: "r5");
+	__asm__ __volatile__ ("ori	4, 3, 0xc00"	::: "r4");
+	__asm__ __volatile__ ("andc	5, 3, 5"	::: "r5");
+	__asm__ __volatile__ ("sync");
+	__asm__ __volatile__ ("mtspr	1008, 4");
+	__asm__ __volatile__ ("isync");
+	__asm__ __volatile__ ("sync");
+	__asm__ __volatile__ ("mtspr	1008, 5");
+	__asm__ __volatile__ ("isync");
+	__asm__ __volatile__ ("sync");
+
+	soft_restart(addr);
+
+#else /* CONFIG_MPC8641HPCN */
+
+	mpc8641_reset_board(cmdtp, flag, argc, argv);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+	while (1) ;		/* not reached */
+}
+
+
+/*
+ * Get timebase clock frequency
+ */
+unsigned long
+get_tbclk(void)
+{
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	return (sys_info.freqSystemBus + 3L) / 4L;
+}
+
+
+#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+}
+#endif	/* CONFIG_WATCHDOG */
+
+
+#if defined(CONFIG_DDR_ECC)
+void
+dma_init(void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+
+	dma->satr0 = 0x00040000;
+	dma->datr0 = 0x00040000;
+	asm("sync; isync");
+}
+
+uint
+dma_check(void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+	volatile uint status = dma->sr0;
+
+	/* While the channel is busy, spin */
+	while ((status & 4) == 4) {
+		status = dma->sr0;
+	}
+
+	if (status != 0) {
+		printf("DMA Error: status = %x\n", status);
+	}
+	return status;
+}
+
+int
+dma_xfer(void *dest, uint count, void *src)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+
+	dma->dar0 = (uint) dest;
+	dma->sar0 = (uint) src;
+	dma->bcr0 = count;
+	dma->mr0 = 0xf000004;
+	asm("sync;isync");
+	dma->mr0 = 0xf000005;
+	asm("sync;isync");
+	return dma_check();
+}
+
+#endif	/* CONFIG_DDR_ECC */
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+	u32 *p;
+	ulong clock;
+	int len;
+
+	clock = bd->bi_busfreq;
+	p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC86XX_TSEC1)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+	memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC2)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+	memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC3)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+	memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC4)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+	memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif

+ 117 - 0
cpu/mpc86xx/cpu_init.c

@@ -0,0 +1,117 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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
+ */
+
+/*
+ * cpu_init.c - low level cpu init
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+
+/*
+ * Breathe some life into the CPU...
+ *
+ * Set up the memory map
+ * initialize a bunch of registers
+ */
+
+void cpu_init_f(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_lbc_t *memctl = &immap->im_lbc;
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset ((void *) gd, 0, sizeof (gd_t));
+
+	/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
+	 * addresses - these have to be modified later when FLASH size
+	 * has been determined
+	 */
+
+#if defined(CFG_OR0_REMAP)
+	memctl->or0 = CFG_OR0_REMAP;
+#endif
+#if defined(CFG_OR1_REMAP)
+	memctl->or1 = CFG_OR1_REMAP;
+#endif
+
+	/* now restrict to preliminary range */
+#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
+	memctl->br0 = CFG_BR0_PRELIM;
+	memctl->or0 = CFG_OR0_PRELIM;
+#endif
+
+#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
+	memctl->or1 = CFG_OR1_PRELIM;
+	memctl->br1 = CFG_BR1_PRELIM;
+#endif
+
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+	memctl->or2 = CFG_OR2_PRELIM;
+	memctl->br2 = CFG_BR2_PRELIM;
+#endif
+
+#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
+	memctl->or3 = CFG_OR3_PRELIM;
+	memctl->br3 = CFG_BR3_PRELIM;
+#endif
+
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+	memctl->or4 = CFG_OR4_PRELIM;
+	memctl->br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+	memctl->or5 = CFG_OR5_PRELIM;
+	memctl->br5 = CFG_BR5_PRELIM;
+#endif
+
+#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
+	memctl->or6 = CFG_OR6_PRELIM;
+	memctl->br6 = CFG_BR6_PRELIM;
+#endif
+
+#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
+	memctl->or7 = CFG_OR7_PRELIM;
+	memctl->br7 = CFG_BR7_PRELIM;
+#endif
+
+	/* enable the timebase bit in HID0 */
+	set_hid0(get_hid0() | 0x4000000);
+
+	/* enable SYNCBE | ABE bits in  HID1 */
+	set_hid1(get_hid1() | 0x00000C00);
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r(void)
+{
+	return 0;
+}

+ 204 - 0
cpu/mpc86xx/interrupts.c

@@ -0,0 +1,204 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 (440 port)
+ * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
+ *
+ * (C) Copyright 2003 Motorola Inc. (MPC85xx port)
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port)
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <mpc86xx.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <ppc_asm.tmpl>
+
+unsigned long decrementer_count;    /* count value for 1e6/HZ microseconds */
+unsigned long timestamp;
+
+
+static __inline__ unsigned long get_msr(void)
+{
+	unsigned long msr;
+
+	asm volatile ("mfmsr %0":"=r" (msr):);
+
+	return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+	asm volatile ("mtmsr %0"::"r" (msr));
+}
+
+static __inline__ unsigned long get_dec(void)
+{
+	unsigned long val;
+
+	asm volatile ("mfdec %0":"=r" (val):);
+
+	return val;
+}
+
+static __inline__ void set_dec(unsigned long val)
+{
+	if (val)
+		asm volatile ("mtdec %0"::"r" (val));
+}
+
+/* interrupt is not supported yet */
+int interrupt_init_cpu(unsigned *decrementer_count)
+{
+	return 0;
+}
+
+int interrupt_init(void)
+{
+	int ret;
+
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	ret = interrupt_init_cpu(&decrementer_count);
+
+	if (ret)
+		return ret;
+
+	decrementer_count = get_tbclk() / CFG_HZ;
+	debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n",
+	      (get_tbclk() / 1000000),
+	      decrementer_count);
+
+	set_dec(decrementer_count);
+
+	set_msr(get_msr() | MSR_EE);
+
+	debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n",
+	      get_msr(),
+	      get_dec());
+
+	return 0;
+}
+
+void enable_interrupts(void)
+{
+	set_msr(get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts(void)
+{
+	ulong msr = get_msr();
+
+	set_msr(msr & ~MSR_EE);
+	return (msr & MSR_EE) != 0;
+}
+
+void increment_timestamp(void)
+{
+	timestamp++;
+}
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void timer_interrupt_cpu(struct pt_regs *regs)
+{
+	/* nothing to do here */
+}
+
+void timer_interrupt(struct pt_regs *regs)
+{
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	timer_interrupt_cpu(regs);
+
+	timestamp++;
+
+	ppcDcbf(&timestamp);
+
+	/* Restore Decrementer Count */
+	set_dec(decrementer_count);
+
+#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
+	if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0)
+		WATCHDOG_RESET();
+#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
+
+#ifdef CONFIG_STATUS_LED
+	status_led_tick(timestamp);
+#endif /* CONFIG_STATUS_LED */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+	board_show_activity(timestamp);
+#endif /* CONFIG_SHOW_ACTIVITY */
+
+}
+
+void reset_timer(void)
+{
+	timestamp = 0;
+}
+
+ulong get_timer(ulong base)
+{
+	return timestamp - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+/*
+ * Install and free a interrupt handler. Not implemented yet.
+ */
+
+void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+}
+
+void irq_free_handler(int vec)
+{
+}
+
+/*
+ * irqinfo - print information about PCI devices,not implemented.
+ */
+int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	printf("\nInterrupt-unsupported:\n");
+
+	return 0;
+}
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
+{
+	puts("external_interrupt (oops!)\n");
+}

+ 146 - 0
cpu/mpc86xx/pci.c

@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) Freescale Semiconductor,Inc.
+ * 2005, 2006. All rights reserved.
+ *
+ * Ed Swarthout (ed.swarthout@freescale.com)
+ * Jason Jin (Jason.jin@freescale.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
+ */
+
+/*
+ * PCIE Configuration space access support for PCIE Bridge
+ */
+#include <common.h>
+#include <pci.h>
+
+#if defined(CONFIG_PCI)
+void
+pci_mpc86xx_init(struct pci_controller *hose)
+{
+	volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
+	volatile ccsr_pex_t *pcie1 = &immap->im_pex1;
+	u16 temp16;
+	u32 temp32;
+
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
+	uint pcie1_host = (host1_agent == 2) || (host1_agent == 3);
+	uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1);
+	uint devdisr = gur->devdisr;
+	uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
+
+	if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 ||
+	     io_sel == 7 || io_sel == 0xf)
+	    && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
+		printf("PCI-EXPRESS 1: Configured as %s \n",
+		       pcie1_agent ? "Agent" : "Host");
+		if (pcie1_agent)
+			return;	/*Don't scan bus when configured as agent */
+		printf("               Scanning PCIE bus");
+		debug("0x%08x=0x%08x ",
+		      &pcie1->pme_msg_det,
+		      pcie1->pme_msg_det);
+		if (pcie1->pme_msg_det) {
+			pcie1->pme_msg_det = 0xffffffff;
+			debug(" with errors.  Clearing.  Now 0x%08x",
+			      pcie1->pme_msg_det);
+		}
+		debug("\n");
+	} else {
+		printf("PCI-EXPRESS 1 disabled!\n");
+		return;
+	}
+
+	/*
+	 * Set first_bus=0 only skipped B0:D0:F0 which is
+	 * a reserved device in M1575, but make it easy for
+	 * most of the scan process.
+	 */
+	hose->first_busno = 0x00;
+	hose->last_busno = 0xfe;
+
+	pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004));
+
+	pci_hose_read_config_word(hose,
+				  PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16);
+	temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
+	    PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+	pci_hose_write_config_word(hose,
+				   PCI_BDF(0, 0, 0), PCI_COMMAND, temp16);
+
+	pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff);
+	pci_hose_write_config_byte(hose,
+				   PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80);
+
+	pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+				   &temp32);
+	temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
+	pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+				    temp32);
+
+	pcie1->powar1 = 0;
+	pcie1->powar2 = 0;
+	pcie1->piwar1 = 0;
+	pcie1->piwar1 = 0;
+
+	pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+	pcie1->powar1 = 0x8004401c;	/* 512M MEM space */
+	pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+	pcie1->potear1 = 0x00000000;
+
+	pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+	pcie1->powar2 = 0x80088017;	/* 16M IO space */
+	pcie1->potar2 = 0x00000000;
+	pcie1->potear2 = 0x00000000;
+
+	pcie1->pitar1 = 0x00000000;
+	pcie1->piwbar1 = 0x00000000;
+	/* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */
+	pcie1->piwar1 = 0xa0f5501e;
+
+	pci_set_region(hose->regions + 0,
+		       CFG_PCI_MEMORY_BUS,
+		       CFG_PCI_MEMORY_PHYS,
+		       CFG_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+	pci_set_region(hose->regions + 1,
+		       CFG_PCI1_MEM_BASE,
+		       CFG_PCI1_MEM_PHYS,
+		       CFG_PCI1_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	pci_set_region(hose->regions + 2,
+		       CFG_PCI1_IO_BASE,
+		       CFG_PCI1_IO_PHYS,
+		       CFG_PCI1_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 3;
+
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+	debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno);
+	debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno);
+
+	printf("....PCIE1 scan & enumeration done\n");
+}
+#endif				/* CONFIG_PCI */

+ 199 - 0
cpu/mpc86xx/pcie_indirect.c

@@ -0,0 +1,199 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (c) Freescale Semiconductor, Inc.
+ * 2006. All rights reserved.
+ *
+ * Jason Jin <Jason.jin@freescale.com>
+ *
+ * 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.
+ *
+ * partly derived from
+ * arch/powerpc/platforms/86xx/mpc86xx_pcie.c
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PCI_CFG_OUT 	out_be32
+#define PEX_FIX		out_be32(hose->cfg_addr+0x4, 0x0400ffff)
+
+static int
+indirect_read_config_pcie(struct pci_controller *hose,
+			  pci_dev_t dev,
+			  int offset,
+			  int len,
+			  u32 *val)
+{
+	int bus = PCI_BUS(dev);
+
+	volatile unsigned char *cfg_data;
+	u32 temp;
+
+	PEX_FIX;
+	if (bus == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000001);
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000000);
+	}
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	PEX_FIX;
+	temp = in_le32((u32 *) cfg_data);
+	switch (len) {
+	case 1:
+		*val = (temp >> (((offset & 3)) * 8)) & 0xff;
+		break;
+	case 2:
+		*val = (temp >> (((offset & 3)) * 8)) & 0xffff;
+		break;
+	default:
+		*val = temp;
+		break;
+	}
+
+	return 0;
+}
+
+static int
+indirect_write_config_pcie(struct pci_controller *hose,
+			   pci_dev_t dev,
+			   int offset,
+			   int len,
+			   u32 val)
+{
+	int bus = PCI_BUS(dev);
+	volatile unsigned char *cfg_data;
+	u32 temp;
+
+	PEX_FIX;
+	if (bus == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000001);
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000000);
+	}
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	switch (len) {
+	case 1:
+		PEX_FIX;
+		temp = in_le32((u32 *) cfg_data);
+		temp = (temp & ~(0xff << ((offset & 3) * 8))) |
+		    (val << ((offset & 3) * 8));
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, temp);
+		break;
+	case 2:
+		PEX_FIX;
+		temp = in_le32((u32 *) cfg_data);
+		temp = (temp & ~(0xffff << ((offset & 3) * 8)));
+		temp |= (val << ((offset & 3) * 8));
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, temp);
+		break;
+	default:
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, val);
+		break;
+	}
+	PEX_FIX;
+	return 0;
+}
+
+static int
+indirect_read_config_byte_pcie(struct pci_controller *hose,
+			       pci_dev_t dev,
+			       int offset,
+			       u8 *val)
+{
+	u32 val32;
+	indirect_read_config_pcie(hose, dev, offset, 1, &val32);
+	*val = (u8) val32;
+	return 0;
+}
+
+static int
+indirect_read_config_word_pcie(struct pci_controller *hose,
+			       pci_dev_t dev,
+			       int offset,
+			       u16 *val)
+{
+	u32 val32;
+	indirect_read_config_pcie(hose, dev, offset, 2, &val32);
+	*val = (u16) val32;
+	return 0;
+}
+
+static int
+indirect_read_config_dword_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				u32 *val)
+{
+	return indirect_read_config_pcie(hose, dev, offset, 4, val);
+}
+
+static int
+indirect_write_config_byte_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				u8 val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val);
+}
+
+static int
+indirect_write_config_word_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				unsigned short val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val);
+}
+
+static int
+indirect_write_config_dword_pcie(struct pci_controller *hose,
+				 pci_dev_t dev,
+				 int offset,
+				 u32 val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 4, val);
+}
+
+void
+pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
+{
+	pci_set_ops(hose,
+		    indirect_read_config_byte_pcie,
+		    indirect_read_config_word_pcie,
+		    indirect_read_config_dword_pcie,
+		    indirect_write_config_byte_pcie,
+		    indirect_write_config_word_pcie,
+		    indirect_write_config_dword_pcie);
+
+	hose->cfg_addr = (unsigned int *)cfg_addr;
+	hose->cfg_data = (unsigned char *)cfg_data;
+}
+
+#endif				/* CONFIG_PCI */

+ 2 - 0
cpu/mpc86xx/resetvec.S

@@ -0,0 +1,2 @@
+	.section .resetvec,"ax"
+	b _start

+ 1324 - 0
cpu/mpc86xx/spd_sdram.c

@@ -0,0 +1,1324 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@motorola.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/processor.h>
+#include <i2c.h>
+#include <spd.h>
+#include <asm/mmu.h>
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void dma_init(void);
+extern uint dma_check(void);
+extern int dma_xfer(void *dest, uint count, void *src);
+#endif
+
+#ifdef CONFIG_SPD_EEPROM
+
+#ifndef	CFG_READ_SPD
+#define CFG_READ_SPD	i2c_read
+#endif
+
+/*
+ * Only one of the following three should be 1; others should be 0
+ * By default the cache line interleaving is selected if
+ * the CONFIG_DDR_INTERLEAVE flag is defined
+ */
+#define CFG_PAGE_INTERLEAVING		0
+#define CFG_BANK_INTERLEAVING		0
+#define CFG_SUPER_BANK_INTERLEAVING	0
+
+/*
+ * Convert picoseconds into clock cycles (rounding up if needed).
+ */
+
+int
+picos_to_clk(int picos)
+{
+	int clks;
+
+	clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
+	if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
+		clks++;
+	}
+
+	return clks;
+}
+
+
+/*
+ * Calculate the Density of each Physical Rank.
+ * Returned size is in bytes.
+ *
+ * Study these table from Byte 31 of JEDEC SPD Spec.
+ *
+ *		DDR I	DDR II
+ *	Bit	Size	Size
+ *	---	-----	------
+ *	7 high	512MB	512MB
+ *	6	256MB	256MB
+ *	5	128MB	128MB
+ *	4	 64MB	 16GB
+ *	3	 32MB	  8GB
+ *	2	 16MB	  4GB
+ *	1	  2GB	  2GB
+ *	0 low	  1GB	  1GB
+ *
+ * Reorder Table to be linear by stripping the bottom
+ * 2 or 5 bits off and shifting them up to the top.
+ */
+
+unsigned int
+compute_banksize(unsigned int mem_type, unsigned char row_dens)
+{
+	unsigned int bsize;
+
+	if (mem_type == SPD_MEMTYPE_DDR) {
+		/* Bottom 2 bits up to the top. */
+		bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
+		debug("DDR: DDR I rank density = 0x%08x\n", bsize);
+	} else {
+		/* Bottom 5 bits up to the top. */
+		bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27;
+		debug("DDR: DDR II rank density = 0x%08x\n", bsize);
+	}
+	return bsize;
+}
+
+
+/*
+ * Convert a two-nibble BCD value into a cycle time.
+ * While the spec calls for nano-seconds, picos are returned.
+ *
+ * This implements the tables for bytes 9, 23 and 25 for both
+ * DDR I and II.  No allowance for distinguishing the invalid
+ * fields absent for DDR I yet present in DDR II is made.
+ * (That is, cycle times of .25, .33, .66 and .75 ns are
+ * allowed for both DDR II and I.)
+ */
+
+unsigned int
+convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
+{
+	/*
+	 * Table look up the lower nibble, allow DDR I & II.
+	 */
+	unsigned int tenths_ps[16] = {
+		0,
+		100,
+		200,
+		300,
+		400,
+		500,
+		600,
+		700,
+		800,
+		900,
+		250,
+		330,
+		660,
+		750,
+		0,	/* undefined */
+		0	/* undefined */
+	};
+
+	unsigned int whole_ns = (spd_val & 0xF0) >> 4;
+	unsigned int tenth_ns = spd_val & 0x0F;
+	unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
+
+	return ps;
+}
+
+
+/*
+ * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+	unsigned int refresh_time_ns[8] = {
+		15625000,	/* 0 Normal    1.00x */
+		3900000,	/* 1 Reduced    .25x */
+		7800000,	/* 2 Extended   .50x */
+		31300000,	/* 3 Extended  2.00x */
+		62500000,	/* 4 Extended  4.00x */
+		125000000,	/* 5 Extended  8.00x */
+		15625000,	/* 6 Normal    1.00x  filler */
+		15625000,	/* 7 Normal    1.00x  filler */
+	};
+
+	return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
+long int
+spd_init(unsigned char i2c_address, unsigned int ddr_num,
+	 unsigned int dimm_num, unsigned int start_addr)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_ddr_t *ddr;
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	spd_eeprom_t spd;
+	unsigned int n_ranks;
+	unsigned int rank_density;
+	unsigned int odt_rd_cfg, odt_wr_cfg;
+	unsigned int odt_cfg, mode_odt_enable;
+	unsigned int refresh_clk;
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+	unsigned char clk_adjust;
+#endif
+	unsigned int dqs_cfg;
+	unsigned char twr_clk, twtr_clk, twr_auto_clk;
+	unsigned int tCKmin_ps, tCKmax_ps;
+	unsigned int max_data_rate;
+	unsigned int busfreq;
+	unsigned sdram_cfg_1;
+	unsigned int memsize;
+	unsigned char caslat, caslat_ctrl;
+	unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+	unsigned int trcd_clk;
+	unsigned int trtp_clk;
+	unsigned char cke_min_clk;
+	unsigned char add_lat;
+	unsigned char wr_lat;
+	unsigned char wr_data_delay;
+	unsigned char four_act;
+	unsigned char cpo;
+	unsigned char burst_len;
+	unsigned int mode_caslat;
+	unsigned char sdram_type;
+	unsigned char d_init;
+	unsigned int law_size;
+	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+	unsigned int tCycle_ps, modfreq;
+
+	if (ddr_num == 1)
+		ddr = &immap->im_ddr1;
+	else
+		ddr = &immap->im_ddr2;
+
+	/*
+	 * Read SPD information.
+	 */
+	debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address);
+	memset((void *)&spd, 0, sizeof(spd));
+	CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd));
+
+	/*
+	 * Check for supported memory module types.
+	 */
+	if (spd.mem_type != SPD_MEMTYPE_DDR &&
+	    spd.mem_type != SPD_MEMTYPE_DDR2) {
+		debug("Warning: Unable to locate DDR I or DDR II module for DIMM %d of DDR controller %d.\n"
+		      "         Fundamental memory type is 0x%0x\n",
+		      dimm_num,
+		      ddr_num,
+		      spd.mem_type);
+		return 0;
+	}
+
+	debug("\nFound memory of type 0x%02lx  ", spd.mem_type);
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		debug("DDR I\n");
+	else
+		debug("DDR II\n");
+
+	/*
+	 * These test gloss over DDR I and II differences in interpretation
+	 * of bytes 3 and 4, but irrelevantly.  Multiple asymmetric banks
+	 * are not supported on DDR I; and not encoded on DDR II.
+	 *
+	 * Also note that the 8548 controller can support:
+	 *    12 <= nrow <= 16
+	 * and
+	 *     8 <= ncol <= 11 (still, for DDR)
+	 *     6 <= ncol <=  9 (for FCRAM)
+	 */
+	if (spd.nrow_addr < 12 || spd.nrow_addr > 14) {
+		printf("DDR: Unsupported number of Row Addr lines: %d.\n",
+		       spd.nrow_addr);
+		return 0;
+	}
+	if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
+		printf("DDR: Unsupported number of Column Addr lines: %d.\n",
+		       spd.ncol_addr);
+		return 0;
+	}
+
+	/*
+	 * Determine the number of physical banks controlled by
+	 * different Chip Select signals.  This is not quite the
+	 * same as the number of DIMM modules on the board.  Feh.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		n_ranks = spd.nrows;
+	} else {
+		n_ranks = (spd.nrows & 0x7) + 1;
+	}
+
+	debug("DDR: number of ranks = %d\n", n_ranks);
+
+	if (n_ranks > 2) {
+		printf("DDR: Only 2 chip selects are supported: %d\n",
+		       n_ranks);
+		return 0;
+	}
+
+	/*
+	 * Adjust DDR II IO voltage biasing.  It just makes it work.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		gur->ddrioovcr = (0
+				  | 0x80000000		/* Enable */
+				  | 0x10000000		/* VSEL to 1.8V */
+				  );
+	}
+
+	/*
+	 * Determine the size of each Rank in bytes.
+	 */
+	rank_density = compute_banksize(spd.mem_type, spd.row_dens);
+
+	debug("Start address for this controller is 0x%08lx\n", start_addr);
+
+	/*
+	 * ODT configuration recommendation from DDR Controller Chapter.
+	 */
+	odt_rd_cfg = 0;			/* Never assert ODT */
+	odt_wr_cfg = 0;			/* Never assert ODT */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		odt_wr_cfg = 1;		/* Assert ODT on writes to CS0 */
+	}
+
+#ifdef CONFIG_DDR_INTERLEAVE
+
+	if (dimm_num != 1) {
+		printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
+		return 0;
+	} else {
+		/*
+		 * Since interleaved memory only uses CS0, the
+		 * memory sticks have to be identical in size and quantity
+		 * of ranks.  That essentially gives double the size on
+		 * one rank, i.e on CS0 for both controllers put together.
+		 * Confirm this???
+		 */
+		rank_density *= 2;
+
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		start_addr = 0;
+		ddr->cs0_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+		/*
+		 * Default interleaving mode to cache-line interleaving.
+		 */
+		ddr->cs0_config = ( 1 << 31
+#if	(CFG_PAGE_INTERLEAVING == 1)
+				    | (PAGE_INTERLEAVING)
+#elif	(CFG_BANK_INTERLEAVING == 1)
+				    | (BANK_INTERLEAVING)
+#elif	(CFG_SUPER_BANK_INTERLEAVING == 1)
+				    | (SUPER_BANK_INTERLEAVING)
+#else
+				    | (CACHE_LINE_INTERLEAVING)
+#endif
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs0_bnds   = 0x%08x\n", ddr->cs0_bnds);
+		debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+		/*
+		 * Adjustment for dual rank memory to get correct memory
+		 * size (return value of this function).
+		 */
+		if (n_ranks == 2) {
+			n_ranks = 1;
+			rank_density /= 2;
+		} else {
+			rank_density /= 2;
+		}
+	}
+#else	/* CONFIG_DDR_INTERLEAVE */
+
+	if (dimm_num == 1) {
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		ddr->cs0_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+
+		ddr->cs0_config = ( 1 << 31
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs0_bnds   = 0x%08x\n", ddr->cs0_bnds);
+		debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+		if (n_ranks == 2) {
+			/*
+			 * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+			 * second 256 Meg
+			 */
+			ddr->cs1_bnds = (((start_addr + rank_density) >> 8)
+					| (( start_addr + 2*rank_density - 1)
+					   >> 24));
+			ddr->cs1_config = ( 1<<31
+					    | (odt_rd_cfg << 20)
+					    | (odt_wr_cfg << 16)
+					    | (spd.nrow_addr - 12) << 8
+					    | (spd.ncol_addr - 8) );
+			debug("DDR: cs1_bnds   = 0x%08x\n", ddr->cs1_bnds);
+			debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config);
+		}
+
+	} else {
+		/*
+		 * This is the 2nd DIMM slot for this controller
+		 */
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		ddr->cs2_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+
+		ddr->cs2_config = ( 1 << 31
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs2_bnds   = 0x%08x\n", ddr->cs2_bnds);
+		debug("DDR: cs2_config = 0x%08x\n", ddr->cs2_config);
+
+		if (n_ranks == 2) {
+			/*
+			 * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+			 * second 256 Meg
+			 */
+			ddr->cs3_bnds = (((start_addr + rank_density) >> 8)
+					| (( start_addr + 2*rank_density - 1)
+					   >> 24));
+			ddr->cs3_config = ( 1<<31
+					    | (odt_rd_cfg << 20)
+					    | (odt_wr_cfg << 16)
+					    | (spd.nrow_addr - 12) << 8
+					    | (spd.ncol_addr - 8) );
+			debug("DDR: cs3_bnds   = 0x%08x\n", ddr->cs3_bnds);
+			debug("DDR: cs3_config = 0x%08x\n", ddr->cs3_config);
+		}
+	}
+#endif /* CONFIG_DDR_INTERLEAVE */
+
+	/*
+	 * Find the largest CAS by locating the highest 1 bit
+	 * in the spd.cas_lat field.  Translate it to a DDR
+	 * controller field value:
+	 *
+	 *	CAS Lat	DDR I	DDR II	Ctrl
+	 *	Clocks	SPD Bit	SPD Bit	Value
+	 *	-------	-------	-------	-----
+	 *	1.0	0		0001
+	 *	1.5	1		0010
+	 *	2.0	2	2	0011
+	 *	2.5	3		0100
+	 *	3.0	4	3	0101
+	 *	3.5	5		0110
+	 *	4.0		4	0111
+	 *	4.5			1000
+	 *	5.0		5	1001
+	 */
+	caslat = __ilog2(spd.cas_lat);
+	if ((spd.mem_type == SPD_MEMTYPE_DDR)
+	    && (caslat > 5)) {
+		printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat);
+		return 0;
+
+	} else if (spd.mem_type == SPD_MEMTYPE_DDR2
+		   && (caslat < 2 || caslat > 5)) {
+		printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n",
+		       spd.cas_lat);
+		return 0;
+	}
+	debug("DDR: caslat SPD bit is %d\n", caslat);
+
+	/*
+	 * Calculate the Maximum Data Rate based on the Minimum Cycle time.
+	 * The SPD clk_cycle field (tCKmin) is measured in tenths of
+	 * nanoseconds and represented as BCD.
+	 */
+	tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle);
+	debug("DDR: tCKmin = %d ps\n", tCKmin_ps);
+
+	/*
+	 * Double-data rate, scaled 1000 to picoseconds, and back down to MHz.
+	 */
+	max_data_rate = 2 * 1000 * 1000 / tCKmin_ps;
+	debug("DDR: Module max data rate = %d Mhz\n", max_data_rate);
+
+
+	/*
+	 * Adjust the CAS Latency to allow for bus speeds that
+	 * are slower than the DDR module.
+	 */
+	busfreq = get_bus_freq(0) / 1000000;	/* MHz */
+	tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle3);
+	modfreq = 2 * 1000 * 1000 / tCycle_ps;
+
+	if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) {
+		printf("DDR: platform frequency too low for correct DDR2 controller operation\n");
+		return 0;
+	} else if (busfreq < 90) {
+		printf("DDR: platform frequency too low for correct DDR1 operation\n");
+		return 0;
+	}
+
+	if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 2)))) {
+		caslat -= 2;
+	} else {
+		tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle2);
+		modfreq = 2 * 1000 * 1000 / tCycle_ps;
+		if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 1))))
+			caslat -= 1;
+		else if (busfreq > max_data_rate) {
+			printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
+		     	busfreq, max_data_rate);
+			return 0;
+		}
+	}
+
+	/*
+	 * Empirically set ~MCAS-to-preamble override for DDR 2.
+	 * Your milage will vary.
+	 */
+	cpo = 0;
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		if (busfreq <= 333) {
+			cpo = 0x7;
+		} else if (busfreq <= 400) {
+			cpo = 0x9;
+		} else {
+			cpo = 0xa;
+		}
+	}
+
+	/*
+	 * Convert caslat clocks to DDR controller value.
+	 * Force caslat_ctrl to be DDR Controller field-sized.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		caslat_ctrl = (caslat + 1) & 0x07;
+	} else {
+		caslat_ctrl =  (2 * caslat - 1) & 0x0f;
+	}
+
+	debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
+	      caslat, caslat_ctrl);
+
+	/*
+	 * Timing Config 0.
+	 * Avoid writing for DDR I.  The new PQ38 DDR controller
+	 * dreams up non-zero default values to be backwards compatible.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		unsigned char taxpd_clk = 8;		/* By the book. */
+		unsigned char tmrd_clk = 2;		/* By the book. */
+		unsigned char act_pd_exit = 2;		/* Empirical? */
+		unsigned char pre_pd_exit = 6;		/* Empirical? */
+
+		ddr->timing_cfg_0 = (0
+			| ((act_pd_exit & 0x7) << 20)	/* ACT_PD_EXIT */
+			| ((pre_pd_exit & 0x7) << 16)	/* PRE_PD_EXIT */
+			| ((taxpd_clk & 0xf) << 8)	/* ODT_PD_EXIT */
+			| ((tmrd_clk & 0xf) << 0)	/* MRS_CYC */
+			);
+		debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
+
+	}
+
+
+	/*
+	 * Some Timing Config 1 values now.
+	 * Sneak Extended Refresh Recovery in here too.
+	 */
+
+	/*
+	 * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD,
+	 * use conservative value.
+	 * For DDR II, they are bytes 36 and 37, in quarter nanos.
+	 */
+
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		twr_clk = 3;	/* Clocks */
+		twtr_clk = 1;	/* Clocks */
+	} else {
+		twr_clk = picos_to_clk(spd.twr * 250);
+		twtr_clk = picos_to_clk(spd.twtr * 250);
+	}
+
+	/*
+	 * Calculate Trfc, in picos.
+	 * DDR I:  Byte 42 straight up in ns.
+	 * DDR II: Byte 40 and 42 swizzled some, in ns.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		trfc = spd.trfc * 1000;		/* up to ps */
+	} else {
+		unsigned int byte40_table_ps[8] = {
+			0,
+			250,
+			330,
+			500,
+			660,
+			750,
+			0,
+			0
+		};
+
+		trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000
+			+ byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];
+	}
+	trfc_clk = picos_to_clk(trfc);
+
+	/*
+	 * Trcd, Byte 29, from quarter nanos to ps and clocks.
+	 */
+	trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7;
+
+	/*
+	 * Convert trfc_clk to DDR controller fields.  DDR I should
+	 * fit in the REFREC field (16-19) of TIMING_CFG_1, but the
+	 * 8548 controller has an extended REFREC field of three bits.
+	 * The controller automatically adds 8 clocks to this value,
+	 * so preadjust it down 8 first before splitting it up.
+	 */
+	trfc_low = (trfc_clk - 8) & 0xf;
+	trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
+
+	/*
+	 * Sneak in some Extended Refresh Recovery.
+	 */
+	ddr->ext_refrec = (trfc_high << 16);
+	debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec);
+
+	ddr->timing_cfg_1 =
+	    (0
+	     | ((picos_to_clk(spd.trp * 250) & 0x07) << 28)	/* PRETOACT */
+	     | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24)	/* ACTTOPRE */
+	     | (trcd_clk << 20)					/* ACTTORW */
+	     | (caslat_ctrl << 16)				/* CASLAT */
+	     | (trfc_low << 12)					/* REFEC */
+	     | ((twr_clk & 0x07) << 8)				/* WRRREC */
+	     | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4)	/* ACTTOACT */
+	     | ((twtr_clk & 0x07) << 0)				/* WRTORD */
+	     );
+
+	debug("DDR: timing_cfg_1  = 0x%08x\n", ddr->timing_cfg_1);
+
+
+	/*
+	 * Timing_Config_2
+	 * Was: 0x00000800;
+	 */
+
+	/*
+	 * Additive Latency
+	 * For DDR I, 0.
+	 * For DDR II, with ODT enabled, use "a value" less than ACTTORW,
+	 * which comes from Trcd, and also note that:
+	 *	add_lat + caslat must be >= 4
+	 */
+	add_lat = 0;
+	if (spd.mem_type == SPD_MEMTYPE_DDR2
+	    && (odt_wr_cfg || odt_rd_cfg)
+	    && (caslat < 4)) {
+		add_lat = 4 - caslat;
+		if (add_lat >= trcd_clk) {
+			add_lat = trcd_clk - 1;
+		}
+	}
+
+	/*
+	 * Write Data Delay
+	 * Historically 0x2 == 4/8 clock delay.
+	 * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
+	 */
+	wr_data_delay = 3;
+
+	/*
+	 * Write Latency
+	 * Read to Precharge
+	 * Minimum CKE Pulse Width.
+	 * Four Activate Window
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		/*
+		 * This is a lie.  It should really be 1, but if it is
+		 * set to 1, bits overlap into the old controller's
+		 * otherwise unused ACSM field.  If we leave it 0, then
+		 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
+		 */
+		wr_lat = 0;
+
+		trtp_clk = 2;		/* By the book. */
+		cke_min_clk = 1;	/* By the book. */
+		four_act = 1;		/* By the book. */
+
+	} else {
+		wr_lat = caslat - 1;
+
+		/* Convert SPD value from quarter nanos to picos. */
+		trtp_clk = picos_to_clk(spd.trtp * 250);
+
+		cke_min_clk = 3;	/* By the book. */
+		four_act = picos_to_clk(37500);	/* By the book. 1k pages? */
+	}
+
+	ddr->timing_cfg_2 = (0
+		| ((add_lat & 0x7) << 28)		/* ADD_LAT */
+		| ((cpo & 0x1f) << 23)			/* CPO */
+		| ((wr_lat & 0x7) << 19)		/* WR_LAT */
+		| ((trtp_clk & 0x7) << 13)		/* RD_TO_PRE */
+		| ((wr_data_delay & 0x7) << 10)		/* WR_DATA_DELAY */
+		| ((cke_min_clk & 0x7) << 6)		/* CKE_PLS */
+		| ((four_act & 0x1f) << 0)		/* FOUR_ACT */
+		);
+
+	debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
+
+
+	/*
+	 * Determine the Mode Register Set.
+	 *
+	 * This is nominally part specific, but it appears to be
+	 * consistent for all DDR I devices, and for all DDR II devices.
+	 *
+	 *     caslat must be programmed
+	 *     burst length is always 4
+	 *     burst type is sequential
+	 *
+	 * For DDR I:
+	 *     operating mode is "normal"
+	 *
+	 * For DDR II:
+	 *     other stuff
+	 */
+
+	mode_caslat = 0;
+
+	/*
+	 * Table lookup from DDR I or II Device Operation Specs.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		if (1 <= caslat && caslat <= 4) {
+			unsigned char mode_caslat_table[4] = {
+				0x5,	/* 1.5 clocks */
+				0x2,	/* 2.0 clocks */
+				0x6,	/* 2.5 clocks */
+				0x3	/* 3.0 clocks */
+			};
+			mode_caslat = mode_caslat_table[caslat - 1];
+		} else {
+			puts("DDR I: Only CAS Latencies of 1.5, 2.0, "
+			     "2.5 and 3.0 clocks are supported.\n");
+			return 0;
+		}
+
+	} else {
+		if (2 <= caslat && caslat <= 5) {
+			mode_caslat = caslat;
+		} else {
+			puts("DDR II: Only CAS Latencies of 2.0, 3.0, "
+			     "4.0 and 5.0 clocks are supported.\n");
+			return 0;
+		}
+	}
+
+	/*
+	 * Encoded Burst Length of 4.
+	 */
+	burst_len = 2;			/* Fiat. */
+
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		twr_auto_clk = 0;	/* Historical */
+	} else {
+		/*
+		 * Determine tCK max in picos.  Grab tWR and convert to picos.
+		 * Auto-precharge write recovery is:
+		 *	WR = roundup(tWR_ns/tCKmax_ns).
+		 *
+		 * Ponder: Is twr_auto_clk different than twr_clk?
+		 */
+		tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax);
+		twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps;
+	}
+
+	/*
+	 * Mode Reg in bits 16 ~ 31,
+	 * Extended Mode Reg 1 in bits 0 ~ 15.
+	 */
+	mode_odt_enable = 0x0;			/* Default disabled */
+	if (odt_wr_cfg || odt_rd_cfg) {
+		/*
+		 * Bits 6 and 2 in Extended MRS(1)
+		 * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
+		 * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
+		 */
+		mode_odt_enable = 0x40;		/* 150 Ohm */
+	}
+
+	ddr->sdram_mode_1 =
+		(0
+		 | (add_lat << (16 + 3))	/* Additive Latency in EMRS1 */
+		 | (mode_odt_enable << 16)	/* ODT Enable in EMRS1 */
+		 | (twr_auto_clk << 9)		/* Write Recovery Autopre */
+		 | (mode_caslat << 4)		/* caslat */
+		 | (burst_len << 0)		/* Burst length */
+		 );
+
+	debug("DDR: sdram_mode   = 0x%08x\n", ddr->sdram_mode_1);
+
+	/*
+	 * Clear EMRS2 and EMRS3.
+	 */
+	ddr->sdram_mode_2 = 0;
+	debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
+
+	/*
+	 * Determine Refresh Rate.
+	 */
+	refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
+
+	/*
+	 * Set BSTOPRE to 0x100 for page mode
+	 * If auto-charge is used, set BSTOPRE = 0
+	 */
+	ddr->sdram_interval =
+		(0
+		 | (refresh_clk & 0x3fff) << 16
+		 | 0x100
+		 );
+	debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
+
+
+	/*
+	 * Is this an ECC DDR chip?
+	 * But don't mess with it if the DDR controller will init mem.
+	 */
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	if (spd.config == 0x02) {
+		ddr->err_disable = 0x0000000d;
+		ddr->err_sbe = 0x00ff0000;
+	}
+	debug("DDR: err_disable = 0x%08x\n", ddr->err_disable);
+	debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);
+#endif
+
+	asm volatile("sync;isync");
+	udelay(500);
+
+	/*
+	 * SDRAM Cfg 2
+	 */
+
+	/*
+	 * When ODT is enabled, Chap 9 suggests asserting ODT to
+	 * internal IOs only during reads.
+	 */
+	odt_cfg = 0;
+	if (odt_rd_cfg | odt_wr_cfg) {
+		odt_cfg = 0x2;		/* ODT to IOs during reads */
+	}
+
+	/*
+	 * Try to use differential DQS with DDR II.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		dqs_cfg = 0;		/* No Differential DQS for DDR I */
+	} else {
+		dqs_cfg = 0x1;		/* Differential DQS for DDR II */
+	}
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	/*
+	 * Use the DDR controller to auto initialize memory.
+	 */
+	d_init = 1;
+	ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE;
+	debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init);
+#else
+	/*
+	 * Memory will be initialized via DMA, or not at all.
+	 */
+	d_init = 0;
+#endif
+
+	ddr->sdram_cfg_2 = (0
+			    | (dqs_cfg << 26)	/* Differential DQS */
+			    | (odt_cfg << 21)	/* ODT */
+			    | (d_init << 4)	/* D_INIT auto init DDR */
+			    );
+
+	debug("DDR: sdram_cfg_2  = 0x%08x\n", ddr->sdram_cfg_2);
+
+
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+	/*
+	 * Setup the clock control.
+	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+	 *	0110	3/4 cycle late
+	 *	0111	7/8 cycle late
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		clk_adjust = 0x6;
+	else
+		clk_adjust = 0x7;
+
+	ddr->sdram_clk_cntl = (0
+			       | 0x80000000
+			       | (clk_adjust << 23)
+			       );
+	debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
+#endif
+
+	/*
+	 * Figure out memory size in Megabytes.
+	 */
+	debug("# ranks = %d, rank_density = 0x%08lx\n", n_ranks, rank_density);
+	memsize = n_ranks * rank_density / 0x100000;
+	return memsize;
+}
+
+
+unsigned int enable_ddr(unsigned int ddr_num)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	spd_eeprom_t spd1,spd2;
+	volatile ccsr_ddr_t *ddr;
+	unsigned sdram_cfg_1;
+	unsigned char sdram_type, mem_type, config, mod_attr;
+	unsigned char d_init;
+	unsigned int no_dimm1=0, no_dimm2=0;
+
+	/* Set up pointer to enable the current ddr controller */
+	if (ddr_num == 1)
+		ddr = &immap->im_ddr1;
+	else
+		ddr = &immap->im_ddr2;
+
+	/*
+	 * Read both dimm slots and decide whether
+	 * or not to enable this controller.
+	 */
+	memset((void *)&spd1,0,sizeof(spd1));
+	memset((void *)&spd2,0,sizeof(spd2));
+
+	if (ddr_num == 1) {
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS1,
+			     0, 1, (uchar *) &spd1, sizeof(spd1));
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS2,
+			     0, 1, (uchar *) &spd2, sizeof(spd2));
+	} else {
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS3,
+			     0, 1, (uchar *) &spd1, sizeof(spd1));
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS4,
+			     0, 1, (uchar *) &spd2, sizeof(spd2));
+	}
+
+	/*
+	 * Check for supported memory module types.
+	 */
+	if (spd1.mem_type != SPD_MEMTYPE_DDR
+	    && spd1.mem_type != SPD_MEMTYPE_DDR2) {
+		no_dimm1 = 1;
+	} else {
+		debug("\nFound memory of type 0x%02lx  ",spd1.mem_type );
+		if (spd1.mem_type == SPD_MEMTYPE_DDR)
+			debug("DDR I\n");
+		else
+			debug("DDR II\n");
+	}
+
+	if (spd2.mem_type != SPD_MEMTYPE_DDR &&
+	    spd2.mem_type != SPD_MEMTYPE_DDR2) {
+		no_dimm2 = 1;
+	} else {
+		debug("\nFound memory of type 0x%02lx  ",spd2.mem_type );
+		if (spd2.mem_type == SPD_MEMTYPE_DDR)
+			debug("DDR I\n");
+		else
+			debug("DDR II\n");
+	}
+
+#ifdef CONFIG_DDR_INTERLEAVE
+	if (no_dimm1) {
+		printf("For interleaved operation memory modules need to be present in CS0 DIMM slots of both DDR controllers!\n");
+		return 0;
+	}
+#endif
+
+	/*
+	 * Memory is not present in DIMM1 and DIMM2 - so do not enable DDRn
+	 */
+	if (no_dimm1  && no_dimm2) {
+		printf("No memory modules found for DDR controller %d!!\n", ddr_num);
+		return 0;
+	} else {
+		mem_type = no_dimm2 ? spd1.mem_type : spd2.mem_type;
+
+		/*
+		 * Figure out the settings for the sdram_cfg register.
+		 * Build up the entire register in 'sdram_cfg' before
+		 * writing since the write into the register will
+		 * actually enable the memory controller; all settings
+		 * must be done before enabling.
+		 *
+		 * sdram_cfg[0]   = 1 (ddr sdram logic enable)
+		 * sdram_cfg[1]   = 1 (self-refresh-enable)
+		 * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)
+		 *			010 DDR 1 SDRAM
+		 *			011 DDR 2 SDRAM
+		 */
+		sdram_type = (mem_type == SPD_MEMTYPE_DDR) ? 2 : 3;
+		sdram_cfg_1 = (0
+			       | (1 << 31)		/* Enable */
+			       | (1 << 30)		/* Self refresh */
+			       | (sdram_type << 24)	/* SDRAM type */
+			       );
+
+		/*
+		 * sdram_cfg[3] = RD_EN - registered DIMM enable
+		 *   A value of 0x26 indicates micron registered
+		 *   DIMMS (micron.com)
+		 */
+		mod_attr = no_dimm2 ? spd1.mod_attr : spd2.mod_attr;
+		if (mem_type == SPD_MEMTYPE_DDR && mod_attr == 0x26) {
+			sdram_cfg_1 |= 0x10000000;		/* RD_EN */
+		}
+
+#if defined(CONFIG_DDR_ECC)
+
+		config = no_dimm2 ? spd1.config : spd2.config;
+
+		/*
+		 * If the user wanted ECC (enabled via sdram_cfg[2])
+		 */
+		if (config == 0x02) {
+			ddr->err_disable = 0x00000000;
+			asm volatile("sync;isync;");
+			ddr->err_sbe = 0x00ff0000;
+			ddr->err_int_en = 0x0000000d;
+			sdram_cfg_1 |= 0x20000000;		/* ECC_EN */
+		}
+#endif
+
+		/*
+		 * Set 1T or 2T timing based on 1 or 2 modules
+		 */
+		{
+			if (!(no_dimm1 || no_dimm2)) {
+				/*
+				 * 2T timing,because both DIMMS are present.
+				 * Enable 2T timing by setting sdram_cfg[16].
+				 */
+				sdram_cfg_1 |= 0x8000;		/* 2T_EN */
+			}
+		}
+
+		/*
+		 * 200 painful micro-seconds must elapse between
+		 * the DDR clock setup and the DDR config enable.
+		 */
+		udelay(200);
+
+		/*
+		 * Go!
+		 */
+		ddr->sdram_cfg_1 = sdram_cfg_1;
+
+		asm volatile("sync;isync");
+		udelay(500);
+
+		debug("DDR: sdram_cfg   = 0x%08x\n", ddr->sdram_cfg_1);
+
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+		d_init = 1;
+		debug("DDR: memory initializing\n");
+
+		/*
+		 * Poll until memory is initialized.
+		 * 512 Meg at 400 might hit this 200 times or so.
+		 */
+		while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {
+			udelay(1000);
+		}
+		debug("DDR: memory initialized\n\n");
+#endif
+
+		debug("Enabled DDR Controller %d\n", ddr_num);
+		return 1;
+	}
+}
+
+
+long int
+spd_sdram(void)
+{
+	int memsize_ddr1_dimm1 = 0;
+	int memsize_ddr1_dimm2 = 0;
+	int memsize_ddr2_dimm1 = 0;
+	int memsize_ddr2_dimm2 = 0;
+	int memsize_total = 0;
+	int memsize_ddr1 = 0;
+	int memsize_ddr2 = 0;
+	unsigned int ddr1_enabled = 0;
+	unsigned int ddr2_enabled = 0;
+	unsigned int law_size_ddr1;
+	unsigned int law_size_ddr2;
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
+	volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;
+	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+
+#ifdef CONFIG_DDR_INTERLEAVE
+	unsigned int law_size_interleaved;
+
+	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+				      1, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm1;
+
+	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+				      2, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm1;
+
+	if (memsize_ddr1_dimm1 != memsize_ddr2_dimm1) {
+		if (memsize_ddr1_dimm1 <  memsize_ddr2_dimm1)
+			memsize_total -= memsize_ddr1_dimm1;
+		else
+			memsize_total -= memsize_ddr2_dimm1;
+		debug("Total memory available for interleaving 0x%08lx\n",
+		      memsize_total * 1024 * 1024);
+		debug("Adjusting CS0_BNDS to account for unequal DIMM sizes in interleaved memory\n");
+		ddr1->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+		ddr2->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+		debug("DDR1: cs0_bnds   = 0x%08x\n", ddr1->cs0_bnds);
+		debug("DDR2: cs0_bnds   = 0x%08x\n", ddr2->cs0_bnds);
+	}
+
+	ddr1_enabled = enable_ddr(1);
+	ddr2_enabled = enable_ddr(2);
+
+	/*
+	 * Both controllers need to be enabled for interleaving.
+	 */
+	if (ddr1_enabled && ddr2_enabled) {
+		law_size_interleaved = 19 + __ilog2(memsize_total);
+
+		/*
+		 * Set up LAWBAR for DDR 1 space.
+		 */
+		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+		mcm->lawar1 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR_INTERLEAVED
+			       | (LAWAR_SIZE & law_size_interleaved));
+		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+		debug("Interleaved memory size is 0x%08lx\n", memsize_total);
+
+#ifdef	CONFIG_DDR_INTERLEAVE
+#if (CFG_PAGE_INTERLEAVING == 1)
+		printf("Page ");
+#elif (CFG_BANK_INTERLEAVING == 1)
+		printf("Bank ");
+#elif (CFG_SUPER_BANK_INTERLEAVING == 1)
+		printf("Super-bank ");
+#else
+		printf("Cache-line ");
+#endif
+#endif
+		printf("Interleaved");
+		return memsize_total * 1024 * 1024;
+	}  else {
+		printf("Interleaved memory not enabled - check CS0 DIMM slots for both controllers.\n");
+		return 0;
+	}
+
+#else
+	/*
+	 * Call spd_sdram() routine to init ddr1 - pass I2c address,
+	 * controller number, dimm number, and starting address.
+	 */
+	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+				      1, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm1;
+
+	memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2,
+				      1, 2,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm2;
+
+	/*
+	 * Enable the DDR controller - pass ddr controller number.
+	 */
+	ddr1_enabled = enable_ddr(1);
+
+	/* Keep track of memory to be addressed by DDR1 */
+	memsize_ddr1 = memsize_ddr1_dimm1 + memsize_ddr1_dimm2;
+
+	/*
+	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.  Fnord.
+	 */
+	if (ddr1_enabled) {
+		law_size_ddr1 = 19 + __ilog2(memsize_ddr1);
+
+		/*
+		 * Set up LAWBAR for DDR 1 space.
+		 */
+		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+		mcm->lawar1 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR1
+			       | (LAWAR_SIZE & law_size_ddr1));
+		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+	}
+
+#if  (CONFIG_NUM_DDR_CONTROLLERS > 1)
+	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+				      2, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm1;
+
+	memsize_ddr2_dimm2 = spd_init(SPD_EEPROM_ADDRESS4,
+				      2, 2,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm2;
+
+	ddr2_enabled = enable_ddr(2);
+
+	/* Keep track of memory to be addressed by DDR2 */
+	memsize_ddr2 = memsize_ddr2_dimm1 + memsize_ddr2_dimm2;
+
+	if (ddr2_enabled) {
+		law_size_ddr2 = 19 + __ilog2(memsize_ddr2);
+
+		/*
+		 * Set up LAWBAR for DDR 2 space.
+		 */
+		if (ddr1_enabled)
+			mcm->lawbar8 = (((memsize_ddr1 * 1024 * 1024) >> 12)
+					& 0xfffff);
+		else
+			mcm->lawbar8 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+
+		mcm->lawar8 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR2
+			       | (LAWAR_SIZE & law_size_ddr2));
+		debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);
+		debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);
+	}
+#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */
+
+	debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",
+	      memsize_ddr1, memsize_ddr2);
+
+	/*
+	 * If neither DDR controller is enabled return 0.
+	 */
+	if (!ddr1_enabled && !ddr2_enabled)
+		return 0;
+
+	printf("Non-interleaved");
+	return memsize_total * 1024 * 1024;
+
+#endif /* CONFIG_DDR_INTERLEAVE */
+}
+
+
+#endif /* CONFIG_SPD_EEPROM */
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+
+/*
+ * Initialize all of memory for ECC, then enable errors.
+ */
+
+void
+ddr_enable_ecc(unsigned int dram_size)
+{
+	uint *p = 0;
+	uint i = 0;
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_ddr_t *ddr1= &immap->im_ddr1;
+
+	dma_init();
+
+	for (*p = 0; p < (uint *)(8 * 1024); p++) {
+		if (((unsigned int)p & 0x1f) == 0) {
+			ppcDcbz((unsigned long) p);
+		}
+		*p = (unsigned int)CONFIG_MEM_INIT_VALUE;
+		if (((unsigned int)p & 0x1c) == 0x1c) {
+			ppcDcbf((unsigned long) p);
+		}
+	}
+
+	dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+	dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+	dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+	dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+	dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+	dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+	dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
+
+	for (i = 1; i < dram_size / 0x800000; i++) {
+		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
+	}
+
+	/*
+	 * Enable errors for ECC.
+	 */
+	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+	ddr1->err_disable = 0x00000000;
+	asm volatile("sync;isync");
+	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+}
+
+#endif	/* CONFIG_DDR_ECC  && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */

+ 127 - 0
cpu/mpc86xx/speed.c

@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+#include <asm/processor.h>
+
+
+void get_sys_info(sys_info_t *sysInfo)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	uint plat_ratio, e600_ratio;
+
+	plat_ratio = (gur->porpllsr) & 0x0000003e;
+	plat_ratio >>= 1;
+
+	switch (plat_ratio) {
+	case 0x0:
+		sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ;
+		break;
+	case 0x02:
+	case 0x03:
+	case 0x04:
+	case 0x05:
+	case 0x06:
+	case 0x08:
+	case 0x09:
+	case 0x0a:
+	case 0x0c:
+	case 0x10:
+		sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
+		break;
+	default:
+		sysInfo->freqSystemBus = 0;
+		break;
+	}
+
+	e600_ratio = (gur->porpllsr) & 0x003f0000;
+	e600_ratio >>= 16;
+
+	switch (e600_ratio) {
+	case 0x10:
+		sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus;
+		break;
+	case 0x19:
+		sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus / 2;
+		break;
+	case 0x20:
+		sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus;
+		break;
+	case 0x39:
+		sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus / 2;
+		break;
+	case 0x28:
+		sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus;
+		break;
+	case 0x1d:
+		sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus / 2;
+		break;
+	default:
+		sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus;
+		break;
+	}
+}
+
+
+/*
+ * Measure CPU clock speed (core clock GCLK1, GCLK2)
+ * (Approx. GCLK frequency in Hz)
+ */
+
+int get_clocks(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	gd->cpu_clk = sys_info.freqProcessor;
+	gd->bus_clk = sys_info.freqSystemBus;
+
+	if (gd->cpu_clk != 0)
+		return 0;
+	else
+		return 1;
+}
+
+
+/*
+ * get_bus_freq
+ *	Return system bus freq in Hz
+ */
+
+ulong get_bus_freq(ulong dummy)
+{
+	ulong val;
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	val = sys_info.freqSystemBus;
+
+	return val;
+}

+ 1226 - 0
cpu/mpc86xx/start.S

@@ -0,0 +1,1226 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Srikanth Srinivasan <srikanth.srinivaan@freescale.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
+ */
+
+/*  U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
+ *
+ *
+ *  The processor starts at 0xfff00100 and the code is executed
+ *  from flash. The code is organized to be at an other address
+ *  in memory, but as long we don't jump around before relocating.
+ *  board_init lies at a quite high address and when the cpu has
+ *  jumped there, everything is ok.
+ */
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef	CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the  MMU yet.
+*/
+#undef	MSR_KERNEL
+/* Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+	START_GOT
+	GOT_ENTRY(_GOT2_TABLE_)
+	GOT_ENTRY(_FIXUP_TABLE_)
+
+	GOT_ENTRY(_start)
+	GOT_ENTRY(_start_of_vectors)
+	GOT_ENTRY(_end_of_vectors)
+	GOT_ENTRY(transfer_to_handler)
+
+	GOT_ENTRY(__init_end)
+	GOT_ENTRY(_end)
+	GOT_ENTRY(__bss_start)
+	END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+	.text
+	.long	0x27051956		/* U-Boot Magic Number */
+	.globl	version_string
+version_string:
+	.ascii	U_BOOT_VERSION
+	.ascii	" (", __DATE__, " - ", __TIME__, ")"
+	.ascii	CONFIG_IDENT_STRING, "\0"
+
+	. = EXC_OFF_SYS_RESET
+	.globl	_start
+_start:
+	li	r21, BOOTFLAG_COLD	/* Normal Power-On: Boot from FLASH */
+	b	boot_cold
+	sync
+
+	. = EXC_OFF_SYS_RESET + 0x10
+
+	.globl	_start_warm
+_start_warm:
+	li	r21, BOOTFLAG_WARM	/* Software reboot */
+	b	boot_warm
+	sync
+
+	/* the boot code is located below the exception table */
+
+	.globl	_start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. */
+	STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+	STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+	. = 0x600
+Alignment:
+	EXCEPTION_PROLOG
+	mfspr	r4,DAR
+	stw	r4,_DAR(r21)
+	mfspr	r5,DSISR
+	stw	r5,_DSISR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_Alignment:
+	.long	AlignmentException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+	. = 0x700
+ProgramCheck:
+	EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_ProgramCheck:
+	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+
+	/* I guess we could implement decrementer, and may have
+	 * to someday for timekeeping.
+	 */
+	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
+	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
+	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
+	STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
+	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
+
+	.globl	_end_of_vectors
+_end_of_vectors:
+
+	. = 0x2000
+
+boot_cold:
+boot_warm:
+
+	/* if this is a multi-core system we need to check which cpu
+	 * this is, if it is not cpu 0 send the cpu to the linux reset
+	 * vector */
+#if (CONFIG_NUM_CPUS > 1)
+	mfspr	r0, MSSCR0
+	andi.	r0, r0, 0x0020
+	rlwinm	r0,r0,27,31,31
+	mtspr	PIR, r0
+	beq	1f
+
+	bl	secondary_cpu_setup
+#endif
+
+	/* disable everything */
+1:	li	r0, 0
+	mtspr	HID0, r0
+	sync
+	mtmsr	0
+	bl	invalidate_bats
+	sync
+
+#ifdef CFG_L2
+	/* init the L2 cache */
+	addis	r3, r0, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	mtspr	l2cr, r3
+	/* invalidate the L2 cache */
+	bl	l2cache_invalidate
+	sync
+#endif
+
+	/*
+	 * Calculate absolute address in FLASH and jump there
+	 *------------------------------------------------------*/
+	lis	r3, CFG_MONITOR_BASE@h
+	ori	r3, r3, CFG_MONITOR_BASE@l
+	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
+	mtlr	r3
+	blr
+
+in_flash:
+	/* let the C-code set up the rest			*/
+	/*							*/
+	/* Be careful to keep code relocatable !		*/
+	/*------------------------------------------------------*/
+	/* perform low-level init */
+
+	/* enable extended addressing */
+	bl	enable_ext_addr
+
+	/* setup the bats */
+	bl	setup_bats
+	sync
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+	/* setup ccsrbar */
+	bl	setup_ccsrbar
+#endif
+
+	/* Fix for SMP linux - Changing arbitration to round-robin */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x1000
+	xor	r4, r4, r4
+	li	r4, 0x1000
+	stw	r4, 0(r3)
+
+	/* setup the law entries */
+	bl	law_entry
+	sync
+
+	/* Don't use this feature due to bug in 8641D PD4 */
+	/* Disable ERD_DIS */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x1008
+	lwz	r4, 0(r3)
+	oris	r4, r4, 0x4000
+	stw	r4, 0(r3)
+	sync
+
+#if (EMULATOR_RUN == 1)
+	/* On the emulator we want to adjust these ASAP */
+	/* otherwise things are sloooow */
+	/* Setup OR0 (LALE FIX)*/
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x5004
+	li	r4, 0x0FF3
+	stw	r4, 0(r3)
+	sync
+
+	/* Setup LCRR */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x50D4
+	lis	r4, 0x8000
+	ori	r4, r4, 0x0002
+	stw	r4, 0(r3)
+	sync
+#endif
+#if 1
+	/* make sure timer enabled in guts register too */
+	lis	r3, CFG_CCSRBAR@h
+	oris	r3,r3, 0xE
+	ori	r3,r3,0x0070
+	lwz	r4, 0(r3)
+	lis	r5,0xFFFC
+	ori	r5,r5,0x5FFF
+	and	r4,r4,r5
+	stw	r4,0(r3)
+#endif
+	/*
+	 * Cache must be enabled here for stack-in-cache trick.
+	 * This means we need to enable the BATS.
+	 * Cache should be turned on after BATs, since by default
+	 * everything is write-through.
+	 */
+
+	/* enable address translation */
+	bl	enable_addr_trans
+	sync
+
+	/* enable and invalidate the data cache */
+/*	bl	l1dcache_enable */
+	bl	dcache_enable
+	sync
+
+#if 1
+	bl	icache_enable
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+	bl	lock_ram_in_cache
+	sync
+#endif
+
+	/* set up the stack pointer in our newly created
+	 * cache-ram (r1) */
+	lis	r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
+	ori	r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
+
+	li	r0, 0		/* Make room for stack frame header and */
+	stwu	r0, -4(r1)	/* clear final stack frame so that	*/
+	stwu	r0, -4(r1)	/* stack backtraces terminate cleanly	*/
+
+	GET_GOT			/* initialize GOT access	*/
+
+	/* run low-level CPU init code	   (from Flash) */
+	bl	cpu_init_f
+	sync
+
+#ifdef	RUN_DIAG
+
+	/* Sri:	 Code to run the diagnostic automatically */
+
+	/* Load PX_AUX register address in r4 */
+	lis	r4, 0xf810
+	ori	r4, r4, 0x6
+	/* Load contents of PX_AUX in r3 bits 24 to 31*/
+	lbz	r3, 0(r4)
+
+	/* Mask and obtain the bit in r3 */
+	rlwinm. r3, r3, 0, 24, 24
+	/* If not zero, jump and continue with u-boot */
+	bne	diag_done
+
+	/* Load back contents of PX_AUX in r3 bits 24 to 31 */
+	lbz	r3, 0(r4)
+	/* Set the MSB of the register value */
+	ori	r3, r3, 0x80
+	/* Write value in r3 back to PX_AUX */
+	stb	r3, 0(r4)
+
+	/* Get the address to jump to in r3*/
+	lis	r3, CFG_DIAG_ADDR@h
+	ori	r3, r3, CFG_DIAG_ADDR@l
+
+	/* Load the LR with the branch address */
+	mtlr	r3
+
+	/* Branch to diagnostic */
+	blr
+
+diag_done:
+#endif
+
+/*	bl	l2cache_enable */
+	mr	r3, r21
+
+	/* r3: BOOTFLAG */
+	/* run 1st part of board init code (from Flash)	  */
+	bl	board_init_f
+	sync
+
+	/* NOTREACHED */
+
+	.globl	invalidate_bats
+invalidate_bats:
+
+	/* invalidate BATs */
+	mtspr	IBAT0U, r0
+	mtspr	IBAT1U, r0
+	mtspr	IBAT2U, r0
+	mtspr	IBAT3U, r0
+	mtspr	IBAT4U, r0
+	mtspr	IBAT5U, r0
+	mtspr	IBAT6U, r0
+	mtspr	IBAT7U, r0
+
+	isync
+	mtspr	DBAT0U, r0
+	mtspr	DBAT1U, r0
+	mtspr	DBAT2U, r0
+	mtspr	DBAT3U, r0
+	mtspr	DBAT4U, r0
+	mtspr	DBAT5U, r0
+	mtspr	DBAT6U, r0
+	mtspr	DBAT7U, r0
+
+	isync
+	sync
+	blr
+
+
+	/* setup_bats - set them up to some initial state */
+	.globl	setup_bats
+setup_bats:
+
+	addis	r0, r0, 0x0000
+
+	/* IBAT 0 */
+	addis	r4, r0, CFG_IBAT0L@h
+	ori	r4, r4, CFG_IBAT0L@l
+	addis	r3, r0, CFG_IBAT0U@h
+	ori	r3, r3, CFG_IBAT0U@l
+	mtspr	IBAT0L, r4
+	mtspr	IBAT0U, r3
+	isync
+
+	/* DBAT 0 */
+	addis	r4, r0, CFG_DBAT0L@h
+	ori	r4, r4, CFG_DBAT0L@l
+	addis	r3, r0, CFG_DBAT0U@h
+	ori	r3, r3, CFG_DBAT0U@l
+	mtspr	DBAT0L, r4
+	mtspr	DBAT0U, r3
+	isync
+
+	/* IBAT 1 */
+	addis	r4, r0, CFG_IBAT1L@h
+	ori	r4, r4, CFG_IBAT1L@l
+	addis	r3, r0, CFG_IBAT1U@h
+	ori	r3, r3, CFG_IBAT1U@l
+	mtspr	IBAT1L, r4
+	mtspr	IBAT1U, r3
+	isync
+
+	/* DBAT 1 */
+	addis	r4, r0, CFG_DBAT1L@h
+	ori	r4, r4, CFG_DBAT1L@l
+	addis	r3, r0, CFG_DBAT1U@h
+	ori	r3, r3, CFG_DBAT1U@l
+	mtspr	DBAT1L, r4
+	mtspr	DBAT1U, r3
+	isync
+
+	/* IBAT 2 */
+	addis	r4, r0, CFG_IBAT2L@h
+	ori	r4, r4, CFG_IBAT2L@l
+	addis	r3, r0, CFG_IBAT2U@h
+	ori	r3, r3, CFG_IBAT2U@l
+	mtspr	IBAT2L, r4
+	mtspr	IBAT2U, r3
+	isync
+
+	/* DBAT 2 */
+	addis	r4, r0, CFG_DBAT2L@h
+	ori	r4, r4, CFG_DBAT2L@l
+	addis	r3, r0, CFG_DBAT2U@h
+	ori	r3, r3, CFG_DBAT2U@l
+	mtspr	DBAT2L, r4
+	mtspr	DBAT2U, r3
+	isync
+
+	/* IBAT 3 */
+	addis	r4, r0, CFG_IBAT3L@h
+	ori	r4, r4, CFG_IBAT3L@l
+	addis	r3, r0, CFG_IBAT3U@h
+	ori	r3, r3, CFG_IBAT3U@l
+	mtspr	IBAT3L, r4
+	mtspr	IBAT3U, r3
+	isync
+
+	/* DBAT 3 */
+	addis	r4, r0, CFG_DBAT3L@h
+	ori	r4, r4, CFG_DBAT3L@l
+	addis	r3, r0, CFG_DBAT3U@h
+	ori	r3, r3, CFG_DBAT3U@l
+	mtspr	DBAT3L, r4
+	mtspr	DBAT3U, r3
+	isync
+
+	/* IBAT 4 */
+	addis	r4, r0, CFG_IBAT4L@h
+	ori	r4, r4, CFG_IBAT4L@l
+	addis	r3, r0, CFG_IBAT4U@h
+	ori	r3, r3, CFG_IBAT4U@l
+	mtspr	IBAT4L, r4
+	mtspr	IBAT4U, r3
+	isync
+
+	/* DBAT 4 */
+	addis	r4, r0, CFG_DBAT4L@h
+	ori	r4, r4, CFG_DBAT4L@l
+	addis	r3, r0, CFG_DBAT4U@h
+	ori	r3, r3, CFG_DBAT4U@l
+	mtspr	DBAT4L, r4
+	mtspr	DBAT4U, r3
+	isync
+
+	/* IBAT 5 */
+	addis	r4, r0, CFG_IBAT5L@h
+	ori	r4, r4, CFG_IBAT5L@l
+	addis	r3, r0, CFG_IBAT5U@h
+	ori	r3, r3, CFG_IBAT5U@l
+	mtspr	IBAT5L, r4
+	mtspr	IBAT5U, r3
+	isync
+
+	/* DBAT 5 */
+	addis	r4, r0, CFG_DBAT5L@h
+	ori	r4, r4, CFG_DBAT5L@l
+	addis	r3, r0, CFG_DBAT5U@h
+	ori	r3, r3, CFG_DBAT5U@l
+	mtspr	DBAT5L, r4
+	mtspr	DBAT5U, r3
+	isync
+
+	/* IBAT 6 */
+	addis	r4, r0, CFG_IBAT6L@h
+	ori	r4, r4, CFG_IBAT6L@l
+	addis	r3, r0, CFG_IBAT6U@h
+	ori	r3, r3, CFG_IBAT6U@l
+	mtspr	IBAT6L, r4
+	mtspr	IBAT6U, r3
+	isync
+
+	/* DBAT 6 */
+	addis	r4, r0, CFG_DBAT6L@h
+	ori	r4, r4, CFG_DBAT6L@l
+	addis	r3, r0, CFG_DBAT6U@h
+	ori	r3, r3, CFG_DBAT6U@l
+	mtspr	DBAT6L, r4
+	mtspr	DBAT6U, r3
+	isync
+
+	/* IBAT 7 */
+	addis	r4, r0, CFG_IBAT7L@h
+	ori	r4, r4, CFG_IBAT7L@l
+	addis	r3, r0, CFG_IBAT7U@h
+	ori	r3, r3, CFG_IBAT7U@l
+	mtspr	IBAT7L, r4
+	mtspr	IBAT7U, r3
+	isync
+
+	/* DBAT 7 */
+	addis	r4, r0, CFG_DBAT7L@h
+	ori	r4, r4, CFG_DBAT7L@l
+	addis	r3, r0, CFG_DBAT7U@h
+	ori	r3, r3, CFG_DBAT7U@l
+	mtspr	DBAT7L, r4
+	mtspr	DBAT7U, r3
+	isync
+
+1:
+	addis	r3, 0, 0x0000
+	addis	r5, 0, 0x4	/* upper bound of 0x00040000 for 7400/750 */
+	isync
+
+tlblp:
+	tlbie	r3
+	sync
+	addi	r3, r3, 0x1000
+	cmp	0, 0, r3, r5
+	blt tlblp
+
+	blr
+
+	.globl enable_addr_trans
+enable_addr_trans:
+	/* enable address translation */
+	mfmsr	r5
+	ori	r5, r5, (MSR_IR | MSR_DR)
+	mtmsr	r5
+	isync
+	blr
+
+	.globl disable_addr_trans
+disable_addr_trans:
+	/* disable address translation */
+	mflr	r4
+	mfmsr	r3
+	andi.	r0, r3, (MSR_IR | MSR_DR)
+	beqlr
+	andc	r3, r3, r0
+	mtspr	SRR0, r4
+	mtspr	SRR1, r3
+	rfi
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+	.globl	transfer_to_handler
+transfer_to_handler:
+	stw	r22,_NIP(r21)
+	lis	r22,MSR_POW@h
+	andc	r23,r23,r22
+	stw	r23,_MSR(r21)
+	SAVE_GPR(7, r21)
+	SAVE_4GPRS(8, r21)
+	SAVE_8GPRS(12, r21)
+	SAVE_8GPRS(24, r21)
+	mflr	r23
+	andi.	r24,r23,0x3f00		/* get vector offset */
+	stw	r24,TRAP(r21)
+	li	r22,0
+	stw	r22,RESULT(r21)
+	mtspr	SPRG2,r22		/* r1 is now kernel sp */
+	lwz	r24,0(r23)		/* virtual address of handler */
+	lwz	r23,4(r23)		/* where to go when done */
+	mtspr	SRR0,r24
+	mtspr	SRR1,r20
+	mtlr	r23
+	SYNC
+	rfi				/* jump to handler, enable MMU */
+
+int_return:
+	mfmsr	r28		/* Disable interrupts */
+	li	r4,0
+	ori	r4,r4,MSR_EE
+	andc	r28,r28,r4
+	SYNC			/* Some chip revs need this... */
+	mtmsr	r28
+	SYNC
+	lwz	r2,_CTR(r1)
+	lwz	r0,_LINK(r1)
+	mtctr	r2
+	mtlr	r0
+	lwz	r2,_XER(r1)
+	lwz	r0,_CCR(r1)
+	mtspr	XER,r2
+	mtcrf	0xFF,r0
+	REST_10GPRS(3, r1)
+	REST_10GPRS(13, r1)
+	REST_8GPRS(23, r1)
+	REST_GPR(31, r1)
+	lwz	r2,_NIP(r1)	/* Restore environment */
+	lwz	r0,_MSR(r1)
+	mtspr	SRR0,r2
+	mtspr	SRR1,r0
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	lwz	r1,GPR1(r1)
+	SYNC
+	rfi
+
+	.globl	dc_read
+dc_read:
+	blr
+
+	.globl get_pvr
+get_pvr:
+	mfspr	r3, PVR
+	blr
+
+	.globl get_svr
+get_svr:
+	mfspr	r3, SVR
+	blr
+
+
+/*
+ * Function:	in8
+ * Description:	Input 8 bits
+ */
+	.globl	in8
+in8:
+	lbz	r3,0x0000(r3)
+	blr
+
+/*
+ * Function:	out8
+ * Description:	Output 8 bits
+ */
+	.globl	out8
+out8:
+	stb	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out16
+ * Description:	Output 16 bits
+ */
+	.globl	out16
+out16:
+	sth	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out16r
+ * Description:	Byte reverse and output 16 bits
+ */
+	.globl	out16r
+out16r:
+	sthbrx	r4,r0,r3
+	blr
+
+/*
+ * Function:	out32
+ * Description:	Output 32 bits
+ */
+	.globl	out32
+out32:
+	stw	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out32r
+ * Description:	Byte reverse and output 32 bits
+ */
+	.globl	out32r
+out32r:
+	stwbrx	r4,r0,r3
+	blr
+
+/*
+ * Function:	in16
+ * Description:	Input 16 bits
+ */
+	.globl	in16
+in16:
+	lhz	r3,0x0000(r3)
+	blr
+
+/*
+ * Function:	in16r
+ * Description:	Input 16 bits and byte reverse
+ */
+	.globl	in16r
+in16r:
+	lhbrx	r3,r0,r3
+	blr
+
+/*
+ * Function:	in32
+ * Description:	Input 32 bits
+ */
+	.globl	in32
+in32:
+	lwz	3,0x0000(3)
+	blr
+
+/*
+ * Function:	in32r
+ * Description:	Input 32 bits and byte reverse
+ */
+	.globl	in32r
+in32r:
+	lwbrx	r3,r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbf
+ * Description:	Data Cache block flush
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbf
+ppcDcbf:
+	dcbf	r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbi
+ * Description:	Data Cache block Invalidate
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbi
+ppcDcbi:
+	dcbi	r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbz
+ * Description:	Data Cache block zero.
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbz
+ppcDcbz:
+	dcbz	r0,r3
+	blr
+
+/*
+ * Function:	ppcSync
+ * Description:	Processor Synchronize
+ * Input:	none.
+ * Output:	none.
+ */
+	.globl	ppcSync
+ppcSync:
+	sync
+	blr
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+	.globl	relocate_code
+relocate_code:
+
+	mr	r1,  r3		/* Set new stack pointer		*/
+	mr	r9,  r4		/* Save copy of Global Data pointer	*/
+	mr	r29, r9		/* Save for DECLARE_GLOBAL_DATA_PTR	*/
+	mr	r10, r5		/* Save copy of Destination Address	*/
+
+	mr	r3,  r5				/* Destination Address	*/
+	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_MONITOR_BASE@l
+	lwz	r5, GOT(__init_end)
+	sub	r5, r5, r4
+	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/
+
+	/*
+	 * Fix GOT pointer:
+	 *
+	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+	 *
+	 * Offset:
+	 */
+	sub	r15, r10, r4
+
+	/* First our own GOT */
+	add	r14, r14, r15
+	/* then the one used by the C code */
+	add	r30, r30, r15
+
+	/*
+	 * Now relocate code
+	 */
+#ifdef CONFIG_ECC
+	bl	board_relocate_rom
+	sync
+	mr	r3, r10				/* Destination Address	*/
+	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_MONITOR_BASE@l
+	lwz	r5, GOT(__init_end)
+	sub	r5, r5, r4
+	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/
+#else
+	cmplw	cr1,r3,r4
+	addi	r0,r5,3
+	srwi.	r0,r0,2
+	beq	cr1,4f		/* In place copy is not necessary	*/
+	beq	7f		/* Protect against 0 count		*/
+	mtctr	r0
+	bge	cr1,2f
+
+	la	r8,-4(r4)
+	la	r7,-4(r3)
+1:	lwzu	r0,4(r8)
+	stwu	r0,4(r7)
+	bdnz	1b
+	b	4f
+
+2:	slwi	r0,r0,2
+	add	r8,r4,r0
+	add	r7,r3,r0
+3:	lwzu	r0,-4(r8)
+	stwu	r0,-4(r7)
+	bdnz	3b
+#endif
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:	cmpwi	r6,0
+	add	r5,r3,r5
+	beq	7f		/* Always flush prefetch queue in any case */
+	subi	r0,r6,1
+	andc	r3,r3,r0
+	mr	r4,r3
+5:	dcbst	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	5b
+	sync			/* Wait for all dcbst to complete on bus */
+	mr	r4,r3
+6:	icbi	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	6b
+7:	sync			/* Wait for all icbi to complete on bus */
+	isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	mtlr	r0
+	blr
+
+in_ram:
+#ifdef CONFIG_ECC
+	bl	board_init_ecc
+#endif
+	/*
+	 * Relocation Function, r14 point to got2+0x8000
+	 *
+	 * Adjust got2 pointers, no need to check for 0, this code
+	 * already puts a few entries in the table.
+	 */
+	li	r0,__got2_entries@sectoff@l
+	la	r3,GOT(_GOT2_TABLE_)
+	lwz	r11,GOT(_GOT2_TABLE_)
+	mtctr	r0
+	sub	r11,r3,r11
+	addi	r3,r3,-4
+1:	lwzu	r0,4(r3)
+	add	r0,r0,r11
+	stw	r0,0(r3)
+	bdnz	1b
+
+	/*
+	 * Now adjust the fixups and the pointers to the fixups
+	 * in case we need to move ourselves again.
+	 */
+2:	li	r0,__fixup_entries@sectoff@l
+	lwz	r3,GOT(_FIXUP_TABLE_)
+	cmpwi	r0,0
+	mtctr	r0
+	addi	r3,r3,-4
+	beq	4f
+3:	lwzu	r4,4(r3)
+	lwzux	r0,r4,r11
+	add	r0,r0,r11
+	stw	r10,0(r3)
+	stw	r0,0(r4)
+	bdnz	3b
+4:
+/* clear_bss: */
+	/*
+	 * Now clear BSS segment
+	 */
+	lwz	r3,GOT(__bss_start)
+	lwz	r4,GOT(_end)
+
+	cmplw	0, r3, r4
+	beq	6f
+
+	li	r0, 0
+5:
+	stw	r0, 0(r3)
+	addi	r3, r3, 4
+	cmplw	0, r3, r4
+	bne	5b
+6:
+	mr	r3, r9		/* Init Date pointer		*/
+	mr	r4, r10		/* Destination Address		*/
+	bl	board_init_r
+
+	/* not reached - end relocate_code */
+/*-----------------------------------------------------------------------*/
+
+	/*
+	 * Copy exception vector code to low memory
+	 *
+	 * r3: dest_addr
+	 * r7: source address, r8: end address, r9: target address
+	 */
+	.globl	trap_init
+trap_init:
+	lwz	r7, GOT(_start)
+	lwz	r8, GOT(_end_of_vectors)
+
+	li	r9, 0x100		/* reset vector always at 0x100 */
+
+	cmplw	0, r7, r8
+	bgelr				/* return if r7>=r8 - just in case */
+
+	mflr	r4			/* save link register		*/
+1:
+	lwz	r0, 0(r7)
+	stw	r0, 0(r9)
+	addi	r7, r7, 4
+	addi	r9, r9, 4
+	cmplw	0, r7, r8
+	bne	1b
+
+	/*
+	 * relocate `hdlr' and `int_return' entries
+	 */
+	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	2b
+
+	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	3b
+
+	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	4b
+
+	/* enable execptions from RAM vectors */
+	mfmsr	r7
+	li	r8,MSR_IP
+	andc	r7,r7,r8
+	mtmsr	r7
+
+	mtlr	r4			/* restore link register	*/
+	blr
+
+	/*
+	 * Function: relocate entries for one exception vector
+	 */
+trap_reloc:
+	lwz	r0, 0(r7)		/* hdlr ...			*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 0(r7)
+
+	lwz	r0, 4(r7)		/* int_return ...		*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 4(r7)
+
+	sync
+	isync
+
+	blr
+
+.globl enable_ext_addr
+enable_ext_addr:
+	mfspr	r0, HID0
+	lis	r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
+	ori	r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
+	mtspr	HID0, r0
+	sync
+	isync
+	blr
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+.globl setup_ccsrbar
+setup_ccsrbar:
+	/* Special sequence needed to update CCSRBAR itself */
+	lis	r4, CFG_CCSRBAR_DEFAULT@h
+	ori	r4, r4, CFG_CCSRBAR_DEFAULT@l
+
+	lis	r5, CFG_CCSRBAR@h
+	ori	r5, r5, CFG_CCSRBAR@l
+	srwi	r6,r5,12
+	stw	r6, 0(r4)
+	isync
+
+	lis	r5, 0xffff
+	ori	r5,r5,0xf000
+	lwz	r5, 0(r5)
+	isync
+
+	lis	r3, CFG_CCSRBAR@h
+	lwz	r5, CFG_CCSRBAR@l(r3)
+	isync
+
+	blr
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+lock_ram_in_cache:
+	/* Allocate Initial RAM in data cache.
+	 */
+	lis	r3, (CFG_INIT_RAM_ADDR & ~31)@h
+	ori	r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+	li	r2, ((CFG_INIT_RAM_END & ~31) + \
+		     (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+	mtctr	r2
+1:
+	dcbz	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+#if 1
+/* Lock the data cache */
+	mfspr	r0, HID0
+	ori	r0, r0, 0x1000
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#if 0
+	/* Lock the first way of the data cache */
+	mfspr	r0, LDSTCR
+	ori	r0, r0, 0x0080
+#if defined(CONFIG_ALTIVEC)
+	dssall
+#endif
+	sync
+	mtspr	LDSTCR, r0
+	sync
+	isync
+	blr
+#endif
+
+.globl unlock_ram_in_cache
+unlock_ram_in_cache:
+	/* invalidate the INIT_RAM section */
+	lis	r3, (CFG_INIT_RAM_ADDR & ~31)@h
+	ori	r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+	li	r2, ((CFG_INIT_RAM_END & ~31) + \
+		     (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+	mtctr	r2
+1:	icbi	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+	sync			/* Wait for all icbi to complete on bus */
+	isync
+#if 1
+/* Unlock the data cache and invalidate it */
+	mfspr	r0, HID0
+	li	r3,0x1000
+	andc	r0,r0,r3
+	li	r3,0x0400
+	or	r0,r0,r3
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#if 0
+	/* Unlock the first way of the data cache */
+	mfspr	r0, LDSTCR
+	li	r3,0x0080
+	andc	r0,r0,r3
+#ifdef CONFIG_ALTIVEC
+	dssall
+#endif
+	sync
+	mtspr	LDSTCR, r0
+	sync
+	isync
+	li	r3,0x0400
+	or	r0,r0,r3
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#endif
+
+/* If this is a multi-cpu system then we need to handle the
+ * 2nd cpu.  The assumption is that the 2nd cpu is being
+ * held in boot holdoff mode until the 1st cpu unlocks it
+ * from Linux.	We'll do some basic cpu init and then pass
+ * it to the Linux Reset Vector.
+ * Sri:	 Much of this initialization is not required. Linux
+ * rewrites the bats, and the sprs and also enables the L1 cache.
+ */
+#if (CONFIG_NUM_CPUS > 1)
+.globl secondary_cpu_setup
+secondary_cpu_setup:
+	/* Do only core setup on all cores except cpu0 */
+	bl	invalidate_bats
+	sync
+	bl	enable_ext_addr
+
+#ifdef CFG_L2
+	/* init the L2 cache */
+	addis	r3, r0, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	sync
+	mtspr	l2cr, r3
+#ifdef CONFIG_ALTIVEC
+	dssall
+#endif
+	/* invalidate the L2 cache */
+	bl	l2cache_invalidate
+	sync
+#endif
+
+	/* enable and invalidate the data cache */
+	bl	dcache_enable
+	sync
+
+	/* enable and invalidate the instruction cache*/
+	bl	icache_enable
+	sync
+
+	/* TBEN in HID0 */
+	mfspr	r4, HID0
+	oris	r4, r4, 0x0400
+	mtspr	HID0, r4
+	sync
+	isync
+
+	/*SYNCBE|ABE in HID1*/
+	mfspr	r4, HID1
+	ori	r4, r4, 0x0C00
+	mtspr	HID1, r4
+	sync
+	isync
+
+	lis	r3, CONFIG_LINUX_RESET_VEC@h
+	ori	r3, r3, CONFIG_LINUX_RESET_VEC@l
+	mtlr	r3
+	blr
+
+	/* Never Returns, Running in Linux Now */
+#endif

+ 226 - 0
cpu/mpc86xx/traps.c

@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int cnt = 0;
+	unsigned long i;
+
+	printf("Call backtrace: ");
+	while (sp) {
+		if ((uint) sp > END_OF_MEM)
+			break;
+
+		i = sp[1];
+		if (cnt++ % 7 == 0)
+			printf("\n");
+		printf("%08lX ", i);
+		if (cnt > 32)
+			break;
+		sp = (unsigned long *)*sp;
+	}
+	printf("\n");
+}
+
+void
+show_regs(struct pt_regs *regs)
+{
+	int i;
+
+	printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
+	       " %p TRAP: %04lx DAR: %08lX\n",
+	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+	printf("MSR: %08lx EE: %01x PR: %01x FP:"
+	       " %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs->msr, regs->msr & MSR_EE ? 1 : 0,
+	       regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
+	       regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
+	       regs->msr & MSR_DR ? 1 : 0);
+
+	printf("\n");
+	for (i = 0; i < 32; i++) {
+		if ((i % 8) == 0) {
+			printf("GPR%02d: ", i);
+		}
+
+		printf("%08lX ", regs->gpr[i]);
+		if ((i % 8) == 7) {
+			printf("\n");
+		}
+	}
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	/* Probing PCI using config cycles cause this exception
+	 * when a device is not present.  Catch it and return to
+	 * the PCI exception handler.
+	 */
+	if ((fixup = search_exception_table(regs->nip)) != 0) {
+		regs->nip = fixup;
+		return;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ", regs);
+	switch (regs->msr & 0x000F0000) {
+	case (0x80000000 >> 12):
+		printf("Machine check signal - probably due to mm fault\n"
+		       "with mmu off\n");
+		break;
+	case (0x80000000 >> 13):
+		printf("Transfer error ack signal\n");
+		break;
+	case (0x80000000 >> 14):
+		printf("Data parity signal\n");
+		break;
+	case (0x80000000 >> 15):
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+	unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
+	int i, j;
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+
+	p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
+	p -= 32;
+	for (i = 0; i < 256; i += 16) {
+		printf("%08x: ", (unsigned int)p + i);
+		for (j = 0; j < 16; j++) {
+			printf("%02x ", p[i + j]);
+		}
+		printf("\n");
+	}
+
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+/*
+ * Probe an address by reading.
+ * If not present, return -1,
+ * otherwise return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+	return 0;
+}

+ 33 - 0
doc/README.AVR32

@@ -0,0 +1,33 @@
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed, 30 Aug 2006 17:01:46 +0200
+Subject: [PATCH] AVR32 architecture support
+
+This patch adds common infrastructure code for the Atmel AVR32
+architecture.
+
+AVR32 is a new high-performance 32-bit RISC microprocessor core,
+designed for cost-sensitive embedded applications, with particular
+emphasis on low power consumption and high code density. The AVR32
+architecture is not binary compatible with earlier 8-bit AVR
+architectures.
+
+The AVR32 architecture, including the instruction set, is described
+by the AVR32 Architecture Manual, available from
+
+http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf
+
+A GNU toolchain with support for AVR32 is included with the ATSTK1000
+BSP, which can be downloaded as an ISO image from
+
+http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3918
+
+Alternatively, you can build it yourself by following the
+Getting Started guide at avr32linux.org, which also provides links
+to the necessary sources and patches you need to download:
+
+http://avr32linux.org/twiki/bin/view/Main/GettingStarted
+
+The AVR32 ports of u-boot, the Linux kernel, the GNU toolchain and
+other associated software are actively supported by Atmel Corporation.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>

+ 123 - 0
doc/README.mpc8641hpcn

@@ -0,0 +1,123 @@
+Freescale MPC8641HPCN board
+===========================
+
+Created 05/24/2006 Haiying Wang
+-------------------------------
+
+1. Building U-Boot
+------------------
+The 86xx HPCN code base is known to compile using:
+    Binutils 2.15, Gcc 3.4.3, Glibc 2.3.3
+
+    $ make MPC8641HPCN_config
+    Configuring for MPC8641HPCN board...
+
+    $ make
+
+
+2. Switch and Jumper Setting
+----------------------------
+Jumpers:
+	J14 Pins 1-2 (near plcc32 socket)
+
+Switches:
+	SW1(1-5) = 01100	CFG_COREPLL	= 01000 :: CORE =   2:1
+						  01100 :: CORE = 2.5:1
+						  10000 :: CORE =   3:1
+						  11100 :: CORE = 3.5:1
+						  10100 :: CORE =   4:1
+						  01110 :: CORE = 4.5:1
+	SW1(6-8) = 001		CFG_SYSCLK	= 000	:: SYSCLK = 33MHz
+						  001	:: SYSCLK = 40MHz
+
+	SW2(1-4) = 1100		CFG_CCBPLL	= 0010	:: 2X
+						  0100	:: 4X
+						  0110	:: 6X
+						  1000	:: 8X
+						  1010	:: 10X
+						  1100	:: 12X
+						  1110	:: 14X
+						  0000	:: 16X
+	SW2(5-8) = 1110		CFG_BOOTLOC	= 1110	:: boot 16-bit localbus
+
+	SW3(1-7) = 0011000	CFG_VID		= 0011000 :: VCORE = 1.2V
+						  0100000 :: VCORE = 1.11V
+	SW3(8)	 = 0		VCC_PLAT	= 0	:: VCC_PLAT = 1.2V
+						  1	:: VCC_PLAT = 1.0V
+
+	SW4(1-2) = 11		CFG_HOSTMODE	= 11	:: both prots host/root
+	SW4(3-4) = 11		CFG_BOOTSEQ	= 11	:: no boot seq
+	SW4(5-8) = 0011		CFG_IOPORT	= 0011	:: both PEX
+
+	SW5(1)	 = 1		CFG_FLASHMAP	= 1	:: boot from flash
+						  0	:: boot from PromJet
+	SW5(2)	 = 1		CFG_FLASHBANK	= 1	:: swap upper/lower
+							 halves (virtual banks)
+						  0	:: normal
+	SW5(3)	 = 0		CFG_FLASHWP	= 0	:: not protected
+	SW5(4)	 = 0 		CFG_PORTDIV	= 1	:: 2:1 for PD4
+							   1:1 for PD6
+	SW5(5-6) = 11		CFG_PIXISOPT	= 11	:: s/w determined
+	SW5(7-8) = 11		CFG_LADOPT	= 11	:: s/w determined
+
+	SW6(1)	 = 1		CFG_CPUBOOT	= 1	:: no boot holdoff
+	SW6(2)	 = 1		CFG_BOOTADDR	= 1	:: no traslation
+	SW6(3-5) = 000		CFG_REFCLKSEL	= 000	:: 100MHZ
+	SW6(6)	 = 1		CFG_SERROM_ADDR= 1	::
+	SW6(7)	 = 1		CFG_MEMDEBUG	= 1	::
+	SW6(8)	 = 1		CFG_DDRDEBUG	= 1	::
+
+	SW8(1)	 = 1		ACZ_SYNC	= 1	:: 48MHz on TP49
+	SW8(2)	 = 1		ACB_SYNC	= 1	:: THRMTRIP disabled
+	SW8(3)	 = 1		ACZ_SDOUT	= 1	:: p4 mode
+	SW8(4)	 = 1		ACB_SDOUT	= 1	:: PATA freq. = 133MHz
+	SW8(5)	 = 0		SUSLED		= 0	:: SouthBridge Mode
+	SW8(6)	 = 0		SPREAD		= 0	:: REFCLK SSCG Disabled
+	SW8(7)	 = 1		ACPWR		= 1	:: non-battery
+	SW8(8)	 = 0		CFG_IDWP	= 0	:: write enable
+
+
+3. Flash U-Boot
+---------------
+The flash range 0xFF800000 to 0xFFFFFFFF can be divided into 2 halves.
+It is possible to use either half to boot using u-boot.  Switch 5 bit 2
+is used for this purpose.
+
+0xFF800000 to 0xFFBFFFFF - 4MB
+0xFFC00000 to 0xFFFFFFFF - 4MB
+When this bit is 0, U-Boot is at 0xFFF00000.
+When this bit is 1, U-Boot is at 0xFFB00000.
+
+Use the above mentioned flash commands to program the other half, and
+use switch 5, bit 2 to alternate between the halves.  Note: The booting
+version of U-Boot will always be at 0xFFF00000.
+
+To Flash U-Boot into the booting bank (0xFFC00000 - 0xFFFFFFFF):
+
+	tftp 1000000 u-boot.bin
+	protect off all
+	erase fff00000 ffffffff
+	cp.b 1000000 fff00100 80000
+
+To Flash U-boot into the alternative bank (0xFF800000 - 0xFFBFFFFF):
+
+	tftp 1000000 u-boot.bin
+	erase ffb00000 ffbfffff
+	cp.b 1000000 ffb00100 80000
+
+
+4. Memory Map
+-------------
+
+	Memory Range			Device		Size
+	------------			------		----
+	0x0000_0000	0x7fff_ffff	DDR		2G
+	0x8000_0000	0x9fff_ffff	PCI1/PEX1 MEM	512M
+	0xa000_0000	0xafff_ffff	PCI2/PEX2 MEM	512M
+	0xf800_0000	0xf80f_ffff	CCSR		1M
+	0xf810_0000	0xf81f_ffff	PIXIS		1M
+	0xf840_0000	0xf840_3fff	Stack space	32K
+	0xe200_0000	0xe2ff_ffff	PCI1/PEX1 IO	16M
+	0xe300_0000	0xe3ff_ffff	PCI2/PEX2 IO	16M
+	0xfe00_0000	0xfeff_ffff	Flash(alternate)16M
+	0xff00_0000	0xffff_ffff	Flash(boot bank)16M

+ 4 - 3
drivers/Makefile

@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)libdrivers.a
 
-COBJS	= 3c589.o 5701rls.o ali512x.o \
+COBJS	= 3c589.o 5701rls.o ali512x.o atmel_usart.o \
 	  bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \
 	  cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
 	  e1000.o eepro100.o \
@@ -44,13 +44,14 @@ COBJS	= 3c589.o 5701rls.o ali512x.o \
 	  serial.o serial_max3100.o \
 	  serial_pl010.o serial_pl011.o serial_xuartlite.o \
 	  sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
-	  status_led.o sym53c8xx.o \
+	  status_led.o sym53c8xx.o ahci.o \
 	  ti_pci1410a.o tigon3.o tsec.o \
 	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
 	  videomodes.o w83c553f.o \
 	  ks8695eth.o \
 	  pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o	\
-	  rpx_pcmcia.o
+	  rpx_pcmcia.o \
+	  fsl_i2c.o
 
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))

+ 702 - 0
drivers/ahci.c

@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ * Author: Jason Jin<Jason.jin@freescale.com>
+ *         Zhang Wei<wei.zhang@freescale.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
+ *
+ * with the reference on libata and ahci drvier in kernel
+ *
+ */
+#include <common.h>
+
+#ifdef CONFIG_SCSI_AHCI
+
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <scsi.h>
+#include <ata.h>
+#include <linux/ctype.h>
+#include <ahci.h>
+
+struct ahci_probe_ent *probe_ent = NULL;
+hd_driveid_t *ataid[AHCI_MAX_PORTS];
+
+#define writel_with_flush(a,b)	do { writel(a,b); readl(b); } while (0)
+
+
+static inline u32 ahci_port_base(u32 base, u32 port)
+{
+	return base + 0x100 + (port * 0x80);
+}
+
+
+static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
+			    unsigned int port_idx)
+{
+	base = ahci_port_base(base, port_idx);
+
+	port->cmd_addr = base;
+	port->scr_addr = base + PORT_SCR;
+}
+
+
+#define msleep(a) udelay(a * 1000)
+#define ssleep(a) msleep(a * 1000)
+
+static int waiting_for_cmd_completed(volatile u8 *offset,
+				     int timeout_msec,
+				     u32 sign)
+{
+	int i;
+	u32 status;
+
+	for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
+		msleep(1);
+
+	return (i < timeout_msec) ? 0 : -1;
+}
+
+
+static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+{
+	pci_dev_t pdev = probe_ent->dev;
+	volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
+	u32 tmp, cap_save;
+	u16 tmp16;
+	int i, j;
+	volatile u8 *port_mmio;
+	unsigned short vendor;
+
+	cap_save = readl(mmio + HOST_CAP);
+	cap_save &= ((1 << 28) | (1 << 17));
+	cap_save |= (1 << 27);
+
+	/* global controller reset */
+	tmp = readl(mmio + HOST_CTL);
+	if ((tmp & HOST_RESET) == 0)
+		writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);
+
+	/* reset must complete within 1 second, or
+	 * the hardware should be considered fried.
+	 */
+	ssleep(1);
+
+	tmp = readl(mmio + HOST_CTL);
+	if (tmp & HOST_RESET) {
+		debug("controller reset failed (0x%x)\n", tmp);
+		return -1;
+	}
+
+	writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
+	writel(cap_save, mmio + HOST_CAP);
+	writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
+
+	pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+
+	if (vendor == PCI_VENDOR_ID_INTEL) {
+		u16 tmp16;
+		pci_read_config_word(pdev, 0x92, &tmp16);
+		tmp16 |= 0xf;
+		pci_write_config_word(pdev, 0x92, tmp16);
+	}
+
+	probe_ent->cap = readl(mmio + HOST_CAP);
+	probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
+	probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
+
+	debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
+	      probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+
+	for (i = 0; i < probe_ent->n_ports; i++) {
+		probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
+		port_mmio = (u8 *) probe_ent->port[i].port_mmio;
+		ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
+
+		/* make sure port is not active */
+		tmp = readl(port_mmio + PORT_CMD);
+		if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+			   PORT_CMD_FIS_RX | PORT_CMD_START)) {
+			tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+				 PORT_CMD_FIS_RX | PORT_CMD_START);
+			writel_with_flush(tmp, port_mmio + PORT_CMD);
+
+			/* spec says 500 msecs for each bit, so
+			 * this is slightly incorrect.
+			 */
+			msleep(500);
+		}
+
+		writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
+
+		j = 0;
+		while (j < 100) {
+			msleep(10);
+			tmp = readl(port_mmio + PORT_SCR_STAT);
+			if ((tmp & 0xf) == 0x3)
+				break;
+			j++;
+		}
+
+		tmp = readl(port_mmio + PORT_SCR_ERR);
+		debug("PORT_SCR_ERR 0x%x\n", tmp);
+		writel(tmp, port_mmio + PORT_SCR_ERR);
+
+		/* ack any pending irq events for this port */
+		tmp = readl(port_mmio + PORT_IRQ_STAT);
+		debug("PORT_IRQ_STAT 0x%x\n", tmp);
+		if (tmp)
+			writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+		writel(1 << i, mmio + HOST_IRQ_STAT);
+
+		/* set irq mask (enables interrupts) */
+		writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
+
+		/*register linkup ports */
+		tmp = readl(port_mmio + PORT_SCR_STAT);
+		debug("Port %d status: 0x%x\n", i, tmp);
+		if ((tmp & 0xf) == 0x03)
+			probe_ent->link_port_map |= (0x01 << i);
+	}
+
+	tmp = readl(mmio + HOST_CTL);
+	debug("HOST_CTL 0x%x\n", tmp);
+	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+	tmp = readl(mmio + HOST_CTL);
+	debug("HOST_CTL 0x%x\n", tmp);
+
+	pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
+	tmp |= PCI_COMMAND_MASTER;
+	pci_write_config_word(pdev, PCI_COMMAND, tmp16);
+
+	return 0;
+}
+
+
+static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+{
+	pci_dev_t pdev = probe_ent->dev;
+	volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
+	u32 vers, cap, impl, speed;
+	const char *speed_s;
+	u16 cc;
+	const char *scc_s;
+
+	vers = readl(mmio + HOST_VERSION);
+	cap = probe_ent->cap;
+	impl = probe_ent->port_map;
+
+	speed = (cap >> 20) & 0xf;
+	if (speed == 1)
+		speed_s = "1.5";
+	else if (speed == 2)
+		speed_s = "3";
+	else
+		speed_s = "?";
+
+	pci_read_config_word(pdev, 0x0a, &cc);
+	if (cc == 0x0101)
+		scc_s = "IDE";
+	else if (cc == 0x0106)
+		scc_s = "SATA";
+	else if (cc == 0x0104)
+		scc_s = "RAID";
+	else
+		scc_s = "unknown";
+
+	printf("AHCI %02x%02x.%02x%02x "
+	       "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
+	       (vers >> 24) & 0xff,
+	       (vers >> 16) & 0xff,
+	       (vers >> 8) & 0xff,
+	       vers & 0xff,
+	       ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
+
+	printf("flags: "
+	       "%s%s%s%s%s%s"
+	       "%s%s%s%s%s%s%s\n",
+	       cap & (1 << 31) ? "64bit " : "",
+	       cap & (1 << 30) ? "ncq " : "",
+	       cap & (1 << 28) ? "ilck " : "",
+	       cap & (1 << 27) ? "stag " : "",
+	       cap & (1 << 26) ? "pm " : "",
+	       cap & (1 << 25) ? "led " : "",
+	       cap & (1 << 24) ? "clo " : "",
+	       cap & (1 << 19) ? "nz " : "",
+	       cap & (1 << 18) ? "only " : "",
+	       cap & (1 << 17) ? "pmp " : "",
+	       cap & (1 << 15) ? "pio " : "",
+	       cap & (1 << 14) ? "slum " : "",
+	       cap & (1 << 13) ? "part " : "");
+}
+
+static int ahci_init_one(pci_dev_t pdev)
+{
+	u32 iobase, vendor;
+	int rc;
+
+	memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
+
+	probe_ent = malloc(sizeof(probe_ent));
+	memset(probe_ent, 0, sizeof(probe_ent));
+	probe_ent->dev = pdev;
+
+	pci_read_config_dword(pdev, AHCI_PCI_BAR, &iobase);
+	iobase &= ~0xf;
+
+	probe_ent->host_flags = ATA_FLAG_SATA
+				| ATA_FLAG_NO_LEGACY
+				| ATA_FLAG_MMIO
+				| ATA_FLAG_PIO_DMA
+				| ATA_FLAG_NO_ATAPI;
+	probe_ent->pio_mask = 0x1f;
+	probe_ent->udma_mask = 0x7f;	/*Fixme,assume to support UDMA6 */
+
+	probe_ent->mmio_base = iobase;
+
+	/* Take from kernel:
+	 * JMicron-specific fixup:
+	 * make sure we're in AHCI mode
+	 */
+	pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+	if (vendor == 0x197b)
+		pci_write_config_byte(pdev, 0x41, 0xa1);
+
+	/* initialize adapter */
+	rc = ahci_host_init(probe_ent);
+	if (rc)
+		goto err_out;
+
+	ahci_print_info(probe_ent);
+
+	return 0;
+
+      err_out:
+	return rc;
+}
+
+
+#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
+
+static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
+{
+	struct ahci_ioports *pp = &(probe_ent->port[port]);
+	struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
+	u32 sg_count;
+	int i;
+
+	sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
+	if (sg_count > AHCI_MAX_SG) {
+		printf("Error:Too much sg!\n");
+		return -1;
+	}
+
+	for (i = 0; i < sg_count; i++) {
+		ahci_sg->addr =
+		    cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT);
+		ahci_sg->addr_hi = 0;
+		ahci_sg->flags_size = cpu_to_le32(0x3fffff &
+					  (buf_len < MAX_DATA_BYTE_COUNT
+					   ? (buf_len - 1)
+					   : (MAX_DATA_BYTE_COUNT - 1)));
+		ahci_sg++;
+		buf_len -= MAX_DATA_BYTE_COUNT;
+	}
+
+	return sg_count;
+}
+
+
+static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
+{
+	pp->cmd_slot->opts = cpu_to_le32(opts);
+	pp->cmd_slot->status = 0;
+	pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
+	pp->cmd_slot->tbl_addr_hi = 0;
+}
+
+
+static void ahci_set_feature(u8 port)
+{
+	struct ahci_ioports *pp = &(probe_ent->port[port]);
+	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+	u32 cmd_fis_len = 5;	/* five dwords */
+	u8 fis[20];
+
+	/*set feature */
+	memset(fis, 0, 20);
+	fis[0] = 0x27;
+	fis[1] = 1 << 7;
+	fis[2] = ATA_CMD_SETF;
+	fis[3] = SETFEATURES_XFER;
+	fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
+
+	memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
+	ahci_fill_cmd_slot(pp, cmd_fis_len);
+	writel(1, port_mmio + PORT_CMD_ISSUE);
+	readl(port_mmio + PORT_CMD_ISSUE);
+
+	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
+		printf("set feature error!\n");
+	}
+}
+
+
+static int ahci_port_start(u8 port)
+{
+	struct ahci_ioports *pp = &(probe_ent->port[port]);
+	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+	u32 port_status;
+	u32 mem;
+
+	debug("Enter start port: %d\n", port);
+	port_status = readl(port_mmio + PORT_SCR_STAT);
+	debug("Port %d status: %x\n", port, port_status);
+	if ((port_status & 0xf) != 0x03) {
+		printf("No Link on this port!\n");
+		return -1;
+	}
+
+	mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
+	if (!mem) {
+		free(pp);
+		printf("No mem for table!\n");
+		return -ENOMEM;
+	}
+
+	mem = (mem + 0x800) & (~0x7ff);	/* Aligned to 2048-bytes */
+	memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+
+	/*
+	 * First item in chunk of DMA memory: 32-slot command table,
+	 * 32 bytes each in size
+	 */
+	pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
+	debug("cmd_slot = 0x%x\n", pp->cmd_slot);
+	mem += (AHCI_CMD_SLOT_SZ + 224);
+
+	/*
+	 * Second item: Received-FIS area
+	 */
+	pp->rx_fis = mem;
+	mem += AHCI_RX_FIS_SZ;
+
+	/*
+	 * Third item: data area for storing a single command
+	 * and its scatter-gather table
+	 */
+	pp->cmd_tbl = mem;
+	debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
+
+	mem += AHCI_CMD_TBL_HDR;
+	pp->cmd_tbl_sg = (struct ahci_sg *)mem;
+
+	writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
+
+	writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
+
+	writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+			  PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+			  PORT_CMD_START, port_mmio + PORT_CMD);
+
+	debug("Exit start port %d\n", port);
+
+	return 0;
+}
+
+
+static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
+				int buf_len)
+{
+
+	struct ahci_ioports *pp = &(probe_ent->port[port]);
+	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+	u32 opts;
+	u32 port_status;
+	int sg_count;
+
+	debug("Enter get_ahci_device_data: for port %d\n", port);
+
+	if (port > probe_ent->n_ports) {
+		printf("Invaild port number %d\n", port);
+		return -1;
+	}
+
+	port_status = readl(port_mmio + PORT_SCR_STAT);
+	if ((port_status & 0xf) != 0x03) {
+		debug("No Link on port %d!\n", port);
+		return -1;
+	}
+
+	memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
+
+	sg_count = ahci_fill_sg(port, buf, buf_len);
+	opts = (fis_len >> 2) | (sg_count << 16);
+	ahci_fill_cmd_slot(pp, opts);
+
+	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
+
+	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
+		printf("timeout exit!\n");
+		return -1;
+	}
+	debug("get_ahci_device_data: %d byte transferred.\n",
+	      pp->cmd_slot->status);
+
+	return 0;
+}
+
+
+static char *ata_id_strcpy(u16 *target, u16 *src, int len)
+{
+	int i;
+	for (i = 0; i < len / 2; i++)
+		target[i] = le16_to_cpu(src[i]);
+	return (char *)target;
+}
+
+
+static void dump_ataid(hd_driveid_t *ataid)
+{
+	debug("(49)ataid->capability = 0x%x\n", ataid->capability);
+	debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
+	debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
+	debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
+	debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
+	debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
+	debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
+	debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
+	debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
+	debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
+	debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
+	debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
+	debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
+	debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
+	debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
+}
+
+
+/*
+ * SCSI INQUIRY command operation.
+ */
+static int ata_scsiop_inquiry(ccb *pccb)
+{
+	u8 hdr[] = {
+		0,
+		0,
+		0x5,		/* claim SPC-3 version compatibility */
+		2,
+		95 - 4,
+	};
+	u8 fis[20];
+	u8 *tmpid;
+	u8 port;
+
+	/* Clean ccb data buffer */
+	memset(pccb->pdata, 0, pccb->datalen);
+
+	memcpy(pccb->pdata, hdr, sizeof(hdr));
+
+	if (pccb->datalen <= 35)
+		return 0;
+
+	memset(fis, 0, 20);
+	/* Construct the FIS */
+	fis[0] = 0x27;		/* Host to device FIS. */
+	fis[1] = 1 << 7;	/* Command FIS. */
+	fis[2] = ATA_CMD_IDENT;	/* Command byte. */
+
+	/* Read id from sata */
+	port = pccb->target;
+	if (!(tmpid = malloc(sizeof(hd_driveid_t))))
+		return -ENOMEM;
+
+	if (get_ahci_device_data(port, (u8 *) & fis, 20,
+				 tmpid, sizeof(hd_driveid_t))) {
+		debug("scsi_ahci: SCSI inquiry command failure.\n");
+		return -EIO;
+	}
+
+	if (ataid[port])
+		free(ataid[port]);
+	ataid[port] = (hd_driveid_t *) tmpid;
+
+	memcpy(&pccb->pdata[8], "ATA     ", 8);
+	ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
+	ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
+
+	dump_ataid(ataid[port]);
+	return 0;
+}
+
+
+/*
+ * SCSI READ10 command operation.
+ */
+static int ata_scsiop_read10(ccb * pccb)
+{
+	u64 lba = 0;
+	u32 len = 0;
+	u8 fis[20];
+
+	lba = (((u64) pccb->cmd[2]) << 24) | (((u64) pccb->cmd[3]) << 16)
+	    | (((u64) pccb->cmd[4]) << 8) | ((u64) pccb->cmd[5]);
+	len = (((u32) pccb->cmd[7]) << 8) | ((u32) pccb->cmd[8]);
+
+	/* For 10-byte and 16-byte SCSI R/W commands, transfer
+	 * length 0 means transfer 0 block of data.
+	 * However, for ATA R/W commands, sector count 0 means
+	 * 256 or 65536 sectors, not 0 sectors as in SCSI.
+	 *
+	 * WARNING: one or two older ATA drives treat 0 as 0...
+	 */
+	if (!len)
+		return 0;
+	memset(fis, 0, 20);
+
+	/* Construct the FIS */
+	fis[0] = 0x27;		/* Host to device FIS. */
+	fis[1] = 1 << 7;	/* Command FIS. */
+	fis[2] = ATA_CMD_RD_DMA;	/* Command byte. */
+
+	/* LBA address, only support LBA28 in this driver */
+	fis[4] = pccb->cmd[5];
+	fis[5] = pccb->cmd[4];
+	fis[6] = pccb->cmd[3];
+	fis[7] = (pccb->cmd[2] & 0x0f) | 0xe0;
+
+	/* Sector Count */
+	fis[12] = pccb->cmd[8];
+	fis[13] = pccb->cmd[7];
+
+	/* Read from ahci */
+	if (get_ahci_device_data(pccb->target, (u8 *) & fis, 20,
+				 pccb->pdata, pccb->datalen)) {
+		debug("scsi_ahci: SCSI READ10 command failure.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+/*
+ * SCSI READ CAPACITY10 command operation.
+ */
+static int ata_scsiop_read_capacity10(ccb *pccb)
+{
+	u8 buf[8];
+
+	if (!ataid[pccb->target]) {
+		printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
+		       "\tNo ATA info!\n"
+		       "\tPlease run SCSI commmand INQUIRY firstly!\n");
+		return -EPERM;
+	}
+
+	memset(buf, 0, 8);
+
+	*(u32 *) buf = le32_to_cpu(ataid[pccb->target]->lba_capacity);
+
+	buf[6] = 512 >> 8;
+	buf[7] = 512 & 0xff;
+
+	memcpy(pccb->pdata, buf, 8);
+
+	return 0;
+}
+
+
+/*
+ * SCSI TEST UNIT READY command operation.
+ */
+static int ata_scsiop_test_unit_ready(ccb *pccb)
+{
+	return (ataid[pccb->target]) ? 0 : -EPERM;
+}
+
+
+int scsi_exec(ccb *pccb)
+{
+	int ret;
+
+	switch (pccb->cmd[0]) {
+	case SCSI_READ10:
+		ret = ata_scsiop_read10(pccb);
+		break;
+	case SCSI_RD_CAPAC:
+		ret = ata_scsiop_read_capacity10(pccb);
+		break;
+	case SCSI_TST_U_RDY:
+		ret = ata_scsiop_test_unit_ready(pccb);
+		break;
+	case SCSI_INQUIRY:
+		ret = ata_scsiop_inquiry(pccb);
+		break;
+	default:
+		printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
+		return FALSE;
+	}
+
+	if (ret) {
+		debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
+		return FALSE;
+	}
+	return TRUE;
+
+}
+
+
+void scsi_low_level_init(int busdevfunc)
+{
+	int i;
+	u32 linkmap;
+
+	ahci_init_one(busdevfunc);
+
+	linkmap = probe_ent->link_port_map;
+
+	for (i = 0; i < CFG_SCSI_MAX_SCSI_ID; i++) {
+		if (((linkmap >> i) & 0x01)) {
+			if (ahci_port_start((u8) i)) {
+				printf("Can not start port %d\n", i);
+				continue;
+			}
+			ahci_set_feature((u8) i);
+		}
+	}
+}
+
+
+void scsi_bus_reset(void)
+{
+	/*Not implement*/
+}
+
+
+void scsi_print_error(ccb * pccb)
+{
+	/*The ahci error info can be read in the ahci driver*/
+}
+#endif

+ 88 - 0
drivers/atmel_usart.c

@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <common.h>
+
+#ifdef CONFIG_ATMEL_USART
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+#include "atmel_usart.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void serial_setbrg(void)
+{
+	unsigned long divisor;
+	unsigned long usart_hz;
+
+	/*
+	 *              Master Clock
+	 * Baud Rate = --------------
+	 *                16 * CD
+	 */
+	usart_hz = pm_get_clock_freq(gd->console_uart->resource[0].u.clock.id);
+	divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
+	usart3_writel(gd->console_uart, BRGR, USART3_BF(CD, divisor));
+}
+
+int serial_init(void)
+{
+	usart3_writel(gd->console_uart, CR,
+		      USART3_BIT(RSTRX) | USART3_BIT(RSTTX));
+
+	serial_setbrg();
+
+	usart3_writel(gd->console_uart, CR,
+		      USART3_BIT(RXEN) | USART3_BIT(TXEN));
+	usart3_writel(gd->console_uart, MR,
+		      USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
+		      | USART3_BF(USCLKS, USART3_USCLKS_MCK)
+		      | USART3_BF(CHRL, USART3_CHRL_8)
+		      | USART3_BF(PAR, USART3_PAR_NONE)
+		      | USART3_BF(NBSTOP, USART3_NBSTOP_1));
+
+	return 0;
+}
+
+void serial_putc(char c)
+{
+	if (c == '\n')
+		serial_putc('\r');
+
+	while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(TXRDY))) ;
+	usart3_writel(gd->console_uart, THR, c);
+}
+
+void serial_puts(const char *s)
+{
+	while (*s)
+		serial_putc(*s++);
+}
+
+int serial_getc(void)
+{
+	while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY))) ;
+	return usart3_readl(gd->console_uart, RHR);
+}
+
+int serial_tstc(void)
+{
+	return (usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY)) != 0;
+}
+
+#endif /* CONFIG_ATMEL_USART */

+ 314 - 0
drivers/atmel_usart.h

@@ -0,0 +1,314 @@
+/*
+ * Register definitions for the Atmel USART3 module.
+ *
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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 __DRIVERS_ATMEL_USART_H__
+#define __DRIVERS_ATMEL_USART_H__
+
+/* USART3 register offsets */
+#define USART3_CR				0x0000
+#define USART3_MR				0x0004
+#define USART3_IER				0x0008
+#define USART3_IDR				0x000c
+#define USART3_IMR				0x0010
+#define USART3_CSR				0x0014
+#define USART3_RHR				0x0018
+#define USART3_THR				0x001c
+#define USART3_BRGR				0x0020
+#define USART3_RTOR				0x0024
+#define USART3_TTGR				0x0028
+#define USART3_FIDI				0x0040
+#define USART3_NER				0x0044
+#define USART3_XXR				0x0048
+#define USART3_IFR				0x004c
+#define USART3_RPR				0x0100
+#define USART3_RCR				0x0104
+#define USART3_TPR				0x0108
+#define USART3_TCR				0x010c
+#define USART3_RNPR				0x0110
+#define USART3_RNCR				0x0114
+#define USART3_TNPR				0x0118
+#define USART3_TNCR				0x011c
+#define USART3_PTCR				0x0120
+#define USART3_PTSR				0x0124
+
+/* Bitfields in CR */
+#define USART3_RSTRX_OFFSET			2
+#define USART3_RSTRX_SIZE			1
+#define USART3_RSTTX_OFFSET			3
+#define USART3_RSTTX_SIZE			1
+#define USART3_RXEN_OFFSET			4
+#define USART3_RXEN_SIZE			1
+#define USART3_RXDIS_OFFSET			5
+#define USART3_RXDIS_SIZE			1
+#define USART3_TXEN_OFFSET			6
+#define USART3_TXEN_SIZE			1
+#define USART3_TXDIS_OFFSET			7
+#define USART3_TXDIS_SIZE			1
+#define USART3_RSTSTA_OFFSET			8
+#define USART3_RSTSTA_SIZE			1
+#define USART3_STTBRK_OFFSET			9
+#define USART3_STTBRK_SIZE			1
+#define USART3_STPBRK_OFFSET			10
+#define USART3_STPBRK_SIZE			1
+#define USART3_STTTO_OFFSET			11
+#define USART3_STTTO_SIZE			1
+#define USART3_SENDA_OFFSET			12
+#define USART3_SENDA_SIZE			1
+#define USART3_RSTIT_OFFSET			13
+#define USART3_RSTIT_SIZE			1
+#define USART3_RSTNACK_OFFSET			14
+#define USART3_RSTNACK_SIZE			1
+#define USART3_RETTO_OFFSET			15
+#define USART3_RETTO_SIZE			1
+#define USART3_DTREN_OFFSET			16
+#define USART3_DTREN_SIZE			1
+#define USART3_DTRDIS_OFFSET			17
+#define USART3_DTRDIS_SIZE			1
+#define USART3_RTSEN_OFFSET			18
+#define USART3_RTSEN_SIZE			1
+#define USART3_RTSDIS_OFFSET			19
+#define USART3_RTSDIS_SIZE			1
+#define USART3_COMM_TX_OFFSET			30
+#define USART3_COMM_TX_SIZE			1
+#define USART3_COMM_RX_OFFSET			31
+#define USART3_COMM_RX_SIZE			1
+
+/* Bitfields in MR */
+#define USART3_USART_MODE_OFFSET		0
+#define USART3_USART_MODE_SIZE			4
+#define USART3_USCLKS_OFFSET			4
+#define USART3_USCLKS_SIZE			2
+#define USART3_CHRL_OFFSET			6
+#define USART3_CHRL_SIZE			2
+#define USART3_SYNC_OFFSET			8
+#define USART3_SYNC_SIZE			1
+#define USART3_PAR_OFFSET			9
+#define USART3_PAR_SIZE				3
+#define USART3_NBSTOP_OFFSET			12
+#define USART3_NBSTOP_SIZE			2
+#define USART3_CHMODE_OFFSET			14
+#define USART3_CHMODE_SIZE			2
+#define USART3_MSBF_OFFSET			16
+#define USART3_MSBF_SIZE			1
+#define USART3_MODE9_OFFSET			17
+#define USART3_MODE9_SIZE			1
+#define USART3_CLKO_OFFSET			18
+#define USART3_CLKO_SIZE			1
+#define USART3_OVER_OFFSET			19
+#define USART3_OVER_SIZE			1
+#define USART3_INACK_OFFSET			20
+#define USART3_INACK_SIZE			1
+#define USART3_DSNACK_OFFSET			21
+#define USART3_DSNACK_SIZE			1
+#define USART3_MAX_ITERATION_OFFSET		24
+#define USART3_MAX_ITERATION_SIZE		3
+#define USART3_FILTER_OFFSET			28
+#define USART3_FILTER_SIZE			1
+
+/* Bitfields in CSR */
+#define USART3_RXRDY_OFFSET			0
+#define USART3_RXRDY_SIZE			1
+#define USART3_TXRDY_OFFSET			1
+#define USART3_TXRDY_SIZE			1
+#define USART3_RXBRK_OFFSET			2
+#define USART3_RXBRK_SIZE			1
+#define USART3_ENDRX_OFFSET			3
+#define USART3_ENDRX_SIZE			1
+#define USART3_ENDTX_OFFSET			4
+#define USART3_ENDTX_SIZE			1
+#define USART3_OVRE_OFFSET			5
+#define USART3_OVRE_SIZE			1
+#define USART3_FRAME_OFFSET			6
+#define USART3_FRAME_SIZE			1
+#define USART3_PARE_OFFSET			7
+#define USART3_PARE_SIZE			1
+#define USART3_TIMEOUT_OFFSET			8
+#define USART3_TIMEOUT_SIZE			1
+#define USART3_TXEMPTY_OFFSET			9
+#define USART3_TXEMPTY_SIZE			1
+#define USART3_ITERATION_OFFSET			10
+#define USART3_ITERATION_SIZE			1
+#define USART3_TXBUFE_OFFSET			11
+#define USART3_TXBUFE_SIZE			1
+#define USART3_RXBUFF_OFFSET			12
+#define USART3_RXBUFF_SIZE			1
+#define USART3_NACK_OFFSET			13
+#define USART3_NACK_SIZE			1
+#define USART3_RIIC_OFFSET			16
+#define USART3_RIIC_SIZE			1
+#define USART3_DSRIC_OFFSET			17
+#define USART3_DSRIC_SIZE			1
+#define USART3_DCDIC_OFFSET			18
+#define USART3_DCDIC_SIZE			1
+#define USART3_CTSIC_OFFSET			19
+#define USART3_CTSIC_SIZE			1
+#define USART3_RI_OFFSET			20
+#define USART3_RI_SIZE				1
+#define USART3_DSR_OFFSET			21
+#define USART3_DSR_SIZE				1
+#define USART3_DCD_OFFSET			22
+#define USART3_DCD_SIZE				1
+#define USART3_CTS_OFFSET			23
+#define USART3_CTS_SIZE				1
+
+/* Bitfields in RHR */
+#define USART3_RXCHR_OFFSET			0
+#define USART3_RXCHR_SIZE			9
+
+/* Bitfields in THR */
+#define USART3_TXCHR_OFFSET			0
+#define USART3_TXCHR_SIZE			9
+
+/* Bitfields in BRGR */
+#define USART3_CD_OFFSET			0
+#define USART3_CD_SIZE				16
+
+/* Bitfields in RTOR */
+#define USART3_TO_OFFSET			0
+#define USART3_TO_SIZE				16
+
+/* Bitfields in TTGR */
+#define USART3_TG_OFFSET			0
+#define USART3_TG_SIZE				8
+
+/* Bitfields in FIDI */
+#define USART3_FI_DI_RATIO_OFFSET		0
+#define USART3_FI_DI_RATIO_SIZE			11
+
+/* Bitfields in NER */
+#define USART3_NB_ERRORS_OFFSET			0
+#define USART3_NB_ERRORS_SIZE			8
+
+/* Bitfields in XXR */
+#define USART3_XOFF_OFFSET			0
+#define USART3_XOFF_SIZE			8
+#define USART3_XON_OFFSET			8
+#define USART3_XON_SIZE				8
+
+/* Bitfields in IFR */
+#define USART3_IRDA_FILTER_OFFSET		0
+#define USART3_IRDA_FILTER_SIZE			8
+
+/* Bitfields in RCR */
+#define USART3_RXCTR_OFFSET			0
+#define USART3_RXCTR_SIZE			16
+
+/* Bitfields in TCR */
+#define USART3_TXCTR_OFFSET			0
+#define USART3_TXCTR_SIZE			16
+
+/* Bitfields in RNCR */
+#define USART3_RXNCR_OFFSET			0
+#define USART3_RXNCR_SIZE			16
+
+/* Bitfields in TNCR */
+#define USART3_TXNCR_OFFSET			0
+#define USART3_TXNCR_SIZE			16
+
+/* Bitfields in PTCR */
+#define USART3_RXTEN_OFFSET			0
+#define USART3_RXTEN_SIZE			1
+#define USART3_RXTDIS_OFFSET			1
+#define USART3_RXTDIS_SIZE			1
+#define USART3_TXTEN_OFFSET			8
+#define USART3_TXTEN_SIZE			1
+#define USART3_TXTDIS_OFFSET			9
+#define USART3_TXTDIS_SIZE			1
+
+/* Constants for USART_MODE */
+#define USART3_USART_MODE_NORMAL		0
+#define USART3_USART_MODE_RS485			1
+#define USART3_USART_MODE_HARDWARE		2
+#define USART3_USART_MODE_MODEM			3
+#define USART3_USART_MODE_ISO7816_T0		4
+#define USART3_USART_MODE_ISO7816_T1		6
+#define USART3_USART_MODE_IRDA			8
+
+/* Constants for USCLKS */
+#define USART3_USCLKS_MCK			0
+#define USART3_USCLKS_MCK_DIV			1
+#define USART3_USCLKS_SCK			3
+
+/* Constants for CHRL */
+#define USART3_CHRL_5				0
+#define USART3_CHRL_6				1
+#define USART3_CHRL_7				2
+#define USART3_CHRL_8				3
+
+/* Constants for PAR */
+#define USART3_PAR_EVEN				0
+#define USART3_PAR_ODD				1
+#define USART3_PAR_SPACE			2
+#define USART3_PAR_MARK				3
+#define USART3_PAR_NONE				4
+#define USART3_PAR_MULTI			6
+
+/* Constants for NBSTOP */
+#define USART3_NBSTOP_1				0
+#define USART3_NBSTOP_1_5			1
+#define USART3_NBSTOP_2				2
+
+/* Constants for CHMODE */
+#define USART3_CHMODE_NORMAL			0
+#define USART3_CHMODE_ECHO			1
+#define USART3_CHMODE_LOCAL_LOOP		2
+#define USART3_CHMODE_REMOTE_LOOP		3
+
+/* Constants for MSBF */
+#define USART3_MSBF_LSBF			0
+#define USART3_MSBF_MSBF			1
+
+/* Constants for OVER */
+#define USART3_OVER_X16				0
+#define USART3_OVER_X8				1
+
+/* Constants for CD */
+#define USART3_CD_DISABLE			0
+#define USART3_CD_BYPASS			1
+
+/* Constants for TO */
+#define USART3_TO_DISABLE			0
+
+/* Constants for TG */
+#define USART3_TG_DISABLE			0
+
+/* Constants for FI_DI_RATIO */
+#define USART3_FI_DI_RATIO_DISABLE		0
+
+/* Bit manipulation macros */
+#define USART3_BIT(name)				\
+	(1 << USART3_##name##_OFFSET)
+#define USART3_BF(name,value)				\
+	(((value) & ((1 << USART3_##name##_SIZE) - 1))	\
+	 << USART3_##name##_OFFSET)
+#define USART3_BFEXT(name,value)			\
+	(((value) >> USART3_##name##_OFFSET)		\
+	 & ((1 << USART3_##name##_SIZE) - 1))
+#define USART3_BFINS(name,value,old)			\
+	(((old) & ~(((1 << USART3_##name##_SIZE) - 1)	\
+		    << USART3_##name##_OFFSET))		\
+	 | USART3_BF(name,value))
+
+/* Register access macros */
+#define usart3_readl(port,reg)				\
+	readl((port)->regs + USART3_##reg)
+#define usart3_writel(port,reg,value)			\
+	writel((value), (port)->regs + USART3_##reg)
+
+#endif /* __DRIVERS_ATMEL_USART_H__ */

+ 241 - 0
drivers/fsl_i2c.c

@@ -0,0 +1,241 @@
+/*
+ * 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_I2C
+#ifdef CONFIG_HARD_I2C
+
+#include <command.h>
+#include <i2c.h>		/* Functional interface */
+
+#include <asm/io.h>
+#include <asm/fsl_i2c.h>	/* HW definitions */
+
+#define I2C_TIMEOUT	(CFG_HZ / 4)
+#define I2C		((struct fsl_i2c *)(CFG_IMMR + CFG_I2C_OFFSET))
+
+
+void
+i2c_init(int speed, int slaveadd)
+{
+	/* stop I2C controller */
+	writeb(0x0, &I2C->cr);
+
+	/* set clock */
+	writeb(0x3f, &I2C->fdr);
+
+	/* set default filter */
+	writeb(0x10, &I2C->dfsrr);
+
+	/* write slave address */
+	writeb(slaveadd, &I2C->adr);
+
+	/* clear status register */
+	writeb(0x0, &I2C->sr);
+
+	/* start I2C controller */
+	writeb(I2C_CR_MEN, &I2C->cr);
+}
+
+static __inline__ int
+i2c_wait4bus(void)
+{
+	ulong timeval = get_timer(0);
+
+	while (readb(&I2C->sr) & I2C_SR_MBB) {
+		if (get_timer(timeval) > I2C_TIMEOUT) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static __inline__ int
+i2c_wait(int write)
+{
+	u32 csr;
+	ulong timeval = get_timer(0);
+
+	do {
+		csr = readb(&I2C->sr);
+		if (!(csr & I2C_SR_MIF))
+			continue;
+
+		writeb(0x0, &I2C->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 && (csr & I2C_SR_RXAK)) {
+			debug("i2c_wait: No RXACK\n");
+			return -1;
+		}
+
+		return 0;
+	} while (get_timer (timeval) < I2C_TIMEOUT);
+
+	debug("i2c_wait: timed out\n");
+	return -1;
+}
+
+static __inline__ int
+i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
+	       | (rsta ? I2C_CR_RSTA : 0),
+	       &I2C->cr);
+
+	writeb((dev << 1) | dir, &I2C->dr);
+
+	if (i2c_wait(I2C_WRITE) < 0)
+		return 0;
+
+	return 1;
+}
+
+static __inline__ int
+__i2c_write(u8 *data, int length)
+{
+	int i;
+
+	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
+	       &I2C->cr);
+
+	for (i = 0; i < length; i++) {
+		writeb(data[i], &I2C->dr);
+
+		if (i2c_wait(I2C_WRITE) < 0)
+			break;
+	}
+
+	return i;
+}
+
+static __inline__ int
+__i2c_read(u8 *data, int length)
+{
+	int i;
+
+	writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
+	       &I2C->cr);
+
+	/* dummy read */
+	readb(&I2C->dr);
+
+	for (i = 0; i < length; i++) {
+		if (i2c_wait(I2C_READ) < 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->cr);
+
+		/* Generate stop on last byte */
+		if (i == length - 1)
+			writeb(I2C_CR_MEN | I2C_CR_TXAK, &I2C->cr);
+
+		data[i] = readb(&I2C->dr);
+	}
+
+	return i;
+}
+
+int
+i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+	int i = 0;
+	u8 *a = (u8*)&addr;
+
+	if (i2c_wait4bus() >= 0
+	    && i2c_write_addr(dev, I2C_WRITE, 0) != 0
+	    && __i2c_write(&a[4 - alen], alen) == alen
+	    && i2c_write_addr(dev, I2C_READ, 1) != 0) {
+		i = __i2c_read(data, length);
+	}
+
+	writeb(I2C_CR_MEN, &I2C->cr);
+
+	if (i == length)
+	    return 0;
+
+	return -1;
+}
+
+int
+i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+	int i = 0;
+	u8 *a = (u8*)&addr;
+
+	if (i2c_wait4bus() >= 0
+	    && i2c_write_addr(dev, I2C_WRITE, 0) != 0
+	    && __i2c_write(&a[4 - alen], alen) == alen) {
+		i = __i2c_write(data, length);
+	}
+
+	writeb(I2C_CR_MEN, &I2C->cr);
+
+	if (i == length)
+	    return 0;
+
+	return -1;
+}
+
+int
+i2c_probe(uchar chip)
+{
+	int tmp;
+
+	/*
+	 * Try to read the first location of the chip.  The underlying
+	 * driver doesn't appear to support sending just the chip address
+	 * and looking for an <ACK> back.
+	 */
+	udelay(10000);
+
+	return i2c_read(chip, 0, 1, (uchar *)&tmp, 1);
+}
+
+uchar
+i2c_reg_read(uchar i2c_addr, uchar reg)
+{
+	uchar buf[1];
+
+	i2c_read(i2c_addr, reg, 1, buf, 1);
+
+	return buf[0];
+}
+
+void
+i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+{
+	i2c_write(i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
+#endif /* CONFIG_FSL_I2C */

+ 2 - 1
drivers/pci_auto.c

@@ -102,7 +102,8 @@ void pciauto_setup_device(struct pci_controller *hose,
 
 		/* Check the BAR type and set our address mask */
 		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
-			bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+			bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
+				   & 0xffff) + 1;
 			bar_res = io;
 
 			DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);

+ 1 - 0
drivers/rtl8139.c

@@ -196,6 +196,7 @@ static void rtl_disable(struct eth_device *dev);
 
 static struct pci_device_id supported[] = {
        {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
+       {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139},
        {}
 };
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 346 - 262
drivers/tsec.c


+ 36 - 1
drivers/tsec.h

@@ -27,7 +27,7 @@
 #define TSEC_SIZE	0x01000
 
 /* FIXME:  Should these be pushed back to 83xx and 85xx config files? */
-#if defined(CONFIG_MPC85xx)
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
     #define TSEC_BASE_ADDR	(CFG_IMMR + CFG_TSEC1_OFFSET)
 #elif defined(CONFIG_MPC83XX)
     #define TSEC_BASE_ADDR	(CFG_IMMRBAR + CFG_TSEC1_OFFSET)
@@ -133,6 +133,24 @@
 #define MIIM_GBIT_CON		0x09
 #define MIIM_GBIT_CON_ADVERT	0x0e00
 
+/* Entry for Vitesse VSC8244 regs starts here */
+/* Vitesse VSC8244 Auxiliary Control/Status Register */
+#define MIIM_VSC8244_AUX_CONSTAT        0x1c
+#define MIIM_VSC8244_AUXCONSTAT_INIT    0x0000
+#define MIIM_VSC8244_AUXCONSTAT_DUPLEX  0x0020
+#define MIIM_VSC8244_AUXCONSTAT_SPEED   0x0018
+#define MIIM_VSC8244_AUXCONSTAT_GBIT    0x0010
+#define MIIM_VSC8244_AUXCONSTAT_100     0x0008
+#define MIIM_CONTROL_INIT_LOOPBACK      0x4000
+
+/* Vitesse VSC8244 Extended PHY Control Register 1 */
+#define MIIM_VSC8244_EPHY_CON           0x17
+#define MIIM_VSC8244_EPHYCON_INIT       0x0006
+
+/* Vitesse VSC8244 Serial LED Control Register */
+#define MIIM_VSC8244_LED_CON            0x1b
+#define MIIM_VSC8244_LEDCON_INIT        0xF011
+
 /* 88E1011 PHY Status Register */
 #define MIIM_88E1011_PHY_STATUS         0x11
 #define MIIM_88E1011_PHYSTAT_SPEED      0xc000
@@ -142,6 +160,23 @@
 #define MIIM_88E1011_PHYSTAT_SPDDONE	0x0800
 #define MIIM_88E1011_PHYSTAT_LINK	0x0400
 
+#define MIIM_88E1011_PHY_SCR		0x10
+#define MIIM_88E1011_PHY_MDI_X_AUTO	0x0060
+
+/* 88E1111 PHY LED Control Register */
+#define MIIM_88E1111_PHY_LED_CONTROL   24
+#define MIIM_88E1111_PHY_LED_DIRECT    0x4100
+#define MIIM_88E1111_PHY_LED_COMBINE   0x411C
+
+/* 88E1145 Extended PHY Specific Control Register */
+#define MIIM_88E1145_PHY_EXT_CR 20
+#define MIIM_M88E1145_RGMII_RX_DELAY	0x0080
+#define MIIM_M88E1145_RGMII_TX_DELAY	0x0002
+
+#define MIIM_88E1145_PHY_PAGE   29
+#define MIIM_88E1145_PHY_CAL_OV 30
+
+
 /* DM9161 Control register values */
 #define MIIM_DM9161_CR_STOP	0x0400
 #define MIIM_DM9161_CR_RSTAN	0x1200

+ 34 - 16
examples/Makefile

@@ -57,53 +57,66 @@ ifeq ($(ARCH),blackfin)
 LOAD_ADDR = 0x1000
 endif
 
+ifeq ($(ARCH),avr32)
+LOAD_ADDR = 0x00000000
+endif
+
 include $(TOPDIR)/config.mk
 
+ELF	= hello_world
 SREC	= hello_world.srec
-BIN	= hello_world.bin hello_world
+BIN	= hello_world.bin
 
 ifeq ($(CPU),mpc8xx)
+ELF	= test_burst
 SREC	= test_burst.srec
-BIN	= test_burst.bin test_burst
+BIN	= test_burst.bin
 endif
 
 ifeq ($(ARCH),i386)
-SREC   += 82559_eeprom.srec
-BIN    += 82559_eeprom.bin 82559_eeprom
+ELF	+= 82559_eeprom
+SREC	+= 82559_eeprom.srec
+BIN	+= 82559_eeprom.bin
 endif
 
 ifeq ($(ARCH),ppc)
-SREC   += sched.srec
-BIN    += sched.bin sched
+ELF	+= sched
+SREC	+= sched.srec
+BIN	+= sched.bin
 endif
 
 ifeq ($(ARCH),blackfin)
+ELF	+= smc91111_eeprom
 SREC	+= smc91111_eeprom.srec
-BIN 	+= smc91111_eeprom.bin smc91111_eeprom
+BIN 	+= smc91111_eeprom.bin
 endif
 
 # The following example is pretty 8xx specific...
 ifeq ($(CPU),mpc8xx)
-SREC   += timer.srec
-BIN    += timer.bin timer
+ELF	+= timer
+SREC	+= timer.srec
+BIN	+= timer.bin
 endif
 
 # The following example is 8260 specific...
 ifeq ($(CPU),mpc8260)
-SREC   += mem_to_mem_idma2intr.srec
-BIN    += mem_to_mem_idma2intr.bin mem_to_mem_idma2intr
+ELF	+= mem_to_mem_idma2intr
+SREC	+= mem_to_mem_idma2intr.srec
+BIN	+= mem_to_mem_idma2intr.bin
 endif
 
 # Demo for 52xx IRQs
 ifeq ($(CPU),mpc5xxx)
-SREC   += interrupt.srec
-BIN    += interrupt.bin interrupt
+ELF	+= interrupt
+SREC	+= interrupt.srec
+BIN	+= interrupt.bin
 endif
 
 # Utility for resetting i82559 EEPROM
 ifeq ($(BOARD),oxc)
-SREC   += eepro100_eeprom.srec
-BIN    += eepro100_eeprom.bin eepro100_eeprom
+ELF	+= eepro100_eeprom
+SREC	+= eepro100_eeprom.srec
+BIN	+= eepro100_eeprom.bin
 endif
 
 ifeq ($(BIG_ENDIAN),y)
@@ -126,6 +139,7 @@ LIBOBJS	= $(addprefix $(obj),$(LIBAOBJS) $(LIBCOBJS))
 
 SRCS	:= $(COBJS:.o=.c) $(LIBCOBJS:.o=.c) $(if $(LIBAOBJS),$(LIBAOBJS:.o=.S))
 OBJS	:= $(addprefix $(obj),$(COBJS))
+ELF	:= $(addprefix $(obj),$(ELF))
 BIN	:= $(addprefix $(obj),$(BIN))
 SREC	:= $(addprefix $(obj),$(SREC))
 
@@ -134,19 +148,23 @@ clibdir := $(shell dirname `$(CC) $(CFLAGS) -print-file-name=libc.a`)
 
 CPPFLAGS += -I..
 
-all:	$(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN)
+all:	$(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF)
 
 #########################################################################
 $(LIB):	$(obj).depend $(LIBOBJS)
 		$(AR) $(ARFLAGS) $@ $(LIBOBJS)
 
+$(ELF):
 $(obj)%:	$(obj)%.o $(LIB)
 		$(LD) -g $(EX_LDFLAGS) -Ttext $(LOAD_ADDR) \
 			-o $@ -e $(notdir $(<:.o=)) $< $(LIB) \
 			-L$(gcclibdir) -lgcc
+
+$(SREC):
 $(obj)%.srec:	$(obj)%
 		$(OBJCOPY) -O srec $< $@ 2>/dev/null
 
+$(BIN):
 $(obj)%.bin:	$(obj)%
 		$(OBJCOPY) -O binary $< $@ 2>/dev/null
 

+ 13 - 0
examples/stubs.c

@@ -138,6 +138,19 @@ gd_t *global_data;
 "	P0 = [P0 + %1]\n"		\
 "	JUMP (P0)\n"			\
 	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0");
+#elif defined(CONFIG_AVR32)
+/*
+ * r6 holds the pointer to the global_data. r8 is call clobbered.
+ */
+#define EXPORT_FUNC(x)					\
+	asm volatile(					\
+		"	.globl\t" #x "\n"		\
+		#x ":\n"				\
+		"	ld.w	r8, r6[%0]\n"		\
+		"	ld.w	pc, r8[%1]\n"		\
+		:					\
+		: "i"(offsetof(gd_t, jt)), "i"(XF_ ##x)	\
+		: "r8");
 #else
 #error stubs definition missing for this architecture
 #endif

+ 190 - 0
include/ahci.h

@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ * Author: Jason Jin<Jason.jin@freescale.com>
+ *         Zhang Wei<wei.zhang@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef _AHCI_H_
+#define _AHCI_H_
+
+#define AHCI_PCI_BAR		0x24
+#define AHCI_MAX_SG		56 /* hardware max is 64K */
+#define AHCI_CMD_SLOT_SZ	32
+#define AHCI_RX_FIS_SZ		256
+#define AHCI_CMD_TBL_HDR	0x80
+#define AHCI_CMD_TBL_CDB	0x40
+#define AHCI_CMD_TBL_SZ		AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
+#define AHCI_PORT_PRIV_DMA_SZ	AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ	\
+				+ AHCI_RX_FIS_SZ
+#define AHCI_CMD_ATAPI		(1 << 5)
+#define AHCI_CMD_WRITE		(1 << 6)
+#define AHCI_CMD_PREFETCH	(1 << 7)
+#define AHCI_CMD_RESET		(1 << 8)
+#define AHCI_CMD_CLR_BUSY	(1 << 10)
+
+#define RX_FIS_D2H_REG		0x40	/* offset of D2H Register FIS data */
+
+/* Global controller registers */
+#define HOST_CAP		0x00 /* host capabilities */
+#define HOST_CTL		0x04 /* global host control */
+#define HOST_IRQ_STAT		0x08 /* interrupt status */
+#define HOST_PORTS_IMPL		0x0c /* bitmap of implemented ports */
+#define HOST_VERSION		0x10 /* AHCI spec. version compliancy */
+
+/* HOST_CTL bits */
+#define HOST_RESET		(1 << 0)  /* reset controller; self-clear */
+#define HOST_IRQ_EN		(1 << 1)  /* global IRQ enable */
+#define HOST_AHCI_EN		(1 << 31) /* AHCI enabled */
+
+/* Registers for each SATA port */
+#define PORT_LST_ADDR		0x00 /* command list DMA addr */
+#define PORT_LST_ADDR_HI	0x04 /* command list DMA addr hi */
+#define PORT_FIS_ADDR		0x08 /* FIS rx buf addr */
+#define PORT_FIS_ADDR_HI	0x0c /* FIS rx buf addr hi */
+#define PORT_IRQ_STAT		0x10 /* interrupt status */
+#define PORT_IRQ_MASK		0x14 /* interrupt enable/disable mask */
+#define PORT_CMD		0x18 /* port command */
+#define PORT_TFDATA		0x20 /* taskfile data */
+#define PORT_SIG		0x24 /* device TF signature */
+#define PORT_CMD_ISSUE		0x38 /* command issue */
+#define PORT_SCR		0x28 /* SATA phy register block */
+#define PORT_SCR_STAT		0x28 /* SATA phy register: SStatus */
+#define PORT_SCR_CTL		0x2c /* SATA phy register: SControl */
+#define PORT_SCR_ERR		0x30 /* SATA phy register: SError */
+#define PORT_SCR_ACT		0x34 /* SATA phy register: SActive */
+
+/* PORT_IRQ_{STAT,MASK} bits */
+#define PORT_IRQ_COLD_PRES	(1 << 31) /* cold presence detect */
+#define PORT_IRQ_TF_ERR		(1 << 30) /* task file error */
+#define PORT_IRQ_HBUS_ERR	(1 << 29) /* host bus fatal error */
+#define PORT_IRQ_HBUS_DATA_ERR	(1 << 28) /* host bus data error */
+#define PORT_IRQ_IF_ERR		(1 << 27) /* interface fatal error */
+#define PORT_IRQ_IF_NONFATAL	(1 << 26) /* interface non-fatal error */
+#define PORT_IRQ_OVERFLOW	(1 << 24) /* xfer exhausted available S/G */
+#define PORT_IRQ_BAD_PMP	(1 << 23) /* incorrect port multiplier */
+
+#define PORT_IRQ_PHYRDY		(1 << 22) /* PhyRdy changed */
+#define PORT_IRQ_DEV_ILCK	(1 << 7) /* device interlock */
+#define PORT_IRQ_CONNECT	(1 << 6) /* port connect change status */
+#define PORT_IRQ_SG_DONE	(1 << 5) /* descriptor processed */
+#define PORT_IRQ_UNK_FIS	(1 << 4) /* unknown FIS rx'd */
+#define PORT_IRQ_SDB_FIS	(1 << 3) /* Set Device Bits FIS rx'd */
+#define PORT_IRQ_DMAS_FIS	(1 << 2) /* DMA Setup FIS rx'd */
+#define PORT_IRQ_PIOS_FIS	(1 << 1) /* PIO Setup FIS rx'd */
+#define PORT_IRQ_D2H_REG_FIS	(1 << 0) /* D2H Register FIS rx'd */
+
+#define PORT_IRQ_FATAL		PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR 	\
+				| PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR
+
+#define DEF_PORT_IRQ		PORT_IRQ_FATAL | PORT_IRQ_PHYRDY 	\
+				| PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE 	\
+				| PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS 	\
+				| PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS	\
+				| PORT_IRQ_D2H_REG_FIS
+
+/* PORT_CMD bits */
+#define PORT_CMD_ATAPI		(1 << 24) /* Device is ATAPI */
+#define PORT_CMD_LIST_ON	(1 << 15) /* cmd list DMA engine running */
+#define PORT_CMD_FIS_ON		(1 << 14) /* FIS DMA engine running */
+#define PORT_CMD_FIS_RX		(1 << 4) /* Enable FIS receive DMA engine */
+#define PORT_CMD_CLO		(1 << 3) /* Command list override */
+#define PORT_CMD_POWER_ON	(1 << 2) /* Power up device */
+#define PORT_CMD_SPIN_UP	(1 << 1) /* Spin up device */
+#define PORT_CMD_START		(1 << 0) /* Enable port DMA engine */
+
+#define PORT_CMD_ICC_ACTIVE	(0x1 << 28) /* Put i/f in active state */
+#define PORT_CMD_ICC_PARTIAL	(0x2 << 28) /* Put i/f in partial state */
+#define PORT_CMD_ICC_SLUMBER	(0x6 << 28) /* Put i/f in slumber state */
+
+#define AHCI_MAX_PORTS		32
+
+/* SETFEATURES stuff */
+#define SETFEATURES_XFER	0x03
+#define XFER_UDMA_7		0x47
+#define XFER_UDMA_6		0x46
+#define XFER_UDMA_5		0x45
+#define XFER_UDMA_4		0x44
+#define XFER_UDMA_3		0x43
+#define XFER_UDMA_2		0x42
+#define XFER_UDMA_1		0x41
+#define XFER_UDMA_0		0x40
+#define XFER_MW_DMA_2		0x22
+#define XFER_MW_DMA_1		0x21
+#define XFER_MW_DMA_0		0x20
+#define XFER_SW_DMA_2		0x12
+#define XFER_SW_DMA_1		0x11
+#define XFER_SW_DMA_0		0x10
+#define XFER_PIO_4		0x0C
+#define XFER_PIO_3		0x0B
+#define XFER_PIO_2		0x0A
+#define XFER_PIO_1		0x09
+#define XFER_PIO_0		0x08
+#define XFER_PIO_SLOW		0x00
+
+#define ATA_FLAG_SATA		(1 << 3)
+#define ATA_FLAG_NO_LEGACY	(1 << 4) /* no legacy mode check */
+#define ATA_FLAG_MMIO		(1 << 6) /* use MMIO, not PIO */
+#define ATA_FLAG_SATA_RESET	(1 << 7) /* (obsolete) use COMRESET */
+#define ATA_FLAG_PIO_DMA	(1 << 8) /* PIO cmds via DMA */
+#define ATA_FLAG_NO_ATAPI	(1 << 11) /* No ATAPI support */
+
+struct ahci_cmd_hdr {
+	u32	opts;
+	u32	status;
+	u32	tbl_addr;
+	u32	tbl_addr_hi;
+	u32	reserved[4];
+};
+
+struct ahci_sg {
+	u32	addr;
+	u32	addr_hi;
+	u32	reserved;
+	u32	flags_size;
+};
+
+struct ahci_ioports {
+	u32	cmd_addr;
+	u32	scr_addr;
+	u32	port_mmio;
+	struct ahci_cmd_hdr	*cmd_slot;
+	struct ahci_sg		*cmd_tbl_sg;
+	u32	cmd_tbl;
+	u32	rx_fis;
+};
+
+struct ahci_probe_ent {
+	pci_dev_t 	dev;
+	struct ahci_ioports	port[AHCI_MAX_PORTS];
+	u32	n_ports;
+	u32	hard_port_no;
+	u32	host_flags;
+	u32	host_set_flags;
+	u32	mmio_base;
+	u32     pio_mask;
+	u32	udma_mask;
+	u32	flags;
+	u32	cap;	/* cache of HOST_CAP register */
+	u32	port_map; /* cache of HOST_PORTS_IMPL reg */
+	u32	link_port_map; /*linkup port map*/
+};
+
+#endif

+ 46 - 0
include/asm-avr32/addrspace.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_ADDRSPACE_H
+#define __ASM_AVR32_ADDRSPACE_H
+
+/* Memory segments when segmentation is enabled */
+#define P0SEG		0x00000000
+#define P1SEG		0x80000000
+#define P2SEG		0xa0000000
+#define P3SEG		0xc0000000
+#define P4SEG		0xe0000000
+
+/* Returns the privileged segment base of a given address */
+#define PXSEG(a)	(((unsigned long)(a)) & 0xe0000000)
+
+/* Returns the physical address of a PnSEG (n=1,2) address */
+#define PHYSADDR(a)	(((unsigned long)(a)) & 0x1fffffff)
+
+/*
+ * Map an address to a certain privileged segment
+ */
+#define P1SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P1SEG))
+#define P2SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P2SEG))
+#define P3SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
+#define P4SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
+
+#endif /* __ASM_AVR32_ADDRSPACE_H */

+ 232 - 0
include/asm-avr32/arch-at32ap7000/hmatrix2.h

@@ -0,0 +1,232 @@
+/*
+ * Register definition for the High-speed Bus Matrix
+ */
+#ifndef __ASM_AVR32_HMATRIX2_H__
+#define __ASM_AVR32_HMATRIX2_H__
+
+/* HMATRIX2 register offsets */
+#define HMATRIX2_MCFG0				0x0000
+#define HMATRIX2_MCFG1				0x0004
+#define HMATRIX2_MCFG2				0x0008
+#define HMATRIX2_MCFG3				0x000c
+#define HMATRIX2_MCFG4				0x0010
+#define HMATRIX2_MCFG5				0x0014
+#define HMATRIX2_MCFG6				0x0018
+#define HMATRIX2_MCFG7				0x001c
+#define HMATRIX2_MCFG8				0x0020
+#define HMATRIX2_MCFG9				0x0024
+#define HMATRIX2_MCFG10				0x0028
+#define HMATRIX2_MCFG11				0x002c
+#define HMATRIX2_MCFG12				0x0030
+#define HMATRIX2_MCFG13				0x0034
+#define HMATRIX2_MCFG14				0x0038
+#define HMATRIX2_MCFG15				0x003c
+#define HMATRIX2_SCFG0				0x0040
+#define HMATRIX2_SCFG1				0x0044
+#define HMATRIX2_SCFG2				0x0048
+#define HMATRIX2_SCFG3				0x004c
+#define HMATRIX2_SCFG4				0x0050
+#define HMATRIX2_SCFG5				0x0054
+#define HMATRIX2_SCFG6				0x0058
+#define HMATRIX2_SCFG7				0x005c
+#define HMATRIX2_SCFG8				0x0060
+#define HMATRIX2_SCFG9				0x0064
+#define HMATRIX2_SCFG10				0x0068
+#define HMATRIX2_SCFG11				0x006c
+#define HMATRIX2_SCFG12				0x0070
+#define HMATRIX2_SCFG13				0x0074
+#define HMATRIX2_SCFG14				0x0078
+#define HMATRIX2_SCFG15				0x007c
+#define HMATRIX2_PRAS0				0x0080
+#define HMATRIX2_PRBS0				0x0084
+#define HMATRIX2_PRAS1				0x0088
+#define HMATRIX2_PRBS1				0x008c
+#define HMATRIX2_PRAS2				0x0090
+#define HMATRIX2_PRBS2				0x0094
+#define HMATRIX2_PRAS3				0x0098
+#define HMATRIX2_PRBS3				0x009c
+#define HMATRIX2_PRAS4				0x00a0
+#define HMATRIX2_PRBS4				0x00a4
+#define HMATRIX2_PRAS5				0x00a8
+#define HMATRIX2_PRBS5				0x00ac
+#define HMATRIX2_PRAS6				0x00b0
+#define HMATRIX2_PRBS6				0x00b4
+#define HMATRIX2_PRAS7				0x00b8
+#define HMATRIX2_PRBS7				0x00bc
+#define HMATRIX2_PRAS8				0x00c0
+#define HMATRIX2_PRBS8				0x00c4
+#define HMATRIX2_PRAS9				0x00c8
+#define HMATRIX2_PRBS9				0x00cc
+#define HMATRIX2_PRAS10				0x00d0
+#define HMATRIX2_PRBS10				0x00d4
+#define HMATRIX2_PRAS11				0x00d8
+#define HMATRIX2_PRBS11				0x00dc
+#define HMATRIX2_PRAS12				0x00e0
+#define HMATRIX2_PRBS12				0x00e4
+#define HMATRIX2_PRAS13				0x00e8
+#define HMATRIX2_PRBS13				0x00ec
+#define HMATRIX2_PRAS14				0x00f0
+#define HMATRIX2_PRBS14				0x00f4
+#define HMATRIX2_PRAS15				0x00f8
+#define HMATRIX2_PRBS15				0x00fc
+#define HMATRIX2_MRCR				0x0100
+#define HMATRIX2_SFR0				0x0110
+#define HMATRIX2_SFR1				0x0114
+#define HMATRIX2_SFR2				0x0118
+#define HMATRIX2_SFR3				0x011c
+#define HMATRIX2_SFR4				0x0120
+#define HMATRIX2_SFR5				0x0124
+#define HMATRIX2_SFR6				0x0128
+#define HMATRIX2_SFR7				0x012c
+#define HMATRIX2_SFR8				0x0130
+#define HMATRIX2_SFR9				0x0134
+#define HMATRIX2_SFR10				0x0138
+#define HMATRIX2_SFR11				0x013c
+#define HMATRIX2_SFR12				0x0140
+#define HMATRIX2_SFR13				0x0144
+#define HMATRIX2_SFR14				0x0148
+#define HMATRIX2_SFR15				0x014c
+#define HMATRIX2_VERSION			0x01fc
+
+/* Bitfields in MCFG0 */
+#define HMATRIX2_ULBT_OFFSET			0
+#define HMATRIX2_ULBT_SIZE			3
+
+/* Bitfields in SCFG0 */
+#define HMATRIX2_SLOT_CYCLE_OFFSET		0
+#define HMATRIX2_SLOT_CYCLE_SIZE		8
+#define HMATRIX2_DEFMSTR_TYPE_OFFSET		16
+#define HMATRIX2_DEFMSTR_TYPE_SIZE		2
+#define HMATRIX2_FIXED_DEFMSTR_OFFSET		18
+#define HMATRIX2_FIXED_DEFMSTR_SIZE		4
+#define HMATRIX2_ARBT_OFFSET			24
+#define HMATRIX2_ARBT_SIZE			2
+
+/* Bitfields in PRAS0 */
+#define HMATRIX2_M0PR_OFFSET			0
+#define HMATRIX2_M0PR_SIZE			4
+#define HMATRIX2_M1PR_OFFSET			4
+#define HMATRIX2_M1PR_SIZE			4
+#define HMATRIX2_M2PR_OFFSET			8
+#define HMATRIX2_M2PR_SIZE			4
+#define HMATRIX2_M3PR_OFFSET			12
+#define HMATRIX2_M3PR_SIZE			4
+#define HMATRIX2_M4PR_OFFSET			16
+#define HMATRIX2_M4PR_SIZE			4
+#define HMATRIX2_M5PR_OFFSET			20
+#define HMATRIX2_M5PR_SIZE			4
+#define HMATRIX2_M6PR_OFFSET			24
+#define HMATRIX2_M6PR_SIZE			4
+#define HMATRIX2_M7PR_OFFSET			28
+#define HMATRIX2_M7PR_SIZE			4
+
+/* Bitfields in PRBS0 */
+#define HMATRIX2_M8PR_OFFSET			0
+#define HMATRIX2_M8PR_SIZE			4
+#define HMATRIX2_M9PR_OFFSET			4
+#define HMATRIX2_M9PR_SIZE			4
+#define HMATRIX2_M10PR_OFFSET			8
+#define HMATRIX2_M10PR_SIZE			4
+#define HMATRIX2_M11PR_OFFSET			12
+#define HMATRIX2_M11PR_SIZE			4
+#define HMATRIX2_M12PR_OFFSET			16
+#define HMATRIX2_M12PR_SIZE			4
+#define HMATRIX2_M13PR_OFFSET			20
+#define HMATRIX2_M13PR_SIZE			4
+#define HMATRIX2_M14PR_OFFSET			24
+#define HMATRIX2_M14PR_SIZE			4
+#define HMATRIX2_M15PR_OFFSET			28
+#define HMATRIX2_M15PR_SIZE			4
+
+/* Bitfields in MRCR */
+#define HMATRIX2_RBC0_OFFSET			0
+#define HMATRIX2_RBC0_SIZE			1
+#define HMATRIX2_RBC1_OFFSET			1
+#define HMATRIX2_RBC1_SIZE			1
+#define HMATRIX2_RBC2_OFFSET			2
+#define HMATRIX2_RBC2_SIZE			1
+#define HMATRIX2_RBC3_OFFSET			3
+#define HMATRIX2_RBC3_SIZE			1
+#define HMATRIX2_RBC4_OFFSET			4
+#define HMATRIX2_RBC4_SIZE			1
+#define HMATRIX2_RBC5_OFFSET			5
+#define HMATRIX2_RBC5_SIZE			1
+#define HMATRIX2_RBC6_OFFSET			6
+#define HMATRIX2_RBC6_SIZE			1
+#define HMATRIX2_RBC7_OFFSET			7
+#define HMATRIX2_RBC7_SIZE			1
+#define HMATRIX2_RBC8_OFFSET			8
+#define HMATRIX2_RBC8_SIZE			1
+#define HMATRIX2_RBC9_OFFSET			9
+#define HMATRIX2_RBC9_SIZE			1
+#define HMATRIX2_RBC10_OFFSET			10
+#define HMATRIX2_RBC10_SIZE			1
+#define HMATRIX2_RBC11_OFFSET			11
+#define HMATRIX2_RBC11_SIZE			1
+#define HMATRIX2_RBC12_OFFSET			12
+#define HMATRIX2_RBC12_SIZE			1
+#define HMATRIX2_RBC13_OFFSET			13
+#define HMATRIX2_RBC13_SIZE			1
+#define HMATRIX2_RBC14_OFFSET			14
+#define HMATRIX2_RBC14_SIZE			1
+#define HMATRIX2_RBC15_OFFSET			15
+#define HMATRIX2_RBC15_SIZE			1
+
+/* Bitfields in SFR0 */
+#define HMATRIX2_SFR_OFFSET			0
+#define HMATRIX2_SFR_SIZE			32
+
+/* Bitfields in SFR4 */
+#define HMATRIX2_CS1A_OFFSET			1
+#define HMATRIX2_CS1A_SIZE			1
+#define HMATRIX2_CS3A_OFFSET			3
+#define HMATRIX2_CS3A_SIZE			1
+#define HMATRIX2_CS4A_OFFSET			4
+#define HMATRIX2_CS4A_SIZE			1
+#define HMATRIX2_CS5A_OFFSET			5
+#define HMATRIX2_CS5A_SIZE			1
+#define HMATRIX2_DBPUC_OFFSET			8
+#define HMATRIX2_DBPUC_SIZE			1
+
+/* Bitfields in VERSION */
+#define HMATRIX2_VERSION_OFFSET			0
+#define HMATRIX2_VERSION_SIZE			12
+#define HMATRIX2_MFN_OFFSET			16
+#define HMATRIX2_MFN_SIZE			3
+
+/* Constants for ULBT */
+#define HMATRIX2_ULBT_INFINITE			0
+#define HMATRIX2_ULBT_SINGLE			1
+#define HMATRIX2_ULBT_FOUR_BEAT			2
+#define HMATRIX2_ULBT_SIXTEEN_BEAT		4
+
+/* Constants for DEFMSTR_TYPE */
+#define HMATRIX2_DEFMSTR_TYPE_NO_DEFAULT	0
+#define HMATRIX2_DEFMSTR_TYPE_LAST_DEFAULT	1
+#define HMATRIX2_DEFMSTR_TYPE_FIXED_DEFAULT	2
+
+/* Constants for ARBT */
+#define HMATRIX2_ARBT_ROUND_ROBIN		0
+#define HMATRIX2_ARBT_FIXED_PRIORITY		1
+
+/* Bit manipulation macros */
+#define HMATRIX2_BIT(name)					\
+	(1 << HMATRIX2_##name##_OFFSET)
+#define HMATRIX2_BF(name,value)					\
+	(((value) & ((1 << HMATRIX2_##name##_SIZE) - 1))	\
+	 << HMATRIX2_##name##_OFFSET)
+#define HMATRIX2_BFEXT(name,value)				\
+	(((value) >> HMATRIX2_##name##_OFFSET)			\
+	 & ((1 << HMATRIX2_##name##_SIZE) - 1))
+#define HMATRIX2_BFINS(name,value,old)				\
+	(((old) & ~(((1 << HMATRIX2_##name##_SIZE) - 1)		\
+		    << HMATRIX2_##name##_OFFSET))		\
+	 | HMATRIX2_BF(name,value))
+
+/* Register access macros */
+#define hmatrix2_readl(port,reg)				\
+	readl((port)->regs + HMATRIX2_##reg)
+#define hmatrix2_writel(port,reg,value)				\
+	writel((value), (port)->regs + HMATRIX2_##reg)
+
+#endif /* __ASM_AVR32_HMATRIX2_H__ */

+ 61 - 0
include/asm-avr32/arch-at32ap7000/memory-map.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_PART_MEMORY_MAP_H__
+#define __ASM_AVR32_PART_MEMORY_MAP_H__
+
+#define AUDIOC_BASE                             0xFFF02800
+#define DAC_BASE                                0xFFF02000
+#define DMAC_BASE                               0xFF200000
+#define ECC_BASE                                0xFFF03C00
+#define HISI_BASE                               0xFFF02C00
+#define HMATRIX_BASE                            0xFFF00800
+#define HSDRAMC_BASE                            0xFFF03800
+#define HSMC_BASE                               0xFFF03400
+#define LCDC_BASE                               0xFF000000
+#define MACB0_BASE                              0xFFF01800
+#define MACB1_BASE                              0xFFF01C00
+#define MMCI_BASE                               0xFFF02400
+#define PIOA_BASE                               0xFFE02800
+#define PIOB_BASE                               0xFFE02C00
+#define PIOC_BASE                               0xFFE03000
+#define PIOD_BASE                               0xFFE03400
+#define PIOE_BASE                               0xFFE03800
+#define PSIF_BASE                               0xFFE03C00
+#define PWM_BASE                                0xFFF01400
+#define SM_BASE                                 0xFFF00000
+#define INTC_BASE				0XFFF00400
+#define SPI0_BASE                               0xFFE00000
+#define SPI1_BASE                               0xFFE00400
+#define SSC0_BASE                               0xFFE01C00
+#define SSC1_BASE                               0xFFE02000
+#define SSC2_BASE                               0xFFE02400
+#define TIMER0_BASE                             0xFFF00C00
+#define TIMER1_BASE                             0xFFF01000
+#define TWI_BASE                                0xFFE00800
+#define USART0_BASE                             0xFFE00C00
+#define USART1_BASE                             0xFFE01000
+#define USART2_BASE                             0xFFE01400
+#define USART3_BASE                             0xFFE01800
+#define USB_FIFO                                0xFF300000
+#define USB_BASE                                0xFFF03000
+
+#endif /* __ASM_AVR32_PART_MEMORY_MAP_H__ */

+ 146 - 0
include/asm-avr32/arch-at32ap7000/platform.h

@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _ASM_AVR32_ARCH_PM_H
+#define _ASM_AVR32_ARCH_PM_H
+
+#include <config.h>
+
+enum clock_domain_id {
+	CLOCK_CPU,
+	CLOCK_HSB,
+	CLOCK_PBA,
+	CLOCK_PBB,
+	NR_CLOCK_DOMAINS,
+};
+
+enum resource_type {
+	RESOURCE_GPIO,
+	RESOURCE_CLOCK,
+};
+
+enum gpio_func {
+	GPIO_FUNC_GPIO,
+	GPIO_FUNC_A,
+	GPIO_FUNC_B,
+};
+
+enum device_id {
+	DEVICE_HEBI,
+	DEVICE_PBA_BRIDGE,
+	DEVICE_PBB_BRIDGE,
+	DEVICE_HRAMC,
+	/* GPIO controllers must be kept together */
+	DEVICE_PIOA,
+	DEVICE_PIOB,
+	DEVICE_PIOC,
+	DEVICE_PIOD,
+	DEVICE_PIOE,
+	DEVICE_SM,
+	DEVICE_INTC,
+	DEVICE_HMATRIX,
+#if defined(CFG_HPDC)
+	DEVICE_HPDC,
+#endif
+#if defined(CFG_MACB0)
+	DEVICE_MACB0,
+#endif
+#if defined(CFG_MACB1)
+	DEVICE_MACB1,
+#endif
+#if defined(CFG_LCDC)
+	DEVICE_LCDC,
+#endif
+#if defined(CFG_USART0)
+	DEVICE_USART0,
+#endif
+#if defined(CFG_USART1)
+	DEVICE_USART1,
+#endif
+#if defined(CFG_USART2)
+	DEVICE_USART2,
+#endif
+#if defined(CFG_USART3)
+	DEVICE_USART3,
+#endif
+#if defined(CFG_MMCI)
+	DEVICE_MMCI,
+#endif
+#if defined(CFG_DMAC)
+	DEVICE_DMAC,
+#endif
+	NR_DEVICES,
+	NO_DEVICE = -1,
+};
+
+struct resource {
+	enum resource_type type;
+	union {
+		struct {
+			unsigned long base;
+		} iomem;
+		struct {
+			unsigned char nr_pins;
+			enum device_id gpio_dev;
+			enum gpio_func func;
+			unsigned short start;
+		} gpio;
+		struct {
+			enum clock_domain_id id;
+			unsigned char index;
+		} clock;
+	} u;
+};
+
+struct device {
+	void *regs;
+	unsigned int nr_resources;
+	const struct resource *resource;
+};
+
+struct clock_domain {
+	unsigned short reg;
+	enum clock_domain_id id;
+	enum device_id bridge;
+};
+
+extern const struct device chip_device[NR_DEVICES];
+extern const struct clock_domain chip_clock[NR_CLOCK_DOMAINS];
+
+/**
+ * Set up PIO, clock management and I/O memory for a device.
+ */
+const struct device *get_device(enum device_id devid);
+void put_device(const struct device *dev);
+
+int gpio_set_func(enum device_id gpio_devid, unsigned int start,
+		  unsigned int nr_pins, enum gpio_func func);
+void gpio_free(enum device_id gpio_devid, unsigned int start,
+	       unsigned int nr_pins);
+
+void pm_init(void);
+int pm_enable_clock(enum clock_domain_id id, unsigned int index);
+void pm_disable_clock(enum clock_domain_id id, unsigned int index);
+unsigned long pm_get_clock_freq(enum clock_domain_id domain);
+
+void cpu_enable_sdram(void);
+
+#endif /* _ASM_AVR32_ARCH_PM_H */

+ 25 - 0
include/asm-avr32/bitops.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_BITOPS_H
+#define __ASM_AVR32_BITOPS_H
+
+#endif /* __ASM_AVR32_BITOPS_H */

+ 37 - 0
include/asm-avr32/byteorder.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_BYTEORDER_H
+#define __ASM_AVR32_BYTEORDER_H
+
+#include <asm/types.h>
+
+#define __arch__swab32(x) __builtin_bswap_32(x)
+#define __arch__swab16(x) __builtin_bswap_16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __BYTEORDER_HAS_U64__
+# define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* __ASM_AVR32_BYTEORDER_H */

+ 83 - 0
include/asm-avr32/cacheflush.h

@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_CACHEFLUSH_H
+#define __ASM_AVR32_CACHEFLUSH_H
+
+/*
+ * Invalidate any cacheline containing virtual address vaddr without
+ * writing anything back to memory.
+ *
+ * Note that this function may corrupt unrelated data structures when
+ * applied on buffers that are not cacheline aligned in both ends.
+ */
+static inline void dcache_invalidate_line(volatile void *vaddr)
+{
+	asm volatile("cache %0[0], 0x0b" : : "r"(vaddr) : "memory");
+}
+
+/*
+ * Make sure any cacheline containing virtual address vaddr is written
+ * to memory.
+ */
+static inline void dcache_clean_line(volatile void *vaddr)
+{
+	asm volatile("cache %0[0], 0x0c" : : "r"(vaddr) : "memory");
+}
+
+/*
+ * Make sure any cacheline containing virtual address vaddr is written
+ * to memory and then invalidate it.
+ */
+static inline void dcache_flush_line(volatile void *vaddr)
+{
+	asm volatile("cache %0[0], 0x0d" : : "r"(vaddr) : "memory");
+}
+
+/*
+ * Invalidate any instruction cacheline containing virtual address
+ * vaddr.
+ */
+static inline void icache_invalidate_line(volatile void *vaddr)
+{
+	asm volatile("cache %0[0], 0x01" : : "r"(vaddr) : "memory");
+}
+
+/*
+ * Applies the above functions on all lines that are touched by the
+ * specified virtual address range.
+ */
+void dcache_invalidate_range(volatile void *start, size_t len);
+void dcache_clean_range(volatile void *start, size_t len);
+void dcache_flush_range(volatile void *start, size_t len);
+void icache_invalidate_range(volatile void *start, size_t len);
+
+static inline void dcache_flush_unlocked(void)
+{
+	asm volatile("cache %0[5], 0x08" : : "r"(0) : "memory");
+}
+
+/*
+ * Make sure any pending writes are completed before continuing.
+ */
+#define sync_write_buffer() asm volatile("sync 0" : : : "memory")
+
+#endif /* __ASM_AVR32_CACHEFLUSH_H */

+ 39 - 0
include/asm-avr32/div64.h

@@ -0,0 +1,39 @@
+#ifndef _ASM_GENERIC_DIV64_H
+#define _ASM_GENERIC_DIV64_H
+/*
+ * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
+ * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
+ *
+ * The semantics of do_div() are:
+ *
+ * uint32_t do_div(uint64_t *n, uint32_t base)
+ * {
+ * 	uint32_t remainder = *n % base;
+ * 	*n = *n / base;
+ * 	return remainder;
+ * }
+ *
+ * NOTE: macro parameter n is evaluated multiple times,
+ *       beware of side effects!
+ */
+
+#include <linux/types.h>
+
+extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({				\
+	uint32_t __base = (base);			\
+	uint32_t __rem;					\
+	(void)(((typeof((n)) *)0) == ((uint64_t *)0));	\
+	if (((n) >> 32) == 0) {			\
+		__rem = (uint32_t)(n) % __base;		\
+		(n) = (uint32_t)(n) / __base;		\
+	} else 						\
+		__rem = __div64_32(&(n), __base);	\
+	__rem;						\
+ })
+
+#endif /* _ASM_GENERIC_DIV64_H */

+ 64 - 0
include/asm-avr32/dma-mapping.h

@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_DMA_MAPPING_H
+#define __ASM_AVR32_DMA_MAPPING_H
+
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+
+enum dma_data_direction {
+	DMA_BIDIRECTIONAL	= 0,
+	DMA_TO_DEVICE		= 1,
+	DMA_FROM_DEVICE		= 2,
+};
+extern void *dma_alloc_coherent(size_t len, unsigned long *handle);
+
+static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
+					   enum dma_data_direction dir)
+{
+	extern void __bad_dma_data_direction(void);
+
+	switch (dir) {
+	case DMA_BIDIRECTIONAL:
+		dcache_flush_range(vaddr, len);
+		break;
+	case DMA_TO_DEVICE:
+		dcache_clean_range(vaddr, len);
+		break;
+	case DMA_FROM_DEVICE:
+		dcache_invalidate_range(vaddr, len);
+		break;
+	default:
+		/* This will cause a linker error */
+		__bad_dma_data_direction();
+	}
+
+	return virt_to_phys(vaddr);
+}
+
+static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+				    unsigned long paddr)
+{
+
+}
+
+#endif /* __ASM_AVR32_DMA_MAPPING_H */

+ 132 - 0
include/asm-avr32/errno.h

@@ -0,0 +1,132 @@
+#ifndef _ASM_AVR32_ERRNO_H
+#define _ASM_AVR32_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Argument list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _ASM_AVR32_ERRNO_H */

+ 59 - 0
include/asm-avr32/global_data.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_GLOBAL_DATA_H__
+#define __ASM_GLOBAL_DATA_H__
+
+/*
+ * The following data structure is placed in some memory wich is
+ * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
+ * some locked parts of the data cache) to allow for a minimum set of
+ * global variables during system initialization (until we have set
+ * up the memory controller so that we can use RAM).
+ *
+ * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
+ */
+
+typedef	struct	global_data {
+	bd_t		*bd;
+	unsigned long	flags;
+	const struct device	*console_uart;
+	const struct device	*sm;
+	unsigned long	baudrate;
+	unsigned long	sdram_size;
+	unsigned long	have_console;	/* serial_init() was called */
+	unsigned long	reloc_off;	/* Relocation Offset */
+	unsigned long	env_addr;	/* Address of env struct */
+	unsigned long	env_valid;	/* Checksum of env valid? */
+	unsigned long	cpu_hz;		/* cpu core clock frequency */
+	void		**jt;		/* jump table */
+} gd_t;
+
+/*
+ * Global Data Flags
+ */
+#define GD_FLG_RELOC	0x00001		/* Code was relocated to RAM	 */
+#define GD_FLG_DEVINIT	0x00002		/* Devices have been initialized */
+#define GD_FLG_SILENT	0x00004		/* Silent mode			 */
+
+#define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm("r5")
+
+#endif /* __ASM_GLOBAL_DATA_H__ */

+ 33 - 0
include/asm-avr32/initcalls.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005, 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_INITCALLS_H__
+#define __ASM_AVR32_INITCALLS_H__
+
+#include <config.h>
+
+extern int cpu_init(void);
+extern int timer_init(void);
+extern void board_init_memories(void);
+extern void board_init_pio(void);
+extern void board_init_info(void);
+
+#endif /* __ASM_AVR32_INITCALLS_H__ */

+ 92 - 0
include/asm-avr32/io.h

@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_IO_H
+#define __ASM_AVR32_IO_H
+
+#ifdef __KERNEL__
+
+/*
+ * Generic IO read/write.  These perform native-endian accesses.  Note
+ * that some architectures will want to re-define __raw_{read,write}w.
+ */
+extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
+extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
+extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
+
+extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
+extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
+extern void __raw_readsl(unsigned int addr, void *data, int longlen);
+
+#define __raw_writeb(v,a)       (*(volatile unsigned char  *)(a) = (v))
+#define __raw_writew(v,a)       (*(volatile unsigned short *)(a) = (v))
+#define __raw_writel(v,a)       (*(volatile unsigned int   *)(a) = (v))
+
+#define __raw_readb(a)          (*(volatile unsigned char  *)(a))
+#define __raw_readw(a)          (*(volatile unsigned short *)(a))
+#define __raw_readl(a)          (*(volatile unsigned int   *)(a))
+
+/* As long as I/O is only performed in P4 (or possibly P3), we're safe */
+#define writeb(v,a)		__raw_writeb(v,a)
+#define writew(v,a)		__raw_writew(v,a)
+#define writel(v,a)		__raw_writel(v,a)
+
+#define readb(a)		__raw_readb(a)
+#define readw(a)		__raw_readw(a)
+#define readl(a)		__raw_readl(a)
+
+/*
+ * Bad read/write accesses...
+ */
+extern void __readwrite_bug(const char *fn);
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+/*
+ * All I/O is memory mapped, so these macros doesn't make very much sense
+ */
+#define outb(v,p)		__raw_writeb(v, p)
+#define outw(v,p)		__raw_writew(cpu_to_le16(v),p)
+#define outl(v,p)		__raw_writel(cpu_to_le32(v),p)
+
+#define inb(p)	({ unsigned int __v = __raw_readb(p); __v; })
+#define inw(p)	({ unsigned int __v = __le16_to_cpu(__raw_readw(p)); __v; })
+#define inl(p)	({ unsigned int __v = __le32_to_cpu(__raw_readl(p)); __v; })
+
+#include <asm/addrspace.h>
+
+/* virt_to_phys will only work when address is in P1 or P2 */
+static __inline__ unsigned long virt_to_phys(volatile void *address)
+{
+	return PHYSADDR(address);
+}
+
+static __inline__ void * phys_to_virt(unsigned long address)
+{
+	return (void *)P1SEGADDR(address);
+}
+
+#define cached(addr) ((void *)P1SEGADDR(addr))
+#define uncached(addr) ((void *)P2SEGADDR(addr))
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_AVR32_IO_H */

+ 144 - 0
include/asm-avr32/posix_types.h

@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_POSIX_TYPES_H
+#define __ASM_AVR32_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef  __FD_SET
+static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef  __FD_CLR
+static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+
+#undef  __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef  __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
+{
+	unsigned long *__tmp = __p->fds_bits;
+	int __i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 16:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			__tmp[ 8] = 0; __tmp[ 9] = 0;
+			__tmp[10] = 0; __tmp[11] = 0;
+			__tmp[12] = 0; __tmp[13] = 0;
+			__tmp[14] = 0; __tmp[15] = 0;
+			return;
+
+		case 8:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			return;
+
+		case 4:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			return;
+		}
+	}
+	__i = __FDSET_LONGS;
+	while (__i) {
+		__i--;
+		*__tmp = 0;
+		__tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* __ASM_AVR32_POSIX_TYPES_H */

+ 97 - 0
include/asm-avr32/processor.h

@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_PROCESSOR_H
+#define __ASM_AVR32_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+#define current_text_addr() ({ void *pc; __asm__("mov %0,pc" : "=r"(pc)); pc; })
+
+struct avr32_cpuinfo {
+	unsigned long loops_per_jiffy;
+};
+
+extern struct avr32_cpuinfo boot_cpu_data;
+
+#ifdef CONFIG_SMP
+extern struct avr32_cpuinfo cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+#endif
+
+/* TODO: Make configurable (2GB will serve as a reasonable default) */
+#define TASK_SIZE	0x80000000
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
+#define cpu_relax()		barrier()
+#define cpu_sync_pipeline()	asm volatile("sub pc, -2" : : : "memory")
+
+/* This struct contains the CPU context as stored by switch_to() */
+struct thread_struct {
+	unsigned long pc;
+	unsigned long ksp;	/* Kernel stack pointer */
+	unsigned long r7;
+	unsigned long r6;
+	unsigned long r5;
+	unsigned long r4;
+	unsigned long r3;
+	unsigned long r2;
+	unsigned long r1;
+	unsigned long r0;
+};
+
+#define INIT_THREAD {						\
+	.ksp = sizeof(init_stack) + (long)&init_stack,		\
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+#define start_thread(regs, new_pc, new_sp)	 \
+	set_fs(USER_DS);			 \
+	regs->sr = 0;		/* User mode. */ \
+	regs->gr[REG_PC] = new_pc;		 \
+	regs->gr[REG_SP] = new_sp
+
+struct task_struct;
+
+/* Free all resources held by a thread */
+extern void release_thread(struct task_struct *);
+
+/* Create a kernel thread without removing it from tasklists */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while(0)
+
+/* Return saved PC of a blocked thread */
+#define thread_saved_pc(tsk)    (tsk->thread.pc)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_AVR32_PROCESSOR_H */

+ 148 - 0
include/asm-avr32/ptrace.h

@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_PTRACE_H
+#define __ASM_AVR32_PTRACE_H
+
+/*
+ * Status Register bits
+ */
+#define SR_H		0x40000000
+#define SR_R		0x20000000
+#define SR_J		0x10000000
+#define SR_DM		0x08000000
+#define SR_D		0x04000000
+#define MODE_NMI	0x01c00000
+#define MODE_EXCEPTION	0x01800000
+#define MODE_INT3	0x01400000
+#define MODE_INT2	0x01000000
+#define MODE_INT1	0x00c00000
+#define MODE_INT0	0x00800000
+#define MODE_SUPERVISOR	0x00400000
+#define MODE_USER	0x00000000
+#define MODE_MASK	0x01c00000
+#define SR_EM		0x00200000
+#define SR_I3M		0x00100000
+#define SR_I2M		0x00080000
+#define SR_I1M		0x00040000
+#define SR_I0M		0x00020000
+#define SR_GM		0x00010000
+
+#define MODE_SHIFT	22
+#define SR_EM_BIT	21
+#define SR_I3M_BIT	20
+#define SR_I2M_BIT	19
+#define SR_I1M_BIT	18
+#define SR_I0M_BIT	17
+#define SR_GM_BIT	16
+
+/* The user-visible part */
+#define SR_Q		0x00000010
+#define SR_V		0x00000008
+#define SR_N		0x00000004
+#define SR_Z		0x00000002
+#define SR_C		0x00000001
+
+/*
+ * The order is defined by the stdsp instruction. r0 is stored first, so it
+ * gets the highest address.
+ *
+ * Registers 0-12 are general-purpose registers (r12 is normally used for
+ * the function return value).
+ * Register 13 is the stack pointer
+ * Register 14 is the link register
+ * Register 15 is the program counter
+ */
+#define FRAME_SIZE_FULL 72
+#define REG_R12_ORIG	68
+#define REG_R0		64
+#define REG_R1		60
+#define REG_R2		56
+#define REG_R3		52
+#define REG_R4		48
+#define REG_R5		44
+#define REG_R6		40
+#define REG_R7		36
+#define REG_R8		32
+#define REG_R9		28
+#define REG_R10		34
+#define REG_R11		20
+#define REG_R12		16
+#define REG_SP		12
+#define REG_LR		 8
+
+#define FRAME_SIZE_MIN	 8
+#define REG_PC		 4
+#define REG_SR		 0
+
+#ifndef __ASSEMBLY__
+struct pt_regs {
+	/* These are always saved */
+	unsigned long sr;
+	unsigned long pc;
+
+	/* These are sometimes saved */
+	unsigned long lr;
+	unsigned long sp;
+	unsigned long r12;
+	unsigned long r11;
+	unsigned long r10;
+	unsigned long r9;
+	unsigned long r8;
+	unsigned long r7;
+	unsigned long r6;
+	unsigned long r5;
+	unsigned long r4;
+	unsigned long r3;
+	unsigned long r2;
+	unsigned long r1;
+	unsigned long r0;
+
+	/* Only saved on system call */
+	unsigned long r12_orig;
+};
+
+#ifdef __KERNEL__
+# define user_mode(regs) (((regs)->sr & MODE_MASK) == MODE_USER)
+# define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs (struct pt_regs *);
+
+static __inline__ int valid_user_regs(struct pt_regs *regs)
+{
+	/*
+	 * Some of the Java bits might be acceptable if/when we
+	 * implement some support for that stuff...
+	 */
+	if ((regs->sr & 0xffff0000) == 0)
+		return 1;
+
+	/*
+	 * Force status register flags to be sane and report this
+	 * illegal behaviour...
+	 */
+	regs->sr &= 0x0000ffff;
+	return 0;
+}
+#endif
+
+#endif /* ! __ASSEMBLY__ */
+
+#endif /* __ASM_AVR32_PTRACE_H */

+ 33 - 0
include/asm-avr32/sdram.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_AVR32_SDRAM_H
+#define __ASM_AVR32_SDRAM_H
+
+struct sdram_info {
+	unsigned long phys_addr;
+	unsigned int row_bits, col_bits, bank_bits;
+	unsigned int cas, twr, trc, trp, trcd, tras, txsr;
+};
+
+extern unsigned long sdram_init(const struct sdram_info *info);
+
+#endif /* __ASM_AVR32_SDRAM_H */

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác